From 76e862060ec459fa175b50c05b4a866006bbb008 Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 12:41:06 -0400 Subject: [PATCH 01/16] Tidy up whitespace in java.base * remove trailing whitespace * indent with tabs consistently * avoid space before tab * collapse sequences of two or more blank lines * remove extra trailing blank lines Signed-off-by: Keith W. Campbell --- .../com/ibm/jit/BigDecimalConverters.java | 210 +- .../com/ibm/jit/BigDecimalExtension.java | 5680 ++++++++--------- .../share/classes/com/ibm/jit/JITHelpers.java | 1 - .../ibm/oti/reflect/TypeAnnotationParser.java | 8 +- .../share/classes/com/ibm/oti/util/Msg.java | 85 +- .../classes/com/ibm/oti/util/PriviAction.java | 265 +- .../com/ibm/oti/util/RuntimePermissions.java | 6 +- .../com/ibm/oti/util/WeakReferenceNode.java | 16 +- .../com/ibm/oti/vm/AbstractClassLoader.java | 9 +- .../com/ibm/oti/vm/BootstrapClassLoader.java | 6 +- .../com/ibm/oti/vm/J9UnmodifiableClass.java | 1 - .../classes/com/ibm/oti/vm/JarRunner.java | 17 +- .../share/classes/com/ibm/oti/vm/MsgHelp.java | 62 +- .../share/classes/com/ibm/oti/vm/ORBBase.java | 8 +- .../classes/com/ibm/oti/vm/VMLangAccess.java | 1 - .../share/classes/java/lang/Class.java | 76 +- .../classes/java/lang/ClassCastException.java | 14 +- .../share/classes/java/lang/ClassLoader.java | 3 - .../classes/java/lang/InstantiationError.java | 10 +- .../java/lang/InstantiationException.java | 14 +- .../lang/InternalAnonymousClassLoader.java | 6 +- .../classes/java/lang/J9VMInternals.java | 1 - .../classes/java/lang/RuntimePermission.java | 4 +- .../classes/java/lang/StackTraceElement.java | 35 +- .../share/classes/java/lang/String.java | 1 - .../share/classes/java/lang/System.java | 8 +- .../share/classes/java/lang/Thread.java | 10 - .../share/classes/java/lang/ThreadGroup.java | 3 +- .../share/classes/java/lang/Throwable.java | 1 - .../share/classes/java/lang/VMAccess.java | 1 - .../lang/invoke/ArgumentConversionHandle.java | 1 - .../java/lang/invoke/AsTypeHandle.java | 5 +- .../java/lang/invoke/BoundMethodHandle.java | 12 +- .../lang/invoke/BruteArgumentMoverHandle.java | 57 +- .../classes/java/lang/invoke/CacheKey.java | 6 +- .../classes/java/lang/invoke/CallSite.java | 30 +- .../classes/java/lang/invoke/CatchHandle.java | 3 +- .../java/lang/invoke/CollectHandle.java | 10 +- .../java/lang/invoke/ConstantCallSite.java | 23 +- .../java/lang/invoke/ConstructorHandle.java | 17 +- .../java/lang/invoke/ConvertHandle.java | 109 +- .../DefaultMethodConflictException.java | 5 +- .../java/lang/invoke/DirectHandle.java | 77 +- .../lang/invoke/DynamicInvokerHandle.java | 2 +- .../java/lang/invoke/ExplicitCastHandle.java | 3 +- .../java/lang/invoke/FieldGetterHandle.java | 7 +- .../classes/java/lang/invoke/FieldHandle.java | 20 +- .../java/lang/invoke/FieldSetterHandle.java | 13 +- .../java/lang/invoke/FilterReturnHandle.java | 2 +- .../classes/java/lang/invoke/FoldHandle.java | 14 +- .../java/lang/invoke/GuardWithTestHandle.java | 14 +- .../classes/java/lang/invoke/HandleCache.java | 30 +- .../java/lang/invoke/IndirectHandle.java | 25 +- .../java/lang/invoke/Insert1Handle.java | 9 +- .../java/lang/invoke/Insert1IntHandle.java | 8 +- .../java/lang/invoke/Insert2Handle.java | 9 +- .../java/lang/invoke/Insert3Handle.java | 9 +- .../java/lang/invoke/InsertHandle.java | 2 +- .../java/lang/invoke/InterfaceHandle.java | 14 +- .../java/lang/invoke/InvokeExactHandle.java | 5 +- .../java/lang/invoke/InvokeGenericHandle.java | 12 +- .../java/lang/invoke/LambdaFormEditor.java | 4 +- .../classes/java/lang/invoke/LoopHandle.java | 1 - .../java/lang/invoke/MethodHandle.java | 15 +- .../java/lang/invoke/MethodHandleCache.java | 14 +- .../java/lang/invoke/MethodHandleInfo.java | 67 +- .../java/lang/invoke/MethodHandleNatives.java | 10 +- .../lang/invoke/MethodHandleResolver.java | 2 - .../java/lang/invoke/MethodHandles.java | 10 +- .../classes/java/lang/invoke/MethodType.java | 6 - .../MutableCallSiteDynamicInvokerHandle.java | 9 +- .../java/lang/invoke/PassThroughHandle.java | 8 +- .../java/lang/invoke/PermuteHandle.java | 44 +- .../java/lang/invoke/PrimitiveHandle.java | 50 +- .../java/lang/invoke/ReceiverBoundHandle.java | 47 +- .../java/lang/invoke/SecurityFrame.java | 13 +- .../java/lang/invoke/SimpleMethodHandle.java | 6 +- .../java/lang/invoke/SpreadHandle.java | 4 +- .../lang/invoke/StaticFieldGetterHandle.java | 9 +- .../lang/invoke/StaticFieldSetterHandle.java | 7 +- .../lang/invoke/VMCONSTANTPOOL_CLASS.java | 1 - .../lang/invoke/VMCONSTANTPOOL_FIELD.java | 1 - .../lang/invoke/VMCONSTANTPOOL_METHOD.java | 1 - .../invoke/VarHandleInvokeGenericHandle.java | 1 - .../lang/invoke/VarargsCollectorHandle.java | 32 +- .../java/lang/invoke/VirtualHandle.java | 13 +- .../java/lang/invoke/VolatileCallSite.java | 19 +- .../lang/invoke/WrongMethodTypeException.java | 11 +- .../classes/java/lang/ref/FinalReference.java | 2 +- .../java/lang/ref/PhantomReference.java | 10 +- .../classes/java/lang/ref/ReferenceQueue.java | 28 +- .../classes/java/lang/ref/SoftReference.java | 8 +- .../classes/java/lang/ref/WeakReference.java | 2 +- .../classes/java/lang/reflect/Array.java | 276 +- .../classes/jdk/internal/misc/Unsafe.java | 1 - .../tools/attach/target/Advertisement.java | 29 +- .../tools/attach/target/AttachHandler.java | 1 - .../attach/target/AttachmentConnection.java | 10 +- .../tools/attach/target/CommonDirectory.java | 42 +- .../tools/attach/target/DiagnosticUtils.java | 2 +- .../tools/attach/target/FileLock.java | 12 +- .../tools/attach/target/FilelockTimer.java | 4 +- .../IbmAttachOperationFailedException.java | 9 +- .../internal/tools/attach/target/Reply.java | 6 +- .../tools/attach/target/TargetDirectory.java | 40 +- .../tools/attach/target/WaitLoop.java | 20 +- .../tools/attach/target/package-info.java | 26 +- .../InvalidDumpOptionExceptionBase.java | 2 +- 108 files changed, 3946 insertions(+), 4104 deletions(-) diff --git a/jcl/src/java.base/share/classes/com/ibm/jit/BigDecimalConverters.java b/jcl/src/java.base/share/classes/com/ibm/jit/BigDecimalConverters.java index 5ddceff9e69..0056a76cc6d 100644 --- a/jcl/src/java.base/share/classes/com/ibm/jit/BigDecimalConverters.java +++ b/jcl/src/java.base/share/classes/com/ibm/jit/BigDecimalConverters.java @@ -28,119 +28,119 @@ public class BigDecimalConverters extends BigDecimalExtension { - public static BigDecimal signedPackedDecimalToBigDecimal(byte[] packedDecimal, int scale) - { - if (DFPFacilityAvailable() && DFPUseDFP() && - (packedDecimal.length <= 8 && -scale >= -398 && -scale < 369)) - { - // fast conversion with hardware packed to DFP instruction - long longPack = 0; - if (packedDecimal.length == 8) - { - // explicitly unrolled loop to take advantage of sequential load - longPack = ((long)(packedDecimal[0] & 0xFF) << 56) - + ((long)(packedDecimal[1] & 0xFF) << 48) - + ((long)(packedDecimal[2] & 0xFF) << 40) - + ((long)(packedDecimal[3] & 0xFF) << 32) - + ((long)(packedDecimal[4] & 0xFF) << 24) - + ((long)(packedDecimal[5] & 0xFF) << 16) - + ((long)(packedDecimal[6] & 0xFF) << 8) - + ((long)(packedDecimal[7] & 0xFF)); - } - else - { - // slow way to load value into dfp - for(int i = 0; i < packedDecimal.length; ++i) - { - longPack = longPack << 8; - longPack += ((long)(packedDecimal[i] & 0xFF)); - } - } + public static BigDecimal signedPackedDecimalToBigDecimal(byte[] packedDecimal, int scale) + { + if (DFPFacilityAvailable() && DFPUseDFP() && + (packedDecimal.length <= 8 && -scale >= -398 && -scale < 369)) + { + // fast conversion with hardware packed to DFP instruction + long longPack = 0; + if (packedDecimal.length == 8) + { + // explicitly unrolled loop to take advantage of sequential load + longPack = ((long)(packedDecimal[0] & 0xFF) << 56) + + ((long)(packedDecimal[1] & 0xFF) << 48) + + ((long)(packedDecimal[2] & 0xFF) << 40) + + ((long)(packedDecimal[3] & 0xFF) << 32) + + ((long)(packedDecimal[4] & 0xFF) << 24) + + ((long)(packedDecimal[5] & 0xFF) << 16) + + ((long)(packedDecimal[6] & 0xFF) << 8) + + ((long)(packedDecimal[7] & 0xFF)); + } + else + { + // slow way to load value into dfp + for(int i = 0; i < packedDecimal.length; ++i) + { + longPack = longPack << 8; + longPack += ((long)(packedDecimal[i] & 0xFF)); + } + } - BigDecimal bd = createZeroBigDecimal(); - if (DFPConvertPackedToDFP(bd, longPack, 398 - scale, true)) - { - // successfully converted to dfp - setflags(bd, 0x00); - return bd; - } - } - return slowSignedPackedToBigDecimal(packedDecimal, scale); - } + BigDecimal bd = createZeroBigDecimal(); + if (DFPConvertPackedToDFP(bd, longPack, 398 - scale, true)) + { + // successfully converted to dfp + setflags(bd, 0x00); + return bd; + } + } + return slowSignedPackedToBigDecimal(packedDecimal, scale); + } - private static BigDecimal slowSignedPackedToBigDecimal(byte[] packedDecimal, int scale) - { - String buffer = new String(); - // convert the packed decimal to string buffer - for(int i = 0; i < packedDecimal.length - 1; ++i) - { - buffer += ((packedDecimal[i] & 0xF0) >> 4) + "" + (packedDecimal[i] & 0x0F); //$NON-NLS-1$ - } - buffer += ((packedDecimal[packedDecimal.length - 1] & 0xF0) >> 4); + private static BigDecimal slowSignedPackedToBigDecimal(byte[] packedDecimal, int scale) + { + String buffer = new String(); + // convert the packed decimal to string buffer + for(int i = 0; i < packedDecimal.length - 1; ++i) + { + buffer += ((packedDecimal[i] & 0xF0) >> 4) + "" + (packedDecimal[i] & 0x0F); //$NON-NLS-1$ + } + buffer += ((packedDecimal[packedDecimal.length - 1] & 0xF0) >> 4); - // check to see if the packed decimal is negative - byte sign = (byte)(packedDecimal[packedDecimal.length - 1] & 0x0F); - if (sign == 0x0B || sign == 0x0D) - { - buffer = "-" + buffer; //$NON-NLS-1$ - } - return new BigDecimal(new BigInteger(new String(buffer)), scale); - } + // check to see if the packed decimal is negative + byte sign = (byte)(packedDecimal[packedDecimal.length - 1] & 0x0F); + if (sign == 0x0B || sign == 0x0D) + { + buffer = "-" + buffer; //$NON-NLS-1$ + } + return new BigDecimal(new BigInteger(new String(buffer)), scale); + } - public static byte[] BigDecimalToSignedPackedDecimal(BigDecimal bd) - { - if (DFPFacilityAvailable() && ((getflags(bd) & 0x3) == 0x0)) - { - long longPack = DFPConvertDFPToPacked(getlaside(bd), true); - if (longPack != Long.MAX_VALUE) - { - // conversion from DFP to packed decimal was successful - byte [] packedDecimal = new byte[8]; - packedDecimal[0] = (byte)((longPack >> 56) & 0xFF); - packedDecimal[1] = (byte)((longPack >> 48) & 0xFF); - packedDecimal[2] = (byte)((longPack >> 40) & 0xFF); - packedDecimal[3] = (byte)((longPack >> 32) & 0xFF); - packedDecimal[4] = (byte)((longPack >> 24) & 0xFF); - packedDecimal[5] = (byte)((longPack >> 16) & 0xFF); - packedDecimal[6] = (byte)((longPack >> 8) & 0xFF); - packedDecimal[7] = (byte)((longPack) & 0xFF); - return packedDecimal; - } - } + public static byte[] BigDecimalToSignedPackedDecimal(BigDecimal bd) + { + if (DFPFacilityAvailable() && ((getflags(bd) & 0x3) == 0x0)) + { + long longPack = DFPConvertDFPToPacked(getlaside(bd), true); + if (longPack != Long.MAX_VALUE) + { + // conversion from DFP to packed decimal was successful + byte[] packedDecimal = new byte[8]; + packedDecimal[0] = (byte)((longPack >> 56) & 0xFF); + packedDecimal[1] = (byte)((longPack >> 48) & 0xFF); + packedDecimal[2] = (byte)((longPack >> 40) & 0xFF); + packedDecimal[3] = (byte)((longPack >> 32) & 0xFF); + packedDecimal[4] = (byte)((longPack >> 24) & 0xFF); + packedDecimal[5] = (byte)((longPack >> 16) & 0xFF); + packedDecimal[6] = (byte)((longPack >> 8) & 0xFF); + packedDecimal[7] = (byte)((longPack) & 0xFF); + return packedDecimal; + } + } - // slow path to manually convert BigDecimal to packed decimal - return slowBigDecimalToSignedPacked(bd); - } + // slow path to manually convert BigDecimal to packed decimal + return slowBigDecimalToSignedPacked(bd); + } - private static byte [] slowBigDecimalToSignedPacked(BigDecimal bd) - { - // digits are right justified in the return byte array - BigInteger value = bd.unscaledValue(); - char [] buffer = value.abs().toString().toCharArray(); - int size = buffer.length / 2 + 1; - byte [] packedDecimal = new byte[size]; + private static byte[] slowBigDecimalToSignedPacked(BigDecimal bd) + { + // digits are right justified in the return byte array + BigInteger value = bd.unscaledValue(); + char[] buffer = value.abs().toString().toCharArray(); + int size = buffer.length / 2 + 1; + byte[] packedDecimal = new byte[size]; - int numDigitsLeft= buffer.length - 1; - int endPosition = numDigitsLeft % 2; - int index = size - 2; + int numDigitsLeft= buffer.length - 1; + int endPosition = numDigitsLeft % 2; + int index = size - 2; - // take care of the sign nibble and the right most digit - packedDecimal[size - 1] = (byte)((buffer[numDigitsLeft] - '0') << 4); - packedDecimal[size - 1] |= ((value.signum() == -1) ? 0x0D : 0x0C); + // take care of the sign nibble and the right most digit + packedDecimal[size - 1] = (byte)((buffer[numDigitsLeft] - '0') << 4); + packedDecimal[size - 1] |= ((value.signum() == -1) ? 0x0D : 0x0C); - // compact 2 digits into each byte - for(int i = numDigitsLeft - 1; i >= endPosition; i -= 2, --index) - { - packedDecimal[index] = (byte)(buffer[i] - '0'); - packedDecimal[index] |= (byte)((buffer[i - 1] - '0') << 4); - } + // compact 2 digits into each byte + for (int i = numDigitsLeft - 1; i >= endPosition; i -= 2, --index) + { + packedDecimal[index] = (byte)(buffer[i] - '0'); + packedDecimal[index] |= (byte)((buffer[i - 1] - '0') << 4); + } - // if there's a left over digit, put it in the last byte - if(endPosition > 0) - { - packedDecimal[index] = (byte)(buffer[0] - '0'); - } + // if there's a left over digit, put it in the last byte + if (endPosition > 0) + { + packedDecimal[index] = (byte)(buffer[0] - '0'); + } - return packedDecimal; - } - } + return packedDecimal; + } +} diff --git a/jcl/src/java.base/share/classes/com/ibm/jit/BigDecimalExtension.java b/jcl/src/java.base/share/classes/com/ibm/jit/BigDecimalExtension.java index 89146b172bd..e7f79134df1 100644 --- a/jcl/src/java.base/share/classes/com/ibm/jit/BigDecimalExtension.java +++ b/jcl/src/java.base/share/classes/com/ibm/jit/BigDecimalExtension.java @@ -30,2873 +30,2821 @@ */ public class BigDecimalExtension implements java.math.BigDecimal.BigDecimalExtension { - // Used to keep behavior of DFPHWAvailable consistent between - // jitted code and interpreter - // DO NOT CHANGE OR MOVE THIS LINE - // IT MUST BE THE FIRST THING IN THE INITIALIZATION - private static final boolean DFP_HW_AVAILABLE = DFPCheckHWAvailable(); - - /* - * public static final int ROUND_CEILING 2 - * DFP hardware uses the value 010 == 2 - * public static final int ROUND_DOWN 1 - * DFP hardware uses the value 001 = 1 - * public static final int ROUND_FLOOR 3 - * DFP hardware uses the value 011 = 3 - * public static final int ROUND_HALF_DOWN 5 - * DFP hardware uses the value 101 = 5 - * public static final int ROUND_HALF_EVEN 6 <--mismatch in HW/Classlib spec - * DFP hardware uses the value 000 = 0 - * public static final int ROUND_HALF_UP 4 - * DFP hardware uses the value 100 = 4 - * public static final int ROUND_UNNECESSARY 7 - * DFP hardware uses the value 111 = 7 - * public static final int ROUND_UP 0 <--mismatch in HW/Classlib spec - * DFP hardware uses the value 110 = 6 - */ - - /** - * LUT for DFP double combination field - gives us the leftmost - * digit of the coefficient, as well as the first two bits of the - * exponent in form: 0xXY where X = LMD, Y = first two bits - */ - private static byte []doubleDFPComboField = comboinit(); - - // LUT for converting DPD to BCD, 1024 elements - private static short []DPD2BCD = dpd2bcdinit(); - - // DFP 0 with exponent 0 - private static final long dfpZERO = 2465720795985346560L; - - private static final BigInteger MAXDFP64 = BigInteger.valueOf(9999999999999999L); - private static final BigInteger MINDFP64 = BigInteger.valueOf(-9999999999999999L); - - /* Used for Hysteresis for mixed-representation - * We want the BigDecimal class to choose the best representation - * for construction and operations. We start assuming the LL - * is the best representation. Over the course of time, using - * hysterisis, we might alter this decision. - * - * The constructors are annotated with the checks on deciding - * which representation to use, and other APIs contribute - * to biasing towards or away from a representation. - * - * NOTE: Hysterisis only works on platforms that supports DFP - * since we prepend a DFPHWAvailable check before performing - * mods to the counters, and before basing decisions off them. - */ - private static int hys_threshold = 1000; // threshold for representation change - // above means that hys_counter must reach -/+ MAX_VALUE before changing rep - private static boolean hys_type; // false = non-dfp, true = dfp - private static int hys_counter; // increment for dfp, decrement for non-dfp - - private static BigDecimalExtension instance; - - protected BigDecimalExtension() { - } - - public static BigDecimalExtension getInstance() { - if (instance == null) { - instance = new BigDecimalExtension(); - } - return instance; - } - - public boolean performHardwareUsageHeuristic(MathContext set, int bias) { - if (DFPPerformHysteresis() && - set.getPrecision() == 16 && set.getRoundingMode().ordinal() == BigDecimal.ROUND_HALF_EVEN){ - performHardwareUsageHeuristic(bias); - return true; - } - return false; - } - - private void performHardwareUsageHeuristic(int bias) { - int sum = hys_counter + bias; - hys_counter += bias & ~(((sum^bias) & (sum^hys_counter)) >>> 31); - - if (hys_counter<-hys_threshold){ - hys_type = false; //nonDFP - hys_counter=0; - } - else if (hys_counter>hys_threshold){ - hys_type = true; // DFP - hys_counter=0; - } - } - - public boolean isAvailable() { - return DFPHWAvailable(); - } - - public boolean useExtension() { - return DFPUseDFP(); - } - - public boolean suitableForExtension(int nDigits, int scale) { - return (nDigits < 17 && scale >= -398 && scale < 369); - } - - public int add(BigDecimal res, BigDecimal lhs, BigDecimal rhs) { - int resExp =-(Math.max(lhs.scale(), rhs.scale())); - /* Precision = 0, rounding = UNNECESSARY */ - if (resExp >=-398 && resExp<=369){ - if(DFPScaledAdd(res, getlaside(rhs), getlaside(lhs), resExp+398)){ - // we can and out the flags because we don't have - // a sense of the exponent/precision/sign - // of this result, nor do we want to use DFP hw - // to figure it out, so we do not cache anything - - //set res as DFP - (already set to 00) - - // because DFP add takes the exclusive or of the sign bits - //for the result, need to make sure result of add 0 by -0 - //doesn't store a negative sign... - long laside = getlaside(res); - if(isDFPZero(laside)) { - laside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, laside); - } - return HARDWARE_OPERATION_SUCCESS; - } - } - return HARDWARE_OPERATION_FAIL; - } - - public int add(BigDecimal res, BigDecimal lhs, BigDecimal rhs, MathContext set) { - boolean passed = false; - int prec = set.getPrecision(); - int rm = set.getRoundingMode().ordinal(); - long lhslaside = getlaside(lhs); - long rhslaside = getlaside(rhs); - - // need to special case this since DFP hardware - // doesn't conform to BigDecimal API when adding - // to a 0.. - if (prec != 0 && set.getRoundingMode().ordinal() != BigDecimal.ROUND_UNNECESSARY){ - boolean lZero = isDFPZero(lhslaside); - boolean rZero = isDFPZero(rhslaside); - - if(lZero || rZero) { - if(!lZero) { - clone(lhs, res); // rhs is zero - if (rhs.scale() > lhs.scale()){ - if (set.getPrecision()-rhs.precision() >0) { - clone(res.setScale(Math.abs(-rhs.scale())), res); //might return BI - } - } - } else if (!rZero) { - clone(rhs, res); // lhs is zero - if (lhs.scale() > rhs.scale()){ - if (set.getPrecision()-rhs.precision() >0) { - clone(res.setScale(Math.abs(-lhs.scale())), res); //might return BI - } - } - } else { - BigDecimal temp = BigDecimal.valueOf(0, Math.max(lhs.scale(), rhs.scale())); // both operands are zero - clone(temp, res); //CMVC 136111 -- res could be one of statics (shared) - } - - if (set != MathContext.UNLIMITED) { - if(finish(res, set.getPrecision(), set.getRoundingMode().ordinal()) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - - } - return HARDWARE_OPERATION_SUCCESS; - } - } - - // we can and out the flags because we don't have - // a sense of the exponent/precision/sign - // of this result, nor do we want to use DFP hw - // to figure it out, so we do not cache anything - - // fast path for MathContext64 - if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN){ - if(DFPAdd(res, rhslaside, lhslaside, 64, 0, 0)){ - passed =true; - } - } else if (prec == 0) { // same as scaled DFPAddition - int resExp =-(Math.max(lhs.scale(), rhs.scale())); - if (resExp >=-398 && resExp <= 369){ - if(DFPScaledAdd(res, rhslaside, lhslaside, resExp+398)){ - //set res as DFP - (already set to 00) - passed = true; - } - } - } else if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY){ // fast path for NO ROUNDING, as well as the ArithmeticException - if(DFPAdd(res, rhslaside, lhslaside, 0, 0, 0)){ - performHardwareUsageHeuristic(set, -3); - // set res as DFP - (already set to 00) - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { // See if we need to throw an arithmetic exception - return HARDWARE_OPERATION_FAIL; - } - passed = true; - } - } else if (prec <=16) { // Otherwise, if a precision to round to is specified - - // NOTE: We do the following two if statements - // since the constants used for HALF_EVEN and ROUND_UP in - // the classlib do not map correctly to the DFP hardware - // rounding mode bits. All other classlib RoundingModes, however, do. - - //the default DFP rounding mode - if (rm == BigDecimal.ROUND_HALF_EVEN) - rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - else if (rm == BigDecimal.ROUND_UP) - rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - - // defect 144394 - boolean dfpPassed = prec == 16 ? - DFPAdd(res, rhslaside, lhslaside, 1, 16, rm) : - DFPAdd(res, rhslaside, lhslaside, 1, prec, rm); - if(dfpPassed){ - performHardwareUsageHeuristic(set, -3); - // set res as DFP - (already set to 00) - passed=true; - } - } - - // because DFP add takes the exclusive or of the sign bits - //for the result, need to make sure result of add 0 by -0 - //doesn't store a negative sign... - if (passed){ - long reslaside = getlaside(res); - if(isDFPZero(reslaside)) { - reslaside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, reslaside); - } - return HARDWARE_OPERATION_SUCCESS; - } - return HARDWARE_OPERATION_FAIL; - } - - public int subtract(BigDecimal res, BigDecimal lhs, BigDecimal rhs) { - - int resExp =-(Math.max(lhs.scale(), rhs.scale())); - // Precision = 0, rounding = UNNECESSARY - if (resExp >=-398 && resExp<=369){ - if(DFPScaledSubtract(res, getlaside(rhs), getlaside(lhs), resExp+398)){ - // set res as DFP - (already set to 00) - - // because DFP subtract takes the exclusive or of the sign bits - //for the result, need to make sure result of subtract 0 by -0 - //doesn't store a negative sign... - long laside = getlaside(res); - if(isDFPZero(laside)) { - laside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, laside); - } - return HARDWARE_OPERATION_SUCCESS; - - } - } - return HARDWARE_OPERATION_FAIL; - } - - public int subtract(BigDecimal res, BigDecimal lhs, BigDecimal rhs, MathContext set) { - boolean passed = false; - int prec = set.getPrecision(); - int rm = set.getRoundingMode().ordinal(); - long lhslaside = getlaside(lhs); - long rhslaside = getlaside(rhs); - - // need to special case this since DFP hardware - // doesn't conform to BigDecimal API when adding - // to a 0.. - if (prec != 0 && set.getRoundingMode().ordinal() != BigDecimal.ROUND_UNNECESSARY){ - boolean lZero = isDFPZero(lhslaside); - boolean rZero = isDFPZero(rhslaside); - if(lZero || rZero) { - if(!lZero) { - clone(lhs, res); // rhs is zero - if (rhs.scale() > lhs.scale()){ - if (set.getPrecision()-rhs.precision() >0) { - clone(res.setScale(Math.abs(-rhs.scale())), res); //might return BI - } - } - } else if (!rZero) { - clone(rhs.negate(), res); // lhs is zero - if (lhs.scale() > rhs.scale()){ - if (set.getPrecision()-rhs.precision() >0) { - clone(res.setScale(Math.abs(-lhs.scale())), res); //might return BI - } - } - } else { - BigDecimal temp = BigDecimal.valueOf(0, Math.max(lhs.scale(), rhs.scale())); // both operands are zero - clone(temp, res); //CMVC 136111 -- res could be one of statics (shared) - } - - if (set != MathContext.UNLIMITED) { - if(finish(res, set.getPrecision(), set.getRoundingMode().ordinal()) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - } - return HARDWARE_OPERATION_SUCCESS; - } - } - - - - // at this point, not dealing with 0s - // fast path for MathContext64 - if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN){ - if(DFPSubtract(res, rhslaside, lhslaside, 64, 0, 0)){ - // set res as DFP - (already set to 00) - passed=true; - } - } else if (prec == 0){ // same as DFPScaledSubtract - int resExp =-(Math.max(lhs.scale(), rhs.scale())); - if (resExp >=-398 && resExp<=369){ - if(DFPScaledSubtract(res, rhslaside, lhslaside, resExp+398)){ - // we can and out the flags because we don't have - // a sense of the exponent/precision/sign - // of this result, nor do we want to use DFP hw - // to figure it out, so we do not cache anything - - // set res as DFP - (already set to 00) - passed = true; - } - } - } else if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY){ // fast path for NO ROUNDING, as well as the ArithmeticException - if(DFPSubtract(res, rhslaside, lhslaside, 0, 0, 0)){ - performHardwareUsageHeuristic(set, -3); - // set res as DFP - (already set to 00) - // See if we need to throw an arithmetic exception - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - passed=true; - } - } else if(prec <=16){ // Otherwise, if a precision to round to is specified - - /* NOTE: We do the following two if statements - * since the constants used for HALF_EVEN and ROUND_UP in - * the classlib do not map correctly to the DFP hardware - * rounding mode bits. All other classlib RoundingModes, however, do. - */ - - //the default DFP rounding mode - if (rm == BigDecimal.ROUND_HALF_EVEN) { - rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (rm == BigDecimal.ROUND_UP) { - rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - // defect 144394 - boolean dfpPassed = prec == 16 ? - DFPSubtract(res, rhslaside, lhslaside, 1, 16, rm) : - DFPSubtract(res, rhslaside, lhslaside, 1, prec, rm); - if(dfpPassed){ - performHardwareUsageHeuristic(set, -3); - // set res as DFP - (already set to 00) - passed=true; - } - } - - // because DFP subtracts takes the exclusive or of the sign bits - //for the result, need to make sure result of subtract 0 by -0 - //doesn't store a negative sign... - if (passed){ - long reslaside = getlaside(res); - if(isDFPZero(reslaside)) { - reslaside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, reslaside); - } - return HARDWARE_OPERATION_SUCCESS; - } - return HARDWARE_OPERATION_FAIL; - } - - public int multiply(BigDecimal res, BigDecimal lhs, BigDecimal rhs) { - - int resExp =-(lhs.scale()+rhs.scale()); - - /* Precision = 0, rounding = UNNECESSARY */ - if (resExp >=-398 && resExp<=369){ - if(DFPScaledMultiply(res, getlaside(rhs), getlaside(lhs), resExp+398)){ - // set res as DFP - (already set to 00) - - // because DFP subtract takes the exclusive or of the sign bits - //for the result, need to make sure result of subtract 0 by -0 - //doesn't store a negative sign... - long laside = getlaside(res); - if(isDFPZero(laside)) { - laside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, laside); - } - return HARDWARE_OPERATION_SUCCESS; - } - } - return HARDWARE_OPERATION_FAIL; - } - - public int multiply(BigDecimal res, BigDecimal lhs, BigDecimal rhs, MathContext set) { - - boolean passed = false; - int prec = set.getPrecision(); - int rm = set.getRoundingMode().ordinal(); - long lhslaside = getlaside(lhs); - long rhslaside = getlaside(rhs); - - - // fast path for MathContext64 - if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN){ - if(DFPMultiply(res, rhslaside, lhslaside, 64, 0, 0)){ - // set res as DFP - (already set to 00) - passed = true; - } - } else if (prec == 0){ // same as DFPScaledMultiply - int resExp =-(lhs.scale()+rhs.scale()); - if (resExp >=-398 && resExp<=369){ - if(DFPScaledMultiply(res, rhslaside, lhslaside, resExp+398)){ - // set res as DFP - (already set to 00) - // because DFP multiply takes the exclusive or of the sign bits - //for the result, need to make sure result of multiply by 0 - //doesn't store a negative sign... - passed = true; - } - } - } else if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY){ // fast path for NO ROUNDING, as well as the ArithmeticException - if(DFPMultiply(res, rhslaside, lhslaside, 0, 0, 0)){ - // set res as DFP - (already set to 00) - - // See if we need to throw an arithmetic exception - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - passed=true; - } - } else if (prec <= 16) { // Otherwise, if a precision to round to is specified - /* NOTE: We do the following two if statements - * since the constants used for HALF_EVEN and ROUND_UP in - * the classlib do not map correctly to the DFP hardware - * rounding mode bits. All other classlib RoundingModes, however, do. - */ - - //the default DFP rounding mode - if (rm == BigDecimal.ROUND_HALF_EVEN) { - rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (rm == BigDecimal.ROUND_UP) { - rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - - // defect 144394 - boolean dfpPassed = prec == 16 ? - DFPMultiply(res, rhslaside, lhslaside, 1, 16, rm) : - DFPMultiply(res, rhslaside, lhslaside, 1, prec, rm); - if(dfpPassed) { - // set res as DFP - (already set to 00) - passed =true; - } - } - - // because DFP multiply takes the exclusive or of the sign bits - // for the result, need to make sure result of multiply by 0 - // doesn't store a negative sign... - if (passed){ - long reslaside = getlaside(res); - if(isDFPZero(reslaside)) { - reslaside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, reslaside); - } - return HARDWARE_OPERATION_SUCCESS; - } - return HARDWARE_OPERATION_FAIL; - } - - public int divide(BigDecimal res, BigDecimal lhs, BigDecimal rhs) { - - long rhslaside = getlaside(rhs); - if(isDFPZero(rhslaside)) { - badDivideByZero(); - } - boolean passed = false; - long lhslaside = getlaside(lhs); - - /* - * Interpreted return value: - * Returns -1 if not JIT compiled. - * - * JIT compiled return value: - * Return 1 if JIT compiled and DFP divide is successful. - * Return 0 if JIT compiled, but DFP divide was inexact - * Return -2 if JIT compiled, but other exception (i.e. overflow) - */ - - // we need this in order to throw a "non-terminating decimal expansion" error - int desiredPrecision = (int)Math.min(lhs.precision() + Math.ceil(10*rhs.precision()/3),Integer.MAX_VALUE); - - int ret = DFPDivide(res, rhslaside, lhslaside, true, 0, 0, 0); - - // we passed, just check for non-terminating decimal expansion - if (ret == 1){ - if (res.precision() > desiredPrecision) { - /*[MSG "K0460", "Non-terminating decimal expansion"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0460")); //$NON-NLS-1$ - } - // set res as DFP - (already set to 00) - passed=true; - } - - //otherwise, we had an inexact, or failure... so we'll continue on slow path - - // because DFP divide takes the exclusive or of the sign bits - //for the result, need to make sure result of multiply by 0 - //doesn't store a negative sign... - if (passed){ - long reslaside = getlaside(res); - if(isDFPZero(reslaside)) { - reslaside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, reslaside); - } - return HARDWARE_OPERATION_SUCCESS; - } - - return HARDWARE_OPERATION_FAIL; - } - - public int divide(BigDecimal res, BigDecimal lhs, BigDecimal rhs, MathContext set) { - - long rhslaside = getlaside(rhs); - if(isDFPZero(rhslaside)) { - badDivideByZero(); - } - long lhslaside = getlaside(lhs); - int prec = set.getPrecision(); - int rm = set.getRoundingMode().ordinal(); - boolean passed=false; - - // fast path for MathContext64 - if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN){ - int ret = DFPDivide(res, rhslaside, lhslaside, false, 64, 0, 0); - if (ret == 1){ - // set res as DFP - (already set to 00) - passed = true; - } - } else if (prec <= 16) { - - //the default DFP rounding mode - if (rm == BigDecimal.ROUND_HALF_EVEN) { - rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (rm == BigDecimal.ROUND_UP) { - rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - - // defect 144394 - int ret = prec == 16 ? - DFPDivide(res, rhslaside, lhslaside, true, 1, 16, rm) : - DFPDivide(res, rhslaside, lhslaside, true, 1, prec, rm); - if (ret == 0 && rm == BigDecimal.ROUND_UNNECESSARY) { - /*[MSG "K0461", "Inexact result requires rounding"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0461")); //$NON-NLS-1$ - } - //otherwise, we divide perfectly and returned 1, or divided - //and got inexact (in the absence of checking for ROUND_UNNECESSARY - //but that's ok because we had: - // REREOUND + TGDT + CHECKINEXACT - - //d120228 - if (ret == 1){ - performHardwareUsageHeuristic(set, 10); - // set res as DFP - (already set to 00) - passed = true; - } - } - // because DFP divide takes the exclusive or of the sign bits - //for the result, need to make sure result of multiply by 0 - //doesn't store a negative sign... - if (passed){ - long reslaside = getlaside(res); - if(isDFPZero(reslaside)) { - reslaside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, reslaside); - } - return HARDWARE_OPERATION_SUCCESS; - } - - return HARDWARE_OPERATION_FAIL; - } - - public int negate(BigDecimal res, MathContext set) { - - int signum = res.signum(); - int flags = getflags(res); - long laside = getlaside(res); - // we're going to cache a new sign bit... - - flags |= 0x4; - - // need to flip DFP sign bit and cached sign - if (signum == -1){ - laside &= 0x7FFFFFFFFFFFFFFFL; //flip DFP sign bit - flags &= 0xFFFFFF9F; //clear the cached sign bits - flags |= ( 1 << 5) & 0x60;// ispos - } - else if (signum == 1){ - laside |= 0x8000000000000000L; //flip DFP sign bit - flags &= 0xFFFFFF9F; //clear the cached sign bits - flags |= (3 << 5) & 0x60; // isneg - } - if (getbi(res) != null) { - setbi(res, getbi(res).negate()); - } - setflags(res, flags); - setlaside(res, laside); - - return HARDWARE_OPERATION_SUCCESS; - } - - public int compareTo(BigDecimal lhs, BigDecimal rhs) { - - int res = DFPCompareTo(getlaside(lhs), getlaside(rhs)); - if (res != -2) { - return res; - } - return HARDWARE_OPERATION_FAIL; - } - - public int getScale(BigDecimal bd) { - - int myscale = getscale(bd); - // have we cached it? - if ((getflags(bd) & 0x8) != 0) { - return myscale; - } - - //caching it - - setflags(bd, getflags(bd) | 0x8); //cache on - - int newExp = DFPExponent(getlaside(bd)); - if (newExp == 1000) { - myscale = -(extractDFPExponent(getlaside(bd))-398); - } else { - myscale = -(newExp-398); - } - setscale(bd, myscale); - return myscale; - } - - public int setScale(BigDecimal bd, int scale) { - - if (-scale >= -398 && -scale <= 369){ - int ret = DFPSetScale(bd, getlaside(bd), -scale+398, false, 0, true); - if (ret == 1){ - if(DFPPerformHysteresis()) { - performHardwareUsageHeuristic(5); - } - - /* cache - SGP ESRR */ - - // set representation to DFP - // (already 00) - - // because DFPSetScale maintains the sign of the DFP - // -23 might get scaled down to -0 - long laside = getlaside(bd); - int flags = getflags(bd); - if(isDFPZero(laside)){ - laside &= 0x7FFFFFFFFFFFFFFFL; - flags |= 0x4; - flags &= 0xFFFFFF9F; //clear signum bits for 0 - } - else{ - // cache the sign of the src - flags|= 0x4; - flags |= (bd.signum()<<5)&0x60; - } - - // cache the exponent - flags|=0x8; - //NOTE: We do not cache precision! - flags&=0xFFFFFFEF; //clear prec cache bit - - setscale(bd, scale); - setflags(bd, flags); - setlaside(bd, laside); - - - return HARDWARE_OPERATION_SUCCESS; - } - else if (ret == 0) { - /*[MSG "K0455", "Requires rounding: {0}"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0455", Long.toString(scale))); //$NON-NLS-1$ - } - } - - return HARDWARE_OPERATION_FAIL; - } - - public int setScale(BigDecimal bd, int scale, int roundingMode) { - - if (-scale >= -398 && -scale <= 369){ - - // If the rounding mode is UNNECESSARY, then we can set - // the scale as if we were setting in the previous API - // i.e. with no concern to rounding (the 3rd parameter) - if (roundingMode == BigDecimal.ROUND_UNNECESSARY){ - - //120991 (changed last param from false to true) - int ret = DFPSetScale(bd, getlaside(bd), -scale+398,false, 0, true); - if (ret == 1){ - if (DFPPerformHysteresis()){ - performHardwareUsageHeuristic(5); - } - - /* cache - SGP ESRR */ - - // set representation to DFP - // (already 00) - - // because DFPSetScale maintains the sign of the DFP - // -23 might get scaled down to -0 - long laside = getlaside(bd); - int flags = 0; - - if(isDFPZero(laside)){ - laside &= 0x7FFFFFFFFFFFFFFFL; - flags|=0x4; - flags&=0xFFFFFF9F; //clear signum bits for 0 - } - else{ - // cache the sign of the src - flags|=0x4; - flags |=(bd.signum()<<5)&0x60; - } - - // cache the exponent - flags|=0x8; - - setscale(bd, scale); - setflags(bd, flags); - setlaside(bd, laside); - return HARDWARE_OPERATION_SUCCESS; - - } - } - else{ - - //the default DFP rounding mode - if (roundingMode == BigDecimal.ROUND_HALF_EVEN) { - roundingMode = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (roundingMode == BigDecimal.ROUND_UP) { - roundingMode = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - int ret = DFPSetScale(bd, getlaside(bd), -scale+398,true, roundingMode, false); - if (ret == 1){ - if (DFPPerformHysteresis()){ - performHardwareUsageHeuristic(5); - } - - /* cache - SGP ESRR */ - - // set representation to DFP - // (already 00) - - // because DFPSetScale maintains the sign of the DFP - // -23 might get scaled down to -0 - long laside = getlaside(bd); - int flags = 0; - - if(isDFPZero(laside)){ - laside &= 0x7FFFFFFFFFFFFFFFL; - flags |= 0x4; - flags &= 0xFFFFFF9F; //clear signum bits for 0 - } - else{ - // cache the sign of the src - flags |= 0x4; - flags |= (bd.signum()<<5)&0x60; - } - - // cache the exponent - flags |= 0x8; - setscale(bd, scale); - setflags(bd, flags); - setlaside(bd, laside); - - return HARDWARE_OPERATION_SUCCESS; - } - } - } - return HARDWARE_OPERATION_FAIL; - } - - public String toStringNoDecimal(BigDecimal bd) { - // Get the unscaled value; - long laside = getlaside(bd); - long lVal = DFPUnscaledValue(laside); - if (lVal == Long.MAX_VALUE){ - lVal = DFPBCDDigits(laside); - if (lVal == 10) { - lVal = extractDFPDigitsBCD(laside); - } - // now extract each 4 bit BCD digit from left to right - long val=0; //to store the result - int i=0; - while (lVal!= 0){ - val += (lVal & 0xF) * powerOfTenLL(i++); - lVal >>>= 4; - } - //is the sign negative? - return Long.toString(val * bd.signum()); - } else { - return Long.toString(lVal); - } - } - - public String toString(BigDecimal bd, int length) { - // Get the exponent - // Need to store it as a long since we may have - // stored Long.MIN_VALUE (which needs to be printed - // to screen as Long.MIN_VALUE - - long actualExp = -(long)bd.scale(); - - // Get the precision - int precision = bd.precision(); - - // Get the unscaled value; - long laside = getlaside(bd); - long bcd = DFPBCDDigits(laside); - if (bcd == 10) - bcd = extractDFPDigitsBCD(laside); - - long adjExp= actualExp + precision -1; - - // two cases to consider: - /* - * case 1: precision > 1 - * singlenumber.remaining numbersE(+/-adjusted exponent) - * case 2: else - * numberE(+/-adjusted exponent) - */ - - int expPrecision = numDigits(adjExp); - - // Fill 'er up - - // the character array to fill up - char [] str; - int index=0; - - if (length <=22) - str = (char [])thLocalToString.get(); - else - str = new char [ length ]; - - // the sign - if (bd.signum() == -1){ - str[index++] = '-'; - } - - // the first digit - str[index++] = (char)(digitAtBCD(bcd,precision,0)|0x0030); - - if (precision > 1){ - - // the decimal dot - str[index++] = '.'; - - // rest of the digits - for (int i=0;i < precision-1 ;i++) - str[index++] = (char)(digitAtBCD(bcd,precision,i+1)|0x0030); - } - - // E - str[index++] = 'E'; - - // the + - if (actualExp>0) - str[index++] = '+'; - else if (actualExp<0) - str[index++] = '-'; - - // exponent digits - for (int i=0; i < expPrecision; i++) - str[index++] = (char)(digitAt(adjExp,expPrecision,i)|0x0030); - - return new String(str, 0, length); - } - - public String toStringPadded(BigDecimal bd, int sign, int precision, int strlen) { - //NOTE : unscaledValue is in BCD form - char [] str; - int actualExp = -bd.scale(); - int signLen=0; - if (sign == -1) - signLen = 1; - long laside = getlaside(bd); - // Get the unscaled value; - long unscaledValue= DFPBCDDigits(laside); - if (unscaledValue == 10) { - unscaledValue = extractDFPDigitsBCD(laside); - } - // if scale is less than precision, won't have - // any leading zeros, and our number will have a decimal - // point somewhere in the middle... - - /* - * 1234 scale 1 = 123.4 - * 1234 scale 2 = 12.34 - * 1234 scale 3 = 1.234 - * 123400 scale 3 = 123.400 <-- need to handle trailing zeros for BI rep - * 123400 scale 5 = 12340.0 <-- need to handle trailing zeros for BI rep - * - * NOTE: don't need to handle scale <= 0 since this is taken care of - * in other branches in toStringHelper - */ - if (-actualExp < precision){ - int i=0; - - // for LL - // 1 no need to fill with trailing zeros - // 2 lay down sign - // 3 lay down all digits after decimal point - // 4 lay down digits before decimal point - - int length= signLen + 1 /*for .*/ + precision; - - if (length <=22) - str = (char [])thLocalToString.get(); - else - str = new char [ length ]; - int start=0; - int decimalPointLoc = length-(-actualExp)-1; - - // 2 Place sign - if (signLen !=0){ - str[start++]='-'; - } - - int curBCD = 0; - - //3 lay down all digits after decimal point - for (i=(length-1); i > decimalPointLoc; i--){ - curBCD = (int)(unscaledValue & 0xF); - unscaledValue >>>=4; - str[i] = (char)(curBCD|0x0030); - } - - // lay down decimal point - str[i--]='.'; - - //4 lay down all digits before decimal point - for (;i >=start; i--){ - curBCD = (int) (unscaledValue & 0xF); - unscaledValue >>>=4; - str[i] = (char)(curBCD|0x0030); - } - } - else{ - // easy case.. where scale >= precision - - /* - * 1234 scale 4 = 0.1234 - * 1234 scale 5 = 0.01234 - * 1234 scale 6 = 0.001234 - */ - - int numZeros = -actualExp - precision; - - // for both LL & BI - // 1 fill with zeros - // 2 lay down sign & lay down decimal point - // 3 lay down all digits - - int length= signLen + 1 /*for 0*/ + - 1 /*for .*/+ numZeros + precision; - - if (length <=22) - str = (char [])thLocalToString.get(); - else - str = new char [ length ]; - int start=0; - int i=0; - - //1 Fill with 0 - Arrays.fill(str,0,length,'0'); - - //2 Place sign - if (signLen !=0) - str[start++]='-'; - - //2 skip leading zero - start++; - - //2 Place decimal point - str[start++]='.'; - - //2 skip more leading zeros that occur after decimal point - start+=(-actualExp - precision); - - // fill up laside bytes (from back to front) - int curBCD=0; - for (i=length-1; i >= start; i--){ - curBCD = (int) (unscaledValue & 0xF); - unscaledValue >>>=4; - str[i] = (char)(curBCD|0x0030); - } - } - - return new String(str, 0, strlen); - } - - public int valueOf(BigDecimal res, long value, int scale) { - - if (DFPUseDFP()) { - if (value == 0 && scale == 0){ - createZero(res); - return HARDWARE_OPERATION_SUCCESS; - } - - if (value <= 9999999999999999L && value >= -9999999999999999L && -scale>= -398 && -scale<= 369){ - - // NOTE: When we don't specify rounding in DFP, we'll never - // fail, so don't bother checking the return value - if (DFPLongExpConstructor(res, value, -scale + 398, 0, 0, 0, false)){ - int tempFlags = getflags(res); - /* cache: SGP ESRR */ - - // store DFP representation - // (already 00) - - // cache the exponent for all DFP paths - tempFlags|=0x8; //cache on - setscale(res, scale); - - // cache the sign for DFP, on all paths - tempFlags|=0x4; //cache on - if (value < 0) { - tempFlags |= 0x60; //isneg - } else if (value > 0) { - tempFlags |= 0x20; //ispos - //iszero is already 00 - } - setflags(res, tempFlags); - return HARDWARE_OPERATION_SUCCESS; - } - } - } - - return HARDWARE_OPERATION_FAIL; - } - - public int round(BigDecimal res, int precision, int roundingMode) { - - // Only enter here iff precision > 0 - if (res.precision() > precision){ // and only perform if request is shorter then us - long laside = getlaside(res); - int flags = getflags(res); - long bcd = DFPBCDDigits(laside); - if (bcd == 10) { - bcd = extractDFPDigitsBCD(laside); - } - - if (roundingMode== BigDecimal.ROUND_UNNECESSARY){ - if (!allzeroBCD(bcd, res.precision() - precision)) { - /*[MSG "K0468", "Rounding mode unnecessary, but rounding changes value"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0468")); //$NON-NLS-1$ - } - } - - //the default DFP rounding mode - if (roundingMode == BigDecimal.ROUND_HALF_EVEN) { - roundingMode = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (roundingMode == BigDecimal.ROUND_UP) { - roundingMode = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - if(!DFPRound(res, laside, precision, roundingMode)) { - return HARDWARE_OPERATION_FAIL; - } else { - /* cache - SGP ESRR */ - // if successful, update the precision cache... - flags = getflags(res); - flags |= 0x10; //cache on - flags &= 0x7F; - flags |= precision << 7; - - //exponent may have changed, but we don't know - //to what... - flags &= 0xFFFFFFF7; //clear exponent cache bit - setflags(res, flags); - } - - // if the result is still in DFP and is 0, make - // sure the sign bit is off... - laside = getlaside(res); - if ((flags & 0x3) == 0x0 && isDFPZero(laside)) { - laside &= 0x7FFFFFFFFFFFFFFFL; - setlaside(res, laside); - } - } - - return HARDWARE_OPERATION_SUCCESS; - } - - public int convertToLongLookaside(BigDecimal res) { - - long laside = getlaside(res); - int flags = getflags(res); - //quick check for 0 - if (laside == dfpZERO){ - - // set representation as long lookaside - flags &= 0xFFFFFFFC; //clear bits - flags |= 0x00000001; - - // reset exponent - setscale(res, 0); - // set long lookaside - setlaside(res, 0); - - // cache the precision of 1 - flags &= 0x7F; // clear the cached precision - flags |= 0x10; //caching the precision - flags |= 1 << 7; //precision of 1 - } - else{ - - // need to store representation and new long lookaside last - // since helper functions that are called - // depend on the correct internal representation flag bit - - int signum = res.signum();; - - //store the exponent - setscale(res, res.scale()); - - //cache the precision - int prec = res.precision(); - flags &= 0x7F; // clear the cached precision - flags &= 0xFFFFFFEF;//clear bits - flags |= 0x10; //cache on - flags |= prec << 7; - - long lVal = DFPUnscaledValue(laside); - - if (lVal == Long.MAX_VALUE){ - lVal = DFPBCDDigits(laside); - if (lVal == 10) { - lVal = extractDFPDigitsBCD(laside); - } - // now extract each 4 bit BCD digit from left to right - long val = 0; //to store the result - int i = 0; - while (lVal!= 0) { - val += (lVal & 0xF) * powerOfTenLL(i++); - lVal >>>= 4; - } - - //is the sign negative? - laside = val * signum; - } else { - laside = lVal; - } - - // store representation as long lookaside - flags &= 0xFFFFFFFC; - flags |= 0x00000001; - setlaside(res, laside); - } - setflags(res, flags); - // need to make sure bi is not cached by previous calls to unscaled value - setbi(res, null); - - return HARDWARE_OPERATION_SUCCESS; - } - - public int convertToBigInteger(BigDecimal res) { - - long laside = getlaside(res); - int flags = getflags(res); - //quick check for 0 - if (laside == dfpZERO){ - - //store BigInteger representation - flags &= 0xFFFFFFFC; //clear bits - flags |= 0x00000002; - - //clear exponent - setscale(res, 0); - - //store BI - setbi(res, BigInteger.ZERO); - - // cache the precision of 1 - flags&=0x7F; // clear the cached precision - flags|=0x10; //caching the precision - flags |= 1 << 7; //precision of 1 - } else { - - // need to store representation last - // since helper functions that are called - // depend on the correct internal representation flag bit - - //store the exponent - setscale(res, res.scale()); - - //store the BigInteger - - setbi(res, res.unscaledValue()); - - /* cache - SGP ESRR */ - - //cache the precision - int prec = res.precision(); - flags &= 0x7F; // clear the cached precision - flags |= 0x10; //cache on - flags |= prec << 7; - - // store representation as BigInteger - flags &= 0xFFFFFFFC; //clear bits - flags |= 0x00000002; - } - setlaside(res, laside); - setflags(res, flags); - - return HARDWARE_OPERATION_SUCCESS; - } - - public int convertToExtension(BigDecimal res) { - - int flags = getflags(res); - BigInteger bi = getbi(res); - int scale = getscale(res); - long laside =getlaside(res); - // from BI to DFP - if ((flags & 0x3) == 0x2 && - bi.compareTo(MAXDFP64) <= 0 && - bi.compareTo(MINDFP64) >=0 && - scale > -369 && scale < 398){ - - long lint = bi.longValue(); - - // NOTE: When we don't specify rounding in DFP, we'll never - // fail, so don't bother checking the return value - if (DFPLongExpConstructor(res, lint, -scale + 398, 0, 0, 0, false)){ - - /* cache: SGP ESRR */ - - // store DFP representation - flags &= 0xFFFFFFFC; // clear rep bits - //sets the bits to (00) - - // cache the exponent - flags |= 0x8; //cache on - //res.exp already stores the value - - // cache the sign - flags |= 0x4; //cache on - flags &= 0xFFFFFF9F; //clear signum - if (bi.signum() < 0) { - flags |= 0x60; //isneg - } else if (bi.signum() > 0) { - flags |= 0x20; //ispos - } else { - flags &= 0xFFFFFF9F; - } - - // fix to d124362 - setbi(res, null); - } - } - - // from LL to DFP - else if ((flags & 0x3) == 0x1 && - laside <= 9999999999999999L && - laside >= -9999999999999999L && - scale > -369 && scale < 398){ - - int signum = res.signum(); - - // NOTE: When we don't specify rounding in DFP, we'll never - // fail, so don't bother checking the return value - if (DFPLongExpConstructor(res, laside, -scale + 398, 0, 0, 0, false)){ - - /* cache: SGP ESRR */ - - // store DFP representation - flags &= 0xFFFFFFFC; // clear rep bits - //sets the bits to (00) - - // cache the exponent - flags |= 0x8; //cache on - //res.exp already stores the value - - // cache the sign - flags |= 0x4; //cache on - flags &= 0xFFFFFF9F; //clear signum - if (signum < 0) { - flags |= 0x60; //isneg - } else if (signum > 0) { - flags |= 0x20; //ispos - } else { - flags &= 0xFFFFFF9F; - } - } - } - - setflags(res, flags); - - return HARDWARE_OPERATION_SUCCESS; - } - - public int significance(BigDecimal bd) { - - int tempFlags = getflags(bd); - long laside = getlaside(bd); - - // we're caching it - tempFlags |= 0x10; // cache on - tempFlags &= 0x7F; //clear pre-existing bits - - int sig = DFPSignificance(laside); - if (sig < 0){ - long digits = DFPBCDDigits(laside); - if (digits == 10){ - digits = extractDFPDigitsBCD(laside); - } - int nlz = Long.numberOfLeadingZeros(digits); - nlz>>=2; - nlz=16-nlz; - - // Preceding algorithm would return 0 for 0 - // and we need it to return a precision of 1 - if (nlz == 0) - nlz++; - - - tempFlags |= nlz << 7; - setflags(bd, tempFlags); - return nlz; - } - else{ - // DFPSignificance would return 0 for 0 - // and we need it to return a precision of 1 - if (sig ==0) { - sig++; - } - tempFlags |= sig << 7; - setflags(bd, tempFlags); - return sig; - } - } - - public int signum(BigDecimal bd) { - - int tempFlags = getflags(bd); - long laside = getlaside(bd); - // is it cached? - if ((tempFlags&0x4)!=0) { - return (((tempFlags & 0x00000060) << 25) >>30); - } - - //we're going to cache it - tempFlags |= 0x4; //cache on - - //check for negative first - if ((laside & 0x8000000000000000L) == 0x8000000000000000L){ - tempFlags |= 0x60; //store negative - setflags(bd, tempFlags); - return -1; - } - - //now we're checking for positive or zero - long mask = DFPBCDDigits(laside); - if (mask == 10){ - //still haven't jitted the method - if (isDFPZero(laside)){ - tempFlags&=0xFFFFFF9F; //clear the signum cache (00) - setflags(bd, tempFlags); - return 0; - } else { - tempFlags&=0xFFFFFF9F; //clear the signum cache - tempFlags|=0x20; //store positive - setflags(bd, tempFlags); - return 1; - } - } else if (mask !=0) { - tempFlags&=0xFFFFFF9F; //clear the signum cache - tempFlags|=0x20; //store positive - setflags(bd, tempFlags); - return 1; - } else { - tempFlags&=0xFFFFFF9F; //clear the signum cache (00) - } - setflags(bd, tempFlags); - return 0; - } - - public BigInteger unscaledValue(BigDecimal bd) { - long laside = getlaside(bd); - long lVal = DFPUnscaledValue(laside); - if (lVal != Long.MAX_VALUE) { - setbi(bd, BigInteger.valueOf(lVal)); - return getbi(bd); - } else { - lVal = DFPBCDDigits(laside); - if (lVal == 10) { - lVal = extractDFPDigitsBCD(laside); - } - - //check for zero - if (lVal == 0) { - setbi(bd, BigInteger.ZERO); - return getbi(bd); - } - - // now extract each 4 bit BCD digit from left to right - long val = 0; //to store the result - int i = 0; - while (lVal != 0){ - val += (lVal & 0xF) * powerOfTenLL(i++); - lVal >>>= 4; - } - setbi(bd, BigInteger.valueOf(bd.signum() * val)); - return getbi(bd); - } - } - - public int createZero(BigDecimal res) { - setlaside(res, dfpZERO); - setbi(res, null); - setscale(res, 0); - int flags = getflags(res); - - flags|=0x4; //cache on - - // cache the precision of 1 - flags&=0x7F; // clear the cached precision - flags|=0x10; //caching the precision - flags |= 1 << 7; //precision of 1 - - // cache the exponent (exp already 0) - flags|=0x8; //cache on - setflags(res, flags); - - return HARDWARE_OPERATION_SUCCESS; - } - - public int intConstructor(BigDecimal res, int value, MathContext set) { - // quick path for 0e0 - if (value == 0){ - createZero(res); - return HARDWARE_OPERATION_SUCCESS; - } - - // cache the exp for all DFP paths - // exp remains 0 - int flags = getflags(res); - flags |= 0x8; //cache on - - // cache the sign for DFP, on all paths - flags|=0x4; //cache on - if (value < 0) { - flags|=0x60; //isneg - } else if (value > 0) { - flags|=0x20; //ispos - } - //iszero is already 00 - - // we're going to take the full blown path to - // constructing a DFP internal representation - - int prec = set.getPrecision(); - int rm = set.getRoundingMode().ordinal(); - - // fast path for MathContext64 - if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN){ - if (DFPIntConstructor(res, value, 64, 0, 0)){ - - // We assume in the worst case that the precision and - // exp remain the same since the number of digits - // is at most 16. If we passed in 999999999999999999be767 - // and rounded to +inf, we'd get overflow, fail and take - // the slow path anyway. - - /* cache: SGP ESRR */ - - // cache the precision - flags |= 0x10; - flags |= numDigits(value) << 7; - - // store DFP representation - // (representation bits already 00) - setflags(res, flags); - return HARDWARE_OPERATION_SUCCESS; - } - } - - // fast path for NO ROUNDING, as well as the ArithmeticException - if ((prec == 0) || (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) || - (prec > 16)){ - - /* This case catches: - * -when no rounding is required - * -if rounding is unnecessary and precision !=0, check - * to see that result wasn't inexact (via call to Finish) - * (the latter satisfies the API description of : - * ArithmeticException - if the result is inexact but - * the rounding mode is UNNECESSARY. - */ - - if (DFPIntConstructor(res, value, 0, 0, 0)){ - - /* cache: SGP ESRR */ - - // store DFP representation - // (representation bits already 00) - - // See if we need to throw an arithmetic exception - - /*[IF]*/ - //TODO: Return a special value in DFP hardware to improve - // this case - /*[ENDIF]*/ - - if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { - setflags(res, flags); - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - } else { - // we can cache the precision and exp - // since no rounding meant that (no rounding) - - // cache the precision - flags |= 0x10; //cache on - flags |= numDigits(value) << 7; - setflags(res, flags); - - } - return HARDWARE_OPERATION_SUCCESS; - } - // Otherwise, if a precision to round to is specified - } else if (prec <= 16){ - - /* NOTE: We do the following two if statements - * since the constants used for HALF_EVEN and ROUND_UP in - * the classlib do not map correctly to the DFP hardware - * rounding mode bits. All other classlib RoundingModes, however, do. - */ - - //the default DFP rounding mode - if (rm == BigDecimal.ROUND_HALF_EVEN) { - rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (rm == BigDecimal.ROUND_UP) { - rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - - // now construct in hardware if possible - if(DFPIntConstructor(res, value, 1, prec, rm)){ - - /* cache: SGP ESRR */ - - // store DFP representation - // (representation bits already 00) - - //don't try to cache precision/exp since - //prec might be different precision(val) - - //so turn cache of exp off... - flags &= 0xFFFFFFF7; - - return HARDWARE_OPERATION_SUCCESS; - } - } - return HARDWARE_OPERATION_FAIL; - } - - public int longConstructor(BigDecimal res, long value, int scale, MathContext set) { - // don't want to send in 0 and then round with hardware - // cause it might place a crummy exponent value... - if (value == 0){ - createZero(res); - return HARDWARE_OPERATION_SUCCESS; - // otherwise, make sure the long is within 64-bit DFP range - } else if (value <=9999999999999999L && value >= -9999999999999999L && - -scale>=-398 && -scale<369){ - int flags = getflags(res); - /* cache: SGP ESRR */ - - // cache the sign for DFP, on all paths - flags|=0x4; //cache on - - if (value < 0) { - flags|=0x60; //isneg - } else if (value > 0) { - flags|=0x20; //ispos - } - //iszero is already 00 - - int prec = set.getPrecision(); - int rm = set.getRoundingMode().ordinal(); - - // fast path for MathContext64 - if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN){ - if(DFPLongExpConstructor(res, value, -scale + 398, 64, 0, 0, false)){ - - // We assume in the worst case that the precision and - // exponent remain the same since the number of digits - // is at most 16. If we passed in 999999999999999999be767 - // and rounded to +inf, we'd get overflow, fail and take - // the slow path anyway. - - /* cache: SGP ESRR */ - - // cache the precision - flags |= 0x10; //cache on - flags |= numDigits(value) << 7; - - // cache the exponent - flags |= 0x8; //cache on - - setflags(res, flags); - setscale(res, scale); - - - //store DFP representation - // (already set to 00) - - return HARDWARE_OPERATION_SUCCESS; - } - } - - // fast path for NO ROUNDING, as well as the ArithmeticException - if ((prec == 0) || (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) - || (prec > 16)){ - - /* This case catches: - * -when no rounding is required - * -if rounding is unnecessary and precision !=0, check - * to see that result wasn't inexact (via call to Finish) - * (the latter satisfies the API description of : - * ArithmeticException - if the result is inexact but - * the rounding mode is UNNECESSARY. - */ - - // NOTE: When we don't specify rounding in DFP, we'll never - // fail, so don't bother checking the return value - if (this.DFPLongExpConstructor(res, value, -scale + 398, 0, 0, 0, false)){ - - // store DFP representation - // (already set to 00) - - /*[IF]*/ - //TODO: Return a special value in DFP hardware to improve - // this case - /*[ENDIF]*/ - - // See if we need to throw an arithmetic exception - if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { - setflags(res, flags); - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - } else { - - // cache the exponent - flags|=0x8; //cache on - - // cache the precision - flags |= 0x10; //cache on - flags |= numDigits(value) << 7; - - setflags(res, flags); - setscale(res, scale); - } - return HARDWARE_OPERATION_SUCCESS; - } - // Otherwise, if a precision to round to is specified - } else if (prec <=16){ - - /* NOTE: We do the following two if statements - * since the constants used for HALF_EVEN and ROUND_UP in - * the classlib do not map correctly to the DFP hardware - * rounding mode bits. All other classlib RoundingModes, however, do. - */ - - //the default DFP rounding mode - if (rm == BigDecimal.ROUND_HALF_EVEN) { - rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (rm == BigDecimal.ROUND_UP) { - rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - - // now construct in hardware if possible - if(DFPLongExpConstructor(res, value, -scale + 398, 1, prec, rm, false)){ - - //store DFP representation - // (already 00) - - //don't try to cache precision/exponent since - //prec might be different precision(val) - - // so turn caching of exponent off - setflags(res, flags); - - return HARDWARE_OPERATION_SUCCESS; - } - } - } - - return HARDWARE_OPERATION_FAIL; - } - - public int longConstructor(BigDecimal res, long value, int scale, int nDigits, int sign, MathContext set) { - int prec = set.getPrecision(); - int rm = set.getRoundingMode().ordinal(); - - // fast path for 0e0 - if (value == 0 && scale == 0){ - createZero(res); - return HARDWARE_OPERATION_SUCCESS; - } - - /* cache - SGP ESRR */ - - int flags = getflags(res); - - // cache the sign for DFP on all paths.. - flags|=0x4; //cache on - if (value != 0) { //if not-zero, then we set the val - flags|=sign; - } - - // cache the exponent for DFP on all paths.. - flags |= 0x8; //cache on - setscale(res, -scale); - - // fast path for MathContext64 - if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN){ - if (sign == 0x60){ //isneg - if (DFPLongExpConstructor(res, value, scale + 398, 64, 0, 0, true)){ - - // store DFP representation - // (already 00) - long laside = getlaside(res); - // since we use unsigned BCDs to get full 16 digits worth - // lets flip the DFP's sign bit to indicate the fact... - if (sign == 0x60) { //inseg - laside |= 0x8000000000000000l; - } - setlaside(res, laside); - /* cache - SGP ESRR */ - - // cache the precision - flags |= 0x10; - flags |= nDigits << 7; - - setflags(res, flags); - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - return HARDWARE_OPERATION_SUCCESS; - } - } - else{ - if(DFPLongExpConstructor(res, value, scale + 398, 64, 0, 0, true)){ - - // We assume in the worst case that the precision and - // exponent remain the same since the number of digits - // is at most 16. If we passed in 999999999999999999be767 - // and rounded to +inf, we'd get overflow, fail and take - // the slow path anyway. - - // cache the precision - flags|=0x10; - flags |= nDigits << 7; - - setflags(res, flags); - - //store DFP representation - //(already 00) - return HARDWARE_OPERATION_SUCCESS; - } - } - } - - // fast path for NO ROUNDING, as well as the ArithmeticException - if ((prec == 0) || (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) || - (prec > 16)){ - - /* This case catches: - * -when no rounding is required - * -if rounding is unnecessary and precision !=0, check - * to see that result wasn't inexact (via call to Finish) - * (the latter satisfies the API description of : - * ArithmeticException - if the result is inexact but - * the rounding mode is UNNECESSARY. - */ - if (DFPLongExpConstructor(res, value, scale + 398, 0, 0, 0, true)){ - - // store DFP representation - // (already 00) - - // since we use unsigned BCDs to get full 16 digits worth - // lets flip the DFP's sign bit to indicate the fact... - long laside = getlaside(res); - if (sign == 0x60) { //isneg - laside |= 0x8000000000000000l; - } - setlaside(res, laside); - // See if we need to throw an arithmetic exception - if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY){ - - // since we use unsigned BCDs to get full 16 digits worth - // lets flip the DFP's sign bit to indicate the fact... - if (sign == 0x60) { //inseg - laside |= 0x8000000000000000l; - } - setlaside(res, laside); - setflags(res, flags); - - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - } - else{ - // we can cache the precision and exponent - // since no rounding meant that (no rounding) - // cache the precision - flags|=0x10; - flags |= nDigits << 7; - setflags(res, flags); - - - } - return HARDWARE_OPERATION_SUCCESS; - } - } - - // Otherwise, if a precision to round to is specified - else if (prec <=16){ - - /* NOTE: We do the following two if statements - * since the constants used for HALF_EVEN and ROUND_UP in - * the classlib do not map correctly to the DFP hardware - * rounding mode bits. All other classlib RoundingModes, however, do. - */ - - // for negative BCDs - if (sign == 0x60){ - if (DFPLongExpConstructor(res, value, scale + 398, 0, 0, 0, true)){ - - // store DFP representation - // (already 00) - - // since we use unsigned BCDs to get full 16 digits worth - // lets flip the DFP's sign bit to indicate the fact... - long laside = getlaside(res); - laside |= 0x8000000000000000l; - setlaside(res, laside); - - /* cache - SGP ESRR */ - - // can't store precision since it's going to be prec, - // but isn't just yet... - setflags(res, flags); - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - return HARDWARE_OPERATION_SUCCESS; - } - } - else{ - - // NOTE: We do the following rm reversal here because - // doing so in common code above would cause the eventual - // call to roundDFP to switch them back. - - // the default DFP rounding mode - if (rm == BigDecimal.ROUND_HALF_EVEN) { - rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (rm == BigDecimal.ROUND_UP) { - rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - // for positive BCDs - if(DFPLongExpConstructor(res, value, scale + 398, 1, prec, rm, true)){ - - //store DFP representation - //(already 00) - - //don't try to cache precision/exponent since - //exp might be diff due to rounding, and precision - //may be larger than actual - - /* cache - SGP ESRR */ - - //reset caching of exponent - flags&=0xFFFFFFF7; - setflags(res, flags); - - - return HARDWARE_OPERATION_SUCCESS; - } - } - } - //at this point, DFP paths were unsuccessful, want to stick with BI - return HARDWARE_OPERATION_FAIL; - } - - public int bigIntegerConstructor(BigDecimal res, BigInteger bi, int scale, MathContext set) { - - int biPrecision = bi.toString().length() + ((bi.signum() ==-1) ? -1 : 0); - - if (biPrecision < 17 && -scale <= 369 && -scale >= -398){ - - // get the long value with the appropriate sign - long val = bi.longValue(); - - // quick path for 0e0 - if (val == 0 && scale == 0){ - createZero(res); - return HARDWARE_OPERATION_SUCCESS; - } - - // otherwise, we'll need to perform DFP construction - // using the correct precision/roundingmodes - - int prec = set.getPrecision(); - int rm = set.getRoundingMode().ordinal(); - - int flags = getflags(res); - // fast path for MathContext64 - if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN){ - if(DFPLongExpConstructor(res, val, -scale + 398, 64, 0, 0, false)){ - - // We assume in the worst case that the precision and - // exponent remain the same since the number of digits - // is at most 16. If we passed in 999999999999999999be767 - // and rounded to +inf, we'd get overflow, fail and take - // the slow path anyway. - - /* cache - SGP ESRR */ - - // cache the precision - flags |= 0x10; //cache on - flags |= numDigits(val) << 7; - - // cache the sign - flags|=0x4; //cache on - flags|= ((bi.signum() <<5) & 0x60); - - //cache the exponent - flags|=0x8; //cache on - - setflags(res, flags); - setscale(res, scale); - - // store DFP representation - // (representation bits already 00) - - return HARDWARE_OPERATION_SUCCESS; - } - } - - // fast path for NO ROUNDING, as well as the ArithmeticException - if ((prec == 0) || (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) - || (prec > 16)){ - - /* This case catches: - * -when no rounding is required - * -if rounding is unnecessary and precision !=0, check - * to see that result wasn't inexact (via call to Finish) - * (the latter satisfies the API description of : - * ArithmeticException - if the result is inexact but - * the rounding mode is UNNECESSARY. - */ - - // NOTE: When we don't specify rounding in DFP, we'll never - // fail, so don't bother checking the return value - if (DFPLongExpConstructor(res, val, -scale + 398, 0, 0, 0, false)){ - /* cache - SGP ESRR */ - - // cache the sign - flags |= 0x4; // cache on - flags |= ((bi.signum() <<5) & 0x60); - - // store DFP representation - // (representation bits already 00) - - // See if we need to throw an arithmetic exception - - /*[IF]*/ - //TODO: Return a special value in DFP hardware to improve - // this case - /*[ENDIF]*/ - - if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { - setflags(res, flags); - if(finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { - return HARDWARE_OPERATION_FAIL; - } - } else { - // we can cache the precision and exponent - // since no rounding left things as is - - // cache the precision - flags|=0x10; // cache on - flags |= numDigits(val) << 7; - - //cache the exponent - flags|=0x8; // cache on - - setflags(res, flags); - setscale(res, scale); - } - return HARDWARE_OPERATION_SUCCESS; - } - } - - // Otherwise, if a precision to round to is specified - else if (prec <=16){ - - /* NOTE: We do the following two if statements - * since the constants used for HALF_EVEN and ROUND_UP in - * the classlib do not map correctly to the DFP hardware - * rounding mode bits. All other classlib RoundingModes, however, do. - */ - - //the default DFP rounding mode - if (rm == BigDecimal.ROUND_HALF_EVEN) { - rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN - } else if (rm == BigDecimal.ROUND_UP) { - rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP - } - - // now construct in hardware if possible - if(DFPLongExpConstructor(res, val,-scale + 398, 1, prec, rm, false)){ - - /* cache - SGP ESRR */ - - // cache the sign - flags|=0x4; //cache on - flags|=((bi.signum() <<5) & 0x60); - setflags(res, flags); - - //store DFP representation - // (representation bits already 00) - - //don't try to cache precision/exponent since - //prec might be different after rounding - return HARDWARE_OPERATION_SUCCESS; - } - } - } - return HARDWARE_OPERATION_FAIL; - } - - - - - - - - - - - - - - - - - - - - - - - - // DO NOT MODIFY THIS METHOD - /* The method is only called once to setup the flag DFP_HW_AVAILABLE - * Return value - * true - when JIT compiled this method, replaces it with loadconst 1 - * if user -Xnodfp hasn't been supplied - * false - if still interpreting this method or disabled by VM option - */ - private final static boolean DFPCheckHWAvailable() { - return false; - } - - // DO NOT MODIFY THIS METHOD - /* - * Return value - * true - when JIT compiled this method, replaces it with loadconst 1 - * if user -Xnodfp hasn't been supplied - * false - if still interpreting this method or disabled by VM option - */ - private final static boolean DFPHWAvailable(){ - return DFP_HW_AVAILABLE; - } - - /* - * Return value - * true - when JIT compiled this method, replaces it with loadconst 1 - * if user -Xjit:disableDFPHys hasn't been supplied - * false - if still interpreting this method or disabled by JIT option - */ - private final static boolean DFPPerformHysteresis(){ - return false; - } - - /* - * Return value - * true - when JIT compiled this method, replaces it with loadconst 1 - * if -Xjit:disableDFPHys has been supplied OR when hys_type becomes true - * false - when hys_type is false - */ - private final static boolean DFPUseDFP(){ - return hys_type; - } - - // DO NOT MODIFY THIS METHOD - - /* NOTE: The fact we return a boolean means we kill a register - * in the cases we don't want to perform rounding. - * i.e. rndFlag = 0 or 64 since we must load and - * return a 1 value in the generated JIT code. - */ - private final static boolean DFPIntConstructor(BigDecimal bd, int val, int rndFlag, int prec, int rm){ - return false; - } - - // DO NOT MODIFY THIS METHOD - /*[IF]*/ - //TODO: Use this for the longConstructor when it's called with scale=0 - /*[ENDIF]*/ - private final static boolean DFPLongConstructor(BigDecimal bd, long val, int rndFlag, int prec, int rm){ - return false; - } - - // DO NOT MODIFY THIS METHOD - /* - * Interpreted return value: - * true - never - * false - always - * - * Jitted return value: - * true - if rounding succeeded - * false - if rounding failed - * - * Parameters: - * val - long to be converted to DFP - * biasedExp - biased exponent to be inserted into DFP - * rndFlag - * =0 - no rounding - * =1 - rounding according to prec, rm - * =64 - rounding according to MathContext64 - * prec - precision to round constructed DFP to - * rm - rm to use - * bcd - whether long is in bcd form - * - */ - private final static boolean DFPLongExpConstructor(BigDecimal bd, long val, int biasedExp, int rndFlag, int prec, int rm, boolean bcd){ - return false; - } - - // DO NOT MODIFY THIS METHOD - private final static boolean DFPScaledAdd(BigDecimal bd, long lhsDFP,long rhsDFP,int biasedExp){ - return false; - } - - // DO NOT MODIFY THIS METHOD - /* - * Parameters: - * rndFlag - * =0 - no rounding - * =1 - rounding according to prec, rm - * =64 - rounding according to MathContext64 - */ - private final static boolean DFPAdd(BigDecimal bd, long lhsDFP,long rhsDFP, int rndFlag, int precision, int rm){ - return false; - } - - // DO NOT MODIFY THIS METHOD - private final static boolean DFPScaledSubtract(BigDecimal bd, long lhsDFP,long rhsDFP,int biasedExp){ - return false; - } - - // DO NOT MODIFY THIS METHOD - /* - * Parameters: - * rndFlag - * =0 - no rounding - * =1 - rounding according to prec, rm - * =64 - rounding according to MathContext64 - */ - private final static boolean DFPSubtract(BigDecimal res, long lhsDFP, long rhsDFP, int rndFlag, int precision, int rm){ - return false; - } - - // DO NOT MODIFY THIS METHOD - private final static boolean DFPScaledMultiply(BigDecimal res, long lhsDFP,long rhsDFP,int biasedExp){ - return false; - } - - // DO NOT MODIFY THIS METHOD - /* - * Parameters: - * rndFlag - * =0 - no rounding - * =1 - rounding according to prec, rm - * =64 - rounding according to MathContext64 - */ - private final static boolean DFPMultiply(BigDecimal res, long lhsDFP, long rhsDFP, int rndFlag, int precision, int rm){ - return false; - } - - // DO NOT MODIFY THIS METHOD - /* - * Interpreted return value: - * Returns -1 if not JIT compiled. - * - * JIT compiled return value: - * 0 - ok, but inexact exception --> check UNNECESSARY - * 1 - ok, no inexact - * -1 - not ok --> try slow path - * - * rndFlag - * =0 - rounding according to MathContext64 - * =1 - rounding according to prec, rm - */ - private final static int DFPScaledDivide(BigDecimal res, long lhsDFP, long rhsDFP, int scale, int rndFlg, int rm){ - return -1; - } - - // DO NOT MODIFY THIS METHOD - /* - * Interpreted return value: - * -1 = always - * - * JIT compiled return value: - * Return 1 if JIT compiled and DFP divide is successful. - * Return 0 if JIT compiled, but DFP divide was inexact - * Return -1 if JIT compiled, but other exception (i.e. overflow) - * - * rndFlag - * =0 - no rounding - * =1 - rounding according to prec, rm - * =64 - rounding according to MathContext64 - */ - private final static int DFPDivide(BigDecimal bd, long lhsDFP, long rhsDFP, boolean checkForInexact, int rndFlag, int prec, int rm){ - return -1; //return an invalid result - } - - // DO NOT MODIFY THIS METHOD - private final static boolean DFPRound(BigDecimal bd, long dfpSrc, int precision, int rm){ - return false; - } - - // DO NOT MODIFY THIS METHOD - private final static int DFPCompareTo(long lhsDFP, long rhsDFP){ - return -2; //return an invalid result - } - - // DO NOT MODIFY THIS METHOD - private final static long DFPBCDDigits(long dfp){ - return 10; //since each digit in a BCD is from 0 to 9 - } - - // DO NOT MODIFY THIS METHOD - private final static int DFPSignificance(long dfp){ - return -1; //illegal significance - } - - // DO NOT MODIFY THIS METHOD - private final static int DFPExponent(long dfp){ - return 1000; //return a value out of the range of Double DFP - } - - // DO NOT MODIFY THIS METHOD - /* - * Interpreted return value: - * -1 = always - * - * JIT compiled return value: - * Return 1 if passed - * Return 0 if JIT compiled, but inexact result - * Return -1 if JIT compiled, but other failure - * - */ - private final static int DFPSetScale(BigDecimal bd, long srcDFP, int biasedExp, boolean round, int rm, boolean checkInexact){ - return -1; - } - - // DO NOT MODIFY THIS METHOD - private final static long DFPUnscaledValue(long srcDFP){ - return Long.MAX_VALUE; - } - - - - - - - - - - - - - - - - - - - - - - private static final ThreadLocal thLocalToString = new ThreadLocal(){ - /* 22 is the best number for the fastest path - * [-]digits.digits when scale > 0 & scale <=19 - */ - - protected synchronized Object initialValue() { - return new char[22]; - } - }; - - private final static byte [] comboinit(){ - final byte comboCode[]={ - 0, 4, 8, 12, 16, 20, 24, 28, - 1, 5, 9, 13, 17, 21, 25, 29, - 2, 6, 10, 14, 18, 22, 26, 30, - 32, 36, 33, 37, 34, 38 - }; - return comboCode; - } - - private final static short [] dpd2bcdinit(){ - final short[] dpd2bcd = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 128, 129, 2048, 2049, 2176, 2177, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 144, 145, 2064, 2065, 2192, 2193, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 130, 131, 2080, 2081, 2056, - 2057, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 146, 147, - 2096, 2097, 2072, 2073, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 132, 133, 2112, 2113, 136, 137, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 148, 149, 2128, 2129, 152, 153, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 134, 135, 2144, 2145, 2184, 2185, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 150, 151, 2160, - 2161, 2200, 2201, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 384, 385, 2304, 2305, 2432, 2433, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 400, 401, 2320, 2321, 2448, 2449, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 297, 386, 387, 2336, 2337, 2312, 2313, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 402, 403, 2352, 2353, - 2328, 2329, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 388, - 389, 2368, 2369, 392, 393, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 404, 405, 2384, 2385, 408, 409, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 390, 391, 2400, 2401, 2440, 2441, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 406, 407, 2416, 2417, 2456, - 2457, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 640, 641, - 2050, 2051, 2178, 2179, 528, 529, 530, 531, 532, 533, 534, 535, 536, - 537, 656, 657, 2066, 2067, 2194, 2195, 544, 545, 546, 547, 548, 549, - 550, 551, 552, 553, 642, 643, 2082, 2083, 2088, 2089, 560, 561, 562, - 563, 564, 565, 566, 567, 568, 569, 658, 659, 2098, 2099, 2104, 2105, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 644, 645, 2114, - 2115, 648, 649, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, - 660, 661, 2130, 2131, 664, 665, 608, 609, 610, 611, 612, 613, 614, - 615, 616, 617, 646, 647, 2146, 2147, 2184, 2185, 624, 625, 626, 627, - 628, 629, 630, 631, 632, 633, 662, 663, 2162, 2163, 2200, 2201, 768, - 769, 770, 771, 772, 773, 774, 775, 776, 777, 896, 897, 2306, 2307, - 2434, 2435, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 912, - 913, 2322, 2323, 2450, 2451, 800, 801, 802, 803, 804, 805, 806, 807, - 808, 809, 898, 899, 2338, 2339, 2344, 2345, 816, 817, 818, 819, 820, - 821, 822, 823, 824, 825, 914, 915, 2354, 2355, 2360, 2361, 832, 833, - 834, 835, 836, 837, 838, 839, 840, 841, 900, 901, 2370, 2371, 904, - 905, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 916, 917, - 2386, 2387, 920, 921, 864, 865, 866, 867, 868, 869, 870, 871, 872, - 873, 902, 903, 2402, 2403, 2440, 2441, 880, 881, 882, 883, 884, 885, - 886, 887, 888, 889, 918, 919, 2418, 2419, 2456, 2457, 1024, 1025, 1026, - 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1152, 1153, 2052, 2053, 2180, 2181, - 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1168, 1169, 2068, - 2069, 2196, 2197, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, - 1154, 1155, 2084, 2085, 2120, 2121, 1072, 1073, 1074, 1075, 1076, 1077, 1078, - 1079, 1080, 1081, 1170, 1171, 2100, 2101, 2136, 2137, 1088, 1089, 1090, 1091, - 1092, 1093, 1094, 1095, 1096, 1097, 1156, 1157, 2116, 2117, 1160, 1161, 1104, - 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1172, 1173, 2132, 2133, - 1176, 1177, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1158, - 1159, 2148, 2149, 2184, 2185, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, - 1144, 1145, 1174, 1175, 2164, 2165, 2200, 2201, 1280, 1281, 1282, 1283, 1284, - 1285, 1286, 1287, 1288, 1289, 1408, 1409, 2308, 2309, 2436, 2437, 1296, 1297, - 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1424, 1425, 2324, 2325, 2452, - 2453, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1410, 1411, - 2340, 2341, 2376, 2377, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, - 1337, 1426, 1427, 2356, 2357, 2392, 2393, 1344, 1345, 1346, 1347, 1348, 1349, - 1350, 1351, 1352, 1353, 1412, 1413, 2372, 2373, 1416, 1417, 1360, 1361, 1362, - 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1428, 1429, 2388, 2389, 1432, 1433, - 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1414, 1415, 2404, - 2405, 2440, 2441, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, - 1430, 1431, 2420, 2421, 2456, 2457, 1536, 1537, 1538, 1539, 1540, 1541, 1542, - 1543, 1544, 1545, 1664, 1665, 2054, 2055, 2182, 2183, 1552, 1553, 1554, 1555, - 1556, 1557, 1558, 1559, 1560, 1561, 1680, 1681, 2070, 2071, 2198, 2199, 1568, - 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1666, 1667, 2086, 2087, - 2152, 2153, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1682, - 1683, 2102, 2103, 2168, 2169, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, - 1608, 1609, 1668, 1669, 2118, 2119, 1672, 1673, 1616, 1617, 1618, 1619, 1620, - 1621, 1622, 1623, 1624, 1625, 1684, 1685, 2134, 2135, 1688, 1689, 1632, 1633, - 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1670, 1671, 2150, 2151, 2184, - 2185, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1686, 1687, - 2166, 2167, 2200, 2201, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, - 1801, 1920, 1921, 2310, 2311, 2438, 2439, 1808, 1809, 1810, 1811, 1812, 1813, - 1814, 1815, 1816, 1817, 1936, 1937, 2326, 2327, 2454, 2455, 1824, 1825, 1826, - 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1922, 1923, 2342, 2343, 2408, 2409, - 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1938, 1939, 2358, - 2359, 2424, 2425, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, - 1924, 1925, 2374, 2375, 1928, 1929, 1872, 1873, 1874, 1875, 1876, 1877, 1878, - 1879, 1880, 1881, 1940, 1941, 2390, 2391, 1944, 1945, 1888, 1889, 1890, 1891, - 1892, 1893, 1894, 1895, 1896, 1897, 1926, 1927, 2406, 2407, 2440, 2441, 1904, - 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1942, 1943, 2422, 2423, - 2456, 2457}; - return dpd2bcd; - } - - /** - * LUT for powers of ten - */ - private static final long [/*19*/]powersOfTenLL={ - 1L, 10L, 100L, 1000L, /*0 to 4 */ - 10000L, 100000L, 1000000L, 10000000L, /*5 to 8*/ - 100000000L, 1000000000L, 10000000000L, 100000000000L, /*9 to 12*/ - 1000000000000L, 10000000000000L, 100000000000000L, 1000000000000000L, /*13 to 16 */ - 10000000000000000L, 100000000000000000L, 1000000000000000000L /*17 to 18 */ - }; - - private final static boolean isDFPZero(long laside){ - // quick check for 0 - if (laside == dfpZERO) { - return true; - } - // if DPF is ZERO, then the combo field will be XX000 where XX is I don't care - // values, and then coefficient continuation field will be all 0s - return ((laside & 0x0003FFFFFFFFFFFFL) == 0 && ((laside >>> 58) & 0x7) == 0); - } - - private final void clone(BigDecimal src, BigDecimal tar) { - int tempFlags = getflags(src); - setflags(tar, tempFlags); - setlaside(tar, getlaside(src)); - setscale(tar, getscale(src)); - if ((tempFlags & 0x3) == 0x2) { - setbi(tar, getbi(src)); - } - } - - private final int finish(BigDecimal bd, int prec, int rm){ - if (prec > 0 && bd.precision() > prec) { - if ((getflags(bd) & 0x3) == 0x0) { - return round(bd, prec, rm); - } else { - MathContext mc = new MathContext(prec, RoundingMode.valueOf(rm)); - clone(bd.round(mc), bd); - } - } - return HARDWARE_OPERATION_SUCCESS; - } - - protected final static int getflags(BigDecimal bd) { - throw new RuntimeException("getflags not compiled\n"); //$NON-NLS-1$ - } - - protected final static long getlaside(BigDecimal bd) { - throw new RuntimeException("getlaside not compiled\n"); //$NON-NLS-1$ - } - - protected final static int getscale(BigDecimal bd) { - throw new RuntimeException("getscale not compiled\n"); //$NON-NLS-1$ - } - - protected final static BigInteger getbi(BigDecimal bd) { - throw new RuntimeException("getbi not compiled\n"); //$NON-NLS-1$ - } - - protected final static void setflags(BigDecimal bd, int flags) { - throw new RuntimeException("setflags not compiled\n"); //$NON-NLS-1$ - } - - protected final static void setlaside(BigDecimal bd, long laside) { - throw new RuntimeException("setlaside not compiled\n"); //$NON-NLS-1$ - } - - protected final static void setscale(BigDecimal bd, int scale) { - throw new RuntimeException("setscale not compiled\n"); //$NON-NLS-1$ - } - - protected final static void setbi(BigDecimal bd, BigInteger bi) { - throw new RuntimeException("setbi not compiled\n"); //$NON-NLS-1$ - } - - private final static long extractDFPDigitsBCD(long dfpNum){ - - int combo=0; // 5 bit combo field - - //quick check for 0 - if (dfpNum == dfpZERO) - return 0; - - // store the combo field bits - combo = (int)(dfpNum >>> 58); //shift out extraneous bits - combo &= 0x1F; //and out sign bit - - // MANTISSA - - // store the mantissa continuation field bits 14 to 62 (50 bits in total) - long ccf = dfpNum & 0x0003FFFFFFFFFFFFL; - - // Convert each set of 10 DPD bits from continuation bits to 12 BCD digits - long ccBCD=0; - long bcd=0; - for (int i=0; i <5; i++){ //5 groups of 10 bits - bcd = DPD2BCD[(int)((ccf & 0x3FF0000000000L)>>>40)]; - ccBCD <<=12; - ccBCD|=bcd; - ccf <<= 10; //shift out top 10 bits - } - - //ccBCD contains 15 BCD digits, now need to prepend the first one - ccBCD|=(((long)(doubleDFPComboField[combo]>>>2))<<60); - return ccBCD; - } - - - private final static boolean allzeroBCD(long num, int numDigsToCheck){ - - // isolate numDigsToCheck rightmost digits... - long mask = 0xFFFFFFFFFFFFFFFFL; - mask >>>= (64-numDigsToCheck)*4; - return ((mask & num) == 0); - } - - private final static int extractDFPExponent(long dfpNum){ - - byte combo=0; // 5 bit combo field - - // store the combo field bits - combo = (byte)(dfpNum >>> 58); //shift out extraneous bits - //combo &= 0x1F; //and out sign bit - not sure why I was doing this - - // store the biased exponent field bits 6 to 13 - short bxf = (short)(dfpNum >>> 50); //shift out extraneous bits - bxf &= 0x00FF; //and out sign and combo field - - // parse the combo field - byte exp2Digits = (byte)(doubleDFPComboField[combo] & 0x03); - - // unbias the exponent - short unbExp = (short)(exp2Digits); - unbExp <<= 8; - unbExp|=bxf; - return unbExp; - } - - private static final long powerOfTenLL(long i){ - if (i > -1 && i <= 18) - return powersOfTenLL[(int)i]; - else - return -1; - } - - /* Return number of digits in lon - * The value '0' has numDigits = 1. - */ - private final static int numDigits(long lon){ - //if (lon <0) lon*=-1; //need to make it positive for this to work - lon = Math.abs(lon); - - //hardcode powers of ten to avoid LUT lookups - - //rhs of the tree - if (lon < 1000000000L /*powerOfTenLL[9]*/){ - if (lon < 100000000L /*powerOfTenLL[8]*/){ - if (lon < 10000L /*powerOfTenLL[4]*/){ - if (lon < 100L /* powerOfTenLL[2]*/){ - if (lon < 10L /*powerOfTenLL[1]*/) - return 1; - else - return 2; - } - else if (lon < 1000L /*powerOfTenLL[3]*/) - return 3; - else - return 4; - } - else if (lon < 1000000L /*powerOfTenLL[6]*/){ - if ( lon < 100000L /*powerOfTenLL[5]*/) - return 5; - else - return 6; - } - else if (lon < 10000000L /*powerOfTenLL[7]*/) - return 7; - else return 8; - } - else - return 9; - } - //lhs of the tree - else{ - if (lon < 10000000000L /*powerOfTenLL[10]*/) - return 10; - else if (lon < 100000000000000L /*powerOfTenLL[14]*/){ - if (lon < 1000000000000L /*powerOfTenLL[12]*/){ - if (lon < 100000000000L /*powerOfTenLL[11]*/) - return 11; - else - return 12; - } - else if (lon < 10000000000000L /*powerOfTenLL[13]*/) - return 13; - else - return 14; - } - else if (lon < 10000000000000000L /*powerOfTenLL[16]*/){ - if (lon < 1000000000000000L /*powerOfTenLL[15]*/) - return 15; - else - return 16; - } - else if (lon < 100000000000000000L /*powerOfTenLL[17]*/) - return 17; - else if (lon < 1000000000000000000L /*powerOfTenLL[18]*/) - return 18; - return 19; - } - } - - private final static int digitAtBCD(long bcd, int numDigits, int indexFromLeft){ - - int indexFromRight = numDigits-indexFromLeft-1; - switch (indexFromRight){ - case 0: - return (int)(bcd & 0x000000000000000FL); - case 1: - return (int)((bcd & 0x00000000000000F0L)>>>4); - case 2: - return (int)((bcd & 0x0000000000000F00L)>>>8); - case 3: - return (int)((bcd & 0x000000000000F000L)>>>12); - case 4: - return (int)((bcd & 0x00000000000F0000L)>>>16); - case 5: - return (int)((bcd & 0x0000000000F00000L)>>>20); - case 6: - return (int)((bcd & 0x000000000F000000L)>>>24); - case 7: - return (int)((bcd & 0x00000000F0000000L)>>>28); - case 8: - return (int)((bcd & 0xF00000000L)>>>32); - case 9: - return (int)((bcd & 0xF000000000L)>>>36); - case 10: - return (int)((bcd & 0xF0000000000L)>>>40); - case 11: - return (int)((bcd & 0xF00000000000L)>>44); - case 12: - return (int)((bcd & 0xF000000000000L)>>>48); - case 13: - return (int)((bcd & 0xF0000000000000L)>>>52); - case 14: - return (int)((bcd & 0xF00000000000000L)>>>56); - case 15: - return (int)((bcd & 0xF000000000000000L)>>>60); - default: - return 0; - } - } - - private final static int digitAt(long lon, int numdigits, int loc){ - - lon = Math.abs(lon); - if (loc > numdigits-1)return -1; - if (loc < 0) return -1; - int indexFromRight = numdigits-loc-1; - if (lon <= Integer.MAX_VALUE){ - int temp=(int)lon; - switch (indexFromRight){ - case 0: - break; - case 1: - temp /=10; - break; - case 2: - temp /=100; - break; - case 3: - temp /=1000; - break; - case 4: - temp /=10000; - break; - case 5: - temp /=100000; - break; - case 6: - temp /=1000000; - break; - case 7: - temp /=10000000; - break; - case 8: - temp /=100000000; - break; - case 9: - temp /=1000000000; //unsure whether remaining cases would - break; //ever be taken in the Integer case - case 10: - temp /=10000000000L; - break; - case 11: - temp /=100000000000L; - break; - case 12: - temp /=1000000000000L; - break; - case 13: - temp /=10000000000000L; - break; - case 14: - temp /=100000000000000L; - break; - case 15: - temp /=1000000000000000L; - break; - case 16: - temp /=10000000000000000L; - break; - case 17: - temp /=100000000000000000L; - break; - case 18: - temp /=1000000000000000000L; - break; - } - - // find remainder - if (temp <= Integer.MAX_VALUE){ - int intTmp = (int)temp; - int tmpVal = intTmp; - intTmp = uDivideByTen(intTmp); - return (tmpVal - ((intTmp << 3) + (intTmp << 1))); - } - else{ - long tmpVal = temp; - temp/=10; - return (int)(tmpVal - (((temp << 3) + (temp << 1)))); - } - } - else{ - long temp=lon; - switch (indexFromRight){ - case 0: - break; - case 1: - temp /= 10; - break; - case 2: - temp /= 100; - break; - case 3: - temp /= 1000; - break; - case 4: - temp /= 10000; - break; - case 5: - temp /= 100000; - break; - case 6: - temp /= 1000000; - break; - case 7: - temp /= 10000000; - break; - case 8: - temp /= 100000000; - break; - case 9: - temp /= 1000000000; - break; - case 10: - temp /= 10000000000L; - break; - case 11: - temp /= 100000000000L; - break; - case 12: - temp /= 1000000000000L; - break; - case 13: - temp /= 10000000000000L; - break; - case 14: - temp /= 100000000000000L; - break; - case 15: - temp /= 1000000000000000L; - break; - case 16: - temp /= 10000000000000000L; - break; - case 17: - temp /= 100000000000000000L; - break; - case 18: - temp /= 1000000000000000000L; - break; - } - - // find remainder - if (temp <= Integer.MAX_VALUE){ - int intTmp = (int)temp; - int tmpVal = intTmp; - intTmp = uDivideByTen(intTmp); - return (tmpVal - ((intTmp << 3) + (intTmp << 1))); - } - else{ - long tmpVal = temp; - temp/=10; - return (int)(tmpVal - (((temp << 3) + (temp << 1)))); - } - } - } - - private final static int uDivideByTen(int x){ - int q = (x >> 1) + (x >> 2); - q = q + (q >> 4); - q = q + (q >> 8); - q = q + (q >> 16); - q >>=3; - x -= q*10; - return q + ((x + 6) >> 4); - } - - private final void badDivideByZero() { - /*[MSG "K0407", "division by zero"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0407")); //$NON-NLS-1$ - } - private final void conversionOverflow(BigDecimal bd) { - /*[MSG "K0458", "Conversion overflow: {0}"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0458", bd)); //$NON-NLS-1$ - } - private final void nonZeroDecimals(BigDecimal bd) { - /*[MSG "K0457", "Non-zero decimal digits: {0}"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0457", bd)); //$NON-NLS-1$ - } - private final void scaleOutOfRange(long s) { - /*[MSG "K0451", "BigDecimal scale outside legal range: {0}"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0451", Long.toString(s))); //$NON-NLS-1$ - } - private static final void scaleOverflow() { - /*[MSG "K0453", "Scale overflow"]*/ - throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0453")); //$NON-NLS-1$ - } + // Used to keep behavior of DFPHWAvailable consistent between + // jitted code and interpreter + // DO NOT CHANGE OR MOVE THIS LINE + // IT MUST BE THE FIRST THING IN THE INITIALIZATION + private static final boolean DFP_HW_AVAILABLE = DFPCheckHWAvailable(); + + /* + * public static final int ROUND_CEILING 2 + * DFP hardware uses the value 010 == 2 + * public static final int ROUND_DOWN 1 + * DFP hardware uses the value 001 = 1 + * public static final int ROUND_FLOOR 3 + * DFP hardware uses the value 011 = 3 + * public static final int ROUND_HALF_DOWN 5 + * DFP hardware uses the value 101 = 5 + * public static final int ROUND_HALF_EVEN 6 <--mismatch in HW/Classlib spec + * DFP hardware uses the value 000 = 0 + * public static final int ROUND_HALF_UP 4 + * DFP hardware uses the value 100 = 4 + * public static final int ROUND_UNNECESSARY 7 + * DFP hardware uses the value 111 = 7 + * public static final int ROUND_UP 0 <--mismatch in HW/Classlib spec + * DFP hardware uses the value 110 = 6 + */ + + /** + * LUT for DFP double combination field - gives us the leftmost + * digit of the coefficient, as well as the first two bits of the + * exponent in form: 0xXY where X = LMD, Y = first two bits + */ + private static byte[] doubleDFPComboField = comboinit(); + + // LUT for converting DPD to BCD, 1024 elements + private static short[] DPD2BCD = dpd2bcdinit(); + + // DFP 0 with exponent 0 + private static final long dfpZERO = 2465720795985346560L; + + private static final BigInteger MAXDFP64 = BigInteger.valueOf(9999999999999999L); + private static final BigInteger MINDFP64 = BigInteger.valueOf(-9999999999999999L); + + /* Used for Hysteresis for mixed-representation + * We want the BigDecimal class to choose the best representation + * for construction and operations. We start assuming the LL + * is the best representation. Over the course of time, using + * hysterisis, we might alter this decision. + * + * The constructors are annotated with the checks on deciding + * which representation to use, and other APIs contribute + * to biasing towards or away from a representation. + * + * NOTE: Hysterisis only works on platforms that supports DFP + * since we prepend a DFPHWAvailable check before performing + * mods to the counters, and before basing decisions off them. + */ + private static int hys_threshold = 1000; // threshold for representation change + // above means that hys_counter must reach -/+ MAX_VALUE before changing rep + private static boolean hys_type; // false = non-dfp, true = dfp + private static int hys_counter; // increment for dfp, decrement for non-dfp + + private static BigDecimalExtension instance; + + protected BigDecimalExtension() { + } + + public static BigDecimalExtension getInstance() { + if (instance == null) { + instance = new BigDecimalExtension(); + } + return instance; + } + + public boolean performHardwareUsageHeuristic(MathContext set, int bias) { + if (DFPPerformHysteresis() && + set.getPrecision() == 16 && set.getRoundingMode().ordinal() == BigDecimal.ROUND_HALF_EVEN) { + performHardwareUsageHeuristic(bias); + return true; + } + return false; + } + + private void performHardwareUsageHeuristic(int bias) { + int sum = hys_counter + bias; + hys_counter += bias & ~(((sum^bias) & (sum^hys_counter)) >>> 31); + + if (hys_counter<-hys_threshold) { + hys_type = false; //nonDFP + hys_counter=0; + } + else if (hys_counter>hys_threshold) { + hys_type = true; // DFP + hys_counter=0; + } + } + + public boolean isAvailable() { + return DFPHWAvailable(); + } + + public boolean useExtension() { + return DFPUseDFP(); + } + + public boolean suitableForExtension(int nDigits, int scale) { + return (nDigits < 17 && scale >= -398 && scale < 369); + } + + public int add(BigDecimal res, BigDecimal lhs, BigDecimal rhs) { + int resExp =-(Math.max(lhs.scale(), rhs.scale())); + /* Precision = 0, rounding = UNNECESSARY */ + if (resExp >=-398 && resExp<=369) { + if (DFPScaledAdd(res, getlaside(rhs), getlaside(lhs), resExp+398)) { + // we can and out the flags because we don't have + // a sense of the exponent/precision/sign + // of this result, nor do we want to use DFP hw + // to figure it out, so we do not cache anything + + //set res as DFP - (already set to 00) + + // because DFP add takes the exclusive or of the sign bits + //for the result, need to make sure result of add 0 by -0 + //doesn't store a negative sign... + long laside = getlaside(res); + if (isDFPZero(laside)) { + laside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, laside); + } + return HARDWARE_OPERATION_SUCCESS; + } + } + return HARDWARE_OPERATION_FAIL; + } + + public int add(BigDecimal res, BigDecimal lhs, BigDecimal rhs, MathContext set) { + boolean passed = false; + int prec = set.getPrecision(); + int rm = set.getRoundingMode().ordinal(); + long lhslaside = getlaside(lhs); + long rhslaside = getlaside(rhs); + + // need to special case this since DFP hardware + // doesn't conform to BigDecimal API when adding + // to a 0.. + if (prec != 0 && set.getRoundingMode().ordinal() != BigDecimal.ROUND_UNNECESSARY) { + boolean lZero = isDFPZero(lhslaside); + boolean rZero = isDFPZero(rhslaside); + + if (lZero || rZero) { + if (!lZero) { + clone(lhs, res); // rhs is zero + if (rhs.scale() > lhs.scale()) { + if (set.getPrecision()-rhs.precision() >0) { + clone(res.setScale(Math.abs(-rhs.scale())), res); //might return BI + } + } + } else if (!rZero) { + clone(rhs, res); // lhs is zero + if (lhs.scale() > rhs.scale()) { + if (set.getPrecision()-rhs.precision() >0) { + clone(res.setScale(Math.abs(-lhs.scale())), res); //might return BI + } + } + } else { + BigDecimal temp = BigDecimal.valueOf(0, Math.max(lhs.scale(), rhs.scale())); // both operands are zero + clone(temp, res); //CMVC 136111 -- res could be one of statics (shared) + } + + if (set != MathContext.UNLIMITED) { + if (finish(res, set.getPrecision(), set.getRoundingMode().ordinal()) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + + } + return HARDWARE_OPERATION_SUCCESS; + } + } + + // we can and out the flags because we don't have + // a sense of the exponent/precision/sign + // of this result, nor do we want to use DFP hw + // to figure it out, so we do not cache anything + + // fast path for MathContext64 + if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN) { + if (DFPAdd(res, rhslaside, lhslaside, 64, 0, 0)) { + passed =true; + } + } else if (prec == 0) { // same as scaled DFPAddition + int resExp =-(Math.max(lhs.scale(), rhs.scale())); + if (resExp >=-398 && resExp <= 369) { + if (DFPScaledAdd(res, rhslaside, lhslaside, resExp+398)) { + //set res as DFP - (already set to 00) + passed = true; + } + } + } else if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { // fast path for NO ROUNDING, as well as the ArithmeticException + if (DFPAdd(res, rhslaside, lhslaside, 0, 0, 0)) { + performHardwareUsageHeuristic(set, -3); + // set res as DFP - (already set to 00) + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { // See if we need to throw an arithmetic exception + return HARDWARE_OPERATION_FAIL; + } + passed = true; + } + } else if (prec <=16) { // Otherwise, if a precision to round to is specified + + // NOTE: We do the following two if statements + // since the constants used for HALF_EVEN and ROUND_UP in + // the classlib do not map correctly to the DFP hardware + // rounding mode bits. All other classlib RoundingModes, however, do. + + //the default DFP rounding mode + if (rm == BigDecimal.ROUND_HALF_EVEN) + rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + else if (rm == BigDecimal.ROUND_UP) + rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + + // defect 144394 + boolean dfpPassed = prec == 16 ? + DFPAdd(res, rhslaside, lhslaside, 1, 16, rm) : + DFPAdd(res, rhslaside, lhslaside, 1, prec, rm); + if (dfpPassed) { + performHardwareUsageHeuristic(set, -3); + // set res as DFP - (already set to 00) + passed=true; + } + } + + // because DFP add takes the exclusive or of the sign bits + //for the result, need to make sure result of add 0 by -0 + //doesn't store a negative sign... + if (passed) { + long reslaside = getlaside(res); + if (isDFPZero(reslaside)) { + reslaside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, reslaside); + } + return HARDWARE_OPERATION_SUCCESS; + } + return HARDWARE_OPERATION_FAIL; + } + + public int subtract(BigDecimal res, BigDecimal lhs, BigDecimal rhs) { + + int resExp =-(Math.max(lhs.scale(), rhs.scale())); + // Precision = 0, rounding = UNNECESSARY + if (resExp >=-398 && resExp<=369) { + if (DFPScaledSubtract(res, getlaside(rhs), getlaside(lhs), resExp+398)) { + // set res as DFP - (already set to 00) + + // because DFP subtract takes the exclusive or of the sign bits + //for the result, need to make sure result of subtract 0 by -0 + //doesn't store a negative sign... + long laside = getlaside(res); + if (isDFPZero(laside)) { + laside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, laside); + } + return HARDWARE_OPERATION_SUCCESS; + + } + } + return HARDWARE_OPERATION_FAIL; + } + + public int subtract(BigDecimal res, BigDecimal lhs, BigDecimal rhs, MathContext set) { + boolean passed = false; + int prec = set.getPrecision(); + int rm = set.getRoundingMode().ordinal(); + long lhslaside = getlaside(lhs); + long rhslaside = getlaside(rhs); + + // need to special case this since DFP hardware + // doesn't conform to BigDecimal API when adding + // to a 0.. + if (prec != 0 && set.getRoundingMode().ordinal() != BigDecimal.ROUND_UNNECESSARY) { + boolean lZero = isDFPZero(lhslaside); + boolean rZero = isDFPZero(rhslaside); + if (lZero || rZero) { + if (!lZero) { + clone(lhs, res); // rhs is zero + if (rhs.scale() > lhs.scale()) { + if (set.getPrecision()-rhs.precision() >0) { + clone(res.setScale(Math.abs(-rhs.scale())), res); //might return BI + } + } + } else if (!rZero) { + clone(rhs.negate(), res); // lhs is zero + if (lhs.scale() > rhs.scale()) { + if (set.getPrecision()-rhs.precision() >0) { + clone(res.setScale(Math.abs(-lhs.scale())), res); //might return BI + } + } + } else { + BigDecimal temp = BigDecimal.valueOf(0, Math.max(lhs.scale(), rhs.scale())); // both operands are zero + clone(temp, res); //CMVC 136111 -- res could be one of statics (shared) + } + + if (set != MathContext.UNLIMITED) { + if (finish(res, set.getPrecision(), set.getRoundingMode().ordinal()) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + } + return HARDWARE_OPERATION_SUCCESS; + } + } + + // at this point, not dealing with 0s + // fast path for MathContext64 + if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN) { + if (DFPSubtract(res, rhslaside, lhslaside, 64, 0, 0)) { + // set res as DFP - (already set to 00) + passed=true; + } + } else if (prec == 0) { // same as DFPScaledSubtract + int resExp =-(Math.max(lhs.scale(), rhs.scale())); + if (resExp >=-398 && resExp<=369) { + if (DFPScaledSubtract(res, rhslaside, lhslaside, resExp+398)) { + // we can and out the flags because we don't have + // a sense of the exponent/precision/sign + // of this result, nor do we want to use DFP hw + // to figure it out, so we do not cache anything + + // set res as DFP - (already set to 00) + passed = true; + } + } + } else if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { // fast path for NO ROUNDING, as well as the ArithmeticException + if (DFPSubtract(res, rhslaside, lhslaside, 0, 0, 0)) { + performHardwareUsageHeuristic(set, -3); + // set res as DFP - (already set to 00) + // See if we need to throw an arithmetic exception + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + passed=true; + } + } else if (prec <=16) { // Otherwise, if a precision to round to is specified + + /* NOTE: We do the following two if statements + * since the constants used for HALF_EVEN and ROUND_UP in + * the classlib do not map correctly to the DFP hardware + * rounding mode bits. All other classlib RoundingModes, however, do. + */ + + //the default DFP rounding mode + if (rm == BigDecimal.ROUND_HALF_EVEN) { + rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (rm == BigDecimal.ROUND_UP) { + rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + // defect 144394 + boolean dfpPassed = prec == 16 ? + DFPSubtract(res, rhslaside, lhslaside, 1, 16, rm) : + DFPSubtract(res, rhslaside, lhslaside, 1, prec, rm); + if (dfpPassed) { + performHardwareUsageHeuristic(set, -3); + // set res as DFP - (already set to 00) + passed=true; + } + } + + // because DFP subtracts takes the exclusive or of the sign bits + //for the result, need to make sure result of subtract 0 by -0 + //doesn't store a negative sign... + if (passed) { + long reslaside = getlaside(res); + if (isDFPZero(reslaside)) { + reslaside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, reslaside); + } + return HARDWARE_OPERATION_SUCCESS; + } + return HARDWARE_OPERATION_FAIL; + } + + public int multiply(BigDecimal res, BigDecimal lhs, BigDecimal rhs) { + + int resExp =-(lhs.scale()+rhs.scale()); + + /* Precision = 0, rounding = UNNECESSARY */ + if (resExp >=-398 && resExp<=369) { + if (DFPScaledMultiply(res, getlaside(rhs), getlaside(lhs), resExp+398)) { + // set res as DFP - (already set to 00) + + // because DFP subtract takes the exclusive or of the sign bits + //for the result, need to make sure result of subtract 0 by -0 + //doesn't store a negative sign... + long laside = getlaside(res); + if (isDFPZero(laside)) { + laside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, laside); + } + return HARDWARE_OPERATION_SUCCESS; + } + } + return HARDWARE_OPERATION_FAIL; + } + + public int multiply(BigDecimal res, BigDecimal lhs, BigDecimal rhs, MathContext set) { + + boolean passed = false; + int prec = set.getPrecision(); + int rm = set.getRoundingMode().ordinal(); + long lhslaside = getlaside(lhs); + long rhslaside = getlaside(rhs); + + // fast path for MathContext64 + if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN) { + if (DFPMultiply(res, rhslaside, lhslaside, 64, 0, 0)) { + // set res as DFP - (already set to 00) + passed = true; + } + } else if (prec == 0) { // same as DFPScaledMultiply + int resExp =-(lhs.scale()+rhs.scale()); + if (resExp >=-398 && resExp<=369) { + if (DFPScaledMultiply(res, rhslaside, lhslaside, resExp+398)) { + // set res as DFP - (already set to 00) + // because DFP multiply takes the exclusive or of the sign bits + //for the result, need to make sure result of multiply by 0 + //doesn't store a negative sign... + passed = true; + } + } + } else if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { // fast path for NO ROUNDING, as well as the ArithmeticException + if (DFPMultiply(res, rhslaside, lhslaside, 0, 0, 0)) { + // set res as DFP - (already set to 00) + + // See if we need to throw an arithmetic exception + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + passed=true; + } + } else if (prec <= 16) { // Otherwise, if a precision to round to is specified + /* NOTE: We do the following two if statements + * since the constants used for HALF_EVEN and ROUND_UP in + * the classlib do not map correctly to the DFP hardware + * rounding mode bits. All other classlib RoundingModes, however, do. + */ + + //the default DFP rounding mode + if (rm == BigDecimal.ROUND_HALF_EVEN) { + rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (rm == BigDecimal.ROUND_UP) { + rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + + // defect 144394 + boolean dfpPassed = prec == 16 ? + DFPMultiply(res, rhslaside, lhslaside, 1, 16, rm) : + DFPMultiply(res, rhslaside, lhslaside, 1, prec, rm); + if (dfpPassed) { + // set res as DFP - (already set to 00) + passed =true; + } + } + + // because DFP multiply takes the exclusive or of the sign bits + // for the result, need to make sure result of multiply by 0 + // doesn't store a negative sign... + if (passed) { + long reslaside = getlaside(res); + if (isDFPZero(reslaside)) { + reslaside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, reslaside); + } + return HARDWARE_OPERATION_SUCCESS; + } + return HARDWARE_OPERATION_FAIL; + } + + public int divide(BigDecimal res, BigDecimal lhs, BigDecimal rhs) { + + long rhslaside = getlaside(rhs); + if (isDFPZero(rhslaside)) { + badDivideByZero(); + } + boolean passed = false; + long lhslaside = getlaside(lhs); + + /* + * Interpreted return value: + * Returns -1 if not JIT compiled. + * + * JIT compiled return value: + * Return 1 if JIT compiled and DFP divide is successful. + * Return 0 if JIT compiled, but DFP divide was inexact + * Return -2 if JIT compiled, but other exception (i.e. overflow) + */ + + // we need this in order to throw a "non-terminating decimal expansion" error + int desiredPrecision = (int)Math.min(lhs.precision() + Math.ceil(10*rhs.precision()/3),Integer.MAX_VALUE); + + int ret = DFPDivide(res, rhslaside, lhslaside, true, 0, 0, 0); + + // we passed, just check for non-terminating decimal expansion + if (ret == 1) { + if (res.precision() > desiredPrecision) { + /*[MSG "K0460", "Non-terminating decimal expansion"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0460")); //$NON-NLS-1$ + } + // set res as DFP - (already set to 00) + passed=true; + } + + //otherwise, we had an inexact, or failure... so we'll continue on slow path + + // because DFP divide takes the exclusive or of the sign bits + //for the result, need to make sure result of multiply by 0 + //doesn't store a negative sign... + if (passed) { + long reslaside = getlaside(res); + if (isDFPZero(reslaside)) { + reslaside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, reslaside); + } + return HARDWARE_OPERATION_SUCCESS; + } + + return HARDWARE_OPERATION_FAIL; + } + + public int divide(BigDecimal res, BigDecimal lhs, BigDecimal rhs, MathContext set) { + + long rhslaside = getlaside(rhs); + if (isDFPZero(rhslaside)) { + badDivideByZero(); + } + long lhslaside = getlaside(lhs); + int prec = set.getPrecision(); + int rm = set.getRoundingMode().ordinal(); + boolean passed=false; + + // fast path for MathContext64 + if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN) { + int ret = DFPDivide(res, rhslaside, lhslaside, false, 64, 0, 0); + if (ret == 1) { + // set res as DFP - (already set to 00) + passed = true; + } + } else if (prec <= 16) { + + //the default DFP rounding mode + if (rm == BigDecimal.ROUND_HALF_EVEN) { + rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (rm == BigDecimal.ROUND_UP) { + rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + + // defect 144394 + int ret = prec == 16 ? + DFPDivide(res, rhslaside, lhslaside, true, 1, 16, rm) : + DFPDivide(res, rhslaside, lhslaside, true, 1, prec, rm); + if (ret == 0 && rm == BigDecimal.ROUND_UNNECESSARY) { + /*[MSG "K0461", "Inexact result requires rounding"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0461")); //$NON-NLS-1$ + } + //otherwise, we divide perfectly and returned 1, or divided + //and got inexact (in the absence of checking for ROUND_UNNECESSARY + //but that's ok because we had: + // REREOUND + TGDT + CHECKINEXACT + + //d120228 + if (ret == 1) { + performHardwareUsageHeuristic(set, 10); + // set res as DFP - (already set to 00) + passed = true; + } + } + // because DFP divide takes the exclusive or of the sign bits + //for the result, need to make sure result of multiply by 0 + //doesn't store a negative sign... + if (passed) { + long reslaside = getlaside(res); + if (isDFPZero(reslaside)) { + reslaside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, reslaside); + } + return HARDWARE_OPERATION_SUCCESS; + } + + return HARDWARE_OPERATION_FAIL; + } + + public int negate(BigDecimal res, MathContext set) { + + int signum = res.signum(); + int flags = getflags(res); + long laside = getlaside(res); + // we're going to cache a new sign bit... + + flags |= 0x4; + + // need to flip DFP sign bit and cached sign + if (signum == -1) { + laside &= 0x7FFFFFFFFFFFFFFFL; //flip DFP sign bit + flags &= 0xFFFFFF9F; //clear the cached sign bits + flags |= ( 1 << 5) & 0x60;// ispos + } + else if (signum == 1) { + laside |= 0x8000000000000000L; //flip DFP sign bit + flags &= 0xFFFFFF9F; //clear the cached sign bits + flags |= (3 << 5) & 0x60; // isneg + } + if (getbi(res) != null) { + setbi(res, getbi(res).negate()); + } + setflags(res, flags); + setlaside(res, laside); + + return HARDWARE_OPERATION_SUCCESS; + } + + public int compareTo(BigDecimal lhs, BigDecimal rhs) { + + int res = DFPCompareTo(getlaside(lhs), getlaside(rhs)); + if (res != -2) { + return res; + } + return HARDWARE_OPERATION_FAIL; + } + + public int getScale(BigDecimal bd) { + + int myscale = getscale(bd); + // have we cached it? + if ((getflags(bd) & 0x8) != 0) { + return myscale; + } + + //caching it + + setflags(bd, getflags(bd) | 0x8); //cache on + + int newExp = DFPExponent(getlaside(bd)); + if (newExp == 1000) { + myscale = -(extractDFPExponent(getlaside(bd))-398); + } else { + myscale = -(newExp-398); + } + setscale(bd, myscale); + return myscale; + } + + public int setScale(BigDecimal bd, int scale) { + + if (-scale >= -398 && -scale <= 369) { + int ret = DFPSetScale(bd, getlaside(bd), -scale+398, false, 0, true); + if (ret == 1) { + if (DFPPerformHysteresis()) { + performHardwareUsageHeuristic(5); + } + + /* cache - SGP ESRR */ + + // set representation to DFP + // (already 00) + + // because DFPSetScale maintains the sign of the DFP + // -23 might get scaled down to -0 + long laside = getlaside(bd); + int flags = getflags(bd); + if (isDFPZero(laside)) { + laside &= 0x7FFFFFFFFFFFFFFFL; + flags |= 0x4; + flags &= 0xFFFFFF9F; //clear signum bits for 0 + } + else { + // cache the sign of the src + flags|= 0x4; + flags |= (bd.signum()<<5)&0x60; + } + + // cache the exponent + flags|=0x8; + //NOTE: We do not cache precision! + flags&=0xFFFFFFEF; //clear prec cache bit + + setscale(bd, scale); + setflags(bd, flags); + setlaside(bd, laside); + + return HARDWARE_OPERATION_SUCCESS; + } + else if (ret == 0) { + /*[MSG "K0455", "Requires rounding: {0}"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0455", Long.toString(scale))); //$NON-NLS-1$ + } + } + + return HARDWARE_OPERATION_FAIL; + } + + public int setScale(BigDecimal bd, int scale, int roundingMode) { + + if (-scale >= -398 && -scale <= 369) { + + // If the rounding mode is UNNECESSARY, then we can set + // the scale as if we were setting in the previous API + // i.e. with no concern to rounding (the 3rd parameter) + if (roundingMode == BigDecimal.ROUND_UNNECESSARY) { + + //120991 (changed last param from false to true) + int ret = DFPSetScale(bd, getlaside(bd), -scale+398,false, 0, true); + if (ret == 1) { + if (DFPPerformHysteresis()) { + performHardwareUsageHeuristic(5); + } + + /* cache - SGP ESRR */ + + // set representation to DFP + // (already 00) + + // because DFPSetScale maintains the sign of the DFP + // -23 might get scaled down to -0 + long laside = getlaside(bd); + int flags = 0; + + if (isDFPZero(laside)) { + laside &= 0x7FFFFFFFFFFFFFFFL; + flags|=0x4; + flags&=0xFFFFFF9F; //clear signum bits for 0 + } + else { + // cache the sign of the src + flags|=0x4; + flags |=(bd.signum()<<5)&0x60; + } + + // cache the exponent + flags|=0x8; + + setscale(bd, scale); + setflags(bd, flags); + setlaside(bd, laside); + return HARDWARE_OPERATION_SUCCESS; + + } + } + else { + + //the default DFP rounding mode + if (roundingMode == BigDecimal.ROUND_HALF_EVEN) { + roundingMode = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (roundingMode == BigDecimal.ROUND_UP) { + roundingMode = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + int ret = DFPSetScale(bd, getlaside(bd), -scale+398,true, roundingMode, false); + if (ret == 1) { + if (DFPPerformHysteresis()) { + performHardwareUsageHeuristic(5); + } + + /* cache - SGP ESRR */ + + // set representation to DFP + // (already 00) + + // because DFPSetScale maintains the sign of the DFP + // -23 might get scaled down to -0 + long laside = getlaside(bd); + int flags = 0; + + if (isDFPZero(laside)) { + laside &= 0x7FFFFFFFFFFFFFFFL; + flags |= 0x4; + flags &= 0xFFFFFF9F; //clear signum bits for 0 + } + else { + // cache the sign of the src + flags |= 0x4; + flags |= (bd.signum()<<5)&0x60; + } + + // cache the exponent + flags |= 0x8; + setscale(bd, scale); + setflags(bd, flags); + setlaside(bd, laside); + + return HARDWARE_OPERATION_SUCCESS; + } + } + } + return HARDWARE_OPERATION_FAIL; + } + + public String toStringNoDecimal(BigDecimal bd) { + // Get the unscaled value; + long laside = getlaside(bd); + long lVal = DFPUnscaledValue(laside); + if (lVal == Long.MAX_VALUE) { + lVal = DFPBCDDigits(laside); + if (lVal == 10) { + lVal = extractDFPDigitsBCD(laside); + } + // now extract each 4 bit BCD digit from left to right + long val=0; //to store the result + int i=0; + while (lVal!= 0) { + val += (lVal & 0xF) * powerOfTenLL(i++); + lVal >>>= 4; + } + //is the sign negative? + return Long.toString(val * bd.signum()); + } else { + return Long.toString(lVal); + } + } + + public String toString(BigDecimal bd, int length) { + // Get the exponent + // Need to store it as a long since we may have + // stored Long.MIN_VALUE (which needs to be printed + // to screen as Long.MIN_VALUE + + long actualExp = -(long)bd.scale(); + + // Get the precision + int precision = bd.precision(); + + // Get the unscaled value; + long laside = getlaside(bd); + long bcd = DFPBCDDigits(laside); + if (bcd == 10) + bcd = extractDFPDigitsBCD(laside); + + long adjExp= actualExp + precision -1; + + // two cases to consider: + /* + * case 1: precision > 1 + * singlenumber.remaining numbersE(+/-adjusted exponent) + * case 2: else + * numberE(+/-adjusted exponent) + */ + + int expPrecision = numDigits(adjExp); + + // Fill 'er up + + // the character array to fill up + char [] str; + int index=0; + + if (length <=22) + str = (char [])thLocalToString.get(); + else + str = new char [ length ]; + + // the sign + if (bd.signum() == -1) { + str[index++] = '-'; + } + + // the first digit + str[index++] = (char)(digitAtBCD(bcd,precision,0)|0x0030); + + if (precision > 1) { + + // the decimal dot + str[index++] = '.'; + + // rest of the digits + for (int i=0;i < precision-1 ;i++) + str[index++] = (char)(digitAtBCD(bcd,precision,i+1)|0x0030); + } + + // E + str[index++] = 'E'; + + // the + + if (actualExp>0) + str[index++] = '+'; + else if (actualExp<0) + str[index++] = '-'; + + // exponent digits + for (int i=0; i < expPrecision; i++) + str[index++] = (char)(digitAt(adjExp,expPrecision,i)|0x0030); + + return new String(str, 0, length); + } + + public String toStringPadded(BigDecimal bd, int sign, int precision, int strlen) { + //NOTE : unscaledValue is in BCD form + char [] str; + int actualExp = -bd.scale(); + int signLen=0; + if (sign == -1) + signLen = 1; + long laside = getlaside(bd); + // Get the unscaled value; + long unscaledValue= DFPBCDDigits(laside); + if (unscaledValue == 10) { + unscaledValue = extractDFPDigitsBCD(laside); + } + // if scale is less than precision, won't have + // any leading zeros, and our number will have a decimal + // point somewhere in the middle... + + /* + * 1234 scale 1 = 123.4 + * 1234 scale 2 = 12.34 + * 1234 scale 3 = 1.234 + * 123400 scale 3 = 123.400 <-- need to handle trailing zeros for BI rep + * 123400 scale 5 = 12340.0 <-- need to handle trailing zeros for BI rep + * + * NOTE: don't need to handle scale <= 0 since this is taken care of + * in other branches in toStringHelper + */ + if (-actualExp < precision) { + int i=0; + + // for LL + // 1 no need to fill with trailing zeros + // 2 lay down sign + // 3 lay down all digits after decimal point + // 4 lay down digits before decimal point + + int length= signLen + 1 /*for .*/ + precision; + + if (length <=22) + str = (char [])thLocalToString.get(); + else + str = new char [ length ]; + int start=0; + int decimalPointLoc = length-(-actualExp)-1; + + // 2 Place sign + if (signLen !=0) { + str[start++]='-'; + } + + int curBCD = 0; + + //3 lay down all digits after decimal point + for (i=(length-1); i > decimalPointLoc; i--) { + curBCD = (int)(unscaledValue & 0xF); + unscaledValue >>>=4; + str[i] = (char)(curBCD|0x0030); + } + + // lay down decimal point + str[i--]='.'; + + //4 lay down all digits before decimal point + for (;i >=start; i--) { + curBCD = (int) (unscaledValue & 0xF); + unscaledValue >>>=4; + str[i] = (char)(curBCD|0x0030); + } + } + else { + // easy case.. where scale >= precision + + /* + * 1234 scale 4 = 0.1234 + * 1234 scale 5 = 0.01234 + * 1234 scale 6 = 0.001234 + */ + + int numZeros = -actualExp - precision; + + // for both LL & BI + // 1 fill with zeros + // 2 lay down sign & lay down decimal point + // 3 lay down all digits + + int length= signLen + 1 /*for 0*/ + + 1 /*for .*/+ numZeros + precision; + + if (length <=22) + str = (char [])thLocalToString.get(); + else + str = new char [ length ]; + int start=0; + int i=0; + + //1 Fill with 0 + Arrays.fill(str,0,length,'0'); + + //2 Place sign + if (signLen !=0) + str[start++]='-'; + + //2 skip leading zero + start++; + + //2 Place decimal point + str[start++]='.'; + + //2 skip more leading zeros that occur after decimal point + start+=(-actualExp - precision); + + // fill up laside bytes (from back to front) + int curBCD=0; + for (i=length-1; i >= start; i--) { + curBCD = (int) (unscaledValue & 0xF); + unscaledValue >>>=4; + str[i] = (char)(curBCD|0x0030); + } + } + + return new String(str, 0, strlen); + } + + public int valueOf(BigDecimal res, long value, int scale) { + + if (DFPUseDFP()) { + if (value == 0 && scale == 0) { + createZero(res); + return HARDWARE_OPERATION_SUCCESS; + } + + if (value <= 9999999999999999L && value >= -9999999999999999L && -scale>= -398 && -scale<= 369) { + + // NOTE: When we don't specify rounding in DFP, we'll never + // fail, so don't bother checking the return value + if (DFPLongExpConstructor(res, value, -scale + 398, 0, 0, 0, false)) { + int tempFlags = getflags(res); + /* cache: SGP ESRR */ + + // store DFP representation + // (already 00) + + // cache the exponent for all DFP paths + tempFlags|=0x8; //cache on + setscale(res, scale); + + // cache the sign for DFP, on all paths + tempFlags|=0x4; //cache on + if (value < 0) { + tempFlags |= 0x60; //isneg + } else if (value > 0) { + tempFlags |= 0x20; //ispos + //iszero is already 00 + } + setflags(res, tempFlags); + return HARDWARE_OPERATION_SUCCESS; + } + } + } + + return HARDWARE_OPERATION_FAIL; + } + + public int round(BigDecimal res, int precision, int roundingMode) { + + // Only enter here iff precision > 0 + if (res.precision() > precision) { // and only perform if request is shorter then us + long laside = getlaside(res); + int flags = getflags(res); + long bcd = DFPBCDDigits(laside); + if (bcd == 10) { + bcd = extractDFPDigitsBCD(laside); + } + + if (roundingMode== BigDecimal.ROUND_UNNECESSARY) { + if (!allzeroBCD(bcd, res.precision() - precision)) { + /*[MSG "K0468", "Rounding mode unnecessary, but rounding changes value"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0468")); //$NON-NLS-1$ + } + } + + //the default DFP rounding mode + if (roundingMode == BigDecimal.ROUND_HALF_EVEN) { + roundingMode = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (roundingMode == BigDecimal.ROUND_UP) { + roundingMode = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + if (!DFPRound(res, laside, precision, roundingMode)) { + return HARDWARE_OPERATION_FAIL; + } else { + /* cache - SGP ESRR */ + // if successful, update the precision cache... + flags = getflags(res); + flags |= 0x10; //cache on + flags &= 0x7F; + flags |= precision << 7; + + //exponent may have changed, but we don't know + //to what... + flags &= 0xFFFFFFF7; //clear exponent cache bit + setflags(res, flags); + } + + // if the result is still in DFP and is 0, make + // sure the sign bit is off... + laside = getlaside(res); + if ((flags & 0x3) == 0x0 && isDFPZero(laside)) { + laside &= 0x7FFFFFFFFFFFFFFFL; + setlaside(res, laside); + } + } + + return HARDWARE_OPERATION_SUCCESS; + } + + public int convertToLongLookaside(BigDecimal res) { + + long laside = getlaside(res); + int flags = getflags(res); + //quick check for 0 + if (laside == dfpZERO) { + + // set representation as long lookaside + flags &= 0xFFFFFFFC; //clear bits + flags |= 0x00000001; + + // reset exponent + setscale(res, 0); + // set long lookaside + setlaside(res, 0); + + // cache the precision of 1 + flags &= 0x7F; // clear the cached precision + flags |= 0x10; //caching the precision + flags |= 1 << 7; //precision of 1 + } + else { + + // need to store representation and new long lookaside last + // since helper functions that are called + // depend on the correct internal representation flag bit + + int signum = res.signum();; + + //store the exponent + setscale(res, res.scale()); + + //cache the precision + int prec = res.precision(); + flags &= 0x7F; // clear the cached precision + flags &= 0xFFFFFFEF;//clear bits + flags |= 0x10; //cache on + flags |= prec << 7; + + long lVal = DFPUnscaledValue(laside); + + if (lVal == Long.MAX_VALUE) { + lVal = DFPBCDDigits(laside); + if (lVal == 10) { + lVal = extractDFPDigitsBCD(laside); + } + // now extract each 4 bit BCD digit from left to right + long val = 0; //to store the result + int i = 0; + while (lVal!= 0) { + val += (lVal & 0xF) * powerOfTenLL(i++); + lVal >>>= 4; + } + + //is the sign negative? + laside = val * signum; + } else { + laside = lVal; + } + + // store representation as long lookaside + flags &= 0xFFFFFFFC; + flags |= 0x00000001; + setlaside(res, laside); + } + setflags(res, flags); + // need to make sure bi is not cached by previous calls to unscaled value + setbi(res, null); + + return HARDWARE_OPERATION_SUCCESS; + } + + public int convertToBigInteger(BigDecimal res) { + + long laside = getlaside(res); + int flags = getflags(res); + //quick check for 0 + if (laside == dfpZERO) { + + //store BigInteger representation + flags &= 0xFFFFFFFC; //clear bits + flags |= 0x00000002; + + //clear exponent + setscale(res, 0); + + //store BI + setbi(res, BigInteger.ZERO); + + // cache the precision of 1 + flags&=0x7F; // clear the cached precision + flags|=0x10; //caching the precision + flags |= 1 << 7; //precision of 1 + } else { + + // need to store representation last + // since helper functions that are called + // depend on the correct internal representation flag bit + + //store the exponent + setscale(res, res.scale()); + + //store the BigInteger + + setbi(res, res.unscaledValue()); + + /* cache - SGP ESRR */ + + //cache the precision + int prec = res.precision(); + flags &= 0x7F; // clear the cached precision + flags |= 0x10; //cache on + flags |= prec << 7; + + // store representation as BigInteger + flags &= 0xFFFFFFFC; //clear bits + flags |= 0x00000002; + } + setlaside(res, laside); + setflags(res, flags); + + return HARDWARE_OPERATION_SUCCESS; + } + + public int convertToExtension(BigDecimal res) { + + int flags = getflags(res); + BigInteger bi = getbi(res); + int scale = getscale(res); + long laside =getlaside(res); + // from BI to DFP + if ((flags & 0x3) == 0x2 && + bi.compareTo(MAXDFP64) <= 0 && + bi.compareTo(MINDFP64) >=0 && + scale > -369 && scale < 398) { + + long lint = bi.longValue(); + + // NOTE: When we don't specify rounding in DFP, we'll never + // fail, so don't bother checking the return value + if (DFPLongExpConstructor(res, lint, -scale + 398, 0, 0, 0, false)) { + + /* cache: SGP ESRR */ + + // store DFP representation + flags &= 0xFFFFFFFC; // clear rep bits + //sets the bits to (00) + + // cache the exponent + flags |= 0x8; //cache on + //res.exp already stores the value + + // cache the sign + flags |= 0x4; //cache on + flags &= 0xFFFFFF9F; //clear signum + if (bi.signum() < 0) { + flags |= 0x60; //isneg + } else if (bi.signum() > 0) { + flags |= 0x20; //ispos + } else { + flags &= 0xFFFFFF9F; + } + + // fix to d124362 + setbi(res, null); + } + } + + // from LL to DFP + else if ((flags & 0x3) == 0x1 && + laside <= 9999999999999999L && + laside >= -9999999999999999L && + scale > -369 && scale < 398) { + + int signum = res.signum(); + + // NOTE: When we don't specify rounding in DFP, we'll never + // fail, so don't bother checking the return value + if (DFPLongExpConstructor(res, laside, -scale + 398, 0, 0, 0, false)) { + + /* cache: SGP ESRR */ + + // store DFP representation + flags &= 0xFFFFFFFC; // clear rep bits + //sets the bits to (00) + + // cache the exponent + flags |= 0x8; //cache on + //res.exp already stores the value + + // cache the sign + flags |= 0x4; //cache on + flags &= 0xFFFFFF9F; //clear signum + if (signum < 0) { + flags |= 0x60; //isneg + } else if (signum > 0) { + flags |= 0x20; //ispos + } else { + flags &= 0xFFFFFF9F; + } + } + } + + setflags(res, flags); + + return HARDWARE_OPERATION_SUCCESS; + } + + public int significance(BigDecimal bd) { + + int tempFlags = getflags(bd); + long laside = getlaside(bd); + + // we're caching it + tempFlags |= 0x10; // cache on + tempFlags &= 0x7F; //clear pre-existing bits + + int sig = DFPSignificance(laside); + if (sig < 0) { + long digits = DFPBCDDigits(laside); + if (digits == 10) { + digits = extractDFPDigitsBCD(laside); + } + int nlz = Long.numberOfLeadingZeros(digits); + nlz>>=2; + nlz=16-nlz; + + // Preceding algorithm would return 0 for 0 + // and we need it to return a precision of 1 + if (nlz == 0) + nlz++; + + tempFlags |= nlz << 7; + setflags(bd, tempFlags); + return nlz; + } + else { + // DFPSignificance would return 0 for 0 + // and we need it to return a precision of 1 + if (sig ==0) { + sig++; + } + tempFlags |= sig << 7; + setflags(bd, tempFlags); + return sig; + } + } + + public int signum(BigDecimal bd) { + + int tempFlags = getflags(bd); + long laside = getlaside(bd); + // is it cached? + if ((tempFlags&0x4)!=0) { + return (((tempFlags & 0x00000060) << 25) >>30); + } + + //we're going to cache it + tempFlags |= 0x4; //cache on + + //check for negative first + if ((laside & 0x8000000000000000L) == 0x8000000000000000L) { + tempFlags |= 0x60; //store negative + setflags(bd, tempFlags); + return -1; + } + + //now we're checking for positive or zero + long mask = DFPBCDDigits(laside); + if (mask == 10) { + //still haven't jitted the method + if (isDFPZero(laside)) { + tempFlags&=0xFFFFFF9F; //clear the signum cache (00) + setflags(bd, tempFlags); + return 0; + } else { + tempFlags&=0xFFFFFF9F; //clear the signum cache + tempFlags|=0x20; //store positive + setflags(bd, tempFlags); + return 1; + } + } else if (mask !=0) { + tempFlags&=0xFFFFFF9F; //clear the signum cache + tempFlags|=0x20; //store positive + setflags(bd, tempFlags); + return 1; + } else { + tempFlags&=0xFFFFFF9F; //clear the signum cache (00) + } + setflags(bd, tempFlags); + return 0; + } + + public BigInteger unscaledValue(BigDecimal bd) { + long laside = getlaside(bd); + long lVal = DFPUnscaledValue(laside); + if (lVal != Long.MAX_VALUE) { + setbi(bd, BigInteger.valueOf(lVal)); + return getbi(bd); + } else { + lVal = DFPBCDDigits(laside); + if (lVal == 10) { + lVal = extractDFPDigitsBCD(laside); + } + + //check for zero + if (lVal == 0) { + setbi(bd, BigInteger.ZERO); + return getbi(bd); + } + + // now extract each 4 bit BCD digit from left to right + long val = 0; //to store the result + int i = 0; + while (lVal != 0) { + val += (lVal & 0xF) * powerOfTenLL(i++); + lVal >>>= 4; + } + setbi(bd, BigInteger.valueOf(bd.signum() * val)); + return getbi(bd); + } + } + + public int createZero(BigDecimal res) { + setlaside(res, dfpZERO); + setbi(res, null); + setscale(res, 0); + int flags = getflags(res); + + flags|=0x4; //cache on + + // cache the precision of 1 + flags&=0x7F; // clear the cached precision + flags|=0x10; //caching the precision + flags |= 1 << 7; //precision of 1 + + // cache the exponent (exp already 0) + flags|=0x8; //cache on + setflags(res, flags); + + return HARDWARE_OPERATION_SUCCESS; + } + + public int intConstructor(BigDecimal res, int value, MathContext set) { + // quick path for 0e0 + if (value == 0) { + createZero(res); + return HARDWARE_OPERATION_SUCCESS; + } + + // cache the exp for all DFP paths + // exp remains 0 + int flags = getflags(res); + flags |= 0x8; //cache on + + // cache the sign for DFP, on all paths + flags|=0x4; //cache on + if (value < 0) { + flags|=0x60; //isneg + } else if (value > 0) { + flags|=0x20; //ispos + } + //iszero is already 00 + + // we're going to take the full blown path to + // constructing a DFP internal representation + + int prec = set.getPrecision(); + int rm = set.getRoundingMode().ordinal(); + + // fast path for MathContext64 + if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN) { + if (DFPIntConstructor(res, value, 64, 0, 0)) { + + // We assume in the worst case that the precision and + // exp remain the same since the number of digits + // is at most 16. If we passed in 999999999999999999be767 + // and rounded to +inf, we'd get overflow, fail and take + // the slow path anyway. + + /* cache: SGP ESRR */ + + // cache the precision + flags |= 0x10; + flags |= numDigits(value) << 7; + + // store DFP representation + // (representation bits already 00) + setflags(res, flags); + return HARDWARE_OPERATION_SUCCESS; + } + } + + // fast path for NO ROUNDING, as well as the ArithmeticException + if ((prec == 0) || (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) || + (prec > 16)) { + + /* This case catches: + * -when no rounding is required + * -if rounding is unnecessary and precision !=0, check + * to see that result wasn't inexact (via call to Finish) + * (the latter satisfies the API description of : + * ArithmeticException - if the result is inexact but + * the rounding mode is UNNECESSARY. + */ + + if (DFPIntConstructor(res, value, 0, 0, 0)) { + + /* cache: SGP ESRR */ + + // store DFP representation + // (representation bits already 00) + + // See if we need to throw an arithmetic exception + + /*[IF]*/ + //TODO: Return a special value in DFP hardware to improve + // this case + /*[ENDIF]*/ + + if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { + setflags(res, flags); + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + } else { + // we can cache the precision and exp + // since no rounding meant that (no rounding) + + // cache the precision + flags |= 0x10; //cache on + flags |= numDigits(value) << 7; + setflags(res, flags); + + } + return HARDWARE_OPERATION_SUCCESS; + } + // Otherwise, if a precision to round to is specified + } else if (prec <= 16) { + + /* NOTE: We do the following two if statements + * since the constants used for HALF_EVEN and ROUND_UP in + * the classlib do not map correctly to the DFP hardware + * rounding mode bits. All other classlib RoundingModes, however, do. + */ + + //the default DFP rounding mode + if (rm == BigDecimal.ROUND_HALF_EVEN) { + rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (rm == BigDecimal.ROUND_UP) { + rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + + // now construct in hardware if possible + if (DFPIntConstructor(res, value, 1, prec, rm)) { + + /* cache: SGP ESRR */ + + // store DFP representation + // (representation bits already 00) + + //don't try to cache precision/exp since + //prec might be different precision(val) + + //so turn cache of exp off... + flags &= 0xFFFFFFF7; + + return HARDWARE_OPERATION_SUCCESS; + } + } + return HARDWARE_OPERATION_FAIL; + } + + public int longConstructor(BigDecimal res, long value, int scale, MathContext set) { + // don't want to send in 0 and then round with hardware + // cause it might place a crummy exponent value... + if (value == 0) { + createZero(res); + return HARDWARE_OPERATION_SUCCESS; + // otherwise, make sure the long is within 64-bit DFP range + } else if (value <=9999999999999999L && value >= -9999999999999999L && + -scale>=-398 && -scale<369) { + int flags = getflags(res); + /* cache: SGP ESRR */ + + // cache the sign for DFP, on all paths + flags|=0x4; //cache on + + if (value < 0) { + flags|=0x60; //isneg + } else if (value > 0) { + flags|=0x20; //ispos + } + //iszero is already 00 + + int prec = set.getPrecision(); + int rm = set.getRoundingMode().ordinal(); + + // fast path for MathContext64 + if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN) { + if (DFPLongExpConstructor(res, value, -scale + 398, 64, 0, 0, false)) { + + // We assume in the worst case that the precision and + // exponent remain the same since the number of digits + // is at most 16. If we passed in 999999999999999999be767 + // and rounded to +inf, we'd get overflow, fail and take + // the slow path anyway. + + /* cache: SGP ESRR */ + + // cache the precision + flags |= 0x10; //cache on + flags |= numDigits(value) << 7; + + // cache the exponent + flags |= 0x8; //cache on + + setflags(res, flags); + setscale(res, scale); + + //store DFP representation + // (already set to 00) + + return HARDWARE_OPERATION_SUCCESS; + } + } + + // fast path for NO ROUNDING, as well as the ArithmeticException + if ((prec == 0) || (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) + || (prec > 16)) { + + /* This case catches: + * -when no rounding is required + * -if rounding is unnecessary and precision !=0, check + * to see that result wasn't inexact (via call to Finish) + * (the latter satisfies the API description of : + * ArithmeticException - if the result is inexact but + * the rounding mode is UNNECESSARY. + */ + + // NOTE: When we don't specify rounding in DFP, we'll never + // fail, so don't bother checking the return value + if (this.DFPLongExpConstructor(res, value, -scale + 398, 0, 0, 0, false)) { + + // store DFP representation + // (already set to 00) + + /*[IF]*/ + //TODO: Return a special value in DFP hardware to improve + // this case + /*[ENDIF]*/ + + // See if we need to throw an arithmetic exception + if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { + setflags(res, flags); + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + } else { + + // cache the exponent + flags|=0x8; //cache on + + // cache the precision + flags |= 0x10; //cache on + flags |= numDigits(value) << 7; + + setflags(res, flags); + setscale(res, scale); + } + return HARDWARE_OPERATION_SUCCESS; + } + // Otherwise, if a precision to round to is specified + } else if (prec <=16) { + + /* NOTE: We do the following two if statements + * since the constants used for HALF_EVEN and ROUND_UP in + * the classlib do not map correctly to the DFP hardware + * rounding mode bits. All other classlib RoundingModes, however, do. + */ + + //the default DFP rounding mode + if (rm == BigDecimal.ROUND_HALF_EVEN) { + rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (rm == BigDecimal.ROUND_UP) { + rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + + // now construct in hardware if possible + if (DFPLongExpConstructor(res, value, -scale + 398, 1, prec, rm, false)) { + + //store DFP representation + // (already 00) + + //don't try to cache precision/exponent since + //prec might be different precision(val) + + // so turn caching of exponent off + setflags(res, flags); + + return HARDWARE_OPERATION_SUCCESS; + } + } + } + + return HARDWARE_OPERATION_FAIL; + } + + public int longConstructor(BigDecimal res, long value, int scale, int nDigits, int sign, MathContext set) { + int prec = set.getPrecision(); + int rm = set.getRoundingMode().ordinal(); + + // fast path for 0e0 + if (value == 0 && scale == 0) { + createZero(res); + return HARDWARE_OPERATION_SUCCESS; + } + + /* cache - SGP ESRR */ + + int flags = getflags(res); + + // cache the sign for DFP on all paths.. + flags|=0x4; //cache on + if (value != 0) { //if not-zero, then we set the val + flags|=sign; + } + + // cache the exponent for DFP on all paths.. + flags |= 0x8; //cache on + setscale(res, -scale); + + // fast path for MathContext64 + if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN) { + if (sign == 0x60) { //isneg + if (DFPLongExpConstructor(res, value, scale + 398, 64, 0, 0, true)) { + + // store DFP representation + // (already 00) + long laside = getlaside(res); + // since we use unsigned BCDs to get full 16 digits worth + // lets flip the DFP's sign bit to indicate the fact... + if (sign == 0x60) { //inseg + laside |= 0x8000000000000000l; + } + setlaside(res, laside); + /* cache - SGP ESRR */ + + // cache the precision + flags |= 0x10; + flags |= nDigits << 7; + + setflags(res, flags); + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + return HARDWARE_OPERATION_SUCCESS; + } + } + else { + if (DFPLongExpConstructor(res, value, scale + 398, 64, 0, 0, true)) { + + // We assume in the worst case that the precision and + // exponent remain the same since the number of digits + // is at most 16. If we passed in 999999999999999999be767 + // and rounded to +inf, we'd get overflow, fail and take + // the slow path anyway. + + // cache the precision + flags|=0x10; + flags |= nDigits << 7; + + setflags(res, flags); + + //store DFP representation + //(already 00) + return HARDWARE_OPERATION_SUCCESS; + } + } + } + + // fast path for NO ROUNDING, as well as the ArithmeticException + if ((prec == 0) || (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) || + (prec > 16)) { + + /* This case catches: + * -when no rounding is required + * -if rounding is unnecessary and precision !=0, check + * to see that result wasn't inexact (via call to Finish) + * (the latter satisfies the API description of : + * ArithmeticException - if the result is inexact but + * the rounding mode is UNNECESSARY. + */ + if (DFPLongExpConstructor(res, value, scale + 398, 0, 0, 0, true)) { + + // store DFP representation + // (already 00) + + // since we use unsigned BCDs to get full 16 digits worth + // lets flip the DFP's sign bit to indicate the fact... + long laside = getlaside(res); + if (sign == 0x60) { //isneg + laside |= 0x8000000000000000l; + } + setlaside(res, laside); + // See if we need to throw an arithmetic exception + if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { + + // since we use unsigned BCDs to get full 16 digits worth + // lets flip the DFP's sign bit to indicate the fact... + if (sign == 0x60) { //inseg + laside |= 0x8000000000000000l; + } + setlaside(res, laside); + setflags(res, flags); + + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + } + else { + // we can cache the precision and exponent + // since no rounding meant that (no rounding) + // cache the precision + flags|=0x10; + flags |= nDigits << 7; + setflags(res, flags); + + } + return HARDWARE_OPERATION_SUCCESS; + } + } + + // Otherwise, if a precision to round to is specified + else if (prec <=16) { + + /* NOTE: We do the following two if statements + * since the constants used for HALF_EVEN and ROUND_UP in + * the classlib do not map correctly to the DFP hardware + * rounding mode bits. All other classlib RoundingModes, however, do. + */ + + // for negative BCDs + if (sign == 0x60) { + if (DFPLongExpConstructor(res, value, scale + 398, 0, 0, 0, true)) { + + // store DFP representation + // (already 00) + + // since we use unsigned BCDs to get full 16 digits worth + // lets flip the DFP's sign bit to indicate the fact... + long laside = getlaside(res); + laside |= 0x8000000000000000l; + setlaside(res, laside); + + /* cache - SGP ESRR */ + + // can't store precision since it's going to be prec, + // but isn't just yet... + setflags(res, flags); + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + return HARDWARE_OPERATION_SUCCESS; + } + } + else { + + // NOTE: We do the following rm reversal here because + // doing so in common code above would cause the eventual + // call to roundDFP to switch them back. + + // the default DFP rounding mode + if (rm == BigDecimal.ROUND_HALF_EVEN) { + rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (rm == BigDecimal.ROUND_UP) { + rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + // for positive BCDs + if (DFPLongExpConstructor(res, value, scale + 398, 1, prec, rm, true)) { + + //store DFP representation + //(already 00) + + //don't try to cache precision/exponent since + //exp might be diff due to rounding, and precision + //may be larger than actual + + /* cache - SGP ESRR */ + + //reset caching of exponent + flags&=0xFFFFFFF7; + setflags(res, flags); + + return HARDWARE_OPERATION_SUCCESS; + } + } + } + //at this point, DFP paths were unsuccessful, want to stick with BI + return HARDWARE_OPERATION_FAIL; + } + + public int bigIntegerConstructor(BigDecimal res, BigInteger bi, int scale, MathContext set) { + + int biPrecision = bi.toString().length() + ((bi.signum() ==-1) ? -1 : 0); + + if (biPrecision < 17 && -scale <= 369 && -scale >= -398) { + + // get the long value with the appropriate sign + long val = bi.longValue(); + + // quick path for 0e0 + if (val == 0 && scale == 0) { + createZero(res); + return HARDWARE_OPERATION_SUCCESS; + } + + // otherwise, we'll need to perform DFP construction + // using the correct precision/roundingmodes + + int prec = set.getPrecision(); + int rm = set.getRoundingMode().ordinal(); + + int flags = getflags(res); + // fast path for MathContext64 + if (prec == 16 && rm == BigDecimal.ROUND_HALF_EVEN) { + if (DFPLongExpConstructor(res, val, -scale + 398, 64, 0, 0, false)) { + + // We assume in the worst case that the precision and + // exponent remain the same since the number of digits + // is at most 16. If we passed in 999999999999999999be767 + // and rounded to +inf, we'd get overflow, fail and take + // the slow path anyway. + + /* cache - SGP ESRR */ + + // cache the precision + flags |= 0x10; //cache on + flags |= numDigits(val) << 7; + + // cache the sign + flags|=0x4; //cache on + flags|= ((bi.signum() <<5) & 0x60); + + //cache the exponent + flags|=0x8; //cache on + + setflags(res, flags); + setscale(res, scale); + + // store DFP representation + // (representation bits already 00) + + return HARDWARE_OPERATION_SUCCESS; + } + } + + // fast path for NO ROUNDING, as well as the ArithmeticException + if ((prec == 0) || (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) + || (prec > 16)) { + + /* This case catches: + * -when no rounding is required + * -if rounding is unnecessary and precision !=0, check + * to see that result wasn't inexact (via call to Finish) + * (the latter satisfies the API description of : + * ArithmeticException - if the result is inexact but + * the rounding mode is UNNECESSARY. + */ + + // NOTE: When we don't specify rounding in DFP, we'll never + // fail, so don't bother checking the return value + if (DFPLongExpConstructor(res, val, -scale + 398, 0, 0, 0, false)) { + /* cache - SGP ESRR */ + + // cache the sign + flags |= 0x4; // cache on + flags |= ((bi.signum() <<5) & 0x60); + + // store DFP representation + // (representation bits already 00) + + // See if we need to throw an arithmetic exception + + /*[IF]*/ + //TODO: Return a special value in DFP hardware to improve + // this case + /*[ENDIF]*/ + + if (prec > 0 && rm == BigDecimal.ROUND_UNNECESSARY) { + setflags(res, flags); + if (finish(res, prec, rm) == HARDWARE_OPERATION_FAIL) { + return HARDWARE_OPERATION_FAIL; + } + } else { + // we can cache the precision and exponent + // since no rounding left things as is + + // cache the precision + flags|=0x10; // cache on + flags |= numDigits(val) << 7; + + //cache the exponent + flags|=0x8; // cache on + + setflags(res, flags); + setscale(res, scale); + } + return HARDWARE_OPERATION_SUCCESS; + } + } + + // Otherwise, if a precision to round to is specified + else if (prec <=16) { + + /* NOTE: We do the following two if statements + * since the constants used for HALF_EVEN and ROUND_UP in + * the classlib do not map correctly to the DFP hardware + * rounding mode bits. All other classlib RoundingModes, however, do. + */ + + //the default DFP rounding mode + if (rm == BigDecimal.ROUND_HALF_EVEN) { + rm = BigDecimal.ROUND_UP; //correct DFP HW rounding mode for HALF_EVEN + } else if (rm == BigDecimal.ROUND_UP) { + rm = BigDecimal.ROUND_HALF_EVEN; //correct DFP HW rounding mode for HALF_UP + } + + // now construct in hardware if possible + if (DFPLongExpConstructor(res, val,-scale + 398, 1, prec, rm, false)) { + + /* cache - SGP ESRR */ + + // cache the sign + flags|=0x4; //cache on + flags|=((bi.signum() <<5) & 0x60); + setflags(res, flags); + + //store DFP representation + // (representation bits already 00) + + //don't try to cache precision/exponent since + //prec might be different after rounding + return HARDWARE_OPERATION_SUCCESS; + } + } + } + return HARDWARE_OPERATION_FAIL; + } + + // DO NOT MODIFY THIS METHOD + /* The method is only called once to setup the flag DFP_HW_AVAILABLE + * Return value + * true - when JIT compiled this method, replaces it with loadconst 1 + * if user -Xnodfp hasn't been supplied + * false - if still interpreting this method or disabled by VM option + */ + private final static boolean DFPCheckHWAvailable() { + return false; + } + + // DO NOT MODIFY THIS METHOD + /* + * Return value + * true - when JIT compiled this method, replaces it with loadconst 1 + * if user -Xnodfp hasn't been supplied + * false - if still interpreting this method or disabled by VM option + */ + private final static boolean DFPHWAvailable() { + return DFP_HW_AVAILABLE; + } + + /* + * Return value + * true - when JIT compiled this method, replaces it with loadconst 1 + * if user -Xjit:disableDFPHys hasn't been supplied + * false - if still interpreting this method or disabled by JIT option + */ + private final static boolean DFPPerformHysteresis() { + return false; + } + + /* + * Return value + * true - when JIT compiled this method, replaces it with loadconst 1 + * if -Xjit:disableDFPHys has been supplied OR when hys_type becomes true + * false - when hys_type is false + */ + private final static boolean DFPUseDFP() { + return hys_type; + } + + // DO NOT MODIFY THIS METHOD + + /* NOTE: The fact we return a boolean means we kill a register + * in the cases we don't want to perform rounding. + * i.e. rndFlag = 0 or 64 since we must load and + * return a 1 value in the generated JIT code. + */ + private final static boolean DFPIntConstructor(BigDecimal bd, int val, int rndFlag, int prec, int rm) { + return false; + } + + // DO NOT MODIFY THIS METHOD + /*[IF]*/ + //TODO: Use this for the longConstructor when it's called with scale=0 + /*[ENDIF]*/ + private final static boolean DFPLongConstructor(BigDecimal bd, long val, int rndFlag, int prec, int rm) { + return false; + } + + // DO NOT MODIFY THIS METHOD + /* + * Interpreted return value: + * true - never + * false - always + * + * Jitted return value: + * true - if rounding succeeded + * false - if rounding failed + * + * Parameters: + * val - long to be converted to DFP + * biasedExp - biased exponent to be inserted into DFP + * rndFlag + * =0 - no rounding + * =1 - rounding according to prec, rm + * =64 - rounding according to MathContext64 + * prec - precision to round constructed DFP to + * rm - rm to use + * bcd - whether long is in bcd form + * + */ + private final static boolean DFPLongExpConstructor(BigDecimal bd, long val, int biasedExp, int rndFlag, int prec, int rm, boolean bcd) { + return false; + } + + // DO NOT MODIFY THIS METHOD + private final static boolean DFPScaledAdd(BigDecimal bd, long lhsDFP,long rhsDFP,int biasedExp) { + return false; + } + + // DO NOT MODIFY THIS METHOD + /* + * Parameters: + * rndFlag + * =0 - no rounding + * =1 - rounding according to prec, rm + * =64 - rounding according to MathContext64 + */ + private final static boolean DFPAdd(BigDecimal bd, long lhsDFP,long rhsDFP, int rndFlag, int precision, int rm) { + return false; + } + + // DO NOT MODIFY THIS METHOD + private final static boolean DFPScaledSubtract(BigDecimal bd, long lhsDFP,long rhsDFP,int biasedExp) { + return false; + } + + // DO NOT MODIFY THIS METHOD + /* + * Parameters: + * rndFlag + * =0 - no rounding + * =1 - rounding according to prec, rm + * =64 - rounding according to MathContext64 + */ + private final static boolean DFPSubtract(BigDecimal res, long lhsDFP, long rhsDFP, int rndFlag, int precision, int rm) { + return false; + } + + // DO NOT MODIFY THIS METHOD + private final static boolean DFPScaledMultiply(BigDecimal res, long lhsDFP,long rhsDFP,int biasedExp) { + return false; + } + + // DO NOT MODIFY THIS METHOD + /* + * Parameters: + * rndFlag + * =0 - no rounding + * =1 - rounding according to prec, rm + * =64 - rounding according to MathContext64 + */ + private final static boolean DFPMultiply(BigDecimal res, long lhsDFP, long rhsDFP, int rndFlag, int precision, int rm) { + return false; + } + + // DO NOT MODIFY THIS METHOD + /* + * Interpreted return value: + * Returns -1 if not JIT compiled. + * + * JIT compiled return value: + * 0 - ok, but inexact exception --> check UNNECESSARY + * 1 - ok, no inexact + * -1 - not ok --> try slow path + * + * rndFlag + * =0 - rounding according to MathContext64 + * =1 - rounding according to prec, rm + */ + private final static int DFPScaledDivide(BigDecimal res, long lhsDFP, long rhsDFP, int scale, int rndFlg, int rm) { + return -1; + } + + // DO NOT MODIFY THIS METHOD + /* + * Interpreted return value: + * -1 = always + * + * JIT compiled return value: + * Return 1 if JIT compiled and DFP divide is successful. + * Return 0 if JIT compiled, but DFP divide was inexact + * Return -1 if JIT compiled, but other exception (i.e. overflow) + * + * rndFlag + * =0 - no rounding + * =1 - rounding according to prec, rm + * =64 - rounding according to MathContext64 + */ + private final static int DFPDivide(BigDecimal bd, long lhsDFP, long rhsDFP, boolean checkForInexact, int rndFlag, int prec, int rm) { + return -1; //return an invalid result + } + + // DO NOT MODIFY THIS METHOD + private final static boolean DFPRound(BigDecimal bd, long dfpSrc, int precision, int rm) { + return false; + } + + // DO NOT MODIFY THIS METHOD + private final static int DFPCompareTo(long lhsDFP, long rhsDFP) { + return -2; //return an invalid result + } + + // DO NOT MODIFY THIS METHOD + private final static long DFPBCDDigits(long dfp) { + return 10; //since each digit in a BCD is from 0 to 9 + } + + // DO NOT MODIFY THIS METHOD + private final static int DFPSignificance(long dfp) { + return -1; //illegal significance + } + + // DO NOT MODIFY THIS METHOD + private final static int DFPExponent(long dfp) { + return 1000; //return a value out of the range of Double DFP + } + + // DO NOT MODIFY THIS METHOD + /* + * Interpreted return value: + * -1 = always + * + * JIT compiled return value: + * Return 1 if passed + * Return 0 if JIT compiled, but inexact result + * Return -1 if JIT compiled, but other failure + * + */ + private final static int DFPSetScale(BigDecimal bd, long srcDFP, int biasedExp, boolean round, int rm, boolean checkInexact) { + return -1; + } + + // DO NOT MODIFY THIS METHOD + private final static long DFPUnscaledValue(long srcDFP) { + return Long.MAX_VALUE; + } + + private static final ThreadLocal thLocalToString = new ThreadLocal() { + /* 22 is the best number for the fastest path + * [-]digits.digits when scale > 0 & scale <=19 + */ + + protected synchronized Object initialValue() { + return new char[22]; + } + }; + + private final static byte [] comboinit() { + final byte comboCode[]={ + 0, 4, 8, 12, 16, 20, 24, 28, + 1, 5, 9, 13, 17, 21, 25, 29, + 2, 6, 10, 14, 18, 22, 26, 30, + 32, 36, 33, 37, 34, 38 + }; + return comboCode; + } + + private final static short [] dpd2bcdinit() { + final short[] dpd2bcd = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 128, 129, 2048, 2049, 2176, 2177, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 144, 145, 2064, 2065, 2192, 2193, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 130, 131, 2080, 2081, 2056, + 2057, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 146, 147, + 2096, 2097, 2072, 2073, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 132, 133, 2112, 2113, 136, 137, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 148, 149, 2128, 2129, 152, 153, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 134, 135, 2144, 2145, 2184, 2185, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 150, 151, 2160, + 2161, 2200, 2201, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 384, 385, 2304, 2305, 2432, 2433, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 400, 401, 2320, 2321, 2448, 2449, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 386, 387, 2336, 2337, 2312, 2313, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 402, 403, 2352, 2353, + 2328, 2329, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 388, + 389, 2368, 2369, 392, 393, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, 404, 405, 2384, 2385, 408, 409, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 390, 391, 2400, 2401, 2440, 2441, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 406, 407, 2416, 2417, 2456, + 2457, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 640, 641, + 2050, 2051, 2178, 2179, 528, 529, 530, 531, 532, 533, 534, 535, 536, + 537, 656, 657, 2066, 2067, 2194, 2195, 544, 545, 546, 547, 548, 549, + 550, 551, 552, 553, 642, 643, 2082, 2083, 2088, 2089, 560, 561, 562, + 563, 564, 565, 566, 567, 568, 569, 658, 659, 2098, 2099, 2104, 2105, + 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 644, 645, 2114, + 2115, 648, 649, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, + 660, 661, 2130, 2131, 664, 665, 608, 609, 610, 611, 612, 613, 614, + 615, 616, 617, 646, 647, 2146, 2147, 2184, 2185, 624, 625, 626, 627, + 628, 629, 630, 631, 632, 633, 662, 663, 2162, 2163, 2200, 2201, 768, + 769, 770, 771, 772, 773, 774, 775, 776, 777, 896, 897, 2306, 2307, + 2434, 2435, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 912, + 913, 2322, 2323, 2450, 2451, 800, 801, 802, 803, 804, 805, 806, 807, + 808, 809, 898, 899, 2338, 2339, 2344, 2345, 816, 817, 818, 819, 820, + 821, 822, 823, 824, 825, 914, 915, 2354, 2355, 2360, 2361, 832, 833, + 834, 835, 836, 837, 838, 839, 840, 841, 900, 901, 2370, 2371, 904, + 905, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 916, 917, + 2386, 2387, 920, 921, 864, 865, 866, 867, 868, 869, 870, 871, 872, + 873, 902, 903, 2402, 2403, 2440, 2441, 880, 881, 882, 883, 884, 885, + 886, 887, 888, 889, 918, 919, 2418, 2419, 2456, 2457, 1024, 1025, 1026, + 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1152, 1153, 2052, 2053, 2180, 2181, + 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1168, 1169, 2068, + 2069, 2196, 2197, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, + 1154, 1155, 2084, 2085, 2120, 2121, 1072, 1073, 1074, 1075, 1076, 1077, 1078, + 1079, 1080, 1081, 1170, 1171, 2100, 2101, 2136, 2137, 1088, 1089, 1090, 1091, + 1092, 1093, 1094, 1095, 1096, 1097, 1156, 1157, 2116, 2117, 1160, 1161, 1104, + 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1172, 1173, 2132, 2133, + 1176, 1177, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1158, + 1159, 2148, 2149, 2184, 2185, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, + 1144, 1145, 1174, 1175, 2164, 2165, 2200, 2201, 1280, 1281, 1282, 1283, 1284, + 1285, 1286, 1287, 1288, 1289, 1408, 1409, 2308, 2309, 2436, 2437, 1296, 1297, + 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1424, 1425, 2324, 2325, 2452, + 2453, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1410, 1411, + 2340, 2341, 2376, 2377, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, + 1337, 1426, 1427, 2356, 2357, 2392, 2393, 1344, 1345, 1346, 1347, 1348, 1349, + 1350, 1351, 1352, 1353, 1412, 1413, 2372, 2373, 1416, 1417, 1360, 1361, 1362, + 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1428, 1429, 2388, 2389, 1432, 1433, + 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1414, 1415, 2404, + 2405, 2440, 2441, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, + 1430, 1431, 2420, 2421, 2456, 2457, 1536, 1537, 1538, 1539, 1540, 1541, 1542, + 1543, 1544, 1545, 1664, 1665, 2054, 2055, 2182, 2183, 1552, 1553, 1554, 1555, + 1556, 1557, 1558, 1559, 1560, 1561, 1680, 1681, 2070, 2071, 2198, 2199, 1568, + 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1666, 1667, 2086, 2087, + 2152, 2153, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1682, + 1683, 2102, 2103, 2168, 2169, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, + 1608, 1609, 1668, 1669, 2118, 2119, 1672, 1673, 1616, 1617, 1618, 1619, 1620, + 1621, 1622, 1623, 1624, 1625, 1684, 1685, 2134, 2135, 1688, 1689, 1632, 1633, + 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1670, 1671, 2150, 2151, 2184, + 2185, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1686, 1687, + 2166, 2167, 2200, 2201, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, + 1801, 1920, 1921, 2310, 2311, 2438, 2439, 1808, 1809, 1810, 1811, 1812, 1813, + 1814, 1815, 1816, 1817, 1936, 1937, 2326, 2327, 2454, 2455, 1824, 1825, 1826, + 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1922, 1923, 2342, 2343, 2408, 2409, + 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1938, 1939, 2358, + 2359, 2424, 2425, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, + 1924, 1925, 2374, 2375, 1928, 1929, 1872, 1873, 1874, 1875, 1876, 1877, 1878, + 1879, 1880, 1881, 1940, 1941, 2390, 2391, 1944, 1945, 1888, 1889, 1890, 1891, + 1892, 1893, 1894, 1895, 1896, 1897, 1926, 1927, 2406, 2407, 2440, 2441, 1904, + 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1942, 1943, 2422, 2423, + 2456, 2457}; + return dpd2bcd; + } + + /** + * LUT for powers of ten + */ + private static final long[/*19*/] powersOfTenLL = { + 1L, 10L, 100L, 1000L, /*0 to 4 */ + 10000L, 100000L, 1000000L, 10000000L, /*5 to 8*/ + 100000000L, 1000000000L, 10000000000L, 100000000000L, /*9 to 12*/ + 1000000000000L, 10000000000000L, 100000000000000L, 1000000000000000L, /*13 to 16 */ + 10000000000000000L, 100000000000000000L, 1000000000000000000L /*17 to 18 */ + }; + + private final static boolean isDFPZero(long laside) { + // quick check for 0 + if (laside == dfpZERO) { + return true; + } + // if DPF is ZERO, then the combo field will be XX000 where XX is I don't care + // values, and then coefficient continuation field will be all 0s + return ((laside & 0x0003FFFFFFFFFFFFL) == 0 && ((laside >>> 58) & 0x7) == 0); + } + + private final void clone(BigDecimal src, BigDecimal tar) { + int tempFlags = getflags(src); + setflags(tar, tempFlags); + setlaside(tar, getlaside(src)); + setscale(tar, getscale(src)); + if ((tempFlags & 0x3) == 0x2) { + setbi(tar, getbi(src)); + } + } + + private final int finish(BigDecimal bd, int prec, int rm) { + if (prec > 0 && bd.precision() > prec) { + if ((getflags(bd) & 0x3) == 0x0) { + return round(bd, prec, rm); + } else { + MathContext mc = new MathContext(prec, RoundingMode.valueOf(rm)); + clone(bd.round(mc), bd); + } + } + return HARDWARE_OPERATION_SUCCESS; + } + + protected final static int getflags(BigDecimal bd) { + throw new RuntimeException("getflags not compiled\n"); //$NON-NLS-1$ + } + + protected final static long getlaside(BigDecimal bd) { + throw new RuntimeException("getlaside not compiled\n"); //$NON-NLS-1$ + } + + protected final static int getscale(BigDecimal bd) { + throw new RuntimeException("getscale not compiled\n"); //$NON-NLS-1$ + } + + protected final static BigInteger getbi(BigDecimal bd) { + throw new RuntimeException("getbi not compiled\n"); //$NON-NLS-1$ + } + + protected final static void setflags(BigDecimal bd, int flags) { + throw new RuntimeException("setflags not compiled\n"); //$NON-NLS-1$ + } + + protected final static void setlaside(BigDecimal bd, long laside) { + throw new RuntimeException("setlaside not compiled\n"); //$NON-NLS-1$ + } + + protected final static void setscale(BigDecimal bd, int scale) { + throw new RuntimeException("setscale not compiled\n"); //$NON-NLS-1$ + } + + protected final static void setbi(BigDecimal bd, BigInteger bi) { + throw new RuntimeException("setbi not compiled\n"); //$NON-NLS-1$ + } + + private final static long extractDFPDigitsBCD(long dfpNum) { + + int combo=0; // 5 bit combo field + + //quick check for 0 + if (dfpNum == dfpZERO) + return 0; + + // store the combo field bits + combo = (int)(dfpNum >>> 58); //shift out extraneous bits + combo &= 0x1F; //and out sign bit + + // MANTISSA + + // store the mantissa continuation field bits 14 to 62 (50 bits in total) + long ccf = dfpNum & 0x0003FFFFFFFFFFFFL; + + // Convert each set of 10 DPD bits from continuation bits to 12 BCD digits + long ccBCD=0; + long bcd=0; + for (int i=0; i <5; i++) { //5 groups of 10 bits + bcd = DPD2BCD[(int)((ccf & 0x3FF0000000000L)>>>40)]; + ccBCD <<=12; + ccBCD|=bcd; + ccf <<= 10; //shift out top 10 bits + } + + //ccBCD contains 15 BCD digits, now need to prepend the first one + ccBCD|=(((long)(doubleDFPComboField[combo]>>>2))<<60); + return ccBCD; + } + + private final static boolean allzeroBCD(long num, int numDigsToCheck) { + + // isolate numDigsToCheck rightmost digits... + long mask = 0xFFFFFFFFFFFFFFFFL; + mask >>>= (64-numDigsToCheck)*4; + return ((mask & num) == 0); + } + + private final static int extractDFPExponent(long dfpNum) { + + byte combo=0; // 5 bit combo field + + // store the combo field bits + combo = (byte)(dfpNum >>> 58); //shift out extraneous bits + //combo &= 0x1F; //and out sign bit - not sure why I was doing this + + // store the biased exponent field bits 6 to 13 + short bxf = (short)(dfpNum >>> 50); //shift out extraneous bits + bxf &= 0x00FF; //and out sign and combo field + + // parse the combo field + byte exp2Digits = (byte)(doubleDFPComboField[combo] & 0x03); + + // unbias the exponent + short unbExp = (short)(exp2Digits); + unbExp <<= 8; + unbExp|=bxf; + return unbExp; + } + + private static final long powerOfTenLL(long i) { + if (i > -1 && i <= 18) + return powersOfTenLL[(int)i]; + else + return -1; + } + + /* Return number of digits in lon + * The value '0' has numDigits = 1. + */ + private final static int numDigits(long lon) { + //if (lon <0) lon*=-1; //need to make it positive for this to work + lon = Math.abs(lon); + + //hardcode powers of ten to avoid LUT lookups + + //rhs of the tree + if (lon < 1000000000L /*powerOfTenLL[9]*/) { + if (lon < 100000000L /*powerOfTenLL[8]*/) { + if (lon < 10000L /*powerOfTenLL[4]*/) { + if (lon < 100L /* powerOfTenLL[2]*/) { + if (lon < 10L /*powerOfTenLL[1]*/) + return 1; + else + return 2; + } + else if (lon < 1000L /*powerOfTenLL[3]*/) + return 3; + else + return 4; + } + else if (lon < 1000000L /*powerOfTenLL[6]*/) { + if ( lon < 100000L /*powerOfTenLL[5]*/) + return 5; + else + return 6; + } + else if (lon < 10000000L /*powerOfTenLL[7]*/) + return 7; + else return 8; + } + else + return 9; + } + //lhs of the tree + else { + if (lon < 10000000000L /*powerOfTenLL[10]*/) + return 10; + else if (lon < 100000000000000L /*powerOfTenLL[14]*/) { + if (lon < 1000000000000L /*powerOfTenLL[12]*/) { + if (lon < 100000000000L /*powerOfTenLL[11]*/) + return 11; + else + return 12; + } + else if (lon < 10000000000000L /*powerOfTenLL[13]*/) + return 13; + else + return 14; + } + else if (lon < 10000000000000000L /*powerOfTenLL[16]*/) { + if (lon < 1000000000000000L /*powerOfTenLL[15]*/) + return 15; + else + return 16; + } + else if (lon < 100000000000000000L /*powerOfTenLL[17]*/) + return 17; + else if (lon < 1000000000000000000L /*powerOfTenLL[18]*/) + return 18; + return 19; + } + } + + private final static int digitAtBCD(long bcd, int numDigits, int indexFromLeft) { + + int indexFromRight = numDigits-indexFromLeft-1; + switch (indexFromRight) { + case 0: + return (int)(bcd & 0x000000000000000FL); + case 1: + return (int)((bcd & 0x00000000000000F0L)>>>4); + case 2: + return (int)((bcd & 0x0000000000000F00L)>>>8); + case 3: + return (int)((bcd & 0x000000000000F000L)>>>12); + case 4: + return (int)((bcd & 0x00000000000F0000L)>>>16); + case 5: + return (int)((bcd & 0x0000000000F00000L)>>>20); + case 6: + return (int)((bcd & 0x000000000F000000L)>>>24); + case 7: + return (int)((bcd & 0x00000000F0000000L)>>>28); + case 8: + return (int)((bcd & 0xF00000000L)>>>32); + case 9: + return (int)((bcd & 0xF000000000L)>>>36); + case 10: + return (int)((bcd & 0xF0000000000L)>>>40); + case 11: + return (int)((bcd & 0xF00000000000L)>>44); + case 12: + return (int)((bcd & 0xF000000000000L)>>>48); + case 13: + return (int)((bcd & 0xF0000000000000L)>>>52); + case 14: + return (int)((bcd & 0xF00000000000000L)>>>56); + case 15: + return (int)((bcd & 0xF000000000000000L)>>>60); + default: + return 0; + } + } + + private final static int digitAt(long lon, int numdigits, int loc) { + + lon = Math.abs(lon); + if (loc > numdigits-1)return -1; + if (loc < 0) return -1; + int indexFromRight = numdigits-loc-1; + if (lon <= Integer.MAX_VALUE) { + int temp=(int)lon; + switch (indexFromRight) { + case 0: + break; + case 1: + temp /=10; + break; + case 2: + temp /=100; + break; + case 3: + temp /=1000; + break; + case 4: + temp /=10000; + break; + case 5: + temp /=100000; + break; + case 6: + temp /=1000000; + break; + case 7: + temp /=10000000; + break; + case 8: + temp /=100000000; + break; + case 9: + temp /=1000000000; //unsure whether remaining cases would + break; //ever be taken in the Integer case + case 10: + temp /=10000000000L; + break; + case 11: + temp /=100000000000L; + break; + case 12: + temp /=1000000000000L; + break; + case 13: + temp /=10000000000000L; + break; + case 14: + temp /=100000000000000L; + break; + case 15: + temp /=1000000000000000L; + break; + case 16: + temp /=10000000000000000L; + break; + case 17: + temp /=100000000000000000L; + break; + case 18: + temp /=1000000000000000000L; + break; + } + + // find remainder + if (temp <= Integer.MAX_VALUE) { + int intTmp = (int)temp; + int tmpVal = intTmp; + intTmp = uDivideByTen(intTmp); + return (tmpVal - ((intTmp << 3) + (intTmp << 1))); + } + else { + long tmpVal = temp; + temp/=10; + return (int)(tmpVal - (((temp << 3) + (temp << 1)))); + } + } + else { + long temp=lon; + switch (indexFromRight) { + case 0: + break; + case 1: + temp /= 10; + break; + case 2: + temp /= 100; + break; + case 3: + temp /= 1000; + break; + case 4: + temp /= 10000; + break; + case 5: + temp /= 100000; + break; + case 6: + temp /= 1000000; + break; + case 7: + temp /= 10000000; + break; + case 8: + temp /= 100000000; + break; + case 9: + temp /= 1000000000; + break; + case 10: + temp /= 10000000000L; + break; + case 11: + temp /= 100000000000L; + break; + case 12: + temp /= 1000000000000L; + break; + case 13: + temp /= 10000000000000L; + break; + case 14: + temp /= 100000000000000L; + break; + case 15: + temp /= 1000000000000000L; + break; + case 16: + temp /= 10000000000000000L; + break; + case 17: + temp /= 100000000000000000L; + break; + case 18: + temp /= 1000000000000000000L; + break; + } + + // find remainder + if (temp <= Integer.MAX_VALUE) { + int intTmp = (int)temp; + int tmpVal = intTmp; + intTmp = uDivideByTen(intTmp); + return (tmpVal - ((intTmp << 3) + (intTmp << 1))); + } + else { + long tmpVal = temp; + temp/=10; + return (int)(tmpVal - (((temp << 3) + (temp << 1)))); + } + } + } + + private final static int uDivideByTen(int x) { + int q = (x >> 1) + (x >> 2); + q = q + (q >> 4); + q = q + (q >> 8); + q = q + (q >> 16); + q >>=3; + x -= q*10; + return q + ((x + 6) >> 4); + } + + private final void badDivideByZero() { + /*[MSG "K0407", "division by zero"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0407")); //$NON-NLS-1$ + } + private final void conversionOverflow(BigDecimal bd) { + /*[MSG "K0458", "Conversion overflow: {0}"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0458", bd)); //$NON-NLS-1$ + } + private final void nonZeroDecimals(BigDecimal bd) { + /*[MSG "K0457", "Non-zero decimal digits: {0}"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0457", bd)); //$NON-NLS-1$ + } + private final void scaleOutOfRange(long s) { + /*[MSG "K0451", "BigDecimal scale outside legal range: {0}"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0451", Long.toString(s))); //$NON-NLS-1$ + } + private static final void scaleOverflow() { + /*[MSG "K0453", "Scale overflow"]*/ + throw new ArithmeticException(com.ibm.oti.util.Msg.getString("K0453")); //$NON-NLS-1$ + } } /*[ENDIF] #INCLUDE */ /*[REM] do not remove following blank line*/ - diff --git a/jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java b/jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java index 70c0e58b42e..74748ad8209 100644 --- a/jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java +++ b/jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java @@ -162,7 +162,6 @@ public int getJ9ClassFromObject32(Object obj) { return getJ9ClassFromClass32(clazz); } - /* * To be recognized by the JIT and returns true if the hardware supports SIMD case conversion. */ diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/reflect/TypeAnnotationParser.java b/jcl/src/java.base/share/classes/com/ibm/oti/reflect/TypeAnnotationParser.java index 7a896d64ffc..5063dc0d425 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/reflect/TypeAnnotationParser.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/reflect/TypeAnnotationParser.java @@ -38,7 +38,7 @@ public class TypeAnnotationParser { private static final byte[] EMPTY_TYPE_ANNOTATIONS_ATTRIBUTE = new byte[] {0, 0}; /* just num_annotations=0 */ - + /** * @param jlrConstructor constructor for which annotations are to be retrieved * @return annotation attribute bytes, not including the attribute_name_index and attribute_length fields, or null if jlrConstructor is null. @@ -61,7 +61,7 @@ public static byte[] getTypeAnnotationsData(java.lang.reflect.Method jlrMethod) } return result; }; - + /** * @param jlrField field for which annotations are to be retrieved * @return annotation attribute bytes, not including the attribute_name_index and attribute_length fields, or null if jlrField is null. @@ -73,7 +73,7 @@ public static byte[] getTypeAnnotationsData(java.lang.reflect.Field jlrField) { } return result; }; - + /** * @param clazz class for which annotations are to be retrieved * @return annotation attribute bytes, not including the attribute_name_index and attribute_length fields, or null if clazz is null. @@ -97,7 +97,7 @@ private static byte[] getAttributeData(Class clazz) { } return attr; } - + /** * @param clazz class for which annotated interfaces are to be retrieved * @return array (possibly empty) of AnnotatedType objects for the interfaces. diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/util/Msg.java b/jcl/src/java.base/share/classes/com/ibm/oti/util/Msg.java index 8ba2a72a81f..979d59eb109 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/util/Msg.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/util/Msg.java @@ -40,7 +40,7 @@ * * resource bundle. Note that if this file is not available, * or an invalid key is looked up, or resource bundle support - * is not available, the key itself will be returned as the + * is not available, the key itself will be returned as the * associated message. This means that the KEY should * a reasonable human-readable (english) string. * @@ -49,7 +49,7 @@ */ // Declaration of external messages to support the j9zip.jar file for the -Xzero option -/*[PR VMDESIGN 1705] Force the external messages for Zero into Java6 JCLs */ +/*[PR VMDESIGN 1705] Force the external messages for Zero into Java6 JCLs */ /*[MSG "K0059", "Stream is closed"]*/ /*[MSG "K00b7", "File is closed"]*/ /*[MSG "K01c3", "Unable to open: {0}"]*/ @@ -59,21 +59,20 @@ public class Msg { // Properties holding the system messages. static private Hashtable messages; - + static { // Attempt to load the messages. messages = (Hashtable) AccessController.doPrivileged( PriviAction.loadMessages("com/ibm/oti/util/ExternalMessages")); //$NON-NLS-1$ } - /** * Retrieves a message which has no arguments. * * @author OTI * @version initial * - * @param msg String + * @param msg String * the key to look up. * @return String * the message for that key in the system @@ -87,39 +86,39 @@ static public String getString (String msg) { return msg; return resource; } - + /** - * Retrieves a message which takes 1 argument. - * - * @author OTI - * @version initial - * - * @param msg String - * the key to look up. - * @param arg Object - * the object to insert in the formatted output. - * @return String - * the message for that key in the system - * message bundle. - */ - static public String getString (String msg, Object arg) { - String format = msg; - - if (messages != null) { - format = (String) messages.get(msg); - if (format == null) format = msg; - } - - return MsgHelp.format(format, arg); - } - + * Retrieves a message which takes 1 argument. + * + * @author OTI + * @version initial + * + * @param msg String + * the key to look up. + * @param arg Object + * the object to insert in the formatted output. + * @return String + * the message for that key in the system + * message bundle. + */ + static public String getString (String msg, Object arg) { + String format = msg; + + if (messages != null) { + format = (String) messages.get(msg); + if (format == null) format = msg; + } + + return MsgHelp.format(format, arg); + } + /** * Retrieves a message which takes 1 integer argument. * * @author OTI * @version initial * - * @param msg String + * @param msg String * the key to look up. * @param arg int * the integer to insert in the formatted output. @@ -130,14 +129,14 @@ static public String getString (String msg, Object arg) { static public String getString (String msg, int arg) { return getString(msg, Integer.toString(arg)); } - + /** * Retrieves a message which takes 1 character argument. * * @author OTI * @version initial * - * @param msg String + * @param msg String * the key to look up. * @param arg char * the character to insert in the formatted output. @@ -148,14 +147,14 @@ static public String getString (String msg, int arg) { static public String getString (String msg, char arg) { return getString(msg, String.valueOf(arg)); } - + /** * Retrieves a message which takes 2 arguments. * * @author OTI * @version initial * - * @param msg String + * @param msg String * the key to look up. * @param arg1 Object * an object to insert in the formatted output. @@ -168,14 +167,14 @@ static public String getString (String msg, char arg) { static public String getString (String msg, Object arg1, Object arg2) { return getString(msg, new Object[] {arg1, arg2}); } - + /** * Retrieves a message which takes several arguments. * * @author OTI * @version initial * - * @param msg String + * @param msg String * the key to look up. * @param args Object[] * the objects to insert in the formatted output. @@ -185,23 +184,23 @@ static public String getString (String msg, Object arg1, Object arg2) { */ static public String getString (String msg, Object[] args) { String format = msg; - + if (messages != null) { format = (String) messages.get(msg); if (format == null) { format = msg; } } - + return MsgHelp.format(format, args); } /** * Retrieves a message which takes several arguments. * - * @param msg String + * @param msg String * the key to look up. - * @param defaultMsg String + * @param defaultMsg String * the default format string if null is returned from key look up or messages hashtable is null. * @param args Object[] * the objects to insert in the formatted output. @@ -219,14 +218,14 @@ static public String getString (String msg, String defaultMsg, Object[] args) { } return MsgHelp.format(format, args); } - + /** * Retrieves a message which takes 3 arguments. * * @author OTI * @version initial * - * @param msg String + * @param msg String * the key to look up. * @param arg1 Object * an object to insert in the formatted output. diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/util/PriviAction.java b/jcl/src/java.base/share/classes/com/ibm/oti/util/PriviAction.java index 5fcc1b560e4..d27cc46b291 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/util/PriviAction.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/util/PriviAction.java @@ -1,5 +1,4 @@ /*[INCLUDE-IF Sidecar16]*/ - package com.ibm.oti.util; /* @@ -36,151 +35,151 @@ * Helper class to avoid multiple anonymous inner class for * {@link java.security.AccessController#doPrivileged(PrivilegedAction)} * calls. - * + * * @author OTI * @version initial */ public class PriviAction implements PrivilegedAction { - // unique id for each possible action; used in switch statement in run() - private int action; + // unique id for each possible action; used in switch statement in run() + private int action; + + private static final int GET_SYSTEM_PROPERTY = 1; + private static final int GET_SECURITY_POLICY = 2; + private static final int SET_ACCESSIBLE = 3; + private static final int GET_SECURITY_PROPERTY = 4; + private static final int LOAD_MESSAGES = 5; + private static final int GET_BUNDLE = 6; - private static final int GET_SYSTEM_PROPERTY = 1; - private static final int GET_SECURITY_POLICY = 2; - private static final int SET_ACCESSIBLE = 3; - private static final int GET_SECURITY_PROPERTY = 4; - private static final int LOAD_MESSAGES = 5; - private static final int GET_BUNDLE = 6; + // the possible argument types for all calls + //(using generic Object args and cast appropriately in run() is more expensive) + private String stringArg1, stringArg2; + private AccessibleObject accessible; + private Locale locale; - // the possible argument types for all calls - //(using generic Object args and cast appropriately in run() is more expensive) - private String stringArg1, stringArg2; - private AccessibleObject accessible; - private Locale locale; + /** + * Creates a PrivilegedAction to get the security + * property with the given name. + * + * @param property the name of the property + * + * @see Security#getProperty + */ + public static PrivilegedAction getSecurityProperty(String property) { + return new PriviAction(GET_SECURITY_PROPERTY, property); + } - /** - * Creates a PrivilegedAction to get the security - * property with the given name. - * - * @param property the name of the property - * - * @see Security#getProperty - */ - public static PrivilegedAction getSecurityProperty(String property) { - return new PriviAction(GET_SECURITY_PROPERTY, property); - } + /** + * Creates a PrivilegedAction to load messages + * from the given name. + * + * @param resourceName the name of the properties file + * + * @see MsgHelp#loadMessages(String) + */ + public static PrivilegedAction loadMessages(String resourceName) { + return new PriviAction(LOAD_MESSAGES, resourceName); + } - /** - * Creates a PrivilegedAction to load messages - * from the given name. - * - * @param resourceName the name of the properties file - * - * @see MsgHelp#loadMessages(String) - */ - public static PrivilegedAction loadMessages(String resourceName) { - return new PriviAction(LOAD_MESSAGES, resourceName); - } + private PriviAction(int action, String arg) { + this.action = action; + stringArg1 = arg; + } - private PriviAction(int action, String arg) { - this.action = action; - stringArg1 = arg; - } + /** + * Creates a PrivilegedAction to get the current security + * policy object. + * + * @see Policy#getPolicy + */ + public PriviAction() { + action = GET_SECURITY_POLICY; + } - /** - * Creates a PrivilegedAction to get the current security - * policy object. - * - * @see Policy#getPolicy - */ - public PriviAction() { - action = GET_SECURITY_POLICY; - } + /** + * Creates a PrivilegedAction to disable the access + * checks to the given object. + * + * @param object the object whose accessible flag + * will be set to true + * + * @see AccessibleObject#setAccessible(boolean) + */ + public PriviAction(AccessibleObject object) { + action = SET_ACCESSIBLE; + accessible = object; + } - /** - * Creates a PrivilegedAction to disable the access - * checks to the given object. - * - * @param object the object whose accessible flag - * will be set to true - * - * @see AccessibleObject#setAccessible(boolean) - */ - public PriviAction(AccessibleObject object) { - action = SET_ACCESSIBLE; - accessible = object; - } - - /** - * Creates a PrivilegedAction to return the value of - * the system property with the given key. - * - * @param property the key of the system property - * - * @see System#getProperty(String) - */ - public PriviAction(String property) { - action = GET_SYSTEM_PROPERTY; - stringArg1 = property; - } + /** + * Creates a PrivilegedAction to return the value of + * the system property with the given key. + * + * @param property the key of the system property + * + * @see System#getProperty(String) + */ + public PriviAction(String property) { + action = GET_SYSTEM_PROPERTY; + stringArg1 = property; + } - /** - * Creates a PrivilegedAction to return the value of - * the system property with the given key. - * - * @param property the key of the system property - * @param defaultAnswer the return value if the system property - * does not exist - * - * @see System#getProperty(String, String) - */ - public PriviAction(String property, String defaultAnswer) { - action = GET_SYSTEM_PROPERTY; - stringArg1 = property; - stringArg2 = defaultAnswer; - } + /** + * Creates a PrivilegedAction to return the value of + * the system property with the given key. + * + * @param property the key of the system property + * @param defaultAnswer the return value if the system property + * does not exist + * + * @see System#getProperty(String, String) + */ + public PriviAction(String property, String defaultAnswer) { + action = GET_SYSTEM_PROPERTY; + stringArg1 = property; + stringArg2 = defaultAnswer; + } - /** - * Creates a PrivilegedAction to load the resource bundle. - * - * @param bundleName the name of the resource file - * @param locale the locale - * - * @see ResourceBundle#getBundle(String, Locale) - */ - public PriviAction(String bundleName, Locale locale) { - action = GET_BUNDLE; - stringArg1 = bundleName; - this.locale = locale; - } + /** + * Creates a PrivilegedAction to load the resource bundle. + * + * @param bundleName the name of the resource file + * @param locale the locale + * + * @see ResourceBundle#getBundle(String, Locale) + */ + public PriviAction(String bundleName, Locale locale) { + action = GET_BUNDLE; + stringArg1 = bundleName; + this.locale = locale; + } - /** - * Performs the actual privileged computation as defined - * by the constructor. - * - * @see java.security.PrivilegedAction#run() - */ - public Object run() { - switch (action) { - case GET_SYSTEM_PROPERTY: - return System.getProperty(stringArg1, stringArg2); - case GET_SECURITY_PROPERTY: - return Security.getProperty(stringArg1); - case GET_SECURITY_POLICY: - return Policy.getPolicy(); - case LOAD_MESSAGES: - try { - return MsgHelp.loadMessages(stringArg1); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - case GET_BUNDLE: - return ResourceBundle.getBundle(stringArg1, locale); - case SET_ACCESSIBLE: - accessible.setAccessible(true); - // fall through - } - return null; - } + /** + * Performs the actual privileged computation as defined + * by the constructor. + * + * @see java.security.PrivilegedAction#run() + */ + public Object run() { + switch (action) { + case GET_SYSTEM_PROPERTY: + return System.getProperty(stringArg1, stringArg2); + case GET_SECURITY_PROPERTY: + return Security.getProperty(stringArg1); + case GET_SECURITY_POLICY: + return Policy.getPolicy(); + case LOAD_MESSAGES: + try { + return MsgHelp.loadMessages(stringArg1); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + case GET_BUNDLE: + return ResourceBundle.getBundle(stringArg1, locale); + case SET_ACCESSIBLE: + accessible.setAccessible(true); + // fall through + } + return null; + } } diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/util/RuntimePermissions.java b/jcl/src/java.base/share/classes/com/ibm/oti/util/RuntimePermissions.java index c80ec8877f8..8f1a13c3ffd 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/util/RuntimePermissions.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/util/RuntimePermissions.java @@ -35,15 +35,15 @@ public class RuntimePermissions { /** * RuntimePermission "setContextClassLoader" */ - public static final RuntimePermission permissionSetContextClassLoader = new RuntimePermission("setContextClassLoader"); //$NON-NLS-1$ + public static final RuntimePermission permissionSetContextClassLoader = new RuntimePermission("setContextClassLoader"); //$NON-NLS-1$ /** * RuntimePermission "setDefaultUncaughtExceptionHandler" */ - public static final RuntimePermission permissionSetDefaultUncaughtExceptionHandler = new RuntimePermission("setDefaultUncaughtExceptionHandler"); //$NON-NLS-1$ + public static final RuntimePermission permissionSetDefaultUncaughtExceptionHandler = new RuntimePermission("setDefaultUncaughtExceptionHandler"); //$NON-NLS-1$ /** * RuntimePermission "setIO" */ - public static final RuntimePermission permissionSetIO = new RuntimePermission("setIO"); //$NON-NLS-1$ + public static final RuntimePermission permissionSetIO = new RuntimePermission("setIO"); //$NON-NLS-1$ /** * RuntimePermission "setSecurityManager" */ diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/util/WeakReferenceNode.java b/jcl/src/java.base/share/classes/com/ibm/oti/util/WeakReferenceNode.java index 9146724a5e9..689a8a59ffd 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/util/WeakReferenceNode.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/util/WeakReferenceNode.java @@ -26,13 +26,13 @@ /** * WeakReference that can be used as an element in a doubly linked list. - * - * @param The type of the referent + * + * @param The type of the referent */ public class WeakReferenceNode extends WeakReference { private WeakReferenceNode previous; private WeakReferenceNode next; - + /** * Constructs a new WeakReferenceNode * @@ -45,7 +45,7 @@ public WeakReferenceNode(T r, ReferenceQueue q) { /** * Adds the current node before the specified node. - * + * * @param after The node that will be after this node in the list (may be null) */ public void addBefore(WeakReferenceNode after) { @@ -58,9 +58,9 @@ public void addBefore(WeakReferenceNode after) { after.previous = this; } } - + /** - * Removes the current node from any list it may be part of. + * Removes the current node from any list it may be part of. */ public void remove() { if (null != this.previous) { @@ -70,14 +70,14 @@ public void remove() { this.next.previous = this.previous; } } - + /** * @return The node before this node in the list */ public WeakReferenceNode previous() { return previous; } - + /** * @return The node after this node in the list */ diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/vm/AbstractClassLoader.java b/jcl/src/java.base/share/classes/com/ibm/oti/vm/AbstractClassLoader.java index 2dc9d247c1c..72a6a9e4730 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/vm/AbstractClassLoader.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/vm/AbstractClassLoader.java @@ -49,8 +49,8 @@ private static final class CacheLock {} /*[PR JAZZ 88959] Use URLStreamHandler when creating bootstrap resource URLs */ private static URLStreamHandler urlJarStreamHandler; private static URLStreamHandler urlFileStreamHandler; - -public AbstractClassLoader(){ + +public AbstractClassLoader() { } void fillCache(final int i) { @@ -116,7 +116,6 @@ private void setParsedPathElement(int i, String value) { } } - /** * Answers a string representing the URL which matches the * given filename. The argument should be specified using the @@ -126,7 +125,7 @@ private void setParsedPathElement(int i, String value) { * * @param filename the filename String to convert to URL form * @param cpType an int which indicates type of the URL - * + * * @return the URL formatted filename */ static String toURLString(String filename, int cpType) { @@ -274,7 +273,7 @@ public Object run() { } result = reduced; } - + ConcurrentHashMap resourceCache; if (resourceCacheRef == null || (resourceCache = resourceCacheRef.get()) == null) { synchronized(cacheLock) { diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/vm/BootstrapClassLoader.java b/jcl/src/java.base/share/classes/com/ibm/oti/vm/BootstrapClassLoader.java index 6b19e538b46..4384b5b3365 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/vm/BootstrapClassLoader.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/vm/BootstrapClassLoader.java @@ -87,11 +87,11 @@ public Class loadClass(String className) throws ClassNotFoundException { public static ClassLoader singleton() { if (singleton == null) - singleton = new BootstrapClassLoader(); + singleton = new BootstrapClassLoader(); else /*[MSG "K0084", "can only instantiate one BootstrapClassLoader"]*/ - throw new SecurityException(com.ibm.oti.util.Msg.getString("K0084")); //$NON-NLS-1$ - return singleton; + throw new SecurityException(com.ibm.oti.util.Msg.getString("K0084")); //$NON-NLS-1$ + return singleton; } protected Package getPackage(String name) { diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/vm/J9UnmodifiableClass.java b/jcl/src/java.base/share/classes/com/ibm/oti/vm/J9UnmodifiableClass.java index 38f8ba1f76b..647fb011238 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/vm/J9UnmodifiableClass.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/vm/J9UnmodifiableClass.java @@ -38,4 +38,3 @@ public @interface J9UnmodifiableClass { } - diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/vm/JarRunner.java b/jcl/src/java.base/share/classes/com/ibm/oti/vm/JarRunner.java index 4e4e6afe090..987b09560da 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/vm/JarRunner.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/vm/JarRunner.java @@ -31,7 +31,7 @@ public class JarRunner { public static void main(String args[]) throws Exception { - + //Manifest from the jarfile Manifest manifest = getManifest(args[0]); if (null==manifest) { @@ -40,7 +40,7 @@ public static void main(String args[]) throws Exception { System.err.println(com.ibm.oti.util.Msg.getString("K0222", args[0])); //$NON-NLS-1$ return; } - + // Main class name from the jarFile String mainClass = JarRunner.mainClassName(manifest); if (mainClass == null) { @@ -48,21 +48,21 @@ public static void main(String args[]) throws Exception { System.err.println(com.ibm.oti.util.Msg.getString("K01c6", args[0])); //$NON-NLS-1$ return; } - + // Get the main method from the mainClass Class runnable = Class.forName(mainClass, true, ClassLoader.getSystemClassLoader()); Class mainParams[] = new Class[1]; mainParams[0] = args.getClass(); Method mainMethod = runnable.getMethod("main", mainParams); //$NON-NLS-1$ - - // Run the main method + + // Run the main method Object params[] = new Object[1]; String margs[] = new String[args.length - 1]; System.arraycopy(args, 1, margs, 0, (args.length - 1)); params[0] = margs; mainMethod.invoke(null, params); } - + private static String mainClassName(Manifest manifest) throws IOException { Attributes mainAttrib = manifest.getMainAttributes(); String name = mainAttrib.getValue(Attributes.Name.MAIN_CLASS); @@ -70,11 +70,10 @@ private static String mainClassName(Manifest manifest) throws IOException { if (name != null) name = name.replace('/', '.'); return name; } - + private static Manifest getManifest(String jarFileName) throws IOException { /*[PR 98078]*/ JarFile jar = new JarFile(jarFileName); return jar.getManifest(); - } + } } - diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/vm/MsgHelp.java b/jcl/src/java.base/share/classes/com/ibm/oti/vm/MsgHelp.java index 7ced12a15d4..fb586ef5a5c 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/vm/MsgHelp.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/vm/MsgHelp.java @@ -60,7 +60,7 @@ public final class MsgHelp { * the formatted message. */ public static String format (String format, Object[] args) { - return format(format, null, args); + return format(format, null, args); } /** @@ -75,10 +75,10 @@ public static String format (String format, Object[] args) { * the formatted message. */ public static String format (String format, Object arg) { - if(arg == null) { - arg = ""; //$NON-NLS-1$ - } - return format(format, arg, null); + if(arg == null) { + arg = ""; //$NON-NLS-1$ + } + return format(format, arg, null); } /** @@ -95,23 +95,23 @@ public static String format (String format, Object arg) { * @return the formatted message */ private static String format (String format, Object singleArg, Object[] multipleArgs) { - boolean hasSingleArg = singleArg != null; - int argLength = 0; - String argString = null; - String[] argStrings = null; - if(hasSingleArg) { - argLength = 1; - argString = singleArg.toString(); - } else if(multipleArgs != null) { - argLength = multipleArgs.length; - argStrings = new String[argLength]; - for (int i = 0; i < argLength; ++i) { - if (multipleArgs[i] == null) - argStrings[i] = ""; //$NON-NLS-1$ - else - argStrings[i] = multipleArgs[i].toString(); - } - } + boolean hasSingleArg = singleArg != null; + int argLength = 0; + String argString = null; + String[] argStrings = null; + if(hasSingleArg) { + argLength = 1; + argString = singleArg.toString(); + } else if(multipleArgs != null) { + argLength = multipleArgs.length; + argStrings = new String[argLength]; + for (int i = 0; i < argLength; ++i) { + if (multipleArgs[i] == null) + argStrings[i] = ""; //$NON-NLS-1$ + else + argStrings[i] = multipleArgs[i].toString(); + } + } /*[PR 110011] StringBuffer not created with initial size */ StringBuilder answer = new StringBuilder(format.length() + (argLength * 20)); @@ -136,18 +136,18 @@ private static String format (String format, Object singleArg, Object[] multiple answer.append(format.substring(lastI, i+1)); lastI = i+1; } else { - // Got a good one! - String sub = format.substring(lastI, i); - answer.append(sub); - if (argnum >= argLength) { + // Got a good one! + String sub = format.substring(lastI, i); + answer.append(sub); + if (argnum >= argLength) { answer.append(""); //$NON-NLS-1$ - } else if(hasSingleArg) { - answer.append(argString); - } else { + } else if(hasSingleArg) { + answer.append(argString); + } else { answer.append(argStrings[argnum]); - } + } lastI = i + 3; - } + } } } } diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/vm/ORBBase.java b/jcl/src/java.base/share/classes/com/ibm/oti/vm/ORBBase.java index bdcd1c175d6..d6596750346 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/vm/ORBBase.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/vm/ORBBase.java @@ -27,11 +27,11 @@ public abstract class ORBBase { // TODO: JIT Team to provide documentation - public abstract Object quickCopyIfPossible(Object fieldValue, Class type, ClassLoader targetCL, - Map map, Class itsType) throws Exception; + public abstract Object quickCopyIfPossible(Object fieldValue, Class type, ClassLoader targetCL, + Map map, Class itsType) throws Exception; // TODO: JIT Team to provide documentation - public abstract Object deepCopyIfRequired(Object fieldValue, Class type, ClassLoader targetCL, - Map map, Class itsType); + public abstract Object deepCopyIfRequired(Object fieldValue, Class type, ClassLoader targetCL, + Map map, Class itsType); } diff --git a/jcl/src/java.base/share/classes/com/ibm/oti/vm/VMLangAccess.java b/jcl/src/java.base/share/classes/com/ibm/oti/vm/VMLangAccess.java index 18a05452185..1b6e52ca15c 100644 --- a/jcl/src/java.base/share/classes/com/ibm/oti/vm/VMLangAccess.java +++ b/jcl/src/java.base/share/classes/com/ibm/oti/vm/VMLangAccess.java @@ -186,7 +186,6 @@ public interface VMLangAccess { */ public Thread createThread(Runnable runnable, String threadName, boolean isSystemThreadGroup, boolean inheritThreadLocals, boolean isDaemon, ClassLoader contextClassLoader); - /** * Prepare the passed in class * diff --git a/jcl/src/java.base/share/classes/java/lang/Class.java b/jcl/src/java.base/share/classes/java/lang/Class.java index 91e84d3473d..c350346c73c 100644 --- a/jcl/src/java.base/share/classes/java/lang/Class.java +++ b/jcl/src/java.base/share/classes/java/lang/Class.java @@ -637,9 +637,9 @@ public static Class forName(Module module, String name) sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } classLoader = AccessController.doPrivileged(new PrivilegedAction() { - public ClassLoader run() { + public ClassLoader run() { return module.getClassLoader(); - } + } }); } else { classLoader = module.getClassLoader(); @@ -698,9 +698,9 @@ private static Class forNameHelper(Module module, String name, Class calle sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } classLoader = AccessController.doPrivileged(new PrivilegedAction() { - public ClassLoader run() { - return module.getClassLoader(); - } + public ClassLoader run() { + return module.getClassLoader(); + } }); } else { classLoader = module.getClassLoader(); @@ -747,8 +747,8 @@ public ClassLoader run() { * @see java.lang.Class */ private static native Class forNameImpl(String className, - boolean initializeBoolean, - ClassLoader classLoader) + boolean initializeBoolean, + ClassLoader classLoader) throws ClassNotFoundException; /** @@ -838,7 +838,6 @@ ClassLoader getClassLoader0() { return loader; } - /** * Return the ClassLoader for this Class without doing any security * checks. The bootstrap ClassLoader is returned, unlike getClassLoader() @@ -2503,7 +2502,6 @@ private boolean useModularSearch(String absoluteResName, Module thisModule, Clas } /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ - /** * Answers a String object which represents the class's * signature, as described in the class definition of @@ -2721,7 +2719,6 @@ private Object newInstancePrototype(Class callerClass) throws InstantiationEx throw new InstantiationException(this); } - /** * Answers a string describing a path to the receiver's appropriate * package specific subdirectory, with the argument appended if the @@ -3055,7 +3052,6 @@ public boolean desiredAssertionStatus() { @CallerSensitive static final native Class[] getStackClasses(int maxDepth, boolean stopAtPrivileged); - /** * Called from JVM_ClassDepth. * Answers the index in the stack of the first method which @@ -3392,43 +3388,43 @@ private MethodHandle getValueMethod(final Class containedT if (valueMethod == null) { final MethodType methodType = MethodType.methodType(Array.newInstance(containedType, 0).getClass()); valueMethod = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public MethodHandle run() { - try { - MethodHandles.Lookup localImplLookup = implLookup; - if (localImplLookup == null) { - Field privilegedLookupField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP"); //$NON-NLS-1$ - privilegedLookupField.setAccessible(true); - localImplLookup = (MethodHandles.Lookup)privilegedLookupField.get(MethodHandles.Lookup.class); - Field implLookupField = Class.class.getDeclaredField("implLookup"); //$NON-NLS-1$ - long implLookupOffset = getUnsafe().staticFieldOffset(implLookupField); - // Lazy initialization of a non-volatile field. Ensure the Object is initialized - // and flushed to memory before assigning to the implLookup field. + @Override + public MethodHandle run() { + try { + MethodHandles.Lookup localImplLookup = implLookup; + if (localImplLookup == null) { + Field privilegedLookupField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP"); //$NON-NLS-1$ + privilegedLookupField.setAccessible(true); + localImplLookup = (MethodHandles.Lookup)privilegedLookupField.get(MethodHandles.Lookup.class); + Field implLookupField = Class.class.getDeclaredField("implLookup"); //$NON-NLS-1$ + long implLookupOffset = getUnsafe().staticFieldOffset(implLookupField); + // Lazy initialization of a non-volatile field. Ensure the Object is initialized + // and flushed to memory before assigning to the implLookup field. /*[IF JAVA_SPEC_VERSION >= 9] getUnsafe().putObjectRelease(Class.class, implLookupOffset, localImplLookup); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ - getUnsafe().putOrderedObject(Class.class, implLookupOffset, localImplLookup); + getUnsafe().putOrderedObject(Class.class, implLookupOffset, localImplLookup); /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ - } - MethodHandle handle = localImplLookup.findVirtual(Class.this, "value", methodType); //$NON-NLS-1$ - if (AnnotationVars.valueMethodOffset == -1) { - Field valueMethodField = AnnotationVars.class.getDeclaredField("valueMethod"); //$NON-NLS-1$ - AnnotationVars.valueMethodOffset = getUnsafe().objectFieldOffset(valueMethodField); - } - // Lazy initialization of a non-volatile field. Ensure the Object is initialized - // and flushed to memory before assigning to the valueMethod field. + } + MethodHandle handle = localImplLookup.findVirtual(Class.this, "value", methodType); //$NON-NLS-1$ + if (AnnotationVars.valueMethodOffset == -1) { + Field valueMethodField = AnnotationVars.class.getDeclaredField("valueMethod"); //$NON-NLS-1$ + AnnotationVars.valueMethodOffset = getUnsafe().objectFieldOffset(valueMethodField); + } + // Lazy initialization of a non-volatile field. Ensure the Object is initialized + // and flushed to memory before assigning to the valueMethod field. /*[IF JAVA_SPEC_VERSION >= 9] getUnsafe().putObjectRelease(localAnnotationVars, AnnotationVars.valueMethodOffset, handle); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ - getUnsafe().putOrderedObject(localAnnotationVars, AnnotationVars.valueMethodOffset, handle); + getUnsafe().putOrderedObject(localAnnotationVars, AnnotationVars.valueMethodOffset, handle); /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ - return handle; - } catch (NoSuchMethodException e) { - return null; - } catch (IllegalAccessException | NoSuchFieldException e) { - throw newInternalError(e); + return handle; + } catch (NoSuchMethodException e) { + return null; + } catch (IllegalAccessException | NoSuchFieldException e) { + throw newInternalError(e); } - } + } }); } return valueMethod; @@ -3625,7 +3621,6 @@ private AnnotationCache getAnnotationCache() { return annotationCacheResult; } - private native byte[] getDeclaredAnnotationsData(); /** @@ -3901,7 +3896,6 @@ private ClassRepositoryHolder getClassRepositoryHolder() { return localClassRepositoryHolder; } - /** * Answers an array of TypeVariable for the generic parameters declared * on this Class. diff --git a/jcl/src/java.base/share/classes/java/lang/ClassCastException.java b/jcl/src/java.base/share/classes/java/lang/ClassCastException.java index b0bc9ea214f..cf6d49ffa0b 100644 --- a/jcl/src/java.base/share/classes/java/lang/ClassCastException.java +++ b/jcl/src/java.base/share/classes/java/lang/ClassCastException.java @@ -27,7 +27,7 @@ /** * This runtime exception is thrown when a program attempts to cast an object * to a type with which it is not compatible. - * + * * @version initial */ public class ClassCastException extends RuntimeException { @@ -35,7 +35,7 @@ public class ClassCastException extends RuntimeException { /** * Constructs a new instance of this class with its walkback filled in. - * + * * @version initial */ public ClassCastException() { @@ -45,9 +45,9 @@ public ClassCastException() { /** * Constructs a new instance of this class with its walkback and message * filled in. - * + * * @version initial - * + * * @param detailMessage * String The detail message for the exception. */ @@ -58,12 +58,12 @@ public ClassCastException(String detailMessage) { /** * Constructs a new instance of this class with its walkback and message * filled in. - * + * * @version initial - * + * * @param instanceClass * Class The class being cast from. - * + * * @param castClass * Class The class being cast to. */ diff --git a/jcl/src/java.base/share/classes/java/lang/ClassLoader.java b/jcl/src/java.base/share/classes/java/lang/ClassLoader.java index 34b72dea7db..9b4b6746528 100644 --- a/jcl/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/jcl/src/java.base/share/classes/java/lang/ClassLoader.java @@ -1483,7 +1483,6 @@ protected Object getClassLoadingLock(final String className) { return lock; } - /** * Forces a class to be linked (initialized). If the class has * already been linked this operation has no effect. @@ -1560,7 +1559,6 @@ final boolean isAncestorOf (ClassLoader child) { return false; } - /** * A class loader 'callerClassLoader' can access class loader 'requested' without permission check * if any of the following are true @@ -2251,7 +2249,6 @@ private boolean getClassAssertionStatusHelper(String cname) { return getDefaultAssertionStatus(); } - /** * Answers the assertion status of the named package * diff --git a/jcl/src/java.base/share/classes/java/lang/InstantiationError.java b/jcl/src/java.base/share/classes/java/lang/InstantiationError.java index eedaa9adfdf..d6d2fa003cf 100644 --- a/jcl/src/java.base/share/classes/java/lang/InstantiationError.java +++ b/jcl/src/java.base/share/classes/java/lang/InstantiationError.java @@ -23,7 +23,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 */ - + /** * This error is thrown when the VM notices that a * an attempt is being made to create a new instance @@ -38,9 +38,9 @@ */ public class InstantiationError extends IncompatibleClassChangeError { private static final long serialVersionUID = -4885810657349421204L; - + /** - * Constructs a new instance of this class with its + * Constructs a new instance of this class with its * walkback filled in. * * @author OTI @@ -51,7 +51,7 @@ public InstantiationError () { } /** - * Constructs a new instance of this class with its + * Constructs a new instance of this class with its * walkback and message filled in. * * @author OTI @@ -65,7 +65,7 @@ public InstantiationError (String detailMessage) { } /** - * Constructs a new instance of this class with its + * Constructs a new instance of this class with its * walkback and message filled in. * * @author OTI diff --git a/jcl/src/java.base/share/classes/java/lang/InstantiationException.java b/jcl/src/java.base/share/classes/java/lang/InstantiationException.java index d58c2f7390e..0e703895bfa 100644 --- a/jcl/src/java.base/share/classes/java/lang/InstantiationException.java +++ b/jcl/src/java.base/share/classes/java/lang/InstantiationException.java @@ -23,20 +23,20 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 */ - + /** * This exception is thrown when a program attempts - * to access a constructor which is not accessible + * to access a constructor which is not accessible * from the location where the reference is made. * * @author OTI * @version initial */ -public class InstantiationException extends ReflectiveOperationException { +public class InstantiationException extends ReflectiveOperationException { private static final long serialVersionUID = -8441929162975509110L; - + /** - * Constructs a new instance of this class with its + * Constructs a new instance of this class with its * walkback filled in. * * @author OTI @@ -46,7 +46,7 @@ public InstantiationException () { super(); } /** - * Constructs a new instance of this class with its + * Constructs a new instance of this class with its * walkback and message filled in. * * @author OTI @@ -60,7 +60,7 @@ public InstantiationException (String detailMessage) { } /** - * Constructs a new instance of this class with its + * Constructs a new instance of this class with its * walkback and message filled in. * * @author OTI diff --git a/jcl/src/java.base/share/classes/java/lang/InternalAnonymousClassLoader.java b/jcl/src/java.base/share/classes/java/lang/InternalAnonymousClassLoader.java index 731483c9886..f0bee13b581 100644 --- a/jcl/src/java.base/share/classes/java/lang/InternalAnonymousClassLoader.java +++ b/jcl/src/java.base/share/classes/java/lang/InternalAnonymousClassLoader.java @@ -26,7 +26,7 @@ /* * InternalAnonymousClassLoader cannot directly load classes. * This ClassLoader "owns" the native memory for classes that - * have been loaded using sun.misc.Unsafe.defineAnonymousClass. + * have been loaded using sun.misc.Unsafe.defineAnonymousClass. */ final class InternalAnonymousClassLoader extends ClassLoader { @@ -36,11 +36,11 @@ final class InternalAnonymousClassLoader extends ClassLoader { @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - throw new ClassNotFoundException(); + throw new ClassNotFoundException(); } @Override protected Class findClass(String name) throws ClassNotFoundException { - throw new ClassNotFoundException(); + throw new ClassNotFoundException(); } } diff --git a/jcl/src/java.base/share/classes/java/lang/J9VMInternals.java b/jcl/src/java.base/share/classes/java/lang/J9VMInternals.java index 2a36128517b..4aaa989e6ec 100644 --- a/jcl/src/java.base/share/classes/java/lang/J9VMInternals.java +++ b/jcl/src/java.base/share/classes/java/lang/J9VMInternals.java @@ -602,7 +602,6 @@ static final class ClassInitializationLock { */ public static native void dumpString(String str); - private static String[] getClassInfoStrings(final Class clazz, String classPath){ String classLoaderStr = ""; //$NON-NLS-1$ String cpResult = ""; //$NON-NLS-1$ diff --git a/jcl/src/java.base/share/classes/java/lang/RuntimePermission.java b/jcl/src/java.base/share/classes/java/lang/RuntimePermission.java index 72f3f8b430e..4ec32647d2c 100644 --- a/jcl/src/java.base/share/classes/java/lang/RuntimePermission.java +++ b/jcl/src/java.base/share/classes/java/lang/RuntimePermission.java @@ -22,7 +22,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 */ - + /** * RuntimePermission objects represent access to runtime * support. @@ -32,7 +32,7 @@ */ public final class RuntimePermission extends java.security.BasicPermission { private static final long serialVersionUID = 7399184964622342223L; - + /** * Creates an instance of this class with the given name. * diff --git a/jcl/src/java.base/share/classes/java/lang/StackTraceElement.java b/jcl/src/java.base/share/classes/java/lang/StackTraceElement.java index 5c5d45573bb..2c4e4ff9efa 100644 --- a/jcl/src/java.base/share/classes/java/lang/StackTraceElement.java +++ b/jcl/src/java.base/share/classes/java/lang/StackTraceElement.java @@ -26,7 +26,7 @@ /** * StackTraceElement represents a stack frame. - * + * * @see Throwable#getStackTrace() */ public final class StackTraceElement implements java.io.Serializable { @@ -46,7 +46,7 @@ public final class StackTraceElement implements java.io.Serializable { /** * Create a StackTraceElement from the parameters. - * + * * @param cls The class name * @param method The method name * @param file The file name @@ -75,7 +75,7 @@ public StackTraceElement(String cls, String method, String file, int line) { /*[IF JAVA_SPEC_VERSION >= 11]*/ /** * Create a StackTraceElement from the parameters. - * + * * @param classLoaderName The name for the ClassLoader * @param module The module name * @param version The module version @@ -136,18 +136,18 @@ private StackTraceElement() { /** * Returns true if the specified object is another StackTraceElement instance * representing the same execution point as this instance. - * + * * @param obj the object to compare to - * + * */ @Override public boolean equals(Object obj) { if (!(obj instanceof StackTraceElement)) return false; StackTraceElement castObj = (StackTraceElement) obj; - + // Unknown methods are never equal to anything (not strictly to spec, but spec does not allow null method/class names) if ((methodName == null) || (castObj.methodName == null)) return false; - + if (!getMethodName().equals(castObj.getMethodName())) return false; if (!getClassName().equals(castObj.getClassName())) return false; String localFileName = getFileName(); @@ -157,14 +157,14 @@ public boolean equals(Object obj) { if (!localFileName.equals(castObj.getFileName())) return false; } if (getLineNumber() != castObj.getLineNumber()) return false; - + return true; } /*[IF JAVA_SPEC_VERSION >= 11]*/ /** * Answers the name of the module to which the execution point represented by this stack trace element belongs. - * + * * @return the name of the Module or null if it is not available */ public String getModuleName() { @@ -173,7 +173,7 @@ public String getModuleName() { /** * Answers the version of the module to which the execution point represented by this stack trace element belongs. - * + * * @return the version of the Module or null if it is not available. */ public String getModuleVersion() { @@ -233,7 +233,7 @@ void disableIncludeInfoFlags() { /** * Returns the full name (i.e. including package) of the class where this * stack trace element is executing. - * + * * @return the name of the class where this stack trace element is * executing. */ @@ -245,7 +245,7 @@ public String getClassName() { * If available, returns the name of the file containing the Java code * source which was compiled into the class where this stack trace element * is executing. - * + * * @return the name of the Java code source file which was compiled into the * class where this stack trace element is executing. If not * available, a null value is returned. @@ -257,7 +257,7 @@ public String getFileName() { /** * Returns the source file line number for the class where this stack trace * element is executing. - * + * * @return the line number in the source file corresponding to where this * stack trace element is executing. */ @@ -265,12 +265,11 @@ public int getLineNumber() { /*[PR CMVC 82268] does not return the same value passed into the constructor */ return lineNumber; } - /** * Returns the name of the method where this stack trace element is * executing. - * + * * @return the method in which this stack trace element is executing. * Returns <unknown method> if the name of the * method cannot be determined. @@ -297,17 +296,17 @@ public int hashCode() { /*[ENDIF] JAVA_SPEC_VERSION >= 11*/ return hashCode; } - + /** * Returns true if the method name returned by * {@link #getMethodName()} is implemented as a native method. - * + * * @return true if the method is a native method */ public boolean isNativeMethod() { return lineNumber == -2; } - + /** * Returns a string representation of this stack trace element. */ diff --git a/jcl/src/java.base/share/classes/java/lang/String.java b/jcl/src/java.base/share/classes/java/lang/String.java index 25ac5ae0b0d..7d973cd0fd2 100644 --- a/jcl/src/java.base/share/classes/java/lang/String.java +++ b/jcl/src/java.base/share/classes/java/lang/String.java @@ -8689,7 +8689,6 @@ public String stripIndent() { builder.append("\n"); } - if (!trailingNewLine) { builder.setLength(builder.length() - 1); } diff --git a/jcl/src/java.base/share/classes/java/lang/System.java b/jcl/src/java.base/share/classes/java/lang/System.java index d079875ed46..6c938d8d41a 100644 --- a/jcl/src/java.base/share/classes/java/lang/System.java +++ b/jcl/src/java.base/share/classes/java/lang/System.java @@ -667,7 +667,6 @@ private static void arraycopy(Object[] A1, int offset1, Object[] A2, int offset2 } else throw new ArrayIndexOutOfBoundsException(); } - /** * Answers the current time expressed as milliseconds since * the time 00:00:00 UTC on January 1, 1970. @@ -1612,7 +1611,7 @@ private static void simpleMultiLeafArrayCopy(Object src, int srcPos, if (isFwd) iterLength = numOfElemsPerLeaf - destLeafPos; else - iterLength = destLeafPos + 1; + iterLength = destLeafPos + 1; } if (length - count < iterLength) @@ -1621,7 +1620,7 @@ private static void simpleMultiLeafArrayCopy(Object src, int srcPos, if (isFwd) offset = 0; else - offset = iterLength - 1; + offset = iterLength - 1; System.arraycopy(src, newSrcPos - offset, dest, newDestPos - offset, iterLength); @@ -1694,7 +1693,7 @@ private static void multiLeafArrayCopy(Object src, int srcPos, Object dest, if (isFwd) iterLength1 = numOfElemsPerLeaf - firstPos; else - iterLength1 = firstPos + 1; + iterLength1 = firstPos + 1; if (length - count < iterLength1) iterLength1 = length - count; @@ -1744,7 +1743,6 @@ private static void multiLeafArrayCopy(Object src, int srcPos, Object dest, } } - /** * Return platform specific line separator character(s). * Unix is \n while Windows is \r\n as per the prop set by the VM. diff --git a/jcl/src/java.base/share/classes/java/lang/Thread.java b/jcl/src/java.base/share/classes/java/lang/Thread.java index 37a941d4e79..42427755c54 100644 --- a/jcl/src/java.base/share/classes/java/lang/Thread.java +++ b/jcl/src/java.base/share/classes/java/lang/Thread.java @@ -258,7 +258,6 @@ public Thread(Runnable runnable, String threadName) { this(null, runnable, threadName, null, true); } - /** * Constructs a new Thread with no runnable object and the name provided. * The new Thread will belong to the same ThreadGroup as the Thread calling @@ -397,7 +396,6 @@ private Thread(ThreadGroup group, Runnable runnable, String threadName, AccessCo // Same group as Thread that created us group = currentThread.getThreadGroup(); - /*[PR 1FEVFSU] The rest of the configuration/initialization is shared between this constructor and the private one */ initialize(false, group, currentThread, acc, inheritThreadLocals); @@ -423,12 +421,10 @@ private void initialize(boolean booting, ThreadGroup threadGroup, Thread parentT /*[PR 96408]*/ this.group = threadGroup; - if (booting) { System.afterClinitInitialization(); } - // initialize the thread local storage before making other calls if (parentThread != null) { // Non-main thread if (inheritThreadLocals && (null != parentThread.inheritableThreadLocals)) { @@ -525,7 +521,6 @@ public static int activeCount(){ return currentThread().getThreadGroup().activeCount(); } - /** * This method is used for operations that require approval from * a SecurityManager. If there's none installed, this method is a no-op. @@ -620,7 +615,6 @@ public static int enumerate(Thread[] threads) { return currentThread().getThreadGroup().enumerate(threads, true); } - /** * Returns the context ClassLoader for the receiver. * @@ -677,7 +671,6 @@ public final ThreadGroup getThreadGroup() { return group; } - /** * Posts an interrupt request to the receiver * @@ -712,7 +705,6 @@ public void interrupt() { } } - /** * Answers a boolean indicating whether the current Thread * (currentThread()) has a pending interrupt request @@ -810,7 +802,6 @@ public boolean isInterrupted() { private native boolean isInterruptedImpl(); - /** * Blocks the current Thread (Thread.currentThread()) until the * receiver finishes its execution and dies. @@ -1334,7 +1325,6 @@ void blockedOn(Interruptible interruptible) { } } - private native Throwable getStackTraceImpl(); /** diff --git a/jcl/src/java.base/share/classes/java/lang/ThreadGroup.java b/jcl/src/java.base/share/classes/java/lang/ThreadGroup.java index de25925b3d2..a355355d0cc 100644 --- a/jcl/src/java.base/share/classes/java/lang/ThreadGroup.java +++ b/jcl/src/java.base/share/classes/java/lang/ThreadGroup.java @@ -704,7 +704,7 @@ final void remove(java.lang.Thread thread) { } /*[PR CMVC 114880] ThreadGroup is not notified when all threads complete */ - if (isThreadGroupEmpty) { + if (isThreadGroupEmpty) { synchronized (this) { notifyAll(); } @@ -939,7 +939,6 @@ public String toString() { return getClass().getName() + "[name=" + this.getName() + ",maxpri=" + this.getMaxPriority() + "]" ; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ } - /** * Any uncaught exception in any Thread has to be forwarded (by the VM) to the Thread's ThreadGroup * by sending this message (uncaughtException). This allows users to define custom ThreadGroup classes diff --git a/jcl/src/java.base/share/classes/java/lang/Throwable.java b/jcl/src/java.base/share/classes/java/lang/Throwable.java index e723701365b..43b28756913 100644 --- a/jcl/src/java.base/share/classes/java/lang/Throwable.java +++ b/jcl/src/java.base/share/classes/java/lang/Throwable.java @@ -457,7 +457,6 @@ private void readObject(ObjectInputStream s) } } - if (suppressedExceptions != null) { List newList = Collections.EMPTY_LIST; try { diff --git a/jcl/src/java.base/share/classes/java/lang/VMAccess.java b/jcl/src/java.base/share/classes/java/lang/VMAccess.java index 7d5dbc3e7e4..eec13dc0d54 100644 --- a/jcl/src/java.base/share/classes/java/lang/VMAccess.java +++ b/jcl/src/java.base/share/classes/java/lang/VMAccess.java @@ -61,7 +61,6 @@ public Class findClassOrNullHelper(String className, ClassLoader classLoader) return VMAccess.findClassOrNull(className, classLoader); } - /*[IF JAVA_SPEC_VERSION >= 9]*/ /** * Answer the platform class loader. diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/ArgumentConversionHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/ArgumentConversionHandle.java index 5f048531fd6..dae150ad3c5 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/ArgumentConversionHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/ArgumentConversionHandle.java @@ -43,4 +43,3 @@ protected final ThunkTuple computeThunks(Object nextHandleType) { } // }}} JIT support } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/AsTypeHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/AsTypeHandle.java index 7d2f835b8bc..44145b89954 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/AsTypeHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/AsTypeHandle.java @@ -22,9 +22,9 @@ */ package java.lang.invoke; -/* AsTypeHandle is a MethodHandle subclass used to convert the +/* AsTypeHandle is a MethodHandle subclass used to convert the * arguments and return type. - * + * */ final class AsTypeHandle extends ArgumentConversionHandle { @@ -69,4 +69,3 @@ final void compareWithAsType(AsTypeHandle left, Comparator c) { compareWithConvert(left, c); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java index 4d280f7e88c..cf464d501df 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java @@ -31,11 +31,11 @@ abstract class BoundMethodHandle extends MethodHandle { super(mt, lf); OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + LambdaFormEditor editor() { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + static SpeciesData speciesData(LambdaForm lf) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } @@ -54,7 +54,7 @@ static SpeciesData speciesData_LLLL() { static SpeciesData speciesData_LLLLL() { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + LambdaForm.NamedFunction getterFunction(int num) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } @@ -73,7 +73,7 @@ class SpeciesData { MethodHandle constructor() { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + LambdaForm.NamedFunction getterFunction(int num) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } @@ -84,8 +84,8 @@ MethodHandle factory() { } /*[ENDIF] JAVA_SPEC_VERSION >= 10 */ } - + abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object obj); - + abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf); } diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/BruteArgumentMoverHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/BruteArgumentMoverHandle.java index 2f0dd61672d..6b42ae89263 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/BruteArgumentMoverHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/BruteArgumentMoverHandle.java @@ -62,7 +62,6 @@ protected ArgumentMoverHandle(ArgumentMoverHandle originalHandle, MethodType new this.permute = originalHandle.permute; } - // {{{ JIT support protected ThunkTuple computeThunks(Object arg) { @@ -368,21 +367,21 @@ final long extra_J(int index) { // Unbox if needed. These allow us to skip an AsTypeHandle just for unboxing, // though it does impose a checkcast unless the jit can eliminate it. // - final boolean extra_Z(int index) { - return (Boolean)extra_L(index); + final boolean extra_Z(int index) { + return (Boolean)extra_L(index); } final byte extra_B(int index) { return (Byte)extra_L(index); } final short extra_S(int index) { return (Short)extra_L(index); } final char extra_C(int index) { - return (Character)extra_L(index); + return (Character)extra_L(index); } - final float extra_F(int index) { - return (Float)extra_L(index); + final float extra_F(int index) { + return (Float)extra_L(index); } - final double extra_D(int index) { - return (Double)extra_L(index); + final double extra_D(int index) { + return (Double)extra_L(index); } private static Object[] infoAffectingThunks(MethodHandle next, int[] permute, Object[] extra) { @@ -409,26 +408,26 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) { } // }}} JIT support - final void compareWith(MethodHandle right, Comparator c) { - if (right instanceof BruteArgumentMoverHandle) { - ((BruteArgumentMoverHandle)right).compareWithBruteArgumentMover(this, c); - } else { - c.fail(); - } - } - - final void compareWithArgumentMover(ArgumentMoverHandle left, Comparator c) { - // If left were an BruteArgumentMoverHandle, we'd be in - // compareWithBruteArgumentMover, so it doesn't match. - c.fail(); - } - - final void compareWithBruteArgumentMover(BruteArgumentMoverHandle left, Comparator c) { - c.compareStructuralParameter(left.extra.length, this.extra.length); - for (int i = 0; (i < left.extra.length) && (i < this.extra.length); i++) { - c.compareUserSuppliedParameter(left.extra[i], this.extra[i]); - } - super.compareWithArgumentMover(left, c); - } + final void compareWith(MethodHandle right, Comparator c) { + if (right instanceof BruteArgumentMoverHandle) { + ((BruteArgumentMoverHandle)right).compareWithBruteArgumentMover(this, c); + } else { + c.fail(); + } + } + + final void compareWithArgumentMover(ArgumentMoverHandle left, Comparator c) { + // If left were an BruteArgumentMoverHandle, we'd be in + // compareWithBruteArgumentMover, so it doesn't match. + c.fail(); + } + + final void compareWithBruteArgumentMover(BruteArgumentMoverHandle left, Comparator c) { + c.compareStructuralParameter(left.extra.length, this.extra.length); + for (int i = 0; (i < left.extra.length) && (i < this.extra.length); i++) { + c.compareUserSuppliedParameter(left.extra[i], this.extra[i]); + } + super.compareWithArgumentMover(left, c); + } } diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/CacheKey.java b/jcl/src/java.base/share/classes/java/lang/invoke/CacheKey.java index a3b3606c055..5cb1af37af4 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/CacheKey.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/CacheKey.java @@ -25,17 +25,17 @@ /** * Base class for CacheKeys used in the HandleCache. There are two subclasses - * FieldCacheKey and MethodCacheKey used by the HandleCache. + * FieldCacheKey and MethodCacheKey used by the HandleCache. */ abstract class CacheKey { final String name; private final int hashcode; - + public CacheKey(String name, int hashcode){ this.name = name; this.hashcode = hashcode; } - + @Override public int hashCode() { return hashcode; diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/CallSite.java b/jcl/src/java.base/share/classes/java/lang/invoke/CallSite.java index baee3712f1f..a12f34cdd1a 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/CallSite.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/CallSite.java @@ -33,23 +33,23 @@ *
  • ConstantCallSite - if the target will never change
  • *
  • VolatileCallSite - if the target is expected to frequently change. Changes will be immediately visible in all threads.
  • *
  • MutableCallSite - if the target is expected to rarely change and threads may see previous values of the target for some time.
  • - * - * + * + * *

    - * CallSites are created with a MethodType and permanently bound to that type. Any changes to the target - * MethodHandle must be of the identical MethodType or a WrongMethodTypeException will be thrown. - * + * CallSites are created with a MethodType and permanently bound to that type. Any changes to the target + * MethodHandle must be of the identical MethodType or a WrongMethodTypeException will be thrown. + * * @since 1.7 */ public abstract class CallSite { private final MethodType type; private static MethodHandle initialTargetHandleCache; - + CallSite(MethodType type){ type.getClass(); // Throw NPE if null this.type = type; } - + /** * Report the type of CallSite's target MethodHandle. * A CallSite cannot change its type. @@ -58,10 +58,10 @@ public abstract class CallSite { public MethodType type() { return type; } - + /** * Return the target MethodHandle of the CallSite. - * + * * @return the current target MethodHandle */ public abstract MethodHandle getTarget(); @@ -69,21 +69,20 @@ public MethodType type() { /** * Set the CallSite's target to be nextTarget. * The nextTarget MethodHandle must have the same type as the CallSite. - * + * * @param nextTarget - the new target value for the CallSite * @throws WrongMethodTypeException - if the type of nextTarget differs from that of the CallSite. * @throws NullPointerException - if nextTarget is null. */ public abstract void setTarget(MethodHandle nextTarget) throws WrongMethodTypeException, NullPointerException; - + /** - * Return a MethodHandle equivalent to the invokedynamic instruction on this CallSite. + * Return a MethodHandle equivalent to the invokedynamic instruction on this CallSite. * The MethodHandle is equivalent to getTarget().invokeExact(args). - * + * * @return a MethodHandle that is equivalent to an invokedynamic instruction on this CallSite. */ public abstract MethodHandle dynamicInvoker(); - /* Defer the creation of the Exception until called in the IllegalState */ static void throwIllegalStateException() throws IllegalStateException { @@ -100,7 +99,7 @@ static MethodHandle initialTarget(MethodType type) { /* Adapt the initial target to be compliant with what the caller expects */ return MethodHandles.dropArguments(initialTargetHandle, 0, type.ptypes()); } - + /* Initialize the cached MethodHandle for initialTarget */ private static MethodHandle lookupInitialTarget() { try { @@ -111,4 +110,3 @@ private static MethodHandle lookupInitialTarget() { return initialTargetHandleCache; } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/CatchHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/CatchHandle.java index 8793392389e..d7af49e103b 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/CatchHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/CatchHandle.java @@ -45,7 +45,7 @@ MethodHandle cloneWithNewType(MethodType newType) { return new CatchHandle(this, newType); } - public static CatchHandle get(MethodHandle tryTarget, Class exceptionClass, MethodHandle catchTarget, MethodHandle equivalent) { + public static CatchHandle get(MethodHandle tryTarget, Class exceptionClass, MethodHandle catchTarget, MethodHandle equivalent) { return new CatchHandle(tryTarget, exceptionClass, catchTarget, equivalent); } @@ -100,4 +100,3 @@ final void compareWithCatch(CatchHandle left, Comparator c) { c.compareChildHandle(left.catchTarget, this.catchTarget); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/CollectHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/CollectHandle.java index 392d4a21e9a..7a45c3cf809 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/CollectHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/CollectHandle.java @@ -28,7 +28,7 @@ import java.util.List; /*[ENDIF] JAVA_SPEC_VERSION >= 15 */ -/* CollectHandle is a MethodHandle subclass used to call another MethodHandle. +/* CollectHandle is a MethodHandle subclass used to call another MethodHandle. * It accepts the incoming arguments and collects the requested number * of them into an array of type 'T'. *

    @@ -46,7 +46,7 @@ final class CollectHandle extends MethodHandle { @VMCONSTANTPOOL_FIELD final int collectPosition; /* The starting position of arguments to collect */ final Object emptyArray; - + CollectHandle(MethodHandle next, int collectArraySize, int collectPosition) { super(collectMethodType(next.type(), collectArraySize, collectPosition), KIND_COLLECT, new int[]{collectArraySize, collectPosition}); this.collectPosition = collectPosition; @@ -58,7 +58,7 @@ final class CollectHandle extends MethodHandle { emptyArray = null; } } - + CollectHandle(CollectHandle original, MethodType newType) { super(original, newType); this.collectPosition = original.collectPosition; @@ -81,7 +81,7 @@ private static final MethodType collectMethodType(MethodType type, int collectAr } // Change the T[] into a 'T' MethodType newType = type.changeParameterType(collectPosition, arrayComponent); - + // Add necessary additional 'T' to the type if (0 == collectArraySize) { newType = newType.dropParameterTypes(collectPosition , collectPosition + 1); @@ -140,7 +140,7 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) throws Throwa ILGenMacros.push(collectArraySize == 0 ? emptyArray : allocateArray(this)), ILGenMacros.middleN(collectionStart(), numArgsToCollect(), argPlaceholder)); return ILGenMacros.invokeExact_X( - next, + next, ILGenMacros.placeholder( ILGenMacros.firstN(collectionStart(), argPlaceholder), ILGenMacros.pop_L(), diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/ConstantCallSite.java b/jcl/src/java.base/share/classes/java/lang/invoke/ConstantCallSite.java index c86d0f2ed57..dd586cf5c27 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/ConstantCallSite.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/ConstantCallSite.java @@ -23,17 +23,17 @@ package java.lang.invoke; /** - * A ConstantCallSite is permanently bound to its initial target MethodHandle. + * A ConstantCallSite is permanently bound to its initial target MethodHandle. * Any call to {@link #setTarget(MethodHandle)} will result in an UnsupportedOperationException. - * + * * @since 1.7 */ public class ConstantCallSite extends CallSite { - private final MethodHandle target; + private final MethodHandle target; /** * Create a ConstantCallSite with a target MethodHandle that cannot change. - * + * * @param permanentTarget - the target MethodHandle to permanently associate with this CallSite. */ public ConstantCallSite(MethodHandle permanentTarget) { @@ -41,10 +41,10 @@ public ConstantCallSite(MethodHandle permanentTarget) { // .type() call ensures non-null target = permanentTarget; } - + /** * Create a ConstantCallSite and assign the hook MethodHandle's result to its permanent target. - * The hook MethodHandle is invoked as though by (@link MethodHandle#invoke(this)) and must return a MethodHandle that will be installed + * The hook MethodHandle is invoked as though by (@link MethodHandle#invoke(this)) and must return a MethodHandle that will be installed * as the ConstantCallSite's target. *

    * The hook MethodHandle is required if the ConstantCallSite's target needs to have access to the ConstantCallSite instance. This is an @@ -52,9 +52,9 @@ public ConstantCallSite(MethodHandle permanentTarget) { *

    * The hook must return a MethodHandle that is exactly of type targetType. *

    - * Until the result of the hook has been installed in the ConstantCallSite, any call to getTarget() or dynamicInvoker() will throw an + * Until the result of the hook has been installed in the ConstantCallSite, any call to getTarget() or dynamicInvoker() will throw an * IllegalStateException. It is always valid to call type(). - * + * * @param targetType - the type of the ConstantCallSite's target * @param hook - the hook handle, with signature (ConstantCallSite)MethodHandle * @throws Throwable anything thrown by the hook. @@ -74,7 +74,7 @@ protected ConstantCallSite(MethodType targetType, MethodHandle hook) throws Thro } target = handle; } - + /** * Return the target MethodHandle of this CallSite. * @throws IllegalStateException - if the target has not yet been assigned in the ConstantCallSite constructor @@ -87,7 +87,7 @@ public final MethodHandle dynamicInvoker() throws IllegalStateException { /** * Return the target MethodHandle of this CallSite. * The target is defined as though it where a final field. - * + * * @throws IllegalStateException - if the target has not yet been assigned in the ConstantCallSite constructor */ @Override @@ -99,7 +99,7 @@ public final MethodHandle getTarget() throws IllegalStateException { } /** - * Throws UnsupportedOperationException as a ConstantCallSite is permanently + * Throws UnsupportedOperationException as a ConstantCallSite is permanently * bound to its initial target MethodHandle. */ @Override @@ -107,4 +107,3 @@ public final void setTarget(MethodHandle newTarget) { throw new UnsupportedOperationException(); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/ConstructorHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/ConstructorHandle.java index 317bbd3e4bd..30353693891 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/ConstructorHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/ConstructorHandle.java @@ -36,27 +36,27 @@ * The vmSlot will hold a J9Method address of the method. */ final class ConstructorHandle extends PrimitiveHandle { - + static { //Making sure DirectHandle is loaded before the ConstructorHandle is loaded. Therefore, to secure a correct thunk. DirectHandle.load(); } - + public ConstructorHandle(Class referenceClass, MethodType type) throws NoSuchMethodException, IllegalAccessException { super(constructorMethodType(type, referenceClass), referenceClass, "", KIND_CONSTRUCTOR, null); //$NON-NLS-1$ /* Pass referenceClass as SpecialToken as KIND_SPECIAL & KIND_CONSTRUCTOR share lookup code */ this.defc = finishMethodInitialization(referenceClass, type); } - + public ConstructorHandle(Constructor ctor) throws IllegalAccessException { super(constructorMethodType(ctor), ctor.getDeclaringClass(), "", KIND_CONSTRUCTOR, ctor.getModifiers(), ctor.getDeclaringClass()); //$NON-NLS-1$ - + boolean succeed = setVMSlotAndRawModifiersFromConstructor(this, ctor); if (!succeed) { throw new IllegalAccessException(); } } - + ConstructorHandle(ConstructorHandle originalHandle, MethodType newType) { super(originalHandle, newType); } @@ -67,7 +67,7 @@ public ConstructorHandle(Constructor ctor) throws IllegalAccessException { private static final MethodType constructorMethodType(MethodType type, Class referenceClazz) { return type.changeReturnType(referenceClazz); } - + /* * Constructors have type (constructor.getParameterType)constructor.getDeclaringCLass. */ @@ -75,7 +75,7 @@ private static final MethodType constructorMethodType(Constructor constructor Class declaringClass = constructor.getDeclaringClass(); return MethodType.methodType(declaringClass, constructor.getParameterTypes()); } - + @Override boolean canRevealDirect() { return true; @@ -103,7 +103,7 @@ private final Object invokeExact_thunkArchetype_L(int argPlaceholder) { MethodHandle cloneWithNewType(MethodType newType) { return new ConstructorHandle(this, newType); } - + final void compareWith(MethodHandle right, Comparator c) { if (right instanceof ConstructorHandle) { ((ConstructorHandle)right).compareWithConstructor(this, c); @@ -116,4 +116,3 @@ final void compareWithConstructor(ConstructorHandle left, Comparator c) { c.compareStructuralParameter(left.referenceClass, this.referenceClass); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/ConvertHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/ConvertHandle.java index e3cd0bb150e..a0426dd4ff1 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/ConvertHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/ConvertHandle.java @@ -35,11 +35,11 @@ abstract class ConvertHandle extends MethodHandle { final MethodHandle next; ConvertHandle(MethodHandle handle, MethodType type, byte kind, Object thunkArg) { - super(type, kind, thunkArg); - if ((handle == null) || (type == null)) { - throw new IllegalArgumentException(); - } - this.next = handle; + super(type, kind, thunkArg); + if ((handle == null) || (type == null)) { + throw new IllegalArgumentException(); + } + this.next = handle; } ConvertHandle(ConvertHandle originalHandle, MethodType newType) { @@ -50,7 +50,7 @@ abstract class ConvertHandle extends MethodHandle { @VMCONSTANTPOOL_FIELD boolean requiresBoxing = false; - + /* * Determine if the arguments can be converted from the MethodType fromType to that of toType. * Return conversions are handled by FilterReturnHandle. @@ -62,22 +62,22 @@ final void checkConversion(MethodType toType, MethodType fromType) { if (toArgs.length != fromArgs.length) { throwWrongMethodTypeException(fromType, toType, toArgs.length); } - + boolean isExplicitCast = (kind == KIND_EXPLICITCAST); - + // Ensure argsToCollect can be converted to type of array for (int i = 0; i < toArgs.length; i++ ) { Class toClass = toArgs[i]; Class fromClass = fromArgs[i]; - + // identity conversion if (fromClass == toClass) { continue; } - + boolean toIsPrimitive = toClass.isPrimitive(); boolean fromIsPrimitive = fromClass.isPrimitive(); - + // both are reference types, then apply a cast at runtime if (!toIsPrimitive && !fromIsPrimitive) { continue; @@ -91,7 +91,7 @@ final void checkConversion(MethodType toType, MethodType fromType) { } throwWrongMethodTypeException(fromType, toType, i); } - + // unbox + widening primitive conversion if (toIsPrimitive) { if (isExplicitCast) { @@ -107,7 +107,7 @@ final void checkConversion(MethodType toType, MethodType fromType) { } throwWrongMethodTypeException(fromType, toType, i); } - + // toClass is reference type // primitive wrapper is subclass of fromClass if (toClass.isAssignableFrom(MethodTypeHelper.wrapPrimitive(fromClass))) { @@ -117,7 +117,7 @@ final void checkConversion(MethodType toType, MethodType fromType) { throwWrongMethodTypeException(fromType, toType, i); } } - + static final void throwWrongMethodTypeException(MethodType fromType, MethodType toType, int index) throws WrongMethodTypeException { /*[MSG "K05cb", "No conversion from '{0}' to '{1} at index ({2})"]*/ throw new WrongMethodTypeException(Msg.getString("K05cb", fromType.toString(), toType.toString(), Integer.toString(index))); //$NON-NLS-1$ @@ -136,7 +136,7 @@ static final class FilterHelpers { /* local cache of previously looked up filters */ static final ConcurrentHashMap cachedReturnFilters = new ConcurrentHashMap(); - + /* * Return conversions: explicit vs asType handled by the boolean isExplicitCast */ @@ -180,8 +180,7 @@ static MethodHandle getReturnFilter(Class fromReturn, Class toReturn, bool throw new Error(e); } } - - + /* JLSv3: 5.1.2: allowed widening primitive conversions * byte to short, int, long, float, or double * short to int, long, float, or double @@ -200,11 +199,11 @@ static boolean checkIfWideningPrimitiveConversion(Class from, Class to) { return primitiveIndex1(to) > primitiveIndex1(from); } - - /* + + /* * doesn't handle boolean or non-primitive. Also, can't widen to char. * so it's a widening conversion if primitiveIndex1(to) > primitiveIndex1(from) - * + * */ private static int primitiveIndex1(Class c) { int ch = c.getName().charAt(0); @@ -219,12 +218,12 @@ private static int primitiveIndex1(Class c) { 6 - byte */ return (021230546 >> (3*shift)) & 7; // octal value is 0x21230546 in hex - } + } static MethodHandle getPrimitiveReturnFilter(MethodType type, boolean isExplicitCast) throws IllegalAccessException, NoSuchMethodException { Class fromClass = type.parameterType(0); Class toClass = type.returnType(); - + if (!isExplicitCast) { if ((type.returnType() != void.class) && !checkIfWideningPrimitiveConversion(fromClass, toClass)) { throw new WrongMethodTypeException(); @@ -242,12 +241,12 @@ static MethodHandle getPrimitiveReturnFilter(MethodType type, boolean isExplicit } return filter; } - + /*[IF ]*/ /* From 292 javadoc: - * If T0 is a primitive and T1 a reference, a boxing conversion is applied if one exists, - * possibly followed by a reference conversion to a superclass. T1 must be a wrapper - * class or a supertype of one. + * If T0 is a primitive and T1 a reference, a boxing conversion is applied if one exists, + * possibly followed by a reference conversion to a superclass. T1 must be a wrapper + * class or a supertype of one. */ /*[ENDIF]*/ /* @@ -271,11 +270,11 @@ static MethodHandle getBoxingReturnFilter(MethodType type) throws IllegalAccessE } return filter; } - + static MethodHandle getUnboxingReturnFilter(MethodType type, boolean isExplicitCast) throws IllegalAccessException, NoSuchMethodException { Class toUnbox = type.parameterType(0); Class returnType = type.returnType(); - + if (toUnbox.equals(Object.class)) { String methodName; if (isExplicitCast) { @@ -285,7 +284,7 @@ static MethodHandle getUnboxingReturnFilter(MethodType type, boolean isExplicitC } methodName += MethodTypeHelper.getBytecodeStringName(returnType); return privilegedLookup.findStatic(FilterHelpers.class, methodName, MethodType.methodType(returnType, Object.class)); - + } else if (toUnbox.equals(Number.class)) { /* Widening conversions need to validate the conversion at runtime */ if (!isExplicitCast) { @@ -301,7 +300,7 @@ static MethodHandle getUnboxingReturnFilter(MethodType type, boolean isExplicitC String methodName = MethodTypeHelper.getBytecodeStringName(returnType) + "Value"; //$NON-NLS-1$ return privilegedLookup.findVirtual(Number.class, methodName, MethodType.methodType(returnType)); } - + } else if (toUnbox.equals(Boolean.class)) { /* Boolean can be unboxed but there are no widening conversions */ MethodHandle filter = privilegedLookup.findVirtual(Boolean.class, "booleanValue", MethodType.methodType(boolean.class)); //$NON-NLS-1$ @@ -320,13 +319,13 @@ static MethodHandle getUnboxingReturnFilter(MethodType type, boolean isExplicitC } /* widen the return if possible */ return MethodHandles.filterReturnValue(filter, getPrimitiveReturnFilter(MethodType.methodType(returnType, char.class), isExplicitCast)); - + } else if (MethodTypeHelper.WRAPPER_SET.contains(toUnbox)) { /* remaining wrappers may have widening conversions - can be handled by toUnbox#'type'Value() methods (ie: Number subclasses)*/ Class unwrapped = MethodTypeHelper.unwrapPrimitive(toUnbox); boolean justUnwrap = returnType.equals(unwrapped); if (justUnwrap || isExplicitCast || checkIfWideningPrimitiveConversion(unwrapped, returnType)) { - + if (isExplicitCast && !justUnwrap) { /* Special case Boolean/Character --> (!boolean/!char) as it requires a two-step filter */ if ((returnType == char.class) || (returnType == boolean.class)) { @@ -336,14 +335,14 @@ static MethodHandle getUnboxingReturnFilter(MethodType type, boolean isExplicitC return MethodHandles.filterReturnValue(unbox, filter); } } - + return privilegedLookup.findVirtual(toUnbox, returnType.getName()+"Value", MethodType.methodType(returnType)); //$NON-NLS-1$; } } throw new WrongMethodTypeException(); } - + /* * object to object conversion: use Class#cast(Object) */ @@ -361,7 +360,7 @@ static MethodHandle getCastFilter(MethodType type, boolean isExplicitCast) throw public static Object explicitCastInterfaceUnchecked(Object o) { return o; } - + public static boolean explicitObject2Z(Object o) { if (o == null) { return false; @@ -374,7 +373,7 @@ public static boolean explicitObject2Z(Object o) { return (((Number)o).byteValue() & 1) == 1; } } - + public static byte explicitObject2B(Object o) { if (o == null) { return 0; @@ -459,7 +458,7 @@ public static double explicitObject2D(Object o) { return ((Number)o).doubleValue(); } } - + public static boolean explicitNumber2Z(Number n) { if (n == null) { return false; @@ -478,7 +477,7 @@ public static char explicitNumber2C(Number n) { private static final ClassCastException newClassCastException() { return new ClassCastException(); } - + public static boolean object2Z(Object o) { return ((Boolean)o).booleanValue(); } @@ -527,17 +526,17 @@ public static long object2J(Object o) { } throw newClassCastException(); } - + public static byte number2B(Number n) { /* Number can be { Byte, Short, Integer, Long, Float, Double} - * Number -> byte: + * Number -> byte: * Byte -> byte */ return ((Byte)n).byteValue(); //Implicit nullcheck; } public static short number2S(Number n) { /* Number can be { Byte, Short, Integer, Long, Float, Double} - * Number -> short: + * Number -> short: * Byte -> byte -> short * Short -> short */ @@ -549,7 +548,7 @@ public static short number2S(Number n) { } public static int number2I(Number n) { /* Number can be { Byte, Short, Integer, Long, Float, Double} - * Number -> int: + * Number -> int: * Byte -> byte -> int * Short -> short -> int * Integer-> int @@ -562,7 +561,7 @@ public static int number2I(Number n) { } public static long number2J(Number n) { /* Number can be { Byte, Short, Integer, Long, Float, Double} - * Number -> long: + * Number -> long: * Byte -> byte -> long * Short -> short -> long * Integer-> int -> long @@ -577,7 +576,7 @@ public static long number2J(Number n) { public static float number2F(Number n) { /* Number can be { Byte, Short, Integer, Long, Float, Double} - * Number -> float: + * Number -> float: * Byte -> byte -> float * Short -> short -> float * Integer-> int -> float @@ -592,7 +591,7 @@ public static float number2F(Number n) { } public static double number2D(Number n) { /* Number can be { Byte, Short, Integer, Long, Float, Double} - * Number -> double: + * Number -> double: * Byte -> byte -> double * Short -> short -> double * Integer-> int -> double @@ -606,9 +605,9 @@ public static double number2D(Number n) { n.getClass(); // implicit nullcheck. throw newClassCastException(); } - + public static void popObject(Object o) { } - + public static double V2D() { return 0; } public static long V2J() { return 0; } public static float V2F() { return 0; } @@ -618,7 +617,7 @@ public static void popObject(Object o) { } public static byte V2B() { return 0; } public static boolean V2Z() { return false; } public static Object V2object() { return null; } - + public static double Z2D(boolean j) { return j ? 1 : 0; } public static long Z2J(boolean j) { return j ? 1 : 0; } public static float Z2F(boolean j) { return j ? 1 : 0; } @@ -628,7 +627,7 @@ public static void popObject(Object o) { } public static byte Z2B(boolean j) { return (byte)(j ? 1 : 0); } public static void Z2V(boolean j) { } public static Object Z2object(boolean j) { return Boolean.valueOf(j); } - + public static double B2D(byte j) { return j; } public static long B2J(byte j) { return j; } public static float B2F(byte j) { return j; } @@ -638,7 +637,7 @@ public static void Z2V(boolean j) { } public static boolean B2Z(byte j) { return (byte)(j & 1) == 1; } public static void B2V(byte j) { } public static Object B2object(byte j) { return Byte.valueOf(j); } - + public static double S2D(short j) { return j; } public static long S2J(short j) { return j; } public static float S2F(short j) { return j; } @@ -648,7 +647,7 @@ public static void B2V(byte j) { } public static boolean S2Z(short j) { return (((byte)j) & 1) == 1; } public static void S2V(short j) { } public static Object S2object(short j) { return Short.valueOf(j); } - + public static double C2D(char j) { return j; } public static long C2J(char j) { return j; } public static float C2F(char j) { return j; } @@ -658,7 +657,7 @@ public static void S2V(short j) { } public static boolean C2Z(char j) { return (((byte)j) & 1) == 1; } public static void C2V(char j) { } public static Object C2object(char j) { return Character.valueOf(j); } - + public static boolean I2Z(int i) {return (((byte)i) & 1) == 1; } public static byte I2B(int i) { return (byte)i; } public static short I2S(int i) { return (short)i; } @@ -668,7 +667,7 @@ public static void C2V(char j) { } public static double I2D(int i) { return i; } public static void I2V(int j) { } public static Object I2object(int j) { return Integer.valueOf(j); } - + public static float J2F(long j) { return j; } public static double J2D(long j) { return j; } public static int J2I(long j) { return (int)j; } @@ -678,7 +677,7 @@ public static void I2V(int j) { } public static boolean J2Z(long j) { return (((byte)j) & 1) == 1; } public static void J2V(long j) { } public static Object J2object(long j) { return Long.valueOf(j); } - + public static long F2J(float j) { return (long)j; } public static double F2D(float j) { return j; } public static int F2I(float j) { return (int)j; } @@ -688,7 +687,7 @@ public static void J2V(long j) { } public static boolean F2Z(float j) { return (((byte)j) & 1) == 1; } public static void F2V(float j) { } public static Object F2object(float j) { return Float.valueOf(j); } - + public static float D2F(double j) { return (float) j; } public static long D2J(double j) { return (long) j; } public static int D2I(double j) { return (int)j; } diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/DefaultMethodConflictException.java b/jcl/src/java.base/share/classes/java/lang/invoke/DefaultMethodConflictException.java index d4a0b2d23a4..19715262f45 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/DefaultMethodConflictException.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/DefaultMethodConflictException.java @@ -23,7 +23,7 @@ package java.lang.invoke; /** - * DefaultMethodConflictException is thrown when method resolution + * DefaultMethodConflictException is thrown when method resolution * found conflicting definitions of interface default methods. */ @VMCONSTANTPOOL_CLASS @@ -32,7 +32,7 @@ final class DefaultMethodConflictException extends RuntimeException { * Serialized version ID */ private static final long serialVersionUID = 292L; - + /** * Construct a DefaultMethodConflictException with the supplied message. * @param message Describes the method conflicts @@ -41,4 +41,3 @@ final class DefaultMethodConflictException extends RuntimeException { super(message); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/DirectHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/DirectHandle.java index 2b617f5f867..655a54957cc 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/DirectHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/DirectHandle.java @@ -39,11 +39,11 @@ class DirectHandle extends PrimitiveHandle { final boolean isStatic; final boolean originIsFindVirtual; - + DirectHandle(Class referenceClass, String methodName, MethodType type, byte kind, Class specialCaller) throws NoSuchMethodException, IllegalAccessException { this(referenceClass, methodName, type, kind, specialCaller, false); } - + DirectHandle(Class referenceClass, String methodName, MethodType type, byte kind, Class specialCaller, boolean originIsFindVirtual) throws NoSuchMethodException, IllegalAccessException { super(directMethodType(type, kind, specialCaller), referenceClass, methodName, kind, null); assert (kind != KIND_SPECIAL) || (specialCaller != null); @@ -55,11 +55,11 @@ class DirectHandle extends PrimitiveHandle { isStatic = Modifier.isStatic(rawModifiers); this.originIsFindVirtual = originIsFindVirtual; } - + public DirectHandle(Method method, byte kind, Class specialCaller) throws IllegalAccessException { this(method, kind, specialCaller, false); } - + public DirectHandle(Method method, byte kind, Class specialCaller, boolean originIsFindVirtual) throws IllegalAccessException { super(directMethodType(MethodType.methodType(method.getReturnType(), method.getParameterTypes()), kind, specialCaller), method.getDeclaringClass(), method.getName(), kind, method.getModifiers(), null); assert (kind != KIND_SPECIAL) || (specialCaller != null); @@ -72,9 +72,9 @@ public DirectHandle(Method method, byte kind, Class specialCaller, boolean or isStatic = Modifier.isStatic(rawModifiers); this.originIsFindVirtual = originIsFindVirtual; } - + /* - * Create a new DirectHandle from another DirectHandle. + * Create a new DirectHandle from another DirectHandle. * This is used by ReceiverBoundHandle */ DirectHandle(PrimitiveHandle other, byte kind) { @@ -89,7 +89,7 @@ public DirectHandle(Method method, byte kind, Class specialCaller, boolean or isStatic = Modifier.isStatic(other.rawModifiers); this.originIsFindVirtual = other.directHandleOriginatedInFindVirtual(); } - + DirectHandle(DirectHandle originalHandle, MethodType newType) { super(originalHandle, newType); isStatic = originalHandle.isStatic; @@ -110,7 +110,7 @@ private static final MethodType directMethodType(MethodType existingType, byte k } return existingType.insertParameterTypes(0, specialCaller); } - + private void addHandleToClassCache() { MethodHandleCache cache = MethodHandleCache.getCache(defc); cache.addDirectHandle(this); @@ -126,19 +126,19 @@ final void nullCheckIfRequired(Object receiver) throws NullPointerException { boolean canRevealDirect() { return true; } - + @Override boolean directHandleOriginatedInFindVirtual() { return originIsFindVirtual; } - + // {{{ JIT support private static final ThunkTable _thunkTable = new ThunkTable(); protected ThunkTable thunkTable(){ return _thunkTable; } - // ILGen macros - protected static native boolean isAlreadyCompiled(long j9method); - protected static native long compiledEntryPoint(long j9method); + // ILGen macros + protected static native boolean isAlreadyCompiled(long j9method); + protected static native long compiledEntryPoint(long j9method); protected static native void directCall_V(int argPlaceholder); protected static native int directCall_I(int argPlaceholder); @@ -160,9 +160,9 @@ private final void invokeExact_thunkArchetype_V(int argPlaceholder) { if (ILGenMacros.isCustomThunk()) { directCall_V(argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { - ComputedCalls.dispatchDirect_V(compiledEntryPoint(vmSlot), argPlaceholder); + ComputedCalls.dispatchDirect_V(compiledEntryPoint(vmSlot), argPlaceholder); } else { - ComputedCalls.dispatchJ9Method_V(vmSlot, argPlaceholder); + ComputedCalls.dispatchJ9Method_V(vmSlot, argPlaceholder); } } @@ -171,11 +171,11 @@ private final void invokeExact_thunkArchetype_V(Object receiver, int argPlacehol nullCheckIfRequired(receiver); initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - directCall_V(receiver, argPlaceholder); + directCall_V(receiver, argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { ComputedCalls.dispatchDirect_V(compiledEntryPoint(vmSlot), receiver, argPlaceholder); } else { - ComputedCalls.dispatchJ9Method_V(vmSlot, receiver, argPlaceholder); + ComputedCalls.dispatchJ9Method_V(vmSlot, receiver, argPlaceholder); } } @@ -183,11 +183,11 @@ private final void invokeExact_thunkArchetype_V(Object receiver, int argPlacehol private final int invokeExact_thunkArchetype_I(int argPlaceholder) { initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_I(argPlaceholder); + return directCall_I(argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_I(compiledEntryPoint(vmSlot), argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_I(vmSlot, argPlaceholder); + return ComputedCalls.dispatchJ9Method_I(vmSlot, argPlaceholder); } } @@ -196,11 +196,11 @@ private final int invokeExact_thunkArchetype_I(Object receiver, int argPlacehold nullCheckIfRequired(receiver); initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_I(receiver, argPlaceholder); + return directCall_I(receiver, argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_I(compiledEntryPoint(vmSlot), receiver, argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_I(vmSlot, receiver, argPlaceholder); + return ComputedCalls.dispatchJ9Method_I(vmSlot, receiver, argPlaceholder); } } @@ -208,11 +208,11 @@ private final int invokeExact_thunkArchetype_I(Object receiver, int argPlacehold private final long invokeExact_thunkArchetype_J(int argPlaceholder) { initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_J(argPlaceholder); + return directCall_J(argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_J(compiledEntryPoint(vmSlot), argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_J(vmSlot, argPlaceholder); + return ComputedCalls.dispatchJ9Method_J(vmSlot, argPlaceholder); } } @@ -221,11 +221,11 @@ private final long invokeExact_thunkArchetype_J(Object receiver, int argPlacehol nullCheckIfRequired(receiver); initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_J(receiver, argPlaceholder); + return directCall_J(receiver, argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_J(compiledEntryPoint(vmSlot), receiver, argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_J(vmSlot, receiver, argPlaceholder); + return ComputedCalls.dispatchJ9Method_J(vmSlot, receiver, argPlaceholder); } } @@ -233,11 +233,11 @@ private final long invokeExact_thunkArchetype_J(Object receiver, int argPlacehol private final float invokeExact_thunkArchetype_F(int argPlaceholder) { initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_F(argPlaceholder); + return directCall_F(argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_F(compiledEntryPoint(vmSlot), argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_F(vmSlot, argPlaceholder); + return ComputedCalls.dispatchJ9Method_F(vmSlot, argPlaceholder); } } @@ -246,11 +246,11 @@ private final float invokeExact_thunkArchetype_F(Object receiver, int argPlaceho nullCheckIfRequired(receiver); initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_F(receiver, argPlaceholder); + return directCall_F(receiver, argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_F(compiledEntryPoint(vmSlot), receiver, argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_F(vmSlot, receiver, argPlaceholder); + return ComputedCalls.dispatchJ9Method_F(vmSlot, receiver, argPlaceholder); } } @@ -258,11 +258,11 @@ private final float invokeExact_thunkArchetype_F(Object receiver, int argPlaceho private final double invokeExact_thunkArchetype_D(int argPlaceholder) { initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_D(argPlaceholder); + return directCall_D(argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_D(compiledEntryPoint(vmSlot), argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_D(vmSlot, argPlaceholder); + return ComputedCalls.dispatchJ9Method_D(vmSlot, argPlaceholder); } } @@ -271,11 +271,11 @@ private final double invokeExact_thunkArchetype_D(Object receiver, int argPlaceh nullCheckIfRequired(receiver); initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_D(receiver, argPlaceholder); + return directCall_D(receiver, argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_D(compiledEntryPoint(vmSlot), receiver, argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_D(vmSlot, receiver, argPlaceholder); + return ComputedCalls.dispatchJ9Method_D(vmSlot, receiver, argPlaceholder); } } @@ -283,11 +283,11 @@ private final double invokeExact_thunkArchetype_D(Object receiver, int argPlaceh private final Object invokeExact_thunkArchetype_L(int argPlaceholder) { initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_L(argPlaceholder); + return directCall_L(argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_L(compiledEntryPoint(vmSlot), argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_L(vmSlot, argPlaceholder); + return ComputedCalls.dispatchJ9Method_L(vmSlot, argPlaceholder); } } @@ -296,11 +296,11 @@ private final Object invokeExact_thunkArchetype_L(Object receiver, int argPlaceh nullCheckIfRequired(receiver); initializeClassIfRequired(); if (ILGenMacros.isCustomThunk()) { - return directCall_L(receiver, argPlaceholder); + return directCall_L(receiver, argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) { return ComputedCalls.dispatchDirect_L(compiledEntryPoint(vmSlot), receiver, argPlaceholder); } else { - return ComputedCalls.dispatchJ9Method_L(vmSlot, receiver, argPlaceholder); + return ComputedCalls.dispatchJ9Method_L(vmSlot, receiver, argPlaceholder); } } @@ -323,9 +323,8 @@ void compareWith(MethodHandle right, Comparator c) { void compareWithDirect(DirectHandle left, Comparator c) { c.compareStructuralParameter(left.vmSlot, this.vmSlot); } - + //Used by ConstructorHandle //Making sure the DirectHandle class is loaded before ConstructorHandle is loaded. Therefore, to secure a correct thunk. public static void load() {} } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/DynamicInvokerHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/DynamicInvokerHandle.java index 2dc43f2c666..df309d5caeb 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/DynamicInvokerHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/DynamicInvokerHandle.java @@ -30,7 +30,7 @@ class DynamicInvokerHandle extends MethodHandle { @VMCONSTANTPOOL_FIELD final CallSite site; - + DynamicInvokerHandle(CallSite site) { super(site.type(), MethodHandle.KIND_DYNAMICINVOKER, null); //$NON-NLS-1$ this.site = site; diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/ExplicitCastHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/ExplicitCastHandle.java index 4a723359dcf..32c04f9d820 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/ExplicitCastHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/ExplicitCastHandle.java @@ -26,7 +26,7 @@ /* ExplicitCastHandle is a MethodHandle subclass used to implement * MethodHandles.explicitCastArgument() - * + * */ final class ExplicitCastHandle extends ArgumentConversionHandle { @@ -71,4 +71,3 @@ final void compareWithExplicitCast(ExplicitCastHandle left, Comparator c) { compareWithConvert(left, c); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/FieldGetterHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/FieldGetterHandle.java index 6551c232023..22b25b72a2e 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/FieldGetterHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/FieldGetterHandle.java @@ -32,14 +32,14 @@ * an instance field. *

    * vmSlot will hold the field offset in the instance. - * + * */ final class FieldGetterHandle extends FieldHandle { - + FieldGetterHandle(Class referenceClass, String fieldName, Class fieldClass, Class accessClass) throws IllegalAccessException, NoSuchFieldException { super(fieldMethodType(fieldClass, referenceClass), referenceClass, fieldName, fieldClass, KIND_GETFIELD, accessClass); } - + FieldGetterHandle(Field field) throws IllegalAccessException { super(fieldMethodType(field.getType(), field.getDeclaringClass()), field, KIND_GETFIELD, false); } @@ -120,4 +120,3 @@ final void compareWithFieldGetter(FieldGetterHandle left, Comparator c) { compareWithField(left, c); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/FieldHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/FieldHandle.java index eb97785dae5..28152d66629 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/FieldHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/FieldHandle.java @@ -34,8 +34,8 @@ abstract class FieldHandle extends PrimitiveHandle { final Class fieldClass; final boolean isVolatile; - - FieldHandle(MethodType type, Class referenceClass, String fieldName, Class fieldClass, byte kind, Class accessClass) throws IllegalAccessException, NoSuchFieldException { + + FieldHandle(MethodType type, Class referenceClass, String fieldName, Class fieldClass, byte kind, Class accessClass) throws IllegalAccessException, NoSuchFieldException { super(type, referenceClass, fieldName, kind, null); this.fieldClass = fieldClass; /* modifiers is set inside the native */ @@ -43,12 +43,12 @@ abstract class FieldHandle extends PrimitiveHandle { isVolatile = Modifier.isVolatile(rawModifiers); assert(isVMSlotCorrectlyTagged()); } - + FieldHandle(MethodType type, Field field, byte kind, boolean isStatic) throws IllegalAccessException { super(type, field.getDeclaringClass(), field.getName(), kind, field.getModifiers(), null); this.fieldClass = field.getType(); assert(isStatic == Modifier.isStatic(field.getModifiers())); - + boolean succeed = setVMSlotAndRawModifiersFromField(this, field); if (!succeed) { throw new IllegalAccessException(); @@ -56,7 +56,7 @@ abstract class FieldHandle extends PrimitiveHandle { isVolatile = Modifier.isVolatile(rawModifiers); assert(isVMSlotCorrectlyTagged()); } - + FieldHandle(FieldHandle originalHandle, MethodType newType) { super(originalHandle, newType); this.fieldClass = originalHandle.fieldClass; @@ -67,13 +67,13 @@ abstract class FieldHandle extends PrimitiveHandle { final Class finishFieldInitialization(Class accessClass) throws IllegalAccessException, NoSuchFieldException { String signature = MethodTypeHelper.getBytecodeStringName(fieldClass); try { - boolean isStaticLookup = ((KIND_GETSTATICFIELD == this.kind) || (KIND_PUTSTATICFIELD == this.kind)); + boolean isStaticLookup = ((KIND_GETSTATICFIELD == this.kind) || (KIND_PUTSTATICFIELD == this.kind)); return lookupField(referenceClass, name, signature, isStaticLookup, accessClass); } catch (NoSuchFieldError e) { throw new NoSuchFieldException(e.getMessage()); } catch (LinkageError e) { throw (IllegalAccessException) new IllegalAccessException(e.getMessage()).initCause(e); - } + } } /* Ensure the vmSlot is low tagged if static */ @@ -81,14 +81,14 @@ boolean isVMSlotCorrectlyTagged() { if ((KIND_PUTSTATICFIELD == this.kind) || (KIND_GETSTATICFIELD == this.kind)) { return (vmSlot & 1) == 1; } - return (vmSlot & 1) == 0; + return (vmSlot & 1) == 0; } - + @Override boolean canRevealDirect() { return true; } - + final void compareWithField(FieldHandle left, Comparator c) { c.compareStructuralParameter(left.referenceClass, this.referenceClass); c.compareStructuralParameter(left.vmSlot, this.vmSlot); diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/FieldSetterHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/FieldSetterHandle.java index 7d88db77131..93399d4dd33 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/FieldSetterHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/FieldSetterHandle.java @@ -32,25 +32,25 @@ * an instance field. *

    * vmSlot will hold the field offset in the instance. - * + * */ final class FieldSetterHandle extends FieldHandle { - + FieldSetterHandle(Class referenceClass, String fieldName, Class fieldClass, Class accessClass) throws IllegalAccessException, NoSuchFieldException { super(fieldMethodType(referenceClass, fieldClass), referenceClass, fieldName, fieldClass, KIND_PUTFIELD, accessClass); } - + FieldSetterHandle(Field field) throws IllegalAccessException { super(fieldMethodType(field.getDeclaringClass(), field.getType()), field, KIND_PUTFIELD, false); } - + FieldSetterHandle(FieldSetterHandle originalHandle, MethodType newType) { super(originalHandle, newType); } /* * Create the MethodType to be passed to the constructor - * MethodType of a field setter is (instanceType, fieldType)V. + * MethodType of a field setter is (instanceType, fieldType)V. */ private final static MethodType fieldMethodType(Class referenceClass, Class fieldClass) { return MethodType.methodType(void.class, referenceClass, fieldClass); @@ -65,7 +65,7 @@ private final void invokeExact_thunkArchetype_V(Object receiver, int newValue UNSAFE.putInt(receiver, vmSlot + HEADER_SIZE, newValue); } } - + @FrameIteratorSkip private final void invokeExact_thunkArchetype_V(Object receiver, long newValue, int argPlaceholder) { if (isVolatile) { @@ -123,4 +123,3 @@ final void compareWithFieldSetter(FieldSetterHandle left, Comparator c) { compareWithField(left, c); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/FilterReturnHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/FilterReturnHandle.java index e280a1f1569..20d24a686aa 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/FilterReturnHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/FilterReturnHandle.java @@ -31,7 +31,7 @@ final class FilterReturnHandle extends ConvertHandle { @VMCONSTANTPOOL_FIELD final MethodHandle filter; - + FilterReturnHandle(MethodHandle next, MethodHandle filter) { super(next, next.type.changeReturnType(filter.type.returnType()), KIND_FILTERRETURN, filter.type()); //$NON-NLS-1$ this.filter = filter; diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/FoldHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/FoldHandle.java index 33c58a11a23..2a1eda57beb 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/FoldHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/FoldHandle.java @@ -33,7 +33,7 @@ abstract class FoldHandle extends MethodHandle { private final int foldPosition; /* The starting position of fold arguments */ @VMCONSTANTPOOL_FIELD private final int[] argumentIndices; /* An array of argument indexes of fold handle */ - + protected FoldHandle(MethodHandle next, MethodHandle combiner, MethodType type, int foldPosition, int... argumentIndices) { super(type, KIND_FOLDHANDLE, infoAffectingThunks(combiner.type(), foldPosition, argumentIndices)); this.next = next; @@ -60,7 +60,7 @@ public static FoldHandle get(MethodHandle next, MethodHandle combiner, MethodTyp return new FoldNonvoidHandle(next, combiner, type, foldPosition, argumentIndices); } } - + private static Object[] infoAffectingThunks(MethodType combinerType, int foldPosition, int... argumentIndices) { // The number and types of values to fold affect jitted thunks Object[] result = { combinerType, foldPosition, argumentIndices}; @@ -70,10 +70,9 @@ private static Object[] infoAffectingThunks(MethodType combinerType, int foldPos private static final ThunkTable _thunkTable = new ThunkTable(); protected ThunkTable thunkTable(){ return _thunkTable; } - protected final ThunkTuple computeThunks(Object info) { return thunkTable().get(new ThunkKeyWithObjectArray(ThunkKey.computeThunkableType(type()), (Object[])info)); - } + } final void compareWith(MethodHandle right, Comparator c) { if (right instanceof FoldHandle) { @@ -87,11 +86,11 @@ final void compareWithFold(FoldHandle left, Comparator c) { c.compareChildHandle(left.next, this.next); c.compareChildHandle(left.combiner, this.combiner); c.compareStructuralParameter(left.foldPosition, this.foldPosition); - /* The comparator does not address the case where two FoldHandles, + /* The comparator does not address the case where two FoldHandles, * one with empty indices array and the other with non-empty indices array * but the argument indices for them are the same, should share the same thunkArchetype. - * This is because that case will not happen due to the way we create the FoldHandle: - * if the argument indices in the array are exactly the same to the argument indices + * This is because that case will not happen due to the way we create the FoldHandle: + * if the argument indices in the array are exactly the same to the argument indices * starting from the fold position, the FoldHandle will be created as if no array is passed in. */ c.compareStructuralParameter(left.argumentIndices, this.argumentIndices); @@ -159,7 +158,6 @@ final class FoldVoidHandle extends FoldHandle { // {{{ JIT support - @FrameIteratorSkip private final int invokeExact_thunkArchetype_X(int argPlaceholder) { if (ILGenMacros.isShareableThunk()) { diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/GuardWithTestHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/GuardWithTestHandle.java index f707a4f40cd..08cc19d62b2 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/GuardWithTestHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/GuardWithTestHandle.java @@ -66,13 +66,13 @@ public static MethodHandle get(MethodHandle guard, MethodHandle trueTarget, Meth private static final ThunkTable _thunkTable = new ThunkTable(); protected final ThunkTable thunkTable(){ return _thunkTable; } - protected final ThunkTuple computeThunks(Object guardType) { - // Different thunks accommodate guards with different numbers of parameters - return thunkTable().get(new ThunkKeyWithObject(ThunkKey.computeThunkableType(type()), ThunkKey.computeThunkableType((MethodType)guardType))); - } - - private static native int numGuardArgs(); - + protected final ThunkTuple computeThunks(Object guardType) { + // Different thunks accommodate guards with different numbers of parameters + return thunkTable().get(new ThunkKeyWithObject(ThunkKey.computeThunkableType(type()), ThunkKey.computeThunkableType((MethodType)guardType))); + } + + private static native int numGuardArgs(); + @FrameIteratorSkip private final int invokeExact_thunkArchetype_X(int argPlaceholder) { if (ILGenMacros.isShareableThunk()) { diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/HandleCache.java b/jcl/src/java.base/share/classes/java/lang/invoke/HandleCache.java index cdfa72f7e78..0d21dc18c66 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/HandleCache.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/HandleCache.java @@ -34,26 +34,26 @@ final class Cache extends ClassValue>> @Override protected Map> computeValue(Class arg0) { return Collections.synchronizedMap(new WeakHashMap>()); - } + } } /* Cache key for mapping the methodName and MethodType to the actual MethodHandle */ final class MethodCacheKey extends CacheKey { private final MethodType type; private final Class specialCaller; - + public MethodCacheKey(String name, MethodType mt, Class specialCaller) { super(name, calculateHashcode(name, mt, specialCaller)); - + this.type = mt; - this.specialCaller = specialCaller; + this.specialCaller = specialCaller; } - + private static int calculateHashcode(String name, MethodType mt, Class specialCaller) { /* Hash code based off MethodType.hashCode() */ int hash = 31 + mt.hashCode(); hash = 31 * hash + name.hashCode(); - + if (specialCaller != null) { hash = 31 * hash + specialCaller.hashCode(); } @@ -75,20 +75,19 @@ public boolean equals(Object o) { final class FieldCacheKey extends CacheKey { private final Class fieldType; - + public FieldCacheKey(String fieldName, Class fieldType) { super(fieldName, calculateHashcode(fieldName, fieldType)); this.fieldType = fieldType; } - + private static int calculateHashcode(String fieldName, Class fieldType) { /* Hash code based off MethodType.hashCode() */ int hash = 31 + fieldType.hashCode(); hash = 31 * hash + fieldName.hashCode(); return hash; } - - + @Override public boolean equals(Object o){ if ((o == null) || !(o instanceof FieldCacheKey)) { @@ -149,7 +148,7 @@ static Map> getStaticFieldGetterCache(Clas public static MethodHandle getMethodFromPerClassCache(Map> perClassCache, String name, MethodType type) { return getMethodWithSpecialCallerFromPerClassCache(perClassCache, name, type, null); } - + public static MethodHandle getMethodWithSpecialCallerFromPerClassCache(Map> perClassCache, String name, MethodType type, Class specialCaller) { WeakReference handleRef = perClassCache.get(new MethodCacheKey(name, type, specialCaller)); if (handleRef != null) { @@ -157,7 +156,7 @@ public static MethodHandle getMethodWithSpecialCallerFromPerClassCache(Map> perClassCache, String name, Class fieldType) { WeakReference handleRef = perClassCache.get(new FieldCacheKey(name, fieldType)); if (handleRef != null) { @@ -170,17 +169,17 @@ public static MethodHandle getFieldFromPerClassCache(Map> perClassCache, String name, MethodType type, MethodHandle handle) { return putMethodWithSpecialCallerInPerClassCache(perClassCache, name, type, handle, null); } - + /* Update the cache to hold the -> MethodHandle mapping */ public static MethodHandle putMethodWithSpecialCallerInPerClassCache(Map> perClassCache, String name, MethodType type, MethodHandle handle, Class specialCaller) { return cacheHandle(perClassCache, new MethodCacheKey(name, type, specialCaller), handle); } - + /* Update the cache to hold the -> MethodHandle mapping */ public static MethodHandle putFieldInPerClassCache(Map> perClassCache, String fieldName, Class fieldType, MethodHandle handle) { return cacheHandle(perClassCache, new FieldCacheKey(fieldName, fieldType), handle); } - + private static MethodHandle cacheHandle(Map> perClassCache, CacheKey cacheKey, MethodHandle handle){ /* Keep a strong reference to the FieldCacheKey in the MH being cached so that it won't * be immediately collected. Uses a WeakHashMap> to cache. @@ -193,4 +192,3 @@ private static MethodHandle cacheHandle(Map referenceClass, String name, byte kind, int modifiers) { super(type, referenceClass, name, kind, modifiers, null); } - + IndirectHandle(MethodType type, Class referenceClass, String name, byte kind) { super(type, referenceClass, name, kind, null); } @@ -48,10 +48,10 @@ abstract class IndirectHandle extends PrimitiveHandle { protected final long jittedMethodAddress(Object receiver) { long receiverClass = getJ9ClassFromClass(receiver.getClass()); - long result; + long result; if (VTABLE_ENTRY_SIZE == 4) { result = UNSAFE.getInt(receiverClass - vtableOffset(receiver)); - } else { + } else { result = UNSAFE.getLong(receiverClass - vtableOffset(receiver)); } return result; @@ -68,20 +68,20 @@ protected static final MethodType indirectMethodType(Method method) { MethodType originalType = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); return indirectMethodType(originalType, method.getDeclaringClass()); } - - /* Indirect MethodHandles have the receiver type inserted as + + /* Indirect MethodHandles have the receiver type inserted as * first argument of the MH's type. */ protected static final MethodType indirectMethodType(MethodType type, Class referenceClazz) { return type.insertParameterTypes(0, referenceClazz); } - + @Override public MethodHandle bindTo(Object value) throws IllegalArgumentException, ClassCastException { if (null == value) { return super.bindTo(value); } - + /* * Check whether the first parameter has a reference type assignable from value. Note that MethodType.parameterType(0) will * throw an IllegalArgumentException if type has no parameters. @@ -105,18 +105,18 @@ public MethodHandle bindTo(Object value) throws IllegalArgumentException, ClassC /* * An interface method must devirtualize to a public method. If the devirtualized method is not public, * an IllegalAccessError will be thrown when the MethodHandle is invoked. In order to enforce this behaviour, - * we must preserve the original MethodHandle, i.e. not optimize to a ReceiverBoundHandle. + * we must preserve the original MethodHandle, i.e. not optimize to a ReceiverBoundHandle. */ - if (this instanceof InterfaceHandle) { + if (this instanceof InterfaceHandle) { if ((result.getModifiers() & Modifier.PUBLIC) == 0) { throw new IllegalAccessException(); } } - + return result; } catch (IllegalAccessException e) { /* - * Create a receiver bound MethodHandle by inserting the receiver object as an argument. This is done to + * Create a receiver bound MethodHandle by inserting the receiver object as an argument. This is done to * ensure that invocation is done using the original MethodHandle, which will result in an IllegalAccessError. */ return MethodHandles.insertArguments(this, 0, value); @@ -124,10 +124,9 @@ public MethodHandle bindTo(Object value) throws IllegalArgumentException, ClassC throw new Error(e); } } - + final void compareWithIndirect(IndirectHandle left, Comparator c) { c.compareStructuralParameter(left.referenceClass, this.referenceClass); c.compareStructuralParameter(left.vmSlot, this.vmSlot); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/Insert1Handle.java b/jcl/src/java.base/share/classes/java/lang/invoke/Insert1Handle.java index fed746e9f7b..ce4836c9d46 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/Insert1Handle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/Insert1Handle.java @@ -24,12 +24,12 @@ final class Insert1Handle extends InsertHandle { final Object value; - + Insert1Handle(MethodType type, MethodHandle next, int insertionIndex, Object values[]) { super(type, next, insertionIndex, values); this.value = values[0]; } - + Insert1Handle(Insert1Handle originalHandle, MethodType nextType) { super(originalHandle, nextType); this.value = originalHandle.value; @@ -54,15 +54,14 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) { } return ILGenMacros.invokeExact_X(next, ILGenMacros.placeholder( ILGenMacros.firstN(numPrefixArgs(), argPlaceholder), - value, + value, ILGenMacros.lastN(numSuffixArgs(), argPlaceholder))); } // }}} JIT support - + @Override MethodHandle cloneWithNewType(MethodType newType) { return new Insert1Handle(this, newType); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/Insert1IntHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/Insert1IntHandle.java index 1e46320b1ea..8c5b70a9f69 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/Insert1IntHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/Insert1IntHandle.java @@ -32,7 +32,7 @@ final class Insert1IntHandle extends InsertHandle { if (values[0] instanceof Character) { this.value = ((Character)values[0]).charValue(); } else { - this.value = ((Number)values[0]).intValue(); + this.value = ((Number)values[0]).intValue(); } this.nextNoUnbox = nextNoUnbox; } @@ -43,12 +43,11 @@ final class Insert1IntHandle extends InsertHandle { this.nextNoUnbox = originalHandle.nextNoUnbox; } - @Override MethodHandle cloneWithNewType(MethodType newType) { return new Insert1IntHandle(this, newType); } - + // {{{ JIT support private static final ThunkTable _thunkTable = new ThunkTable(); @@ -67,7 +66,6 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) { value, ILGenMacros.lastN(numSuffixArgs(), argPlaceholder))); } - + // }}} JIT support } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/Insert2Handle.java b/jcl/src/java.base/share/classes/java/lang/invoke/Insert2Handle.java index 955eca59b3a..58fc92bfa1f 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/Insert2Handle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/Insert2Handle.java @@ -25,19 +25,19 @@ final class Insert2Handle extends InsertHandle { final Object value_1; final Object value_2; - + Insert2Handle(MethodType type, MethodHandle next, int insertionIndex, Object values[]) { super(type, next, insertionIndex, values); this.value_1 = values[0]; this.value_2 = values[1]; } - + Insert2Handle(Insert2Handle originalHandle, MethodType nextType) { super(originalHandle, nextType); this.value_1 = originalHandle.value_1; this.value_2 = originalHandle.value_2; } - + @Override MethodHandle cloneWithNewType(MethodType newType) { return new Insert2Handle(this, newType); @@ -62,11 +62,10 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) { } return ILGenMacros.invokeExact_X(next, ILGenMacros.placeholder( ILGenMacros.firstN(numPrefixArgs(), argPlaceholder), - value_1, + value_1, value_2, ILGenMacros.lastN(numSuffixArgs(), argPlaceholder))); } // }}} JIT support } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/Insert3Handle.java b/jcl/src/java.base/share/classes/java/lang/invoke/Insert3Handle.java index 871942f2720..aba8449fe28 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/Insert3Handle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/Insert3Handle.java @@ -26,21 +26,21 @@ final class Insert3Handle extends InsertHandle { final Object value_1; final Object value_2; final Object value_3; - + Insert3Handle(MethodType type, MethodHandle next, int insertionIndex, Object values[]) { super(type, next, insertionIndex, values); this.value_1 = values[0]; this.value_2 = values[1]; this.value_3 = values[2]; } - + Insert3Handle(Insert3Handle originalHandle, MethodType nextType) { super(originalHandle, nextType); this.value_1 = originalHandle.value_1; this.value_2 = originalHandle.value_2; this.value_3 = originalHandle.value_3; } - + @Override MethodHandle cloneWithNewType(MethodType newType) { return new Insert3Handle(this, newType); @@ -65,7 +65,7 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) { } return ILGenMacros.invokeExact_X(next, ILGenMacros.placeholder( ILGenMacros.firstN(numPrefixArgs(), argPlaceholder), - value_1, + value_1, value_2, value_3, ILGenMacros.lastN(numSuffixArgs(), argPlaceholder))); @@ -73,4 +73,3 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) { // }}} JIT support } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/InsertHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/InsertHandle.java index 9586dff19c2..fd6d0519f43 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/InsertHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/InsertHandle.java @@ -31,7 +31,7 @@ class InsertHandle extends MethodHandle { final int insertionIndex; private final Object[] values; - /* + /* * next must be an appropriately typed handle to ensure that the bound parameters are typechecked * correctly. */ diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/InterfaceHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/InterfaceHandle.java index 23ea5455bf4..975483bf17e 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/InterfaceHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/InterfaceHandle.java @@ -27,8 +27,8 @@ import static java.lang.invoke.MethodHandleResolver.getJ9ClassFromClass; /* - * InterfaceHandle is a MethodHandle that does interface dispatch - * on the receiver. + * InterfaceHandle is a MethodHandle that does interface dispatch + * on the receiver. *

    * The vmSlot holds the itable index for the correct method. * The type is the same as the method's except with the interface class prepended @@ -48,21 +48,20 @@ final class InterfaceHandle extends IndirectHandle { assert referenceClass.isInterface(); this.defc = finishMethodInitialization(null, type); } - - + InterfaceHandle(Method method) throws IllegalAccessException { super(indirectMethodType(method), method.getDeclaringClass(), method.getName(), KIND_INTERFACE, method.getModifiers()); - + if (!referenceClass.isInterface()) { throw new IllegalArgumentException(); } - + boolean succeed = setVMSlotAndRawModifiersFromMethod(this, referenceClass, method, this.kind, specialCaller); if (!succeed) { throw new IllegalAccessException(); } } - + public InterfaceHandle(InterfaceHandle originalHandle, MethodType newType) { super(originalHandle, newType); } @@ -146,4 +145,3 @@ final void compareWithInterface(InterfaceHandle left, Comparator c) { super.compareWithIndirect(left, c); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/InvokeExactHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/InvokeExactHandle.java index db30e40b0b4..57702c9fb70 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/InvokeExactHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/InvokeExactHandle.java @@ -34,7 +34,7 @@ final class InvokeExactHandle extends PrimitiveHandle { /* MethodType that the first argument MethodHandle must match */ final MethodType nextType; - + InvokeExactHandle(MethodType type) { super(invokeExactMethodType(type), MethodHandle.class, "invokeExact", KIND_INVOKEEXACT, PUBLIC_FINAL_NATIVE, null); //$NON-NLS-1$ nextType = type; @@ -63,7 +63,7 @@ boolean canRevealDirect() { /* This is invokevirtual of MethodHandle.invokeExact() */ return true; } - + // {{{ JIT support private static final ThunkTable _thunkTable = new ThunkTable(); @@ -107,4 +107,3 @@ final void compareWithInvokeExact(InvokeExactHandle left, Comparator c) { // Nothing distinguishes InvokeExactHandles except their type, which Comparator already deals with } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/InvokeGenericHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/InvokeGenericHandle.java index a97f61a8c16..fed49d9e47e 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/InvokeGenericHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/InvokeGenericHandle.java @@ -32,11 +32,10 @@ * Can be thought of as a special case of VirtualHandle. */ final class InvokeGenericHandle extends PrimitiveHandle { - /* MethodType that the first argument MethodHandle will be cast to using asType */ + /* MethodType that the first argument MethodHandle will be cast to using asType */ @VMCONSTANTPOOL_FIELD - final MethodType castType; - - + final MethodType castType; + InvokeGenericHandle(MethodType type) { super(invokeGenericMethodType(type), MethodHandle.class, "invoke", KIND_INVOKEGENERIC, PUBLIC_FINAL_NATIVE, null); //$NON-NLS-1$ if (type == null) { @@ -65,7 +64,7 @@ boolean canRevealDirect() { /* This is invokevirtual of MethodHandle.invoke() */ return true; } - + // {{{ JIT support private static final ThunkTable _thunkTable = new ThunkTable(); @@ -79,7 +78,7 @@ protected ThunkTuple computeThunks(Object arg) { } @FrameIteratorSkip - private final int invokeExact_thunkArchetype_X(MethodHandle next, int argPlaceholder) throws Throwable { + private final int invokeExact_thunkArchetype_X(MethodHandle next, int argPlaceholder) throws Throwable { if (ILGenMacros.isShareableThunk()) { undoCustomizationLogic(next); } @@ -108,4 +107,3 @@ final void compareWithInvokeGeneric(InvokeGenericHandle left, Comparator c) { // Nothing distinguishes InvokeGenericHandles except their type, which Comparator already deals with } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java b/jcl/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java index 9ac9438a59b..78d49dfd3cb 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java @@ -36,11 +36,11 @@ LambdaForm filterRepeatedArgumentForm(LambdaForm.BasicType bt, int[] args) { LambdaForm filterArgumentForm(int num, LambdaForm.BasicType by) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + LambdaForm filterReturnForm(LambdaForm.BasicType bt, boolean flag) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + LambdaForm noteLoopLocalTypesForm(int num, LambdaForm.BasicType[] bts) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/LoopHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/LoopHandle.java index 266498dab9c..056c20d28d3 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/LoopHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/LoopHandle.java @@ -49,7 +49,6 @@ public static LoopHandle get(MethodHandle equivalent, MethodHandle[][] handleCla @Override protected final ThunkTable thunkTable(){ return _thunkTable; } - @SuppressWarnings("boxing") private static Object infoAffectingThunks(int numLoopTargetArgs) { // The number of arguments passed to the loop target affects the code generated in the thunks diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandle.java index c858a1ca4ef..547c8945a77 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -214,7 +214,7 @@ ThunkTuple computeThunks(Object arg) { final static int VTABLE_ENTRY_SIZE = VM.ADDRESS_SIZE; final static int VTABLE_ENTRY_SHIFT = 31 - Integer.numberOfLeadingZeros(VTABLE_ENTRY_SIZE); final static int J9CLASS_OFFSET = vmRefFieldOffset(Class.class); - final static long INTRP_VTABLE_OFFSET = VM.J9CLASS_SIZE; + final static long INTRP_VTABLE_OFFSET = VM.J9CLASS_SIZE; final static int HEADER_SIZE = VM.OBJECT_HEADER_SIZE; static { @@ -419,7 +419,6 @@ private final MethodHandle asSpreaderCommon(int spreadPosition, Class arrayCl return new SpreadHandle(adapted, collectType, arrayClass, spreadCount, spreadPosition); } - /** * Returns a MethodHandle that collects the requested incoming arguments, which must match the * types in MethodType incomingArgs, into an array of arrayClass, called T. @@ -528,7 +527,6 @@ public MethodHandle asType(MethodType newType) throws ClassCastException { /* Unused class parameter is necessary to work around a javac bug */ private static final native int vmRefFieldOffset(Class unused); - /** * Invoke the MethodHandle using an Object[] of arguments. The array must contain at exactly type().parameterCount() arguments. * @@ -853,7 +851,6 @@ public MethodHandle bindTo(Object value) throws IllegalArgumentException, ClassC return MethodHandles.insertArguments(this, 0, value); } - /** * Check if a permutation is unnecessary *

    @@ -1238,7 +1235,6 @@ final class ComputedCalls { public static native double dispatchJ9Method_D(long j9method, Object objectArg, int argPlaceholder); public static native Object dispatchJ9Method_L(long j9method, Object objectArg, int argPlaceholder); - public static void load(){} } @@ -1474,10 +1470,10 @@ static ThunkTuple newCustom(MethodType thunkableType, long invokeExactThunk) { return new ThunkTuple(thunkableType.toMethodDescriptorString(), invokeExactThunk); } - static ThunkTuple copyOf(ThunkTuple tt){ - ThunkTuple t = new ThunkTuple(tt.thunkableSignature, tt.invokeExactThunk); - t.i2jInvokeExactThunk = tt.i2jInvokeExactThunk; - return t; + static ThunkTuple copyOf(ThunkTuple tt){ + ThunkTuple t = new ThunkTuple(tt.thunkableSignature, tt.invokeExactThunk); + t.i2jInvokeExactThunk = tt.i2jInvokeExactThunk; + return t; } private ThunkTuple(String thunkableSignature, long invokeExactThunk){ @@ -1621,7 +1617,6 @@ public static void load(){} // }}} JIT support - // {{{ Comparator support /* diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleCache.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleCache.java index 4b4a0819dcc..ce96dbcd5c0 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleCache.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleCache.java @@ -52,7 +52,7 @@ private MethodHandleCache(Class clazz) { /** * Get the MethodHandle cache for a given class. * If one doesn't exist, it will be created. - * + * * @param clazz the Class that MHs are being cached on * @return the MethodHandleCache object for that class */ @@ -68,8 +68,8 @@ public static MethodHandleCache getCache(Class clazz) { /** * @return a BoundMethodHandle that calls {@link Class#cast(Object)} on the passed in class - * @throws NoSuchMethodException - * @throws IllegalAccessException + * @throws NoSuchMethodException + * @throws IllegalAccessException */ /*[PR JAZZ 58955] Prevent duplicate RBH's of the same class on Class.cast() */ public MethodHandle getClassCastHandle() throws IllegalAccessException, NoSuchMethodException { @@ -92,21 +92,21 @@ public MethodHandle getNullConstantObjectHandle() { } return nullConstantObjectHandle; } - + /** * Add a DirectHandle that needs to be updated upon redefinition of the Class that owns this cache. * The DirectHandle should reference a method in that Class. - * + * * @param handle A DirectHandle to track for class redefinition */ public void addDirectHandle(DirectHandle handle) { WeakReferenceNode ref = new WeakReferenceNode<>(handle, referenceQueue); - + synchronized (this) { ref.addBefore(directHandlesHead); directHandlesHead = ref; } - + processReferenceQueue(); } diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java index b277a3581d1..ab50e08644f 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java @@ -25,7 +25,7 @@ /** * A reference to a cracked MethodHandle, which allows access to its symbolic parts. * Call Lookup.revealDirect to crack a MethodHandle. - * + * * @since 1.8 */ public interface MethodHandleInfo { @@ -34,88 +34,88 @@ public interface MethodHandleInfo { * Getter MethodHandle for an instance field */ static final int REF_getField = 1; - + /** * Getter MethodHandle for an static field */ static final int REF_getStatic = 2; - + /** * Setter MethodHandle for an instance field */ static final int REF_putField = 3; - + /** * Setter MethodHandle for an static field */ static final int REF_putStatic = 4; - + /** * MethodHandle for an instance method */ static final int REF_invokeVirtual = 5; - + /** * MethodHandle for a static method */ static final int REF_invokeStatic = 6; - + /** * MethodHandle for an special method */ static final int REF_invokeSpecial = 7; - + /** * MethodHandle for a constructor */ static final int REF_newInvokeSpecial = 8; - + /** * MethodHandle for an interface method */ static final int REF_invokeInterface = 9; - - /** + + /** * Returns the Class where the cracked MethodHandle's underlying method, field or constructor is declared. - * + * * @return class that declares the underlying member */ Class getDeclaringClass(); - + /** * Returns the simple name of the MethodHandle's underlying member. - * - * @return A string representing the name of the method or field, or "<init>" for constructor. + * + * @return A string representing the name of the method or field, or "<init>" for constructor. */ String getName(); - + /** * Returns the type of the MethodHandle's underlying member as a MethodType. * If the underlying member is non-static, the receiver parameter will not be included. * If the underlying member is field getter, the MethodType will take no parameters, and the return type will be the field type. * If the underlying member is field setter, the MethodType will take one parameter of the field type, and the return type will be void. - * + * * @return A MethodType object representing the signature of the method or field */ MethodType getMethodType(); - + /** * Returns the modifiers of the MethodHandle's underlying member. - * + * * @return An int representing the member's modifiers, or -1 if the underlying member is not accessible. */ int getModifiers(); - + /** * Returns the reference kind of the MethodHandle. The possible reference kinds are the declared MethodHandleInfo.REF fields. - * + * * @return Returns one of the defined reference kinds which represent the MethodHandle kind. */ int getReferenceKind(); - + /** * Returns whether the MethodHandle's underlying method or constructor has variable argument arity. - * + * * @return whether the underlying method has variable arity */ default boolean isVarArgs() { @@ -125,28 +125,28 @@ default boolean isVarArgs() { } return false; } - + /** * Reflects the underlying member as a Method, Field or Constructor. The member must be accessible to the provided lookup object. - * Public members are reflected as if by getMethod, getField or getConstructor. + * Public members are reflected as if by getMethod, getField or getConstructor. * Non-public members are reflected as if by getDeclaredMethod, getDeclaredField or getDeclaredConstructor. - * + * * @param The expected type of the returned Member * @param expected The expected Class of the returned Member * @param lookup The lookup that was used to create the MethodHandle, or a lookup object with equivalent access * @return A Method, Field or Constructor representing the underlying member of the MethodHandle * @throws NullPointerException If either argument is null * @throws IllegalArgumentException If the underlying member is not accessible to the provided lookup object - * @throws ClassCastException If the underlying member is not of the expected type + * @throws ClassCastException If the underlying member is not of the expected type */ T reflectAs(Class expected, MethodHandles.Lookup lookup); - + /** * Returns a string representing the equivalent bytecode for the referenceKind. - * + * * @param referenceKind The referenceKind to lookup * @return a String representing the equivalent bytecode - * @throws IllegalArgumentException If the provided referenceKind is invalid + * @throws IllegalArgumentException If the provided referenceKind is invalid */ static String referenceKindToString(int referenceKind) throws IllegalArgumentException { switch(referenceKind) { @@ -163,10 +163,10 @@ static String referenceKindToString(int referenceKind) throws IllegalArgumentExc /*[MSG "K0582", "Reference kind \"{0\"} is invalid"]*/ throw new IllegalArgumentException(com.ibm.oti.util.Msg.getString("K0582", referenceKind)); //$NON-NLS-1$ } - + /** * Answers a string containing a concise, human-readable description of the receiver. - * + * * @param kind the reference kind, one of the declared MethodHandleInfo.REF fields. * @param defc the class where the member is declared * @param name the name of the member @@ -176,6 +176,5 @@ static String referenceKindToString(int referenceKind) throws IllegalArgumentExc static String toString(int kind, Class defc, String name, MethodType type) { return referenceKindToString(kind) + " " + defc.getName() + "." + name + ":" + type; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - -} +} diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java index fc10f14936c..4441e4707dd 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -64,22 +64,22 @@ static Object staticFieldBase(MemberName memberName) { static boolean refKindIsMethod(byte kind) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + static boolean refKindIsField(byte kind) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + static boolean refKindIsConstructor(byte kind) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); /** * Returns the classData stored in the class. - * + * * @param the class from where to retrieve the classData. - * + * * @return the classData (Object). */ static Object classData(Class c) { diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleResolver.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleResolver.java index e562d84b2eb..14d04ee5c4b 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleResolver.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleResolver.java @@ -88,7 +88,6 @@ final class MethodHandleResolver { */ private static final native MethodHandle getCPMethodHandleAt(Object internalConstantPool, int index); - /** * Get the class name from a constant pool class element, which is located * at the specified index in internalConstantPool. @@ -564,7 +563,6 @@ private static final Class resolveFieldHandleHelper(String typeDescriptor, Lo } /*[ENDIF] !OPENJDK_METHODHANDLES*/ - /** * Gets class object from RAM class address * @param j9class RAM class address diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index bb1ecb14449..6050a6cd845 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -1124,7 +1124,6 @@ MethodHandle handleForMHInvokeMethods(Class clazz, String methodName, MethodT return null; } - /** * Return a MethodHandle that provides read access to a field. * The MethodHandle will have a MethodType taking a single @@ -3175,7 +3174,6 @@ public static MethodHandle filterReturnValue(MethodHandle handle, MethodHandle f throw new IllegalArgumentException(); } - @SuppressWarnings("unused") private static void voidExceptionThrower(Throwable t) throws Throwable { throw t; @@ -3404,8 +3402,8 @@ public static MethodHandle filterArguments(MethodHandle handle, int startPositio * return original(a, e, c) * } * - * @param handle - the handle to call after preprocessing - * @param filterPosition - the starting position to filter arguments + * @param handle - the handle to call after preprocessing + * @param filterPosition - the starting position to filter arguments * @param preprocessor - a methodhandle that preprocesses some of the incoming arguments * @param argumentIndices - an array of indices mapping the handle's arguments to the preprocessors inputs * @return a MethodHandle that preprocesses some of the arguments to the handle @@ -3770,7 +3768,6 @@ private static boolean validatePermutationArray(MethodType permuteType, MethodTy return true; } - /* * Helper method to dropArguments(). This method must be called with cloned array Class... valueType. */ @@ -3782,7 +3779,6 @@ private static MethodHandle dropArgumentsUnsafe(MethodHandle originalHandle, int throw new IllegalArgumentException(com.ibm.oti.util.Msg.getString("K039c")); //$NON-NLS-1$ } - MethodType permuteType = originalType.insertParameterTypes(location, valueTypes); /* Build equivalent permute array */ int[] permute = new int[originalType.parameterCount()]; @@ -3797,7 +3793,6 @@ private static MethodHandle dropArgumentsUnsafe(MethodHandle originalHandle, int return originalHandle.permuteArguments(permuteType, permute); } - /** * This method returns a method handle that delegates to the original method handle, * ignoring a particular range of arguments (starting at a given location and @@ -3814,7 +3809,6 @@ public static MethodHandle dropArguments(MethodHandle originalHandle, int locati return dropArgumentsUnsafe(originalHandle, location, valueTypes); } - /** * This method returns a method handle that delegates to the original method handle, * ignoring a particular range of arguments (starting at a given location and diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodType.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodType.java index 13173184551..c99c743bb6e 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodType.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodType.java @@ -269,7 +269,6 @@ MethodType dropFirstParameterType() throws IndexOutOfBoundsException { return methodType(rtype, Arrays.copyOfRange(ptypes, 1, ptypes.length), false); } - /** * Compares the specified object with this type for equality. * That is, it returns true if and only if the specified object @@ -308,7 +307,6 @@ public MethodType erase() { return methodType(rtype.isPrimitive() ? rtype : Object.class, newParameters, false); } - /** * Convenience Method to create a MethodType from bytecode-level method descriptor. * (See JVM Spec 2nd Ed. section 4.4.3). @@ -385,7 +383,6 @@ public MethodType generic() { return genericMethodType(ptypes.length); } - /** * Returns the MethodType's hash code, which is defined to be * the same as the hash code of a List composed of the return type @@ -404,7 +401,6 @@ public int hashCode(){ return hashcode; } - /** * Helper method to determine if the return type or any of the parameter types * are primitives. @@ -794,7 +790,6 @@ private String createMethodDescriptorString(){ return sb.toString(); } - /** * Return a string representation of the MethodType in the form: '(A0,A2,A3...)R'. * The simple name of each class is used. @@ -835,7 +830,6 @@ public MethodType unwrap(){ return methodType(unwrappedReturnType, args, false); } - /** * Wrapper method on {@link #methodType(Class, Class[])}. Replaces all primitive types with * the appropriate wrapper types, including changing void to {@link java.lang.Void}. diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MutableCallSiteDynamicInvokerHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/MutableCallSiteDynamicInvokerHandle.java index 5d3a62cb36d..52fb419de1d 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MutableCallSiteDynamicInvokerHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MutableCallSiteDynamicInvokerHandle.java @@ -24,22 +24,22 @@ @VMCONSTANTPOOL_CLASS final class MutableCallSiteDynamicInvokerHandle extends DynamicInvokerHandle { - /* mutableSite and the parent's site fields will always be sync. This is + /* mutableSite and the parent's site fields will always be sync. This is * a redefinition as a MCS to enable the thunkArchetype to inline without * a guard */ final MutableCallSite mutableSite; - + MutableCallSiteDynamicInvokerHandle(MutableCallSite site) { super(site); this.mutableSite = site; } - + MutableCallSiteDynamicInvokerHandle(MutableCallSiteDynamicInvokerHandle originalHandle, MethodType newType) { super(originalHandle, newType); this.mutableSite = originalHandle.mutableSite; } - + @Override MethodHandle cloneWithNewType(MethodType newType) { return new MutableCallSiteDynamicInvokerHandle(this, newType); @@ -67,4 +67,3 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) throws Throwa // }}} JIT support } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/PassThroughHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/PassThroughHandle.java index 23c56924327..2e9e25868e7 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/PassThroughHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/PassThroughHandle.java @@ -37,16 +37,16 @@ abstract class PassThroughHandle extends MethodHandle { /** * Create a new PassThroughHandle that will call 'equivalent' MethodHandle * when invoked in the interpreter. - * + * * @param equivalent the equivalent methodhandle, usually using the collect-operate-spread pattern * @param name subclass name - * @param thunkArg extra thunkArg used in computeThunks. + * @param thunkArg extra thunkArg used in computeThunks. */ PassThroughHandle(MethodHandle equivalent, Object thunkArg) { super(equivalent.type, KIND_PASSTHROUGH, thunkArg); this.equivalent = equivalent; } - + /** * Helper constructor. Calls {@link #PassThroughHandle(MethodHandle, Object)} with null thunkArg */ @@ -61,7 +61,7 @@ abstract class PassThroughHandle extends MethodHandle { super(originalHandle, newType); this.equivalent = originalHandle.equivalent; } - + /*[IF JAVA_SPEC_VERSION >= 15]*/ @Override boolean addRelatedMHs(List relatedMHs) { diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/PermuteHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/PermuteHandle.java index 0bc2b9167b2..c203dc2ddbd 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/PermuteHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/PermuteHandle.java @@ -29,25 +29,25 @@ final class PermuteHandle extends MethodHandle { @VMCONSTANTPOOL_FIELD private final MethodHandle next; - + @VMCONSTANTPOOL_FIELD private final int[] permute; PermuteHandle(MethodType type, MethodHandle next, int[] permute) { super(type, KIND_PERMUTE, permute); //$NON-NLS-1$ - this.next = next; - this.permute = permute; + this.next = next; + this.permute = permute; } - + PermuteHandle(PermuteHandle originalHandle, MethodType newType) { super(originalHandle, newType); this.next = originalHandle.next; this.permute = originalHandle.permute; } - + /* * Create a combined permute. This removes a MH from the chain when - * we have a permute(permute(handle, ...) ...). + * we have a permute(permute(handle, ...) ...). */ @Override MethodHandle permuteArguments(MethodType permuteType, int... permute2) { @@ -105,20 +105,20 @@ private final int invokeExact_thunkArchetype_X(int argPlaceholder) { MethodHandle cloneWithNewType(MethodType newType) { return new PermuteHandle(this, newType); } - - final void compareWith(MethodHandle right, Comparator c) { - if (right instanceof PermuteHandle) { - ((PermuteHandle)right).compareWithPermute(this, c); - } else { - c.fail(); - } - } - - final void compareWithPermute(PermuteHandle left, Comparator c) { - c.compareStructuralParameter(left.permute.length, this.permute.length); - for (int i = 0; (i < left.permute.length) && (i < this.permute.length); i++) { - c.compareStructuralParameter(left.permute[i], this.permute[i]); - } - c.compareChildHandle(left.next, this.next); - } + + final void compareWith(MethodHandle right, Comparator c) { + if (right instanceof PermuteHandle) { + ((PermuteHandle)right).compareWithPermute(this, c); + } else { + c.fail(); + } + } + + final void compareWithPermute(PermuteHandle left, Comparator c) { + c.compareStructuralParameter(left.permute.length, this.permute.length); + for (int i = 0; (i < left.permute.length) && (i < this.permute.length); i++) { + c.compareStructuralParameter(left.permute[i], this.permute[i]); + } + c.compareChildHandle(left.next, this.next); + } } diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/PrimitiveHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/PrimitiveHandle.java index e2e7116a028..b5cbb6d64de 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/PrimitiveHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/PrimitiveHandle.java @@ -38,23 +38,23 @@ import static java.lang.invoke.MethodHandleResolver.JITHELPERS; /** - * PrimitiveHandle is a subclass of MethodHandle used for grouping MethodHandles that directly refer a Java-level method. - * + * PrimitiveHandle is a subclass of MethodHandle used for grouping MethodHandles that directly refer a Java-level method. + * */ @VMCONSTANTPOOL_CLASS abstract class PrimitiveHandle extends MethodHandle { - @VMCONSTANTPOOL_FIELD + @VMCONSTANTPOOL_FIELD long vmSlot; /* Either the address of the method to be invoked or the {i,v}table index */ - @VMCONSTANTPOOL_FIELD + @VMCONSTANTPOOL_FIELD int rawModifiers; /* Field/Method modifiers. Currently only used by fields to determine if volatile */ - @VMCONSTANTPOOL_FIELD + @VMCONSTANTPOOL_FIELD Class defc; /* Used by security check. Class containing the method implementation or field. */ /* Used by staticFieldGetterDispatchTargets as the class passed to the readStatic object access barrier. */ - @VMCONSTANTPOOL_FIELD + @VMCONSTANTPOOL_FIELD final Class referenceClass; /* Lookup class for the method or field. */ final String name; /* Name used to look up method */ @@ -87,35 +87,35 @@ abstract class PrimitiveHandle extends MethodHandle { Class getDefc() { return defc; } - + @Override Class getReferenceClass() { return referenceClass; } - + @Override Class getSpecialCaller() { return specialCaller; } - + @Override String getMethodName() { return name; } - + @Override int getModifiers() { return rawModifiers; } - + /* * Wrapper on VM method lookup logic. - * + * * referenceClazz - class that lookup is against * name - method name * signature - method signature * specialCaller - class that invokespecial is against or null - * + * * Sets the vmSlot to hold the correct value for the kind of PrimitiveHandle: * KIND_STATIC - J9Method address * KIND_SPECIAL - J9Method address @@ -127,12 +127,12 @@ int getModifiers() { /* * Wrapper on VM field lookup logic. - * + * * referenceClazz - class that lookup is against * name - field name * signature - field signature * accessClass is the MethodHandles.Lookup().lookupClass(). - * + * * Sets the vmSlot to hold the correct value for the kind of PrimitiveHandle: * KIND_GETFEILD - field offset * KIND_GETSTATICFIELD - field address @@ -140,30 +140,30 @@ int getModifiers() { * KIND_PUTSTATICFIELD - field address */ final native Class lookupField(Class referenceClazz, String name, String signature, boolean isStatic, Class accessClass); - + /* * Rip apart a Field object that points to a field and fill in the - * vmSlot of the PH. The vmSlot for an instance field is the - * J9JNIFieldID->offset. For a static field, its the + * vmSlot of the PH. The vmSlot for an instance field is the + * J9JNIFieldID->offset. For a static field, its the * J9JNIField->offset + declaring classes ramStatics start address. */ static native boolean setVMSlotAndRawModifiersFromField(PrimitiveHandle handle, Field field); - + /* - * Rip apart a Method object and fill in the vmSlot of the PH. + * Rip apart a Method object and fill in the vmSlot of the PH. * The vmSlot for a method depends on the kind of method: * - J9Method address for static and special * - vtable index for virtual * - itable index for interface. */ static native boolean setVMSlotAndRawModifiersFromMethod(PrimitiveHandle handle, Class declaringClass, Method method, byte kind, Class specialToken); - + /* - * Rip apart a Constructor object and fill in the vmSlot of the PH. + * Rip apart a Constructor object and fill in the vmSlot of the PH. * The vmSlot for an method is the address of the J9Method. */ static native boolean setVMSlotAndRawModifiersFromConstructor(PrimitiveHandle handle, Constructor ctor); - + /* * Set the VMSlot for the VirtualHandle from the DirectHandle. DirectHandle must be of KIND_SPECIAL. * Necessary to deal with MethodHandles#findVirtual() being allowed to look up private methods. @@ -179,7 +179,7 @@ final void initializeClassIfRequired() { } } } - + @Override public MethodHandle asVarargsCollector(Class arrayParameter) throws IllegalArgumentException { if (!arrayParameter.isArray()) { @@ -191,7 +191,7 @@ public MethodHandle asVarargsCollector(Class arrayParameter) throws IllegalAr } return new VarargsCollectorHandle(this, arrayParameter, MethodHandles.Lookup.isVarargs(rawModifiers)); } - + /* * Finish initialization of the receiver and return the defining class of the method it represents. */ diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/ReceiverBoundHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/ReceiverBoundHandle.java index e282e549e2e..9680ab62fef 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/ReceiverBoundHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/ReceiverBoundHandle.java @@ -33,7 +33,7 @@ import java.util.List; /*[ENDIF] JAVA_SPEC_VERSION >= 15 */ -/* ReceiverBoundHandle is a DirectHandle subclass used to call methods +/* ReceiverBoundHandle is a DirectHandle subclass used to call methods * that have an exact known address and a bound first parameter. * * The bound first parameter will be inserted into the stack prior to @@ -41,7 +41,7 @@ * receiver or null and the receiver parameter will be used to hammer * that slot. *

    - * This is use-able by both static and special methods as all stack + * This is use-able by both static and special methods as all stack * shapes will have a free slot as their first slot. *

    * It may be necessary to convert the "receiver" object into the right type. @@ -54,7 +54,7 @@ final class ReceiverBoundHandle extends DirectHandle { final Object receiver; final MethodHandle combinableVersion; - + public ReceiverBoundHandle(PrimitiveHandle toBind, Object receiver, MethodHandle combinableVersion) { super(toBind, KIND_BOUND); if (toBind instanceof DirectHandle) { @@ -66,18 +66,18 @@ public ReceiverBoundHandle(PrimitiveHandle toBind, Object receiver, MethodHandle } this.combinableVersion = combinableVersion; } - + private ReceiverBoundHandle(ReceiverBoundHandle originalHandle, MethodType newType) { super(originalHandle, newType); this.receiver = originalHandle.receiver; this.combinableVersion = originalHandle.combinableVersion.cloneWithNewType(newType); } - + @Override MethodHandle cloneWithNewType(MethodType newType) { return new ReceiverBoundHandle(this, newType); } - + /* * MethodType is same as incoming handle minus the first * argument. @@ -116,20 +116,20 @@ boolean addRelatedMHs(List relatedMHs) { VMLangAccess vma = Lookup.getVMLangAccess(); ClassLoader rawLoader = vma.getClassloader(receiver.getClass()); Class injectedSecurityFrame = null; - + synchronized (SecurityFrameInjector.loaderLock) { injectedSecurityFrame = SecurityFrameInjector.probeLoaderToSecurityFrameMap(rawLoader); } - + if ((injectedSecurityFrame == null) || !injectedSecurityFrame.isInstance(receiver)) { - /* Receiver object cannot be an instance of SecurityFrame as its classloader + /* Receiver object cannot be an instance of SecurityFrame as its classloader * doesn't have an injected security frame class. */ return false; } - + final Class finalInjectedSecurityFrame = injectedSecurityFrame; - + MethodHandle target = AccessController.doPrivileged(new PrivilegedAction() { public MethodHandle run() { try { @@ -141,12 +141,12 @@ public MethodHandle run() { } } }); - + if (target.type() == type()) { relatedMHs.add(target); return true; } - + return false; } /*[ENDIF] JAVA_SPEC_VERSION >= 15 */ @@ -154,19 +154,18 @@ public MethodHandle run() { // {{{ JIT support private static final ThunkTable _thunkTable = new ThunkTable(); protected final ThunkTable thunkTable(){ return _thunkTable; } - + @FrameIteratorSkip private final void invokeExact_thunkArchetype_V(int argPlaceholder) { nullCheckIfRequired(receiver); if (ILGenMacros.isCustomThunk()) { - directCall_V(receiver, argPlaceholder); + directCall_V(receiver, argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) - ComputedCalls.dispatchDirect_V(compiledEntryPoint(vmSlot), receiver, argPlaceholder); + ComputedCalls.dispatchDirect_V(compiledEntryPoint(vmSlot), receiver, argPlaceholder); else - ComputedCalls.dispatchJ9Method_V(vmSlot, receiver, argPlaceholder); + ComputedCalls.dispatchJ9Method_V(vmSlot, receiver, argPlaceholder); } - @FrameIteratorSkip private final int invokeExact_thunkArchetype_I(int argPlaceholder) { nullCheckIfRequired(receiver); @@ -178,7 +177,6 @@ private final int invokeExact_thunkArchetype_I(int argPlaceholder) { return ComputedCalls.dispatchJ9Method_I(vmSlot, receiver, argPlaceholder); } - @FrameIteratorSkip private final long invokeExact_thunkArchetype_J(int argPlaceholder) { nullCheckIfRequired(receiver); @@ -190,7 +188,6 @@ private final long invokeExact_thunkArchetype_J(int argPlaceholder) { return ComputedCalls.dispatchJ9Method_J(vmSlot, receiver, argPlaceholder); } - @FrameIteratorSkip private final float invokeExact_thunkArchetype_F(int argPlaceholder) { nullCheckIfRequired(receiver); @@ -202,7 +199,6 @@ private final float invokeExact_thunkArchetype_F(int argPlaceholder) { return ComputedCalls.dispatchJ9Method_F(vmSlot, receiver, argPlaceholder); } - @FrameIteratorSkip private final double invokeExact_thunkArchetype_D(int argPlaceholder) { nullCheckIfRequired(receiver); @@ -214,16 +210,15 @@ private final double invokeExact_thunkArchetype_D(int argPlaceholder) { return ComputedCalls.dispatchJ9Method_D(vmSlot, receiver, argPlaceholder); } - @FrameIteratorSkip - private final Object invokeExact_thunkArchetype_L(int argPlaceholder) { + private final Object invokeExact_thunkArchetype_L(int argPlaceholder) { nullCheckIfRequired(receiver); if (ILGenMacros.isCustomThunk()) { - return directCall_L(receiver, argPlaceholder); + return directCall_L(receiver, argPlaceholder); } else if (isAlreadyCompiled(vmSlot)) - return ComputedCalls.dispatchDirect_L(compiledEntryPoint(vmSlot), receiver, argPlaceholder); + return ComputedCalls.dispatchDirect_L(compiledEntryPoint(vmSlot), receiver, argPlaceholder); else - return ComputedCalls.dispatchJ9Method_L(vmSlot, receiver, argPlaceholder); + return ComputedCalls.dispatchJ9Method_L(vmSlot, receiver, argPlaceholder); } // }}} JIT support diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/SecurityFrame.java b/jcl/src/java.base/share/classes/java/lang/invoke/SecurityFrame.java index 962c02c62a0..b33a419d4a9 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/SecurityFrame.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/SecurityFrame.java @@ -23,11 +23,11 @@ package java.lang.invoke; /* - * A simple class that will be injected in each class loader, as - * required, to act as a "trampoline" to ensure that methods which + * A simple class that will be injected in each class loader, as + * required, to act as a "trampoline" to ensure that methods which * are sensitive to their caller (ie: use getCallerClass()) * can find a class in the correct ClassLoader and ProtectionDomain - * when invoked by MethodHandle invocation. + * when invoked by MethodHandle invocation. */ final class SecurityFrame { @@ -35,14 +35,13 @@ final class SecurityFrame { /* Required for revealDirect() access checking */ @SuppressWarnings("unused") private final Class accessClass; - + public SecurityFrame(MethodHandle target, Class accessClass) { this.target = target.asFixedArity(); - this.accessClass = accessClass; + this.accessClass = accessClass; } - + public Object invoke(Object... args) throws Throwable { return target.invokeWithArguments(args); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/SimpleMethodHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/SimpleMethodHandle.java index 6e6ca642e69..b357b22212b 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/SimpleMethodHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/SimpleMethodHandle.java @@ -30,7 +30,7 @@ * Stub class to compile OpenJDK j.l.i.MethodHandleImpl */ final class SimpleMethodHandle extends BoundMethodHandle { - + private SimpleMethodHandle(MethodType type, LambdaForm form) { super(type, form); OpenJDKCompileStub.OpenJDKCompileStubThrowError(); @@ -39,11 +39,11 @@ private SimpleMethodHandle(MethodType type, LambdaForm form) { BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + static BoundMethodHandle make(MethodType mt, LambdaForm lf) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } - + BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object obj) { throw OpenJDKCompileStub.OpenJDKCompileStubThrowError(); } diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/SpreadHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/SpreadHandle.java index c96f9efa182..d63ef1f7eb6 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/SpreadHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/SpreadHandle.java @@ -30,14 +30,14 @@ final class SpreadHandle extends MethodHandle { @VMCONSTANTPOOL_FIELD - private final MethodHandle next; + private final MethodHandle next; @VMCONSTANTPOOL_FIELD private final Class arrayClass; @VMCONSTANTPOOL_FIELD private final int spreadCount; @VMCONSTANTPOOL_FIELD private final int spreadPosition; /* The starting position of spread arguments */ - + protected SpreadHandle(MethodHandle next, MethodType collectType, Class arrayClass, int spreadCount, int spreadPosition) { super(collectType, KIND_SPREAD, infoAffectingThunks(arrayClass, spreadCount, spreadPosition)); this.arrayClass = arrayClass; diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/StaticFieldGetterHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/StaticFieldGetterHandle.java index 6206c686652..06d2489b072 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/StaticFieldGetterHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/StaticFieldGetterHandle.java @@ -32,18 +32,18 @@ * a static field. *

    * vmSlot will hold the Unsafe field offset + low tag. - * + * */ final class StaticFieldGetterHandle extends FieldHandle { - + StaticFieldGetterHandle(Class referenceClass, String fieldName, Class fieldClass, Class accessClass) throws IllegalAccessException, NoSuchFieldException { super(fieldMethodType(fieldClass), referenceClass, fieldName, fieldClass, KIND_GETSTATICFIELD, accessClass); } - + StaticFieldGetterHandle(Field field) throws IllegalAccessException { super(fieldMethodType(field.getType()), field, KIND_GETSTATICFIELD, true); } - + StaticFieldGetterHandle(StaticFieldGetterHandle originalHandle, MethodType newType) { super(originalHandle, newType); } @@ -125,4 +125,3 @@ final void compareWithStaticFieldGetter(StaticFieldGetterHandle left, Comparator compareWithField(left, c); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/StaticFieldSetterHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/StaticFieldSetterHandle.java index 9025ea85a1f..e19d11d1cce 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/StaticFieldSetterHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/StaticFieldSetterHandle.java @@ -32,14 +32,14 @@ * a static field. *

    * vmSlot will hold the Unsafe field offset + low tag. - * + * */ final class StaticFieldSetterHandle extends FieldHandle { - + StaticFieldSetterHandle(Class referenceClass, String fieldName, Class fieldClass, Class accessClass) throws IllegalAccessException, NoSuchFieldException { super(fieldMethodType(fieldClass), referenceClass, fieldName, fieldClass, KIND_PUTSTATICFIELD, accessClass); } - + StaticFieldSetterHandle(Field field) throws IllegalAccessException { super(fieldMethodType(field.getType()), field, KIND_PUTSTATICFIELD, true); } @@ -125,4 +125,3 @@ final void compareWithStaticFieldSetter(StaticFieldSetterHandle left, Comparator compareWithField(left, c); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_CLASS.java b/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_CLASS.java index d23687fa7ba..14df019ac1c 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_CLASS.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_CLASS.java @@ -31,4 +31,3 @@ @Target({ElementType.TYPE}) @interface VMCONSTANTPOOL_CLASS { } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_FIELD.java b/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_FIELD.java index 238f4c7d84a..ed40283ea04 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_FIELD.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_FIELD.java @@ -32,4 +32,3 @@ @interface VMCONSTANTPOOL_FIELD { } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_METHOD.java b/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_METHOD.java index 818e44265b9..ebb075577db 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_METHOD.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/VMCONSTANTPOOL_METHOD.java @@ -32,4 +32,3 @@ @interface VMCONSTANTPOOL_METHOD { } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/VarHandleInvokeGenericHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/VarHandleInvokeGenericHandle.java index 16190cf47fa..8512d73b746 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/VarHandleInvokeGenericHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/VarHandleInvokeGenericHandle.java @@ -77,4 +77,3 @@ private final int invokeExact_thunkArchetype_X(VarHandle varHandle, int argPlace } // }}} JIT support } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/VarargsCollectorHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/VarargsCollectorHandle.java index 0ad8bdd26de..262448d5b4d 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/VarargsCollectorHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/VarargsCollectorHandle.java @@ -38,14 +38,14 @@ /* * VarargsCollectorHandle is a MethodHandle subclass used to implement * MethodHandle.asVarargsCollector(Class arrayType) - * + * * Type of VarargsCollectorHandle and its 'next' handle will always match */ final class VarargsCollectorHandle extends MethodHandle { final MethodHandle next; final Class arrayType; final boolean isPrimitiveVarargs; - + VarargsCollectorHandle(MethodHandle next, Class arrayType, boolean isPrimitiveVarargs) { super(varargsCollectorType(next.type, arrayType), KIND_VARARGSCOLLECT, null); this.next = next; @@ -55,14 +55,14 @@ final class VarargsCollectorHandle extends MethodHandle { this.arrayType = arrayType; this.isPrimitiveVarargs = isPrimitiveVarargs; } - + VarargsCollectorHandle(VarargsCollectorHandle originalHandle, MethodType newType) { super(originalHandle, newType); this.next = originalHandle.next; this.arrayType = originalHandle.arrayType; this.isPrimitiveVarargs = originalHandle.isPrimitiveVarargs; } - + @Override Class getDefc() throws InternalError { if (isPrimitiveVarargs) { @@ -70,7 +70,7 @@ Class getDefc() throws InternalError { } return super.getDefc(); } - + @Override Class getReferenceClass() throws InternalError { if (isPrimitiveVarargs) { @@ -78,7 +78,7 @@ Class getReferenceClass() throws InternalError { } return super.getReferenceClass(); } - + @Override Class getSpecialCaller() throws InternalError { if (isPrimitiveVarargs) { @@ -86,7 +86,7 @@ Class getSpecialCaller() throws InternalError { } return super.getSpecialCaller(); } - + @Override String getMethodName() throws InternalError { if (isPrimitiveVarargs) { @@ -94,7 +94,7 @@ String getMethodName() throws InternalError { } return super.getMethodName(); } - + @Override int getModifiers() throws InternalError { if (isPrimitiveVarargs) { @@ -102,7 +102,7 @@ int getModifiers() throws InternalError { } return super.getModifiers(); } - + static MethodType varargsCollectorType(MethodType nextType, Class arrayType) { return nextType.changeParameterType(nextType.parameterCount() - 1, arrayType); } @@ -144,21 +144,21 @@ public Object invokeWithArguments(Object... args) throws Throwable, WrongMethodT { if (argsLength < 253) { MethodHandle mh = IWAContainer.getMH(argsLength); - return mh.invokeExact((MethodHandle) this, args); + return mh.invokeExact((MethodHandle) this, args); } MethodHandle mh = this.asType(MethodType.genericMethodType(argsLength)); mh = mh.asSpreader(Object[].class, argsLength); return mh.invokeExact(args); } } - + private CollectHandle previousCollector = null; - + private WrongMethodTypeException throwNewWMTE(IllegalArgumentException iae) { /*[MSG "K0681", "Failed to build collector"]*/ throw new WrongMethodTypeException(com.ibm.oti.util.Msg.getString("K0681"), iae); //$NON-NLS-1$ } - + @Override public MethodHandle asType(MethodType newType) throws ClassCastException { if (type == newType) { @@ -199,7 +199,7 @@ public MethodHandle asType(MethodType newType) throws ClassCastException { } return collector.asType(newType); } - + @Override public MethodHandle asVarargsCollector(Class arrayParameter) throws IllegalArgumentException { if (arrayType == arrayParameter) { @@ -222,7 +222,7 @@ public MethodHandle asFixedArity() { // asType will return 'this' if type is the same return fixedArity.asType(type()); } - + @Override boolean canRevealDirect() { return isPrimitiveVarargs; @@ -240,7 +240,7 @@ boolean addRelatedMHs(List relatedMHs) { private static final ThunkTable _thunkTable = new ThunkTable(); protected final ThunkTable thunkTable(){ return _thunkTable; } - + @FrameIteratorSkip private final int invokeExact_thunkArchetype_X(int argPlaceholder) throws Throwable { /*[IF ]*/ diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/VirtualHandle.java b/jcl/src/java.base/share/classes/java/lang/invoke/VirtualHandle.java index 239ebb3108c..3e5fa9b6738 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/VirtualHandle.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/VirtualHandle.java @@ -26,8 +26,8 @@ import java.lang.reflect.Modifier; /* - * VirtualHandle is a MethodHandle that does virtual dispatch - * on the receiver. + * VirtualHandle is a MethodHandle that does virtual dispatch + * on the receiver. *

    * The vmSlot holds the vtable index for the correct method. * The type is the same as the method's except with the receiver's class prepended @@ -46,18 +46,18 @@ final class VirtualHandle extends IndirectHandle { throw new IllegalAccessException(); } } - + VirtualHandle(DirectHandle nonVirtualHandle) throws IllegalAccessException { super(nonVirtualHandle.type(), nonVirtualHandle.referenceClass, nonVirtualHandle.name, KIND_VIRTUAL, nonVirtualHandle.rawModifiers); this.defc = nonVirtualHandle.defc; - + // Set the vmSlot to an vtable index boolean succeed = setVMSlotAndRawModifiersFromSpecialHandle(this, nonVirtualHandle); if (!succeed) { throw new IllegalAccessException(); } } - + VirtualHandle(VirtualHandle originalHandle, MethodType newType) { super(originalHandle, newType); } @@ -70,7 +70,7 @@ protected final long vtableOffset(Object receiver) { private static final ThunkTable _thunkTable = new ThunkTable(); protected final ThunkTable thunkTable(){ return _thunkTable; } - // ILGen macros + // ILGen macros protected static native void virtualCall_V(Object receiver, int argPlaceholder); protected static native int virtualCall_I(Object receiver, int argPlaceholder); protected static native long virtualCall_J(Object receiver, int argPlaceholder); @@ -151,4 +151,3 @@ final void compareWithVirtual(VirtualHandle left, Comparator c) { super.compareWithIndirect(left, c); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/VolatileCallSite.java b/jcl/src/java.base/share/classes/java/lang/invoke/VolatileCallSite.java index bda796d3f37..389ef90c8d2 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/VolatileCallSite.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/VolatileCallSite.java @@ -23,8 +23,8 @@ package java.lang.invoke; /** - * A VolatileCallSite acts as though its target MethodHandle were a volatile variable. - * This CallSite sub-class should be used if the changes to the target are frequent or if + * A VolatileCallSite acts as though its target MethodHandle were a volatile variable. + * This CallSite sub-class should be used if the changes to the target are frequent or if * changes must be immediately observed by all threads, even if the {@link #setTarget(MethodHandle)} * occurs in a different thread. *

    @@ -36,11 +36,11 @@ */ public class VolatileCallSite extends CallSite { private volatile MethodHandle target; - + /** - * Create a VolatileCallSite with the same type as the volatileTarget + * Create a VolatileCallSite with the same type as the volatileTarget * and the initial target set to volatileTarget. - * + * * @param volatileTarget - the target MethodHandle of the CallSite * @throws NullPointerException - if the volatileTarget is null. */ @@ -49,11 +49,11 @@ public VolatileCallSite(MethodHandle volatileTarget) throws NullPointerException super(volatileTarget.type()); target = volatileTarget; } - + /** * Create a VolatileCallSite with the MethodType type and an * initial target that throws IllegalStateException. - * + * * @param type - the permanent type of this CallSite. * @throws NullPointerException - if the type is null. */ @@ -62,7 +62,7 @@ public VolatileCallSite(MethodType type) throws NullPointerException { // install a target that throws IllegalStateException target = CallSite.initialTarget(type); } - + @Override public final MethodHandle dynamicInvoker() { return new DynamicInvokerHandle(this); @@ -89,6 +89,5 @@ public void setTarget(MethodHandle nextTarget) throws NullPointerException, Wron } target = nextTarget; } - -} +} diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/WrongMethodTypeException.java b/jcl/src/java.base/share/classes/java/lang/invoke/WrongMethodTypeException.java index e83d35004f3..d4d1ceff572 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/WrongMethodTypeException.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/WrongMethodTypeException.java @@ -25,14 +25,14 @@ /** * WrongMethodTypeException is thrown to indicate an attempt to invoke a MethodHandle with the wrong MethodType. * This exception can also be thrown when adapting a MethodHandle in a way that is incompatible with its MethodType. - * + * * @author OTI * @version initial * @since 1.7 */ @VMCONSTANTPOOL_CLASS public class WrongMethodTypeException extends RuntimeException { - + /** * Serialized version ID */ @@ -44,7 +44,7 @@ public class WrongMethodTypeException extends RuntimeException { public WrongMethodTypeException() { super(); } - + /** * Construct a WrongMethodTypeException with the supplied message. * @@ -53,14 +53,13 @@ public WrongMethodTypeException() { public WrongMethodTypeException(String message){ super(message); } - + static WrongMethodTypeException newWrongMethodTypeException(MethodType oldType, MethodType newType) { /*[MSG "K0632", "{0} is not compatible with {1}"]*/ return new WrongMethodTypeException(com.ibm.oti.util.Msg.getString("K0632", newType, oldType)); //$NON-NLS-1$ } - + WrongMethodTypeException(String message, Throwable throwable) { super(message, throwable); } } - diff --git a/jcl/src/java.base/share/classes/java/lang/ref/FinalReference.java b/jcl/src/java.base/share/classes/java/lang/ref/FinalReference.java index 01f2b69ef05..8ff181f198e 100644 --- a/jcl/src/java.base/share/classes/java/lang/ref/FinalReference.java +++ b/jcl/src/java.base/share/classes/java/lang/ref/FinalReference.java @@ -22,7 +22,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 */ - + final class FinalReference extends Reference { public FinalReference(T referent, ReferenceQueue q) { diff --git a/jcl/src/java.base/share/classes/java/lang/ref/PhantomReference.java b/jcl/src/java.base/share/classes/java/lang/ref/PhantomReference.java index 3f19c24f59a..29b5e58adc9 100644 --- a/jcl/src/java.base/share/classes/java/lang/ref/PhantomReference.java +++ b/jcl/src/java.base/share/classes/java/lang/ref/PhantomReference.java @@ -23,14 +23,14 @@ package java.lang.ref; /** - * PhantomReference objects are used to detect referents which + * PhantomReference objects are used to detect referents which * are no longer visible and are eligible to have their storage * reclaimed. * * @author OTI * @version initial * @since JDK1.2 - */ + */ public /*[IF JAVA_SPEC_VERSION >= 19]*/ non-sealed @@ -38,12 +38,12 @@ class PhantomReference extends Reference { /** - * Return the referent of the reference object. Phantom reference + * Return the referent of the reference object. Phantom reference * objects referents are inaccessible, and so null is returned. * * @return Object * Returns null. - */ + */ public T get() { return null; } @@ -55,7 +55,7 @@ public T get() { * referent to track. * @param q * queue to register to the reference object with. - */ + */ public PhantomReference(T r, ReferenceQueue q) { initReference(r, q); } diff --git a/jcl/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java b/jcl/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java index 179a3b8ce11..35622747d5a 100644 --- a/jcl/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java +++ b/jcl/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java @@ -34,13 +34,13 @@ /** * ReferenceQueue is the container on which reference objects - * are enqueued when their reachability type is detected for + * are enqueued when their reachability type is detected for * the referent. * * @author OTI * @version initial * @since 1.2 - */ + */ public class ReferenceQueue extends Object { private Reference[] references; @@ -63,10 +63,10 @@ public class ReferenceQueue extends Object { tmpClass = Class.forName("java.lang.Class$ReflectRef"); //$NON-NLS-1$ } catch (ClassNotFoundException e) {} reflectRefClass = tmpClass; - + Class tmpClass2 = null; try { - tmpClass2 = Class.forName("java.lang.ClassLoader$ClassNameLockRef"); //$NON-NLS-1$ + tmpClass2 = Class.forName("java.lang.ClassLoader$ClassNameLockRef"); //$NON-NLS-1$ } catch (ClassNotFoundException e) {} classNameLockRefClass = tmpClass2; } @@ -78,13 +78,13 @@ public class ReferenceQueue extends Object { * * @return Reference * next available Reference or NULL. - */ + */ /*[IF CRIU_SUPPORT]*/ @NotCheckpointSafe /*[ENDIF] CRIU_SUPPORT */ -public Reference poll () { +public Reference poll () { Reference ref; - + /* Optimization to return immediately and not synchronize if there is nothing in the queue */ if(empty) { return null; @@ -94,7 +94,7 @@ public Reference poll () { return null; } ref = references[head]; - /*[PR 115652] null References when removed */ + /*[PR 115652] null References when removed */ references[head++] = null; ref.dequeue(); if(head == references.length) { @@ -108,7 +108,7 @@ public Reference poll () { } /** - * Return the next available enqueued reference on the queue, blocking + * Return the next available enqueued reference on the queue, blocking * indefinitely until one is available. * * @author OTI @@ -119,13 +119,13 @@ public Reference poll () { * null otherwise. * @exception InterruptedException * to interrupt the wait. - */ + */ public Reference remove() throws InterruptedException { return remove(0L); } /** - * Return the next available enqueued reference on the queue, blocking + * Return the next available enqueued reference on the queue, blocking * up to the time given until one is available. Return null if no * reference became available. * @@ -142,7 +142,7 @@ public Reference remove() throws InterruptedException { * if the wait period is negative. * @exception InterruptedException * to interrupt the wait. - */ + */ public Reference remove(long timeout) throws IllegalArgumentException, InterruptedException { if (timeout < 0) throw new IllegalArgumentException(); @@ -153,7 +153,7 @@ public Reference remove(long timeout) throws IllegalArgumentExcepti if(empty) return null; } ref = references[head]; - /*[PR 115652] null References when removed */ + /*[PR 115652] null References when removed */ references[head++] = null; ref.dequeue(); if(head == references.length) { @@ -259,6 +259,6 @@ void await(long timeout) throws InterruptedException {} public ReferenceQueue() { head = 0; tail = 0; - empty = true; + empty = true; } } diff --git a/jcl/src/java.base/share/classes/java/lang/ref/SoftReference.java b/jcl/src/java.base/share/classes/java/lang/ref/SoftReference.java index a8d3bc58a54..69da49b8510 100644 --- a/jcl/src/java.base/share/classes/java/lang/ref/SoftReference.java +++ b/jcl/src/java.base/share/classes/java/lang/ref/SoftReference.java @@ -29,7 +29,7 @@ * @author OTI * @version initial * @since 1.2 - */ + */ public /*[IF JAVA_SPEC_VERSION >= 19]*/ non-sealed @@ -43,7 +43,7 @@ class SoftReference extends Reference { * * @param r referent to track. * @param q queue to register to the reference object with. - */ + */ public SoftReference(T r, ReferenceQueue q) { initReference(r, q); } @@ -52,7 +52,7 @@ public SoftReference(T r, ReferenceQueue q) { * Constructs a new instance of this class. * * @param r referent to track. - */ + */ public SoftReference(T r) { initReference(r); } @@ -62,7 +62,7 @@ public SoftReference(T r) { * * @return Referent to which reference refers, * or null if object has been cleared. - */ + */ public T get () { /*[PR 124242] SoftReference.get() should reset age*/ if (age != 0) { diff --git a/jcl/src/java.base/share/classes/java/lang/ref/WeakReference.java b/jcl/src/java.base/share/classes/java/lang/ref/WeakReference.java index e09cbd14fd8..a249f6e764f 100644 --- a/jcl/src/java.base/share/classes/java/lang/ref/WeakReference.java +++ b/jcl/src/java.base/share/classes/java/lang/ref/WeakReference.java @@ -29,7 +29,7 @@ * @author OTI * @version initial * @since 1.2 - */ + */ public /*[IF JAVA_SPEC_VERSION >= 19]*/ non-sealed diff --git a/jcl/src/java.base/share/classes/java/lang/reflect/Array.java b/jcl/src/java.base/share/classes/java/lang/reflect/Array.java index 829692f7bf1..7a10db83fc8 100644 --- a/jcl/src/java.base/share/classes/java/lang/reflect/Array.java +++ b/jcl/src/java.base/share/classes/java/lang/reflect/Array.java @@ -22,7 +22,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 */ - + /** * This class provides methods to dynamically create and access arrays. * @@ -101,11 +101,11 @@ public static Object get(Object array, int index) throws IllegalArgumentExceptio * if the index is out of bounds -- negative or greater than or equal to the array length */ public static boolean getBoolean(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - try { - return ((boolean[])array)[index]; - } catch (ClassCastException e) { - throw new IllegalArgumentException(e.getMessage()); - } + try { + return ((boolean[])array)[index]; + } catch (ClassCastException e) { + throw new IllegalArgumentException(e.getMessage()); + } } /** @@ -124,11 +124,11 @@ public static boolean getBoolean(Object array, int index) throws IllegalArgument * if the index is out of bounds -- negative or greater than or equal to the array length */ public static byte getByte(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - try { - return ((byte[])array)[index]; - } catch (ClassCastException e) { - throw new IllegalArgumentException(e.getMessage()); - } + try { + return ((byte[])array)[index]; + } catch (ClassCastException e) { + throw new IllegalArgumentException(e.getMessage()); + } } /** @@ -147,11 +147,11 @@ public static byte getByte(Object array, int index) throws IllegalArgumentExcept * if the index is out of bounds -- negative or greater than or equal to the array length */ public static char getChar(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - try { - return ((char[])array)[index]; - } catch (ClassCastException e) { - throw new IllegalArgumentException(e.getMessage()); - } + try { + return ((char[])array)[index]; + } catch (ClassCastException e) { + throw new IllegalArgumentException(e.getMessage()); + } } /** @@ -170,11 +170,11 @@ public static char getChar(Object array, int index) throws IllegalArgumentExcept * if the index is out of bounds -- negative or greater than or equal to the array length */ public static double getDouble(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == double[].class) { - return ((double[])array)[index]; - } else { - return getFloat(array, index); - } + if (array.getClass() == double[].class) { + return ((double[])array)[index]; + } else { + return getFloat(array, index); + } } /** @@ -193,11 +193,11 @@ public static double getDouble(Object array, int index) throws IllegalArgumentEx * if the index is out of bounds -- negative or greater than or equal to the array length */ public static float getFloat(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == float[].class) { - return ((float[])array)[index]; - } else { - return getLong(array, index); - } + if (array.getClass() == float[].class) { + return ((float[])array)[index]; + } else { + return getLong(array, index); + } } /** @@ -216,14 +216,14 @@ public static float getFloat(Object array, int index) throws IllegalArgumentExce * if the index is out of bounds -- negative or greater than or equal to the array length */ public static int getInt(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - Class arrayClass = array.getClass(); + Class arrayClass = array.getClass(); if (arrayClass == int[].class) { - return ((int[])array)[index]; - } else if (arrayClass == char[].class) { - return ((char[])array)[index]; - } else { - return getShort(array, index); - } + return ((int[])array)[index]; + } else if (arrayClass == char[].class) { + return ((char[])array)[index]; + } else { + return getShort(array, index); + } } /** @@ -239,29 +239,29 @@ public static int getInt(Object array, int index) throws IllegalArgumentExceptio */ public static int getLength(Object array) throws IllegalArgumentException { Class arrayClass = array.getClass(); - if (arrayClass == int[].class) { - return ((int[])array).length; - } else if (arrayClass == boolean[].class) { - return ((boolean[])array).length; - } else if (arrayClass == float[].class) { - return ((float[])array).length; - } else if (arrayClass == char[].class) { - return ((char[])array).length; - } else if (arrayClass == double[].class) { - return ((double[])array).length; - } else if (arrayClass == long[].class) { - return ((long[])array).length; - } else if (arrayClass == short[].class) { - return ((short[])array).length; - } else if (arrayClass == byte[].class) { - return ((byte[])array).length; - } else { - try { - return ((Object[])array).length; - } catch (ClassCastException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } + if (arrayClass == int[].class) { + return ((int[])array).length; + } else if (arrayClass == boolean[].class) { + return ((boolean[])array).length; + } else if (arrayClass == float[].class) { + return ((float[])array).length; + } else if (arrayClass == char[].class) { + return ((char[])array).length; + } else if (arrayClass == double[].class) { + return ((double[])array).length; + } else if (arrayClass == long[].class) { + return ((long[])array).length; + } else if (arrayClass == short[].class) { + return ((short[])array).length; + } else if (arrayClass == byte[].class) { + return ((byte[])array).length; + } else { + try { + return ((Object[])array).length; + } catch (ClassCastException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } } /** @@ -280,11 +280,11 @@ public static int getLength(Object array) throws IllegalArgumentException { * if the index is out of bounds -- negative or greater than or equal to the array length */ public static long getLong(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == long[].class) { - return ((long[])array)[index]; - } else { - return getInt(array, index); - } + if (array.getClass() == long[].class) { + return ((long[])array)[index]; + } else { + return getInt(array, index); + } } /** @@ -303,15 +303,15 @@ public static long getLong(Object array, int index) throws IllegalArgumentExcept * if the index is out of bounds -- negative or greater than or equal to the array length */ public static short getShort(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == short[].class) { - return ((short[])array)[index]; - } else { - return getByte(array, index); - } + if (array.getClass() == short[].class) { + return ((short[])array)[index]; + } else { + return getByte(array, index); + } } private static native Object multiNewArrayImpl(Class componentType, int dimensions, int[] dimensionsArray); -private static native Object newArrayImpl(Class componentType, int dimension); +private static native Object newArrayImpl(Class componentType, int dimension); /** * Return a new multidimensional array of the specified component type and dimensions. @@ -334,15 +334,15 @@ public static Object newInstance(Class componentType, int... dimensions) thro if (componentType == null) { throw new NullPointerException(); } - + int length = dimensions.length; if ((length < 1) || (length > 255) || (componentType == Void.TYPE)) { throw new IllegalArgumentException(); } - + // Native is stack-oriented. Reverse the dimensions. int[] reversed = new int[length]; - + for (int i = 0; i < length; i++) { if (dimensions[i] < 0) { throw new NegativeArraySizeException(String.valueOf(dimensions[i])); @@ -373,7 +373,7 @@ public static Object newInstance(Class componentType, int size) throws Negati if (componentType == null) { throw new NullPointerException(); } - if (size < 0) { + if (size < 0) { throw new NegativeArraySizeException(String.valueOf(size)); } if (componentType == Void.TYPE) { @@ -391,7 +391,7 @@ public static Object newInstance(Class componentType, int size) throws Negati * @param array the array * @param index the index * @param value the new value - * + * * @exception java.lang.NullPointerException * if the array is null * @exception java.lang.IllegalArgumentException @@ -411,33 +411,33 @@ public static void set(Object array, int index, Object value) throws IllegalArgu } Class valueClass = value.getClass(); if (valueClass == Integer.class) { - setInt(array, index, ((Integer)value).intValue()); - } else if (valueClass == Float.class) { - setFloat(array, index, ((Float)value).floatValue()); - } else if (valueClass == Double.class) { - setDouble(array, index, ((Double)value).doubleValue()); - } else if (valueClass == Long.class) { - setLong(array, index, ((Long)value).longValue()); - } else if (valueClass == Short.class) { - setShort(array, index, ((Short)value).shortValue()); - } else if (valueClass == Byte.class) { - setByte(array, index, ((Byte)value).byteValue()); - } else if (valueClass == Boolean.class) { - setBoolean(array, index, ((Boolean)value).booleanValue()); - } else if (valueClass == Character.class) { - setChar(array, index, ((Character)value).charValue()); - } else { - /* value is not primitive type */ - throw new IllegalArgumentException(); - } + setInt(array, index, ((Integer)value).intValue()); + } else if (valueClass == Float.class) { + setFloat(array, index, ((Float)value).floatValue()); + } else if (valueClass == Double.class) { + setDouble(array, index, ((Double)value).doubleValue()); + } else if (valueClass == Long.class) { + setLong(array, index, ((Long)value).longValue()); + } else if (valueClass == Short.class) { + setShort(array, index, ((Short)value).shortValue()); + } else if (valueClass == Byte.class) { + setByte(array, index, ((Byte)value).byteValue()); + } else if (valueClass == Boolean.class) { + setBoolean(array, index, ((Boolean)value).booleanValue()); + } else if (valueClass == Character.class) { + setChar(array, index, ((Character)value).charValue()); + } else { + /* value is not primitive type */ + throw new IllegalArgumentException(); + } } else { - try { - ((Object[])array)[index] = value; - } catch (ClassCastException e) { - throw new IllegalArgumentException(e.getMessage()); - } catch (ArrayStoreException e) { - throw new IllegalArgumentException(e.getMessage()); - } + try { + ((Object[])array)[index] = value; + } catch (ClassCastException e) { + throw new IllegalArgumentException(e.getMessage()); + } catch (ArrayStoreException e) { + throw new IllegalArgumentException(e.getMessage()); + } } } @@ -456,11 +456,11 @@ public static void set(Object array, int index, Object value) throws IllegalArgu * if the index is out of bounds -- negative or greater than or equal to the array length */ public static void setBoolean(Object array, int index, boolean value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - try { - ((boolean[])array)[index] = value; - } catch (ClassCastException e) { - throw new IllegalArgumentException(e.getMessage()); - } + try { + ((boolean[])array)[index] = value; + } catch (ClassCastException e) { + throw new IllegalArgumentException(e.getMessage()); + } } /** @@ -478,11 +478,11 @@ public static void setBoolean(Object array, int index, boolean value) throws Ill * if the index is out of bounds -- negative or greater than or equal to the array length */ public static void setByte(Object array, int index, byte value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == byte[].class) { - ((byte[])array)[index] = value; - } else { - setShort(array, index, value); - } + if (array.getClass() == byte[].class) { + ((byte[])array)[index] = value; + } else { + setShort(array, index, value); + } } /** @@ -500,11 +500,11 @@ public static void setByte(Object array, int index, byte value) throws IllegalAr * if the index is out of bounds -- negative or greater than or equal to the array length */ public static void setChar(Object array, int index, char value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == char[].class) { - ((char[])array)[index] = value; - } else { - setInt(array, index, value); - } + if (array.getClass() == char[].class) { + ((char[])array)[index] = value; + } else { + setInt(array, index, value); + } } /** @@ -522,11 +522,11 @@ public static void setChar(Object array, int index, char value) throws IllegalAr * if the index is out of bounds -- negative or greater than or equal to the array length */ public static void setDouble(Object array, int index, double value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - try { - ((double[])array)[index] = value; - } catch (ClassCastException e) { - throw new IllegalArgumentException(e.getMessage()); - } + try { + ((double[])array)[index] = value; + } catch (ClassCastException e) { + throw new IllegalArgumentException(e.getMessage()); + } } /** @@ -544,11 +544,11 @@ public static void setDouble(Object array, int index, double value) throws Illeg * if the index is out of bounds -- negative or greater than or equal to the array length */ public static void setFloat(Object array, int index, float value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == float[].class) { - ((float[])array)[index] = value; - } else { - setDouble(array, index, value); - } + if (array.getClass() == float[].class) { + ((float[])array)[index] = value; + } else { + setDouble(array, index, value); + } } /** @@ -566,11 +566,11 @@ public static void setFloat(Object array, int index, float value) throws Illegal * if the index is out of bounds -- negative or greater than or equal to the array length */ public static void setInt(Object array, int index, int value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == int[].class) { - ((int[])array)[index] = value; - } else { - setLong(array, index, value); - } + if (array.getClass() == int[].class) { + ((int[])array)[index] = value; + } else { + setLong(array, index, value); + } } /** @@ -588,11 +588,11 @@ public static void setInt(Object array, int index, int value) throws IllegalArgu * if the index is out of bounds -- negative or greater than or equal to the array length */ public static void setLong(Object array, int index, long value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == long[].class) { - ((long[])array)[index] = value; - } else { - setFloat(array, index, value); - } + if (array.getClass() == long[].class) { + ((long[])array)[index] = value; + } else { + setFloat(array, index, value); + } } /** @@ -610,10 +610,10 @@ public static void setLong(Object array, int index, long value) throws IllegalAr * if the index is out of bounds -- negative or greater than or equal to the array length */ public static void setShort(Object array, int index, short value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass() == short[].class) { - ((short[])array)[index] = value; - } else { - setInt(array, index, value); - } + if (array.getClass() == short[].class) { + ((short[])array)[index] = value; + } else { + setInt(array, index, value); + } } } diff --git a/jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java index b1b9936faae..65beb3c394e 100644 --- a/jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -1683,7 +1683,6 @@ public Object allocateUninitializedArray(Class c, int length) { return allocateUninitializedArray0(c, length); } - /** * Atomically sets the parameter value at offset in obj if the compare value * matches the existing value in the object. diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/Advertisement.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/Advertisement.java index e431b8c635a..500ca6197ca 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/Advertisement.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/Advertisement.java @@ -101,7 +101,7 @@ public static Advertisement readAdvertisementFile(InputStream advertStream) thro * @return Create the information to discover and notify this VM */ private static StringBuilder createAdvertContent(String vmId, String displayName) { - StringBuilder contentBuffer = new StringBuilder(512); + StringBuilder contentBuffer = new StringBuilder(512); addKeyAsciiValue(contentBuffer, KEY_VERSION, "0.1"); //$NON-NLS-1$ addKeyValue(contentBuffer, KEY_USER_ID, com.ibm.oti.vm.VM.internalGetProperties().getProperty("user.name")); //$NON-NLS-1$ /* CMVC 161414 - PIDs and UIDs are long */ @@ -113,11 +113,11 @@ private static StringBuilder createAdvertContent(String vmId, String displayName addKeyValue(contentBuffer, GLOBAL_SEMAPHORE, Boolean.TRUE.toString()); File tmpTargetDirectoryFileObject = TargetDirectory.getTargetDirectoryFileObject(); File tmpSyncFileObject = TargetDirectory.getSyncFileObject(); - + if (null != tmpTargetDirectoryFileObject && null != tmpSyncFileObject) { addKeyValue(contentBuffer, KEY_REPLY_FILE, (new File(tmpTargetDirectoryFileObject, Reply.REPLY_FILENAME)).getPath()); addKeyValue(contentBuffer, KEY_ATTACH_NOTIFICATION_SYNC, tmpSyncFileObject.getAbsolutePath()); - + return contentBuffer; } else { return null; @@ -201,7 +201,7 @@ static void createAdvertisementFile(String vmId, String displayName) throws IOEx return; } File advertFile = TargetDirectory.getAdvertisementFileObject(); - /* AttachHandler.terminate() will delete this file on shutdown */ + /* AttachHandler.terminate() will delete this file on shutdown */ IPC.createNewFileWithPermissions(advertFile, TargetDirectory.ADVERTISEMENT_FILE_PERMISSIONS); /* we have a brand new, empty file with correct ownership and permissions */ try (FileOutputStream advertOutputStream = new FileOutputStream(advertFile);){ @@ -210,39 +210,39 @@ static void createAdvertisementFile(String vmId, String displayName) throws IOEx IPC.logMessage("createAdvertisementFile failed to create advertisement file : file object is null"); //$NON-NLS-1$ return; } - + advertOutputStream.write(advertContent.toString().getBytes("ISO8859_1")); //$NON-NLS-1$ if (LOGGING_DISABLED != loggingStatus) { IPC.logMessage("createAdvertisementFile ", advertFile.getAbsolutePath()); //$NON-NLS-1$ } } } - + /** * @return name of advertisement file, not including directory path */ public static String getFilename() { return Advertisement.ADVERT_FILENAME; } - + /** * @return Target virtual machine's display name */ public String getDisplayName() { return props.getProperty(KEY_DISPLAY_NAME); } - + /** - * + * * @return Operating system process ID of the target VM */ public long getProcessId() { - + return pid; } /** - * + * * @return machine-friendly identifier of the target VM */ public String getVmId() { @@ -250,7 +250,7 @@ public String getVmId() { } /** - * + * * @return identifier of the semaphore used to notify the target */ String getNotifier() { @@ -266,7 +266,7 @@ public String getReplyFile() { } /** - * + * * @return user identifier (numeric) */ public long getUid() { @@ -274,7 +274,7 @@ public long getUid() { } /** - * + * * @return true if the target uses the global semaphore (Windows only) */ public boolean isGlobalSemaphore() { @@ -289,5 +289,4 @@ public String getNotificationSync() { return props.getProperty(KEY_ATTACH_NOTIFICATION_SYNC); } - } diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/AttachHandler.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/AttachHandler.java index 64017e48c75..fd276357361 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/AttachHandler.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/AttachHandler.java @@ -302,7 +302,6 @@ private boolean initialize() throws IOException { } } - synchronized (stateSync) { if (isAttachApiTerminated()) { IPC.logMessage("cancel initialize before prepareCommonDirectory"); //$NON-NLS-1$ diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/AttachmentConnection.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/AttachmentConnection.java index 498df833ec1..03b65cd4f21 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/AttachmentConnection.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/AttachmentConnection.java @@ -30,7 +30,7 @@ import java.io.UnsupportedEncodingException; /** - * + * * Manage socket communications between an attacher and a target VM. * */ @@ -46,19 +46,19 @@ public final class AttachmentConnection { * @return array of bytes, not including null termination * @throws IOException if file closed before null found or excessive data received */ - + static byte[] streamReceiveBytes(InputStream channel, int dataLimit, boolean requireNull) throws IOException { final int bufferLen = 100; /* most messages are short */ byte [] msgBuff = new byte[bufferLen]; ByteArrayOutputStream msg = new ByteArrayOutputStream(bufferLen); boolean unlimited = (0 == dataLimit); - + if (null == channel) { /*[MSG "K0575", "channel is null"]*/ throw new IOException(com.ibm.oti.util.Msg.getString("K0575")); //$NON-NLS-1$ } boolean done = false; - while (!done && (unlimited || (dataLimit > msg.size()))) { + while (!done && (unlimited || (dataLimit > msg.size()))) { int nRead = channel.read(msgBuff, 0, bufferLen); if (nRead > 0) { if (msgBuff[nRead-1] == 0) { /* messages are terminated by a null */ @@ -87,7 +87,7 @@ static byte[] streamReceiveBytes(InputStream channel, int dataLimit, boolean req * @return array of bytes, not including null termination * @throws IOException if file closed before null found or excessive data received */ - + static byte[] streamReceiveBytes(InputStream channel, boolean requireNull) throws IOException { return streamReceiveBytes(channel, 0, requireNull); } diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/CommonDirectory.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/CommonDirectory.java index 0a1ad686de6..1b460e32617 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/CommonDirectory.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/CommonDirectory.java @@ -112,7 +112,7 @@ static void prepareCommonDirectory() throws IOException { File cd = getCommonDirFileObject(); if (cd.exists()) { if (!cd.canWrite()) { - IPC.logMessage("could not write ", cd.getAbsolutePath()); //$NON-NLS-1$ + IPC.logMessage("could not write ", cd.getAbsolutePath()); //$NON-NLS-1$ throw new IOException(cd.getAbsolutePath()); } else if (!cd.isDirectory()) { if (!cd.delete()) { /* file where a directory should be */ @@ -155,7 +155,7 @@ public static void obtainControllerLock(String callSite) throws IOException { } /** - * non-blocking lock the controller lockfile. + * non-blocking lock the controller lockfile. * Create the lockfile if necessary. * @param callSite caller info * @return true if lock obtained @@ -176,7 +176,7 @@ static boolean tryObtainControllerLock(String callSite) { + " controllerLockCount=" +controllerLockCount, e); //$NON-NLS-1$ } } - return controllerLockEntered; + return controllerLockEntered; } } @@ -203,7 +203,7 @@ public static void releaseControllerLock(String callSite) { * @param callSite caller info * @throws IOException if file already locked */ - + public static void obtainAttachLock(String callSite) throws IOException { getAttachLock().lockFile(true, callSite + "_obtainAttachLock", IPC.useFileLockWatchdog); //$NON-NLS-1$ } @@ -233,7 +233,7 @@ static void createNotificationFile() throws IOException { } /** - * @param obtainLock + * @param obtainLock * @return name of semaphore * @throws IOException if mkdir fails * Caller is responsible for ensuring that the controller lockfile is held. @@ -249,14 +249,14 @@ static String openSemaphore() throws IOException { } /** - * close the semaphore and reopen it. + * close the semaphore and reopen it. * @return 0 if success */ static int reopenSemaphore() { int status = 0; IPC.logMessage("reopenSemaphore"); //$NON-NLS-1$ closeSemaphore(); - status = IPC.openSemaphore(getCommonDirFileObject().getAbsolutePath(), CONTROLLER_NOTIFIER, true); + status = IPC.openSemaphore(getCommonDirFileObject().getAbsolutePath(), CONTROLLER_NOTIFIER, true); return status; } @@ -339,7 +339,7 @@ public static int countTargetDirectories () { } static private boolean isCommonControlFile(String dirMemberName) { - return (ATTACH_LOCK.equalsIgnoreCase(dirMemberName) || CONTROLLER_LOCKFILE.equalsIgnoreCase(dirMemberName) + return (ATTACH_LOCK.equalsIgnoreCase(dirMemberName) || CONTROLLER_LOCKFILE.equalsIgnoreCase(dirMemberName) || CONTROLLER_NOTIFIER.equalsIgnoreCase(dirMemberName)); } @@ -379,15 +379,15 @@ static void deleteStaleDirectories(String myId) { if (!dirMember.delete()) { IPC.logMessage("error deleting ", dirMemberName); //$NON-NLS-1$ } - } + } } else { /* the member is a directory */ if (dirMemberName.equalsIgnoreCase(myId)) { continue; /* Jazz 26865: no need to check myself */ - } + } long pid; if (Character.isDigit(dirMemberName.charAt(0))) { - /* - * directory name is probably numeric. Doing a quick test and catching the exception + /* + * directory name is probably numeric. Doing a quick test and catching the exception * is faster than doing a full regex match. */ try { @@ -395,7 +395,7 @@ static void deleteStaleDirectories(String myId) { pid = Long.parseLong(dirMemberName); uid = CommonDirectory.getFileOwner(dirMember.getAbsolutePath()); if (((0 != myUid) && (uid != myUid))) { - /* + /* * If I am not running as root and the target is owned by another UID, then ignore the file. */ pid = 0; @@ -403,7 +403,7 @@ static void deleteStaleDirectories(String myId) { } catch (NumberFormatException e) { pid = getPidFromFile(dirMember, myUid); } - } else { + } else { pid = getPidFromFile(dirMember, myUid); } if ((0 != pid) /* the PID is valid and directory is owned by me or I am root */ @@ -418,15 +418,15 @@ static void deleteStaleDirectories(String myId) { /** * Check if the file is owned by the UID. Note that UID 0 "owns" all files. * @param f File or directory - * @param myUid user UID. + * @param myUid user UID. * @return true if the uid owns the file or uid == 0. */ public static boolean isFileOwnedByUid(File f, long myUid) { return (0 == myUid) || (myUid == CommonDirectory.getFileOwner(f.getAbsolutePath())); } - + /** - * reads the process ID from the advertisement file. + * reads the process ID from the advertisement file. * Returns 0 (illegal PID) if the advertisement file does not exist * or the process is not owned by the current user. * @param dirMember directory which should hold an advertisement file @@ -459,7 +459,7 @@ private static long getPidFromFile(File dirMember, long myUid) { IPC.logMessage("getPidFromFile uid = ", (int) uid); //$NON-NLS-1$ } if (((0 != myUid) && (uid != myUid))) { - /* + /* * If I am not running as root and the target is owned by another UID, then ignore the file. */ pid = 0; @@ -476,7 +476,7 @@ private static FileLock getAttachLock() { } return attachLock; } - + /** * Returns a FileLock object, creating it if necessary. * @return FileLock object @@ -490,14 +490,14 @@ private static FileLock getControllerLock() { } return controllerLock; } - + /** * Get the UID of a file's owner * @param path file path * @return UID of file owner */ public static native long getFileOwner(String path); - + static final class DirectorySampler implements FileFilter { private int acceptCount = 16; diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/DiagnosticUtils.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/DiagnosticUtils.java index c18e0c4678a..e29957f39f3 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/DiagnosticUtils.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/DiagnosticUtils.java @@ -510,7 +510,7 @@ private static DiagnosticProperties doCheckpointJVM(String diagnosticCommand) { commandTable.put(DIAGNOSTICS_DUMP_SYSTEM, DiagnosticUtils::doDump); helpTable.put(DIAGNOSTICS_DUMP_SYSTEM, DIAGNOSTICS_DUMP_SYSTEM_HELP); - + commandTable.put(DIAGNOSTICS_STAT_CLASS, DiagnosticUtils::getJstatClass); helpTable.put(DIAGNOSTICS_STAT_CLASS, DIAGNOSTICS_JSTAT_CLASS_HELP); diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/FileLock.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/FileLock.java index e3d5b58496e..20c19bdccaf 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/FileLock.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/FileLock.java @@ -70,17 +70,17 @@ public boolean lockFile(boolean blocking, String callSite, boolean useWatchdog) String lockFileMsg = (blocking ? "locking file " : "non-blocking locking file ") //$NON-NLS-1$//$NON-NLS-2$ + (useWatchdog ? "using watchdog" : "NOT using watchdog"); //$NON-NLS-1$//$NON-NLS-2$ IPC.logMessage(callSite + " : " + lockFileMsg, lockFilepath); //$NON-NLS-1$ - + final int FILE_LOCK_TIMEOUT = 20 * 1000; /* time in milliseconds */ if (locked) { /*[MSG "K0574", "file already locked"]*/ throw new IOException(com.ibm.oti.util.Msg.getString("K0574")); //$NON-NLS-1$ } - + /* lock will usually be uncontended, so don't start a watchdog unless necessary */ fileDescriptor = lockFileImpl(lockFilepath, fileMode, false); locked = (0 <= fileDescriptor); /* negative values indicate error, non-negative values (including 0) are valid FDs */ - + if (!locked && blocking) { /* try again, this time with a blocking lock and a timeout */ FileLockWatchdogTask wdog = null; IPC.logMessage("lock failed, trying blocking lock, fileDescriptor = " + fileDescriptor); //$NON-NLS-1$ @@ -107,7 +107,7 @@ public boolean lockFile(boolean blocking, String callSite, boolean useWatchdog) } } } - + /*[PR 199171] native file locking is not interruptible from Java */ try { IPC.logMessage("FileLock.lockFile() before RandomAccessFile creation"); //$NON-NLS-1$ @@ -193,7 +193,7 @@ static void shutDown() { private static native long lockFileImpl(String filePath, int mode, boolean blocking); private static native int unlockFileImpl(long fileDesc); - + final class FileLockWatchdogTask extends TimerTask { @Override /** @@ -212,7 +212,7 @@ public void run() { /* retry once. If it fails more than once, it's a systemic problem */ } /* unlocks the file if this process, and closes the file descriptor to break the wait */ - unlockFile("FileLock.FileLockWatchdogTask"); //$NON-NLS-1$ + unlockFile("FileLock.FileLockWatchdogTask"); //$NON-NLS-1$ /* delete the file if it's there */ if (!theFile.delete()) { IPC.logMessage("waitAndCheckLock could not delete ", theFile.getAbsolutePath()); //$NON-NLS-1$ diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/FilelockTimer.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/FilelockTimer.java index 2cbe16e0824..eeec3e08a8c 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/FilelockTimer.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/FilelockTimer.java @@ -28,7 +28,6 @@ import java.security.PrivilegedAction; import java.util.Timer; - /** * Allows us to ensure the timer thread is dead, * @@ -68,7 +67,7 @@ public void cancel() { try { Thread timerThread = (Thread) timerThreadField.get(this); if (null != timerThread) { - timerThread.join(10000); /* timeout in ms*/ + timerThread.join(10000); /* timeout in ms*/ } } catch (Exception e) { IPC.logMessage("Exception in FilelockTimer.cancel: ", e.getClass().getName()+":"+e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ @@ -76,4 +75,3 @@ public void cancel() { } } } - diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/IbmAttachOperationFailedException.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/IbmAttachOperationFailedException.java index aaee6915f1b..8f168a117d1 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/IbmAttachOperationFailedException.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/IbmAttachOperationFailedException.java @@ -29,19 +29,18 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 */ - public class IbmAttachOperationFailedException extends IOException { /** - * Constructs a new instance of this class with its + * Constructs a new instance of this class with its * walkback filled in. */ public IbmAttachOperationFailedException() { super("IbmAttachOperationFailedException"); //$NON-NLS-1$ } - + /** - * Constructs a new instance of this class with its + * Constructs a new instance of this class with its * walkback and message filled in. * @param message * details of exception @@ -70,5 +69,5 @@ public String toString() { } return result; } - + } diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/Reply.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/Reply.java index e6697ea8f61..56b73be4d8e 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/Reply.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/Reply.java @@ -62,7 +62,7 @@ public Reply(Integer thePort, String theKey, String targetDirectory, long theUid */ Reply(String notificationDirectory) { targetUid = 0; - replyFile = new File(notificationDirectory, REPLY_FILENAME); + replyFile = new File(notificationDirectory, REPLY_FILENAME); } /** @@ -121,7 +121,7 @@ static Reply readReply(String path) throws IOException { } return rply; } - + private boolean fileDoesNotExist() { return !replyFile.exists(); } @@ -137,7 +137,7 @@ synchronized int getPortNumber() { */ synchronized String getKey() { return key; - } + } /** * Delete the reply file */ diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/TargetDirectory.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/TargetDirectory.java index e69bfbe203b..959abd78675 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/TargetDirectory.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/TargetDirectory.java @@ -33,22 +33,22 @@ public final class TargetDirectory { private static final int VARIANT_LIMIT = 100; - /* + /* * allow owner or group to create, read directories, but only owner can delete. - * Need to allow other processes to lock the sync file. + * Need to allow other processes to lock the sync file. */ static final int ADVERTISEMENT_FILE_PERMISSIONS = 0600; static final String ATTACH_NOTIFICATION_SYNC_FILENAME = "attachNotificationSync"; //$NON-NLS-1$ /** * All users must have write access in order to get an exclusive (i.e write) lock on the file. */ - public static final int SYNC_FILE_PERMISSIONS = 0666; + public static final int SYNC_FILE_PERMISSIONS = 0666; static final int TARGET_DIRECTORY_PERMISSIONS = 01711; private volatile static File targetDirectoryFileObject; private volatile static File syncFileObject; private volatile static File advertisementFileObject; - + /** * Create the directory and files specific to this VM. * @param myVmId proposed ID of this VM @@ -127,9 +127,9 @@ static String createMyDirectory(String myVmId, boolean preserveId) throws IOExce } return newId; } - + /** - * Remove this VM's target files + * Remove this VM's target files * @return true if the files were successfully deleted */ static boolean deleteMyFiles() { @@ -139,7 +139,7 @@ static boolean deleteMyFiles() { if ((null != advertisementFileObject) && advertisementFileObject.delete()) { IPC.logMessage("deleted ", advertisementFileObject.getAbsolutePath()); //$NON-NLS-1$ - advertisementFileObject = null; + advertisementFileObject = null; } else { return false; } @@ -222,7 +222,7 @@ public static void deleteTargetDirectory(String vmId) { IPC.logMessage("skip deleteTargetDirectory since the vmid was never set - we didn't create the directory"); //$NON-NLS-1$ } } - + /** * Recreate this VM's target directory if it was accidentally deleted. * @param myVmId ID of this VM @@ -230,11 +230,11 @@ public static void deleteTargetDirectory(String vmId) { */ static boolean ensureMyAdvertisementExists(String myVmId) { if (!AttachHandler.isAttachApiInitialized()) { - /* - * either initialization is in progress and sync file will be created, - * or initialization failed or was terminated so we cannot create the file + /* + * either initialization is in progress and sync file will be created, + * or initialization failed or was terminated so we cannot create the file */ - IPC.logMessage("ensureTargetDirectoryExists: attach API not initialized"); //$NON-NLS-1$ + IPC.logMessage("ensureTargetDirectoryExists: attach API not initialized"); //$NON-NLS-1$ return false; } if (!advertisementFileObject.exists()) { /* either the file or the enclosing directory is missing */ @@ -248,12 +248,12 @@ static boolean ensureMyAdvertisementExists(String myVmId) { Advertisement.createAdvertisementFile(myVmId, AttachHandler.getMainHandler().getDisplayName()); } catch (IOException e) { IPC.logMessage("ensureTargetDirectoryExists: IOException creating advertisement file"); //$NON-NLS-1$ - return false; + return false; } } return true; } - + /** * create a lock file for this VM * @throws IOException if the file cannot be created @@ -270,11 +270,11 @@ static void createMySyncFile() throws IOException { } /* always do the chmod in case the file got changed accidentally */ IPC.chmod(syncFileCopy.getAbsolutePath(), TargetDirectory.SYNC_FILE_PERMISSIONS); - /* AttachHandler.terminate() will delete this file on shutdown */ + /* AttachHandler.terminate() will delete this file on shutdown */ } } } - + /** * Create the File object for this VM's sync file * @param targetVmId ID of the VM @@ -288,7 +288,7 @@ public static File createSyncFileObject(String targetVmId) { File syncFile=new File(tdp,ATTACH_NOTIFICATION_SYNC_FILENAME); return syncFile; } - + /** * Get the path to the target directory for a given VMID * @param vmId machine-friendly name of the VM @@ -305,7 +305,7 @@ public static String getTargetDirectoryPath(String vmId) { /** * Get the File object for this VM's target directory. - * @return File object + * @return File object */ static File getTargetDirectoryFileObject() { return targetDirectoryFileObject; @@ -317,10 +317,10 @@ static File getTargetDirectoryFileObject() { static File getSyncFileObject() { return syncFileObject; } - + /** * Get the File object for this VM's advertisement file. - * @return File object + * @return File object */ static File getAdvertisementFileObject() { return advertisementFileObject; diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/WaitLoop.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/WaitLoop.java index 388764576e2..08699b482e2 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/WaitLoop.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/WaitLoop.java @@ -62,7 +62,7 @@ private Attachment waitForNotification(boolean retry) throws IOException { if (LOGGING_DISABLED != loggingStatus) { IPC.logMessage("iteration ", AttachHandler.notificationCount, " waitForNotification starting wait"); //$NON-NLS-1$ //$NON-NLS-2$ } - + int status = CommonDirectory.SEMAPHORE_OKAY; if (AttachHandler.startWaitingForSemaphore()) { /* check if we are shutting down */ status = CommonDirectory.waitSemaphore(AttachHandler.vmId); @@ -74,7 +74,7 @@ private Attachment waitForNotification(boolean retry) throws IOException { if (AttachHandler.isAttachApiTerminated()) { /* - * Now that I have woken up, eat the remaining posts to the semaphore + * Now that I have woken up, eat the remaining posts to the semaphore * to avoid waking other processes. */ if (AttachHandler.getDoCancelNotify()) { @@ -84,7 +84,7 @@ private Attachment waitForNotification(boolean retry) throws IOException { CommonDirectory.cancelNotify(AttachHandler.getNumberOfTargets(), true); } return null; - } + } if (status != CommonDirectory.SEMAPHORE_OKAY) { if (retry) { @@ -93,15 +93,15 @@ private Attachment waitForNotification(boolean retry) throws IOException { if (!AttachHandler.isAttachApiTerminated()) { try { /*[PR 164751 avoid scanning the directory when an attach API is launching ]*/ - CommonDirectory.obtainControllerLock("WaitLoop.waitForNotification(" + retry + ")_1"); //$NON-NLS-1$ //$NON-NLS-2$ - status = CommonDirectory.reopenSemaphore(); + CommonDirectory.obtainControllerLock("WaitLoop.waitForNotification(" + retry + ")_1"); //$NON-NLS-1$ //$NON-NLS-2$ + status = CommonDirectory.reopenSemaphore(); CommonDirectory.releaseControllerLock("WaitLoop.waitForNotification(" + retry + ")_2"); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (IOException e) { + } catch (IOException e) { IPC.logMessage("waitForNotification: IOError on controller lock : ", e.toString()); //$NON-NLS-1$ } } } - + /*[PR Jazz 41720 - Recreate notification directory if it is deleted. ]*/ if ((CommonDirectory.SEMAPHORE_OKAY == status) && TargetDirectory.ensureMyAdvertisementExists(AttachHandler.getVmId())) { /*[PR 199483] post to the semaphore to test it */ @@ -165,7 +165,7 @@ public void run() { } catch (IOException e) { IPC.logMessage("WaitLoop.waitForNotification exception: AttachHandler.notificationCount = " + AttachHandler.notificationCount, e.toString()); //$NON-NLS-1$ /*[PR CMVC 188652] Suppress OOM output from attach API */ - } catch (OutOfMemoryError e) { + } catch (OutOfMemoryError e) { IPC.tracepoint(IPC.TRACEPOINT_STATUS_OOM_DURING_WAIT, e.getMessage()); try { IPC.logMessage("WaitLoop.waitForNotification OutOfMemoryError before sleep"); //$NON-NLS-1$ @@ -177,6 +177,6 @@ public void run() { } ++AttachHandler.notificationCount; } - AttachHandler.mainHandler.syncFileLock = null; + AttachHandler.mainHandler.syncFileLock = null; } -} \ No newline at end of file +} diff --git a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/package-info.java b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/package-info.java index cc7ad4f934c..2c5cc9c375d 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/package-info.java +++ b/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/package-info.java @@ -23,7 +23,7 @@ /** *

    Implementation of the Attach API for the J9 Java VM.

    - * + * *

    Execution and Protocols

    *

    The key aspects of this interface are:

    *
      @@ -31,14 +31,14 @@ *
    • Notification. The API provides to initiate the attachment process from the attacher (e.g. JConsole) to the target (e.g. and application program). This implements the com.sun.tools.attach.VirtualMachine.attach() method.
    • *
    • Communication. This is a simple mechanism for communicating status and control information. This is typically used to command the loading of libraries and getting information about the target.
    • *
    - * - * + * + * *

    The API is implemented principally in Java as part of the boot classes, with help from port library natives.

    - * + * *

    Discovery

    *
      *
    1. At startup, the target creates an "AttachHandler" thread at boot time during the JCL initialization.
      - * The AttachHandler thread creates an advertisement directory in a well-known location in the file system, by default + * The AttachHandler thread creates an advertisement directory in a well-known location in the file system, by default * /tmp/.com.ibm.tools.attach.targets/<VM ID> (on Microsoft Windows, substitute C:\temp or C:\Documents and Settings\/<user ID>\Local Settings\Tempfor /tmp). The location of the directory is configurable by a command-line argument "com.ibm.tools.attach.directory".
    2. *
    3. AttachHandler opens a semaphore shared among all VMs.
    4. *
    5. AttachHandler creates an advertisement file and a reply file in the in the advertisement directory. The advertisement file is a Java properties file containing: @@ -51,7 +51,7 @@ *
    6. AttachHandler waits on the semaphore
    7. *
    *

    Creation and updating of the advertisement directory occurs under the protection of a common controller lock file.

    - * + * *

    Notification

    *

    The API uses the VM's port library shared semaphore mechanism.

    *
      @@ -65,14 +65,14 @@ *
    * *
  • The target's AttachHandler wakes up and sees if it has a reply file in its advertisement directory. If so, it creates an "attachment " thread
  • - * + * *
  • The target waits until the all other VMs have been woken up (see "Notification protocol" below) and waits again on the semaphore.
  • *
  • The attachment thread reads the socket number from the reply file
  • *
  • The attachment thread opens the socket and writes an acknowledgment to the socket
  • *
  • The attacher's socket read completes. The attach process is now complete.
  • *
  • The attacher deletes the reply file.
  • * - * + * *

    Communication

    *
      *
    1. The attacher sends commands such as loadAgent() by writing text strings to the socket.
    2. @@ -81,7 +81,7 @@ *
    3. The attachment thread in the target reads the detach command, closes the socket, and terminates. *
    *

    Shutdown

    - * + * *

    On shutdown, the attachHandler:

    *
      * @@ -92,11 +92,11 @@ *
    *

    The target and attacher can have multiple concurrent attachments in progress.

    *

    Security

    - *

    The advertisement directory and contained files have Unix owner read permissions and owner write permissions. + *

    The advertisement directory and contained files have Unix owner read permissions and owner write permissions. * On Windows, the directory and files are read-only permissions except when the attacher is writing the port number.
    * The attacher writes a "key" pass string to the reply file. The target must echo this string when acknowledging the attachment.

    *

    File system artifacts

    - *

    Attach API uses semaphore, files, and file locks to advertise, synchronize and communicate amongst VMs. + *

    Attach API uses semaphore, files, and file locks to advertise, synchronize and communicate amongst VMs. * File system permissions to provide security. *

    Common files

    * The common directory and its files has user, group, and world full permissions, but the sticky bit prevents interference between userids.

    @@ -113,10 +113,10 @@ * * _notifier(none)Provides inter-process wait/notify semantics * _attachlockFileLockmanagerProvides inter-process wait/notify semantics - * + * *

    Per-target files

    *

    As JVM instances start up they create their own "target" directory using the virtual machine ID, usually the process id (PID) - * as the directory name under protection of the controllerLock. + * as the directory name under protection of the controllerLock. * The target has full owner permissions and execute permissions for group and world.

    *

    Inside the target's directory are the following files:

    * diff --git a/jcl/src/java.base/share/classes/openj9/management/internal/InvalidDumpOptionExceptionBase.java b/jcl/src/java.base/share/classes/openj9/management/internal/InvalidDumpOptionExceptionBase.java index c2f624ebabe..e9dc489191d 100644 --- a/jcl/src/java.base/share/classes/openj9/management/internal/InvalidDumpOptionExceptionBase.java +++ b/jcl/src/java.base/share/classes/openj9/management/internal/InvalidDumpOptionExceptionBase.java @@ -36,5 +36,5 @@ public class InvalidDumpOptionExceptionBase extends Exception { public InvalidDumpOptionExceptionBase(String message) { super(message); } - + } From 61e39d939ad85d0a3f05f57bd7b3eb2c637f6d37 Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 13:39:40 -0400 Subject: [PATCH 02/16] Tidy up whitespace in java.desktop * indent with tabs consistently Signed-off-by: Keith W. Campbell --- .../share/classes/java/beans/ConstructorProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jcl/src/java.desktop/share/classes/java/beans/ConstructorProperties.java b/jcl/src/java.desktop/share/classes/java/beans/ConstructorProperties.java index fb6cb0af32b..2dc4d190f03 100644 --- a/jcl/src/java.desktop/share/classes/java/beans/ConstructorProperties.java +++ b/jcl/src/java.desktop/share/classes/java/beans/ConstructorProperties.java @@ -37,6 +37,6 @@ @Retention(value = RUNTIME) public @interface ConstructorProperties { - public String[] value(); + public String[] value(); } From e055251352a3e948d4370362feb400d5e0752117 Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 13:40:47 -0400 Subject: [PATCH 03/16] Tidy up whitespace in java.logging * indent with tabs consistently Signed-off-by: Keith W. Campbell --- .../java/util/logging/LoggingMXBean.java | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/jcl/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java b/jcl/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java index db72bc71a73..d1a6354216f 100644 --- a/jcl/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java +++ b/jcl/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java @@ -48,65 +48,65 @@ */ public interface LoggingMXBean { - /** - * Returns the string name of the specified {@link Logger}instance's - * current log level. - * - * @param loggerName - * the name of a particular Logger instance - * @return if loggerName resolves to an existing registered - * Logger instance, the log level of that instance. - * Note that if it is the case that the Logger just - * inherits its log level rather than specifying its own, then an - * empty string ("") will be returned. If - * loggerName does not resolve to a registered - * instance of Logger then a null - * value is returned. - */ - public String getLoggerLevel(String loggerName); + /** + * Returns the string name of the specified {@link Logger}instance's + * current log level. + * + * @param loggerName + * the name of a particular Logger instance + * @return if loggerName resolves to an existing registered + * Logger instance, the log level of that instance. + * Note that if it is the case that the Logger just + * inherits its log level rather than specifying its own, then an + * empty string ("") will be returned. If + * loggerName does not resolve to a registered + * instance of Logger then a null + * value is returned. + */ + public String getLoggerLevel(String loggerName); - /** - * Returns a list of the names of all of the currently registered - * Logger instances. - * @return a list of the names of all registered Logger objects. - */ - public List getLoggerNames(); + /** + * Returns a list of the names of all of the currently registered + * Logger instances. + * @return a list of the names of all registered Logger objects. + */ + public List getLoggerNames(); - /** - * Returns the name of the parent {@link Logger}of the specified registered - * Logger,loggerName. - * - * @param loggerName - * the name of a particular Logger instance - * @return if loggerName resolves to an existing registered - * Logger instance, the name of its parent - * Logger. If the Logger is the root - * entry in the Logger hierarchy, then an empty - * string ("") will be returned. If - * loggerName does not resolve to a registered - * instance of Logger then a null - * value is returned. - */ - public String getParentLoggerName(String loggerName); + /** + * Returns the name of the parent {@link Logger}of the specified registered + * Logger,loggerName. + * + * @param loggerName + * the name of a particular Logger instance + * @return if loggerName resolves to an existing registered + * Logger instance, the name of its parent + * Logger. If the Logger is the root + * entry in the Logger hierarchy, then an empty + * string ("") will be returned. If + * loggerName does not resolve to a registered + * instance of Logger then a null + * value is returned. + */ + public String getParentLoggerName(String loggerName); - /** - * Attempts to update the log level of the {@link Logger} with name - * loggerName to levelName. - *

    - * If levelName is null then the Logger - * instance's log level is set to be null with the result that - * it will inherit its log level from its nearest parent which does not have - * a null log level value. - *

    - * @param loggerName the name of a registered Logger - * @param levelName the name of the new log level. May be null, - * in which case loggerName will inherit the log level of its - * closest parent with a non-null log level. - * @throws IllegalArgumentException if there is no Logger - * with the name loggerName. Also may be thrown if - * loggerName is not a known log level name. - * @throws SecurityException if there is a security manager active and - * the caller does not have {@link LoggingPermission} of "control". - */ - public void setLoggerLevel(String loggerName, String levelName); + /** + * Attempts to update the log level of the {@link Logger} with name + * loggerName to levelName. + *

    + * If levelName is null then the Logger + * instance's log level is set to be null with the result that + * it will inherit its log level from its nearest parent which does not have + * a null log level value. + *

    + * @param loggerName the name of a registered Logger + * @param levelName the name of the new log level. May be null, + * in which case loggerName will inherit the log level of its + * closest parent with a non-null log level. + * @throws IllegalArgumentException if there is no Logger + * with the name loggerName. Also may be thrown if + * loggerName is not a known log level name. + * @throws SecurityException if there is a security manager active and + * the caller does not have {@link LoggingPermission} of "control". + */ + public void setLoggerLevel(String loggerName, String levelName); } From c6ae2d9cf76bbd5c07632441eccfed7c2e7bc27a Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 13:42:19 -0400 Subject: [PATCH 04/16] Tidy up whitespace in java.base * remove trailing whitespace * collapse sequences of two or more blank lines Signed-off-by: Keith W. Campbell --- .../lang/management/internal/ManagementAccessControl.java | 7 +++---- .../management/internal/ManagementPermissionHelper.java | 2 +- .../java/lang/management/internal/ThreadInfoAccess.java | 8 ++++---- .../ibm/java/lang/management/internal/ThreadInfoUtil.java | 1 - .../share/classes/java/lang/management/ThreadInfo.java | 1 - 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ManagementAccessControl.java b/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ManagementAccessControl.java index d6c71be98f3..b747e8552b7 100644 --- a/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ManagementAccessControl.java +++ b/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ManagementAccessControl.java @@ -29,10 +29,9 @@ * package private methods in the java.management module. */ public class ManagementAccessControl { - - + private static ThreadInfoAccess threadInfoAccess; - + /** * Sets the access object for ThreadInfo. This should only be called once. */ @@ -45,7 +44,7 @@ public static void setThreadInfoAccess(ThreadInfoAccess access) { } /** - * Gets the access object for ThreadInfo. + * Gets the access object for ThreadInfo. */ public static ThreadInfoAccess getThreadInfoAccess() { return threadInfoAccess; diff --git a/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ManagementPermissionHelper.java b/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ManagementPermissionHelper.java index f546bf6d5e9..04d210fb938 100644 --- a/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ManagementPermissionHelper.java +++ b/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ManagementPermissionHelper.java @@ -26,7 +26,7 @@ /* * (non-Javadoc) - * + * * Helper class only loaded when the security manager is enabled via following code snippet * SecurityManager security = System.getSecurityManager(); * if (security != null) { diff --git a/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ThreadInfoAccess.java b/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ThreadInfoAccess.java index 716665ada00..fcda73ab280 100644 --- a/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ThreadInfoAccess.java +++ b/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ThreadInfoAccess.java @@ -29,15 +29,15 @@ * from outside the java.lang.management package. */ public interface ThreadInfoAccess { - + /** * Returns the native thread ID for a given ThreadInfo object. Currently * used to give access to ExtendedThreadInfoImpl without opening * java.management for reflection. - * - * @param threadinfo Object containing information about a snapshot of + * + * @param threadinfo Object containing information about a snapshot of * the state of a thread. - * + * * @return @{long} representing the native thread ID */ public long getNativeTId(ThreadInfo threadinfo); diff --git a/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ThreadInfoUtil.java b/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ThreadInfoUtil.java index 0c5c0d5db16..7ddaa9ca036 100644 --- a/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ThreadInfoUtil.java +++ b/jcl/src/java.management/share/classes/com/ibm/java/lang/management/internal/ThreadInfoUtil.java @@ -163,7 +163,6 @@ public static CompositeData toCompositeData(ThreadInfo info) { return result; } - private ThreadInfoUtil() { super(); } diff --git a/jcl/src/java.management/share/classes/java/lang/management/ThreadInfo.java b/jcl/src/java.management/share/classes/java/lang/management/ThreadInfo.java index a23a6b58c47..c06cedf4608 100644 --- a/jcl/src/java.management/share/classes/java/lang/management/ThreadInfo.java +++ b/jcl/src/java.management/share/classes/java/lang/management/ThreadInfo.java @@ -58,7 +58,6 @@ public class ThreadInfo { private final ThreadInfoBase baseInfo; private static final LockInfo[] EMPTY_LOCKINFO_ARRAY = new LockInfo[0]; - /** * Used by from(). * @param threadIdVal From 8d7f958efa84f391177d273159cf6a82ecde56a4 Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 13:44:39 -0400 Subject: [PATCH 05/16] Tidy up whitespace in jdk.attach * remove trailing whitespace * collapse sequences of two or more blank lines Signed-off-by: Keith W. Campbell --- .../attach/attacher/OpenJ9AttachProvider.java | 14 +++---- .../attach/attacher/OpenJ9VirtualMachine.java | 41 +++++++++---------- .../OpenJ9VirtualMachineDescriptor.java | 11 +++-- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9AttachProvider.java b/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9AttachProvider.java index 955f62439ee..5e94d4d40bf 100644 --- a/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9AttachProvider.java +++ b/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9AttachProvider.java @@ -43,7 +43,7 @@ /** * Concrete subclass of the class that lists the available target VMs - * + * */ /*[IF JAVA_SPEC_VERSION >= 17]*/ @SuppressWarnings("removal") @@ -68,12 +68,12 @@ public OpenJ9VirtualMachine attachVirtualMachine(String id) vm.attachTarget(); return vm; } catch (NullPointerException e) { - /* constructor throws an NPE if the ID or name is not set. + /* constructor throws an NPE if the ID or name is not set. Turn this into an exception the application is expecting */ /*[MSG "K0554", "Virtual machine ID or display name is null"]*/ AttachNotSupportedException exc = new AttachNotSupportedException(com.ibm.oti.util.Msg.getString("K0554")); //$NON-NLS-1$ exc.initCause(e); - throw exc; + throw exc; } } @@ -134,10 +134,10 @@ private List listVirtualMachinesImp() { /*[PR 164751 avoid scanning the directory when an attach API is launching ]*/ CommonDirectory.obtainControllerLock("OpenJ9AttachProvider.listVirtualMachinesImp"); //$NON-NLS-1$ } catch (IOException e) { /*[PR 164751 avoid scanning the directory when an attach API is launching ]*/ - /* + /* * IOException is thrown if we already have the lock. The only other cases where we lock this file are during startup and shutdown. - * The attach API startup is complete, thanks to waitForAttachApiInitialization() and threads using this method terminate before shutdown. - */ + * The attach API startup is complete, thanks to waitForAttachApiInitialization() and threads using this method terminate before shutdown. + */ IPC.logMessage("listVirtualMachines() IOError on controller lock : ", e.toString()); //$NON-NLS-1$ return descriptors; /* An error has occurred. Since the attach API is not working correctly, be conservative and don't list and targets */ } @@ -172,7 +172,7 @@ private List listVirtualMachinesImp() { } /*[PR Jazz 30110 advertisement is from an older version or is corrupt. get the owner via file stat ]*/ if ((myUid != 0) && (0 == uid)) { - /* + /* * If this process's UID is 0, then it is root and should ignore file ownership and clean up everyone's files. * If getFileOwner fails, the uid will appear to be -1, and non-root users will ignore it. * CommonDirectory.deleteStaleDirectories() will handle the case of a target directory which does not have an advertisement directory. diff --git a/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9VirtualMachine.java b/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9VirtualMachine.java index eb9d3d03550..e6d1ddefbe0 100644 --- a/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9VirtualMachine.java +++ b/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9VirtualMachine.java @@ -63,26 +63,26 @@ /** * Handles the initiator end of an attachment to a target VM - * + * */ /*[IF JAVA_SPEC_VERSION >= 17]*/ @SuppressWarnings("removal") /*[ENDIF] JAVA_SPEC_VERSION >= 17 */ public final class OpenJ9VirtualMachine extends VirtualMachine implements Response { - /* - * The expected string is "ATTACH_CONNECTED <32 bit hexadecimal key>". + /* + * The expected string is "ATTACH_CONNECTED <32 bit hexadecimal key>". * If the target replies with an error, we may expect a longer string. * Allow enough for ~100 40-character lines. */ private static final int ATTACH_CONNECTED_MESSAGE_LENGTH_LIMIT = 4000; - /* The units for timeouts are milliseconds, Set to 0 for no timeout. */ + /* The units for timeouts are milliseconds, Set to 0 for no timeout. */ private static final int DEFAULT_ATTACH_TIMEOUT = 120000; /* should be ~2* the TCP timeout, i.e. /proc/sys/net/ipv4/tcp_fin_timeout on Linux */ private static final int DEFAULT_COMMAND_TIMEOUT = 0; private static int MAXIMUM_ATTACH_TIMEOUT; private static int COMMAND_TIMEOUT; - + private static final String INSTRUMENT_LIBRARY = "instrument"; //$NON-NLS-1$ private OutputStream commandStream; private final OpenJ9VirtualMachineDescriptor descriptor; @@ -94,7 +94,7 @@ public final class OpenJ9VirtualMachine extends VirtualMachine implements Respon private FileLock[] targetLocks; private ServerSocket targetServer; private Socket targetSocket; - + static { PrivilegedAction action = () -> { MAXIMUM_ATTACH_TIMEOUT = Integer.getInteger("com.ibm.tools.attach.timeout", DEFAULT_ATTACH_TIMEOUT).intValue(); //$NON-NLS-1$ @@ -313,7 +313,7 @@ public synchronized void loadAgentPath(String agentPath, String options) /** * Execute a diagnostic command on a target VM. - * + * * @param diagnosticCommand name of command to execute * @return properties object containing serialized result * @throws IOException in case of a communication error @@ -365,7 +365,7 @@ private void lockAllAttachNotificationSyncFiles( private static boolean parseResponse(String response) throws IOException, AgentInitializationException, AgentLoadException, IllegalArgumentException - , AttachOperationFailedException + , AttachOperationFailedException { if (response.startsWith(ERROR)) { int responseLength = response.indexOf('\0'); @@ -408,7 +408,7 @@ private static boolean parseResponse(String response) throws IOException, /** * parse the status value from the end of the response string: this will be a * numeric string at the end of the string. - * + * * @param response * @return Integer value of status, or null if the string does not end in a * number @@ -428,7 +428,6 @@ private static Integer getStatusValue(String response) { return ret; } - private void tryAttachTarget(int timeout) throws IOException, AttachNotSupportedException { Reply replyFile = null; @@ -510,9 +509,9 @@ private void tryAttachTarget(int timeout) throws IOException, commandStream = targetSocket.getOutputStream(); targetSocket.setSoTimeout(COMMAND_TIMEOUT); responseStream = targetSocket.getInputStream(); - - /* - * Limit data until the target is verified. + + /* + * Limit data until the target is verified. */ String response = AttachmentConnection.streamReceiveString(responseStream, ATTACH_CONNECTED_MESSAGE_LENGTH_LIMIT); /*[MSG "K0533", "key error: {0}"]*/ @@ -572,7 +571,7 @@ public void startManagementAgent(Properties agentProperties) throw new NullPointerException(); } AttachmentConnection.streamSend(commandStream, Command.START_MANAGEMENT_AGENT); - IPC.sendProperties(agentProperties, commandStream); + IPC.sendProperties(agentProperties, commandStream); String response = AttachmentConnection.streamReceiveString(responseStream); try { parseResponse(response); @@ -614,11 +613,11 @@ public String startLocalManagementAgent() throws IOException { return result; } - + /** * Generate a text description of a target JVM's heap, including the number and * sizes of instances of each class. - * + * * @param opts * String options: "-live" for live object only, or "-all" for all * objects. Default is "live". @@ -670,23 +669,23 @@ private InputStream heapHistoImpl(Object... opts) { } /** - * + * * @note Public API, signature compatible with * com.sun.tools.attach.spi.AttachProvider. */ @Override public boolean equals(Object comparand) { - + if (!(comparand instanceof VirtualMachine)) { return false; } - + VirtualMachine otherVM = (VirtualMachine) comparand; return id().equals(otherVM.id()); } /** - * + * * @note Public API, signature compatible with * com.sun.tools.attach.spi.AttachProvider. */ @@ -696,7 +695,7 @@ public int hashCode() { } /** - * + * * @note Public API, signature compatible with * com.sun.tools.attach.spi.AttachProvider. */ diff --git a/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9VirtualMachineDescriptor.java b/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9VirtualMachineDescriptor.java index fb64293b5b7..81252b4e55d 100644 --- a/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9VirtualMachineDescriptor.java +++ b/jcl/src/jdk.attach/share/classes/com/ibm/tools/attach/attacher/OpenJ9VirtualMachineDescriptor.java @@ -67,7 +67,7 @@ public int hashCode() { OpenJ9VirtualMachineDescriptor(AttachProvider provider, String id, String displayName) { super(provider, id, displayName); - attachSyncFileValue = null; + attachSyncFileValue = null; replyFile = null; processId = 0; uid = 0; @@ -80,7 +80,7 @@ public int hashCode() { */ OpenJ9VirtualMachineDescriptor(AttachProvider provider, String id) { super(provider, id); - attachSyncFileValue = null; + attachSyncFileValue = null; replyFile = null; processId = 0; uid = 0; @@ -95,7 +95,7 @@ public int hashCode() { OpenJ9VirtualMachineDescriptor(AttachProvider provider, Advertisement advert) { super(provider, advert.getVmId(), advert.getDisplayName()); - replyFile = advert.getReplyFile(); + replyFile = advert.getReplyFile(); attachSyncFileValue = advert.getNotificationSync(); processId = advert.getProcessId(); uid = advert.getUid(); @@ -104,7 +104,7 @@ public int hashCode() { } /** - * + * * @return Operating system process ID for the target VM. */ long getProcessId() { @@ -112,7 +112,7 @@ long getProcessId() { } /** - * + * * @return true if the target uses the global semaphore (Windows only) */ public boolean isGlobalSemaphore() { @@ -160,6 +160,5 @@ String getAttachSyncFileValue() { long getUid() { return uid; } - } From 01e4fcf60ead87cfdddf39bac38bebda6f942116 Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 13:47:07 -0400 Subject: [PATCH 06/16] Tidy up whitespace in jdk.jcmd * remove trailing whitespace * remove extra trailing blank lines Signed-off-by: Keith W. Campbell --- .../attacher/AttacherDiagnosticsProvider.java | 11 +++++------ .../openj9/tools/attach/diagnostics/tools/Jcmd.java | 4 ++-- .../openj9/tools/attach/diagnostics/tools/Jmap.java | 4 ++-- .../openj9/tools/attach/diagnostics/tools/Jps.java | 6 +++--- .../openj9/tools/attach/diagnostics/tools/Jstack.java | 1 - .../openj9/tools/attach/diagnostics/tools/Jstat.java | 2 +- .../openj9/tools/attach/diagnostics/tools/Util.java | 6 +++--- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/attacher/AttacherDiagnosticsProvider.java b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/attacher/AttacherDiagnosticsProvider.java index ff7dc88b8a8..4d211e5e82d 100644 --- a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/attacher/AttacherDiagnosticsProvider.java +++ b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/attacher/AttacherDiagnosticsProvider.java @@ -43,10 +43,9 @@ public class AttacherDiagnosticsProvider { private OpenJ9VirtualMachine vm; - /** * Request thread information, including stack traces, from a target VM. - * + * * @param diagnosticCommand name of command to execute * @return properties object containing serialized thread information * @throws IOException in case of a communication error @@ -62,7 +61,7 @@ public Properties executeDiagnosticCommand(String diagnosticCommand) throws IOEx /** * Call equivalent com.sun.tools.attach.VirtualMachine method. - * + * * @param vmid ID of target * @throws IOException on communication error */ @@ -80,7 +79,7 @@ public void attach(String vmid) throws IOException { /** * Call equivalent com.sun.tools.attach.VirtualMachine method. - * + * * @throws IOException on communication error */ public void detach() throws IOException { @@ -92,7 +91,7 @@ public void detach() throws IOException { /** * Call equivalent com.sun.tools.attach.VirtualMachine method. - * + * * @return properties from target VM * @throws IOException on communication error */ @@ -103,7 +102,7 @@ public Properties getSystemProperties() throws IOException { /** * Call equivalent com.sun.tools.attach.VirtualMachine method. - * + * * @return properties from target VM * @throws IOException on communication error */ diff --git a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jcmd.java b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jcmd.java index f3620fad555..fee0300bc49 100644 --- a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jcmd.java +++ b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jcmd.java @@ -43,7 +43,7 @@ public class Jcmd { @SuppressWarnings("nls") private static final String HELPTEXT = "Usage : jcmd %n" + "%n" - + " -J : supply arguments to the Java VM running jcmd%n" + + " -J : supply arguments to the Java VM running jcmd%n" + " -l : list JVM processes on the local machine%n" + " -h : print this help message%n" + "%n" @@ -51,7 +51,7 @@ public class Jcmd { + " : this argument is used to match (either fully or partially) the display name as shown in jcmd or other Attach API-based tools%n" + " <0> : the jcmd command will be sent to all Java processes detected by this utility%n" + "%n" - + " arguments:%n" + + " arguments:%n" + " help : print the list of diagnostic commands%n" + " help : print help for the specific command%n" + " [command arguments] : command from the list returned by \"help\"%n" diff --git a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jmap.java b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jmap.java index b23ef8fac47..824c8ccdbb3 100644 --- a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jmap.java +++ b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jmap.java @@ -56,7 +56,7 @@ public class Jmap { /** * Print a list of Java processes and information about them. - * + * * @param args Arguments to the application */ public static void main(String[] args) { @@ -143,7 +143,7 @@ private static boolean parseArguments(String[] args) { } else { invalidArg = true; } - + if (invalidArg) { errorMessage = "unrecognized option " + arg; break; diff --git a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jps.java b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jps.java index f5f38caf008..775a55017ce 100644 --- a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jps.java +++ b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jps.java @@ -66,7 +66,7 @@ public static void main(String[] args) { AttachProvider theProvider = null; if (0 != providers.size()) { theProvider = providers.get(0); - } + } if (null == theProvider) { System.err.println("no attach providers available"); //$NON-NLS-1$ rc = 1; @@ -75,7 +75,7 @@ public static void main(String[] args) { for (VirtualMachineDescriptor vmd : vmds) { StringBuilder outputBuffer = new StringBuilder(vmd.id()); if (!vmidOnly) { - Util.getTargetInformation(theProvider, vmd, + Util.getTargetInformation(theProvider, vmd, printJvmArguments, noPackageName, printApplicationArguments, outputBuffer); } System.out.println(outputBuffer.toString()); @@ -83,7 +83,7 @@ public static void main(String[] args) { } System.exit(rc); } - + private static void parseArguments(String[] args) { printApplicationArguments = false; printJvmArguments = false; diff --git a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jstack.java b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jstack.java index 8319f7f8abd..f292cf67db6 100644 --- a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jstack.java +++ b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jstack.java @@ -132,4 +132,3 @@ private static boolean parseArguments(String[] args) { return okay; } } - diff --git a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jstat.java b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jstat.java index 73b797e9c9b..8177b7fcbfb 100644 --- a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jstat.java +++ b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Jstat.java @@ -66,7 +66,7 @@ public class Jstat { /** * Print a list of Java processes and information about them. - * + * * @param args * Arguments to the application */ diff --git a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Util.java b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Util.java index d4ecf22df26..2cfe950c5eb 100644 --- a/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Util.java +++ b/jcl/src/jdk.jcmd/share/classes/openj9/tools/attach/diagnostics/tools/Util.java @@ -162,7 +162,7 @@ static void printProperties(PrintStream out, Properties props) { * Print an error message if it is not null or empty. * Print the help content. * Terminates JVM. - * + * * @param error * an error message to indicate the cause of the error * @param help @@ -175,13 +175,13 @@ static void exitJVMWithReasonAndHelp(String error, String help) { System.out.printf(help); System.exit(1); } - + @SuppressWarnings("nls") private static final String[] HELP_OPTIONS = { "-h", "help", "-help", "--help" }; /** * Check if the option matches one of HELP_OPTIONS - * + * * @param option * the option to be checked * @return true if found a match, otherwise false From b697c56382f787d824482388e0d3d2957e52beac Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 13:48:25 -0400 Subject: [PATCH 07/16] Tidy up whitespace in jdk.jlink * indent with tabs consistently Signed-off-by: Keith W. Campbell --- .../plugins/GenerateJLIClassesPlugin.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/jcl/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java b/jcl/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java index b7d5457541b..87d1ac475cf 100644 --- a/jcl/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java +++ b/jcl/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java @@ -38,25 +38,25 @@ */ public class GenerateJLIClassesPlugin implements Plugin { - /** - * This method makes a copy of the ResourcePool. - * Since this plugin is intended to have no effect, - * it lacks any transformational logic. - * @param rp Pool of resources - * @param rpb Builder to create a copy of the pool of resources. - * @return ResourcePool Built copy of the pool of resources. - */ - public ResourcePool transform(ResourcePool rp, ResourcePoolBuilder rpb){ - return null; - } + /** + * This method makes a copy of the ResourcePool. + * Since this plugin is intended to have no effect, + * it lacks any transformational logic. + * @param rp Pool of resources + * @param rpb Builder to create a copy of the pool of resources. + * @return ResourcePool Built copy of the pool of resources. + */ + public ResourcePool transform(ResourcePool rp, ResourcePoolBuilder rpb){ + return null; + } - /** - * This method tells the caller that this plugin is disabled, - * and should not be used. - * @return Set State of the Plugin. - */ - @Override - public Set getState() { - return EnumSet.of(State.DISABLED, State.FUNCTIONAL); - } + /** + * This method tells the caller that this plugin is disabled, + * and should not be used. + * @return Set State of the Plugin. + */ + @Override + public Set getState() { + return EnumSet.of(State.DISABLED, State.FUNCTIONAL); + } } From d8f65bbaf67f8a32b21fb6109268caf94a2b344d Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 13:57:22 -0400 Subject: [PATCH 08/16] Tidy up whitespace in jdk.management * remove trailing whitespace * indent with tabs consistently Signed-off-by: Keith W. Campbell --- .../AvailableProcessorsNotificationInfo.java | 8 +- .../CpuLoadCalculationConstants.java | 4 +- .../lang/management/ExtendedThreadInfo.java | 2 +- .../management/GarbageCollectorMXBean.java | 70 +-- .../lang/management/JvmCpuMonitorInfo.java | 18 +- .../lang/management/JvmCpuMonitorMXBean.java | 14 +- .../com/ibm/lang/management/MemoryMXBean.java | 418 +++++++++--------- .../ibm/lang/management/MemoryPoolMXBean.java | 26 +- .../com/ibm/lang/management/MemoryUsage.java | 28 +- .../MemoryUsageRetrievalException.java | 8 +- .../ProcessingCapacityNotificationInfo.java | 82 ++-- .../ibm/lang/management/ProcessorUsage.java | 28 +- .../ProcessorUsageRetrievalException.java | 2 +- .../ibm/lang/management/RuntimeMXBean.java | 28 +- .../com/ibm/lang/management/ThreadMXBean.java | 100 ++--- .../TotalPhysicalMemoryNotificationInfo.java | 48 +- .../management/UnixOperatingSystemMXBean.java | 12 +- .../internal/ExtendedRuntimeMXBeanImpl.java | 2 +- .../management/internal/JvmCpuMonitor.java | 12 +- .../internal/JvmCpuMonitorInfoUtil.java | 2 +- .../internal/MemoryNotificationThread.java | 130 +++--- .../OperatingSystemNotificationThread.java | 2 +- .../GuestOSInfoRetrievalException.java | 2 +- .../management/GuestOSMXBean.java | 8 +- .../management/GuestOSMemoryUsage.java | 10 +- .../management/GuestOSProcessorUsage.java | 18 +- .../management/HypervisorMXBean.java | 6 +- .../internal/HypervisorMXBeanImpl.java | 8 +- .../GarbageCollectionNotificationInfo.java | 22 +- ...GarbageCollectionNotificationInfoUtil.java | 2 +- .../sun/management/internal/GcInfoUtil.java | 22 +- .../jdk/crac/management/CRaCMXBean.java | 42 +- .../jdk/crac/management/CRaCMXBeanImpl.java | 82 ++-- .../ConfigurationUnavailableException.java | 2 +- .../management/InvalidOptionException.java | 2 +- .../management/OpenJ9DiagnosticsMXBean.java | 17 +- 36 files changed, 643 insertions(+), 644 deletions(-) diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/AvailableProcessorsNotificationInfo.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/AvailableProcessorsNotificationInfo.java index aff3a34d2a3..fe856cb2680 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/AvailableProcessorsNotificationInfo.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/AvailableProcessorsNotificationInfo.java @@ -44,7 +44,7 @@ public class AvailableProcessorsNotificationInfo { /** * Constructs a new instance of this object. - * + * * @param newAvailableProcessors * the new number of processors available */ @@ -56,7 +56,7 @@ public AvailableProcessorsNotificationInfo(int newAvailableProcessors) { /** * Returns the new number of available processors after the change that * initiated this notification. - * + * * @return the number of available processors */ public int getNewAvailableProcessors() { @@ -68,7 +68,7 @@ public int getNewAvailableProcessors() { * AvailableProcessorsNotificationInfo object and attempts to * return the root AvailableProcessorsNotificationInfo * instance. - * + * * @param cd * a CompositeDate that represents a * AvailableProcessorsNotificationInfo. @@ -94,7 +94,7 @@ public static AvailableProcessorsNotificationInfo from(CompositeData cd) { // following method invocations will exit on an // IllegalArgumentException... ManagementUtils.verifyFieldNumber(cd, 1); - String[] attributeNames = { "newAvailableProcessors" }; //$NON-NLS-1$ + String[] attributeNames = { "newAvailableProcessors" }; //$NON-NLS-1$ ManagementUtils.verifyFieldNames(cd, attributeNames); String[] attributeTypes = { "java.lang.Integer" }; //$NON-NLS-1$ ManagementUtils.verifyFieldTypes(cd, attributeNames, attributeTypes); diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/CpuLoadCalculationConstants.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/CpuLoadCalculationConstants.java index f727286df0c..8bdbffe6d1d 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/CpuLoadCalculationConstants.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/CpuLoadCalculationConstants.java @@ -25,7 +25,7 @@ /** * Constants used by {@link com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuLoad()} and * {@link com.ibm.lang.management.OperatingSystemMXBean#getSystemCpuLoad()} methods. - * + * * @author Sridevi * * @since 1.7.1 @@ -55,7 +55,7 @@ public interface CpuLoadCalculationConstants { /** * The minimum time between successive calls required * to obtain a valid CPU load measurement. - * + * * 10 ms in nanoseconds. */ long MINIMUM_INTERVAL = 10000000; diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ExtendedThreadInfo.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ExtendedThreadInfo.java index 5455a3a07ac..0be2edff980 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ExtendedThreadInfo.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ExtendedThreadInfo.java @@ -25,7 +25,7 @@ import java.lang.management.ThreadInfo; /** - * Class encapsulates a ThreadInfo instance along with the corresponding native thread identification + * Class encapsulates a ThreadInfo instance along with the corresponding native thread identification * information as assigned by the operating system. */ public interface ExtendedThreadInfo { diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/GarbageCollectorMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/GarbageCollectorMXBean.java index d53b72adc10..a578eee6c3c 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/GarbageCollectorMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/GarbageCollectorMXBean.java @@ -32,43 +32,43 @@ public interface GarbageCollectorMXBean extends com.sun.management.GarbageCollectorMXBean { - /** - * Returns the start time in milliseconds of the last garbage - * collection that was carried out by this collector. - * - * @return the start time of the most recent collection - */ - public long getLastCollectionStartTime(); + /** + * Returns the start time in milliseconds of the last garbage + * collection that was carried out by this collector. + * + * @return the start time of the most recent collection + */ + public long getLastCollectionStartTime(); - /** - * Returns the end time in milliseconds of the last garbage - * collection that was carried out by this collector. - * - * @return the end time of the most recent collection - */ - public long getLastCollectionEndTime(); + /** + * Returns the end time in milliseconds of the last garbage + * collection that was carried out by this collector. + * + * @return the end time of the most recent collection + */ + public long getLastCollectionEndTime(); - /** - * Returns the amount of heap memory used by objects that are managed - * by the collector corresponding to this bean object. - * - * @return memory used in bytes - */ - public long getMemoryUsed(); + /** + * Returns the amount of heap memory used by objects that are managed + * by the collector corresponding to this bean object. + * + * @return memory used in bytes + */ + public long getMemoryUsed(); - /** - * Returns the cumulative total amount of memory freed, in bytes, by the - * garbage collector corresponding to this bean object. - * - * @return memory freed in bytes - */ - public long getTotalMemoryFreed(); + /** + * Returns the cumulative total amount of memory freed, in bytes, by the + * garbage collector corresponding to this bean object. + * + * @return memory freed in bytes + */ + public long getTotalMemoryFreed(); - /** - * Returns the cumulative total number of compacts that was performed by - * garbage collector corresponding to this bean object. - * - * @return number of compacts performed - */ - public long getTotalCompacts(); + /** + * Returns the cumulative total number of compacts that was performed by + * garbage collector corresponding to this bean object. + * + * @return number of compacts performed + */ + public long getTotalCompacts(); } diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/JvmCpuMonitorInfo.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/JvmCpuMonitorInfo.java index 416aaec039a..6efcd5d93b4 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/JvmCpuMonitorInfo.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/JvmCpuMonitorInfo.java @@ -56,7 +56,7 @@ public JvmCpuMonitorInfo() { /** * Create a new JvmCpuMonitorInfo instance with the given info. - * + * * @param timestamp * @param applicationCpuTime * @param resourceMonitorCpuTime @@ -93,9 +93,9 @@ public long getTimestamp() { /** * This method returns the total CPU usage for all application threads. - * It includes the threads that are in the "Application" category as well as those in the user defined categories (Application-UserX). + * It includes the threads that are in the "Application" category as well as those in the user defined categories (Application-UserX). * This does not include information about "Resource-monitor" threads. - * + * * @return "Application" category CPU usage time in microseconds. */ public long getApplicationCpuTime() { @@ -104,7 +104,7 @@ public long getApplicationCpuTime() { /** * This method returns the total CPU usage for all threads of the "Resource-Monitor" category. - * "Resource-Monitor" thread is any thread, that the application has designated as a "Resource-Monitor". + * "Resource-Monitor" thread is any thread, that the application has designated as a "Resource-Monitor". * * @return "Resource-Monitor" category CPU usage time in microseconds. */ @@ -159,14 +159,14 @@ public long[] getApplicationUserCpuTime() { /* (non-Javadoc) * Setter method for updating JVM CPU usage parameters for this instance. - * + * * @param tstamp The time stamp when the snapshot was taken in microseconds. * @param appTime Total CPU usage of Application Threads. * @param resourceMonitorTime Total CPU usage of resource monitor Thread(s). * @param sysJvmTime Total CPU usage of System-JVM Threads. * @param gcTime Total CPU usage for GC activity. * @param jitTime Total CPU usage of JIT Threads. - * @param appUserTime[] Array of CPU usage of user defined Application Threads. + * @param appUserTime[] Array of CPU usage of user defined Application Threads. */ void updateValues(long tstamp, long appTime, long rmonTime, long sysTime, long gcTime, long jitTime, long appUserTime[]) { @@ -180,13 +180,13 @@ void updateValues(long tstamp, long appTime, long rmonTime, } /** - * Receives a {@link javax.management.openmbean.CompositeData} representing a + * Receives a {@link javax.management.openmbean.CompositeData} representing a * {@link JvmCpuMonitorInfo} object and attempts to return the root * {@link JvmCpuMonitorInfo} instance. * - * @param cd A {@link javax.management.openmbean.CompositeData} that represents a + * @param cd A {@link javax.management.openmbean.CompositeData} that represents a * {@link JvmCpuMonitorInfo}. - * + * * @return if cd is non- null, returns a new instance of * {@link JvmCpuMonitorInfo}, * If cd is null, returns null. diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/JvmCpuMonitorMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/JvmCpuMonitorMXBean.java index cebac2230ef..5460db7b1b6 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/JvmCpuMonitorMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/JvmCpuMonitorMXBean.java @@ -38,7 +38,7 @@ * "Resource-Monitor" threads are special because they do not participate in idle accounting. * This means that any CPU usage of these threads does not count towards determining the state of the application. *
  • A thread can be part of only one category at any given time but can change categories any number of times during its timeline. - *
  • The usage information is in microseconds and increases monotonically. + *
  • The usage information is in microseconds and increases monotonically. *
  • The CPU usage information consists of the following data: *
      *
    1. Attached threads that are live. @@ -56,7 +56,7 @@ *
    *
  • * - * This information is based on repeatedly checking the CPU usage in the following use case scenarios: + * This information is based on repeatedly checking the CPU usage in the following use case scenarios: *
      *
    1. Monitoring application idle and active behavior. *
    2. Calculating the JVM Overhead over a specific interval. @@ -77,7 +77,7 @@ * if (true != mbeanServer.isRegistered(mxbeanName)) { * // JvmCpuMonitorMXBean not registered * } - * JvmCpuMonitorMXBean jcmBean = JMX.newMXBeanProxy(mbeanServer, mxbeanName, JvmCpuMonitorMXBean.class); + * JvmCpuMonitorMXBean jcmBean = JMX.newMXBeanProxy(mbeanServer, mxbeanName, JvmCpuMonitorMXBean.class); * } catch (Exception e) { * // Exception Handling * } @@ -85,14 +85,14 @@ * */ public interface JvmCpuMonitorMXBean extends PlatformManagedObject { - + /** * This function updates the user provided JvmCpuMonitorInfo object * with CPU usage statistics of the various thread categories. * The statistics are an aggregate across all CPUs of the operating system. * * @param jcmInfo User provided JvmCpuMonitorInfo object. - * + * * @return the updated JvmCpuMonitorInfo instance. * * @throws NullPointerException if a null reference is passed. @@ -105,7 +105,7 @@ public JvmCpuMonitorInfo getThreadsCpuUsage(JvmCpuMonitorInfo jcmInfo) * This function creates a new {@link JvmCpuMonitorInfo} object and populates it * with CPU usage statistics of the various thread categories. * The statistics are an aggregate across all CPUs of the operating system. - * + * * @return the new JvmCpuMonitorInfo instance. * * @throws UnsupportedOperationException if CPU monitoring is disabled. @@ -123,7 +123,7 @@ public JvmCpuMonitorInfo getThreadsCpuUsage() * Some notes on the setting the thread categories *
      1. "Application" threads cannot be changed to any "System-JVM" category. *
      2. Threads in the "System-JVM" category cannot be modified. - *
      3. Once a thread is designated as "Resource-Monitor", it cannot be changed. + *
      4. Once a thread is designated as "Resource-Monitor", it cannot be changed. *
      * @param id The target thread id for which the type needs to be set. * @param category The category of the target thread. diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryMXBean.java index 7871e5abe16..bc28ffbe841 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryMXBean.java @@ -26,7 +26,7 @@ /** * The OpenJ9 extension interface for monitoring the virtual machine's memory * management system. - * + * * @since 1.5 */ public interface MemoryMXBean extends java.lang.management.MemoryMXBean { @@ -35,279 +35,279 @@ public interface MemoryMXBean extends java.lang.management.MemoryMXBean { * Get the maximum size in bytes to which the max heap size could be * increased in the currently running VM. This may be larger than the * current max heap size. - * + * * @return value of -Xmx in bytes */ public long getMaxHeapSizeLimit(); - + /** * Get the current maximum heap size in bytes. - * + * * @return current value of -Xsoftmx in bytes */ public long getMaxHeapSize(); - + /** * Get the minimum heap size in bytes. - * + * * @return value of -Xms in bytes */ public long getMinHeapSize(); - + /** * Set the current maximum heap size to size. * The parameter specifies the max heap size in bytes and must be * between getMinHeapSize() and getMaxHeapSizeLimit(). * See -Xsoftmx in the command line reference for additional - * details on the effect of setting softmx. - * + * details on the effect of setting softmx. + * * @param size new -Xsoftmx value in bytes - * @throws UnsupportedOperationException - * if this operation is not supported. - * @throws IllegalArgumentException - * if input value size is either less than - * getMinHeapSize() or greater than getMaxHeapSizeLimit(). - * @throws SecurityException - * if a {@link SecurityManager} is being used and the caller - * does not have the ManagementPermission value - * of "control". + * @throws UnsupportedOperationException + * if this operation is not supported. + * @throws IllegalArgumentException + * if input value size is either less than + * getMinHeapSize() or greater than getMaxHeapSizeLimit(). + * @throws SecurityException + * if a {@link SecurityManager} is being used and the caller + * does not have the ManagementPermission value + * of "control". */ public void setMaxHeapSize( long size ); - + /** * Query whether the VM supports runtime reconfiguration of the * maximum heap size through the setMaxHeapSize() call. - * + * * @return true if setMaxHeapSize is supported, false otherwise */ public boolean isSetMaxHeapSizeSupported(); - - /** - * Returns the total size in bytes of the cache that the JVM is currently - * connected to. - * - * @return the number of bytes in the shared class cache. - */ - public long getSharedClassCacheSize(); - - /** - * Returns the softmx size in bytes of the cache that the JVM is currently - * connected to. - * - * @return the softmx bytes in the shared class cache or cache size if it is not set. - */ - public long getSharedClassCacheSoftmxBytes(); - - /** - * Returns the minimum space reserved for AOT data of the cache that the JVM is currently - * connected to. - * - * @return the minimum shared classes cache space reserved for AOT data in bytes or -1 if it is not set. - */ - public long getSharedClassCacheMinAotBytes(); - - /** - * Returns the maximum space allowed for AOT data of the cache that the JVM is currently - * connected to. - * - * @return the maximum shared classes cache space allowed for AOT data or -1 if it is not set. - */ - public long getSharedClassCacheMaxAotBytes(); - - /** - * Returns the minimum space reserved for JIT data of the cache that the JVM is currently - * connected to. - * - * @return the minimum shared classes cache space reserved for JIT data or -1 if it is not set. - */ - public long getSharedClassCacheMinJitDataBytes(); - - /** - * Returns the maximum space allowed for JIT data of the cache that the JVM is currently - * connected to. - * - * @return the maximum shared classes cache space allowed for JIT data or -1 if it is not set. - */ - public long getSharedClassCacheMaxJitDataBytes(); - - /** + + /** + * Returns the total size in bytes of the cache that the JVM is currently + * connected to. + * + * @return the number of bytes in the shared class cache. + */ + public long getSharedClassCacheSize(); + + /** + * Returns the softmx size in bytes of the cache that the JVM is currently + * connected to. + * + * @return the softmx bytes in the shared class cache or cache size if it is not set. + */ + public long getSharedClassCacheSoftmxBytes(); + + /** + * Returns the minimum space reserved for AOT data of the cache that the JVM is currently + * connected to. + * + * @return the minimum shared classes cache space reserved for AOT data in bytes or -1 if it is not set. + */ + public long getSharedClassCacheMinAotBytes(); + + /** + * Returns the maximum space allowed for AOT data of the cache that the JVM is currently + * connected to. + * + * @return the maximum shared classes cache space allowed for AOT data or -1 if it is not set. + */ + public long getSharedClassCacheMaxAotBytes(); + + /** + * Returns the minimum space reserved for JIT data of the cache that the JVM is currently + * connected to. + * + * @return the minimum shared classes cache space reserved for JIT data or -1 if it is not set. + */ + public long getSharedClassCacheMinJitDataBytes(); + + /** + * Returns the maximum space allowed for JIT data of the cache that the JVM is currently + * connected to. + * + * @return the maximum shared classes cache space allowed for JIT data or -1 if it is not set. + */ + public long getSharedClassCacheMaxJitDataBytes(); + + /** * Set the shared class softmx size to value. * The parameter specifies the softmx in bytes. * See -Xscmx in the command line reference for additional - * details on the effect of setting shared class softmx. - * + * details on the effect of setting shared class softmx. + * * @param value new shared cache soft max value in bytes * @return whether the requested operation has been completed. - * @throws IllegalArgumentException - * if input value value is less than 0. - * @throws SecurityException - * if a {@link SecurityManager} is being used and the caller - * does not have the ManagementPermission value - * of "control". + * @throws IllegalArgumentException + * if input value value is less than 0. + * @throws SecurityException + * if a {@link SecurityManager} is being used and the caller + * does not have the ManagementPermission value + * of "control". */ - public boolean setSharedClassCacheSoftmxBytes(long value); - - /** + public boolean setSharedClassCacheSoftmxBytes(long value); + + /** * Set the minimum shared classes cache space reserved for AOT data to value bytes. * See -Xscminaot in the command line reference for additional - * details on the effect of setting shared class -Xscminaot. - * + * details on the effect of setting shared class -Xscminaot. + * * @param value new -Xscminaot value in bytes * @return whether the requested operation has been completed. - * @throws IllegalArgumentException - * if input value value is less than 0. - * @throws SecurityException - * if a {@link SecurityManager} is being used and the caller - * does not have the ManagementPermission value - * of "control". + * @throws IllegalArgumentException + * if input value value is less than 0. + * @throws SecurityException + * if a {@link SecurityManager} is being used and the caller + * does not have the ManagementPermission value + * of "control". */ - public boolean setSharedClassCacheMinAotBytes(long value); - - /** + public boolean setSharedClassCacheMinAotBytes(long value); + + /** * Set the maximum shared classes cache space allowed for AOT data to value bytes. * See -Xscmaxaot in the command line reference for additional - * details on the effect of setting shared class -Xscmaxaot. - * + * details on the effect of setting shared class -Xscmaxaot. + * * @param value new -Xscmaxaot value in bytes * @return whether the requested operation has been completed. - * @throws IllegalArgumentException - * if input value value is less than 0. - * @throws SecurityException - * if a {@link SecurityManager} is being used and the caller - * does not have the ManagementPermission value - * of "control". + * @throws IllegalArgumentException + * if input value value is less than 0. + * @throws SecurityException + * if a {@link SecurityManager} is being used and the caller + * does not have the ManagementPermission value + * of "control". */ - public boolean setSharedClassCacheMaxAotBytes(long value); - - /** + public boolean setSharedClassCacheMaxAotBytes(long value); + + /** * Set the minimum shared classes cache space reserved for JIT data to value bytes. * See -Xscminjitdata in the command line reference for additional - * details on the effect of setting shared class -Xscminjitdata. - * + * details on the effect of setting shared class -Xscminjitdata. + * * @param value new -Xscminjitdata value in bytes * @return whether the requested operation has been completed. - * @throws IllegalArgumentException - * if input value value is less than 0. - * @throws SecurityException - * if a {@link SecurityManager} is being used and the caller - * does not have the ManagementPermission value - * of "control". + * @throws IllegalArgumentException + * if input value value is less than 0. + * @throws SecurityException + * if a {@link SecurityManager} is being used and the caller + * does not have the ManagementPermission value + * of "control". */ - public boolean setSharedClassCacheMinJitDataBytes(long value); - - /** + public boolean setSharedClassCacheMinJitDataBytes(long value); + + /** * Set the maximum shared classes cache space allowed for JIT data to value bytes. * See -Xscmaxjitdata in the command line reference for additional - * details on the effect of setting shared class -Xscmaxjitdata. - * + * details on the effect of setting shared class -Xscmaxjitdata. + * * @param value new -Xscmaxjitdata value in bytes * @return whether the requested operation has been completed. - * @throws IllegalArgumentException - * if input value value is less than 0. - * @throws SecurityException - * if a {@link SecurityManager} is being used and the caller - * does not have the ManagementPermission value - * of "control". + * @throws IllegalArgumentException + * if input value value is less than 0. + * @throws SecurityException + * if a {@link SecurityManager} is being used and the caller + * does not have the ManagementPermission value + * of "control". */ - public boolean setSharedClassCacheMaxJitDataBytes(long value); - - /** - * Returns the bytes which are not stored into the shared classes cache due to the current setting of softmx in shared classes. - * - * @return the unstored bytes. - */ - public long getSharedClassCacheSoftmxUnstoredBytes(); - - /** - * Returns the bytes which are not stored into the shared classes cache due to the current setting of maximum space allowed for AOT data. - * - * @return the unstored bytes. - */ - public long getSharedClassCacheMaxAotUnstoredBytes(); - - /** - * Returns the bytes which are not stored into the shared classes cache due to the current setting of maximum space allowed for JIT data. - * - * @return the unstored bytes. - */ - public long getSharedClassCacheMaxJitDataUnstoredBytes(); - - /** - * Returns the free space in bytes of the cache that the JVM is - * currently connected to. - * - * @return the number of bytes free in the shared class cache. - */ - public long getSharedClassCacheFreeSpace(); - - /** - * Returns the current GC mode as a human-readable string. - * - * @return a String describing the mode the GC is currently operating in - */ - public String getGCMode(); + public boolean setSharedClassCacheMaxJitDataBytes(long value); + + /** + * Returns the bytes which are not stored into the shared classes cache due to the current setting of softmx in shared classes. + * + * @return the unstored bytes. + */ + public long getSharedClassCacheSoftmxUnstoredBytes(); + + /** + * Returns the bytes which are not stored into the shared classes cache due to the current setting of maximum space allowed for AOT data. + * + * @return the unstored bytes. + */ + public long getSharedClassCacheMaxAotUnstoredBytes(); + + /** + * Returns the bytes which are not stored into the shared classes cache due to the current setting of maximum space allowed for JIT data. + * + * @return the unstored bytes. + */ + public long getSharedClassCacheMaxJitDataUnstoredBytes(); + + /** + * Returns the free space in bytes of the cache that the JVM is + * currently connected to. + * + * @return the number of bytes free in the shared class cache. + */ + public long getSharedClassCacheFreeSpace(); + + /** + * Returns the current GC mode as a human-readable string. + * + * @return a String describing the mode the GC is currently operating in + */ + public String getGCMode(); /*[IF JAVA_SPEC_VERSION < 16]*/ - /** - * Returns the amount of CPU time spent in the GC by the master thread, in - * milliseconds. - * - * @return CPU time used in milliseconds - * - * @deprecated renamed to getGCMainThreadCpuUsed - */ - /*[IF JAVA_SPEC_VERSION >= 11]*/ - @Deprecated(forRemoval=true, since="15") - /*[ELSE] JAVA_SPEC_VERSION >= 11 */ - @Deprecated - /*[ENDIF] JAVA_SPEC_VERSION >= 11 */ - public long getGCMasterThreadCpuUsed(); + /** + * Returns the amount of CPU time spent in the GC by the master thread, in + * milliseconds. + * + * @return CPU time used in milliseconds + * + * @deprecated renamed to getGCMainThreadCpuUsed + */ + /*[IF JAVA_SPEC_VERSION >= 11]*/ + @Deprecated(forRemoval=true, since="15") + /*[ELSE] JAVA_SPEC_VERSION >= 11 */ + @Deprecated + /*[ENDIF] JAVA_SPEC_VERSION >= 11 */ + public long getGCMasterThreadCpuUsed(); /*[ENDIF] JAVA_SPEC_VERSION < 16 */ - /** - * Returns the amount of CPU time spent in the GC by the main thread, in - * milliseconds. - * - * @return CPU time used in milliseconds - */ - public long getGCMainThreadCpuUsed(); + /** + * Returns the amount of CPU time spent in the GC by the main thread, in + * milliseconds. + * + * @return CPU time used in milliseconds + */ + public long getGCMainThreadCpuUsed(); /*[IF JAVA_SPEC_VERSION < 16]*/ - /** - * Returns the total amount of CPU time spent in the GC by all slave threads, in - * milliseconds. - * - * @return CPU time used in milliseconds - * - * @deprecated renamed to getGCWorkerThreadsCpuUsed - */ - /*[IF JAVA_SPEC_VERSION >= 11]*/ - @Deprecated(forRemoval=true, since="15") - /*[ELSE] JAVA_SPEC_VERSION >= 11 */ - @Deprecated - /*[ENDIF] JAVA_SPEC_VERSION >= 11 */ - public long getGCSlaveThreadsCpuUsed(); + /** + * Returns the total amount of CPU time spent in the GC by all slave threads, in + * milliseconds. + * + * @return CPU time used in milliseconds + * + * @deprecated renamed to getGCWorkerThreadsCpuUsed + */ + /*[IF JAVA_SPEC_VERSION >= 11]*/ + @Deprecated(forRemoval=true, since="15") + /*[ELSE] JAVA_SPEC_VERSION >= 11 */ + @Deprecated + /*[ENDIF] JAVA_SPEC_VERSION >= 11 */ + public long getGCSlaveThreadsCpuUsed(); /*[ENDIF] JAVA_SPEC_VERSION < 16 */ - /** - * Returns the total amount of CPU time spent in the GC by all worker threads, - * in milliseconds. - * - * @return CPU time used in milliseconds - */ - public long getGCWorkerThreadsCpuUsed(); + /** + * Returns the total amount of CPU time spent in the GC by all worker threads, + * in milliseconds. + * + * @return CPU time used in milliseconds + */ + public long getGCWorkerThreadsCpuUsed(); /** - * Returns the maximum number of GC worker threads. - * - * @return maximum number of GC worker threads - */ + * Returns the maximum number of GC worker threads. + * + * @return maximum number of GC worker threads + */ public int getMaximumGCThreads(); /** - * Returns the number of GC worker threads that participated in the most recent collection. - * - * @return number of active GC worker threads - */ + * Returns the number of GC worker threads that participated in the most recent collection. + * + * @return number of active GC worker threads + */ public int getCurrentGCThreads(); } diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryPoolMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryPoolMXBean.java index e2e93faecb1..2b6682f51fb 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryPoolMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryPoolMXBean.java @@ -27,10 +27,10 @@ /** * The OpenJ9 interface for managing and monitoring the virtual machine's memory pools. * - * The following list describes 4 common behavior changes for {@link MemoryPoolMXBean}. - * You can revert to the earlier implementation of {@link MemoryPoolMXBean} by setting the + * The following list describes 4 common behavior changes for {@link MemoryPoolMXBean}. + * You can revert to the earlier implementation of {@link MemoryPoolMXBean} by setting the * -XX:+HeapManagementMXBeanCompatibility Java command line option. - * + * *

      1. More detailed heap memory pools can be obtained by calling {@link java.lang.management.ManagementFactory#getMemoryPoolMXBeans}

      * The following names are reported for heap memory pools, listed by garbage collection policy: *

      @@ -69,19 +69,19 @@ *
        *
      • Java heap *
      - * + * *

      2. Memory Usage

      * Memory usage for each heap memory pool can be retrieved by using {@link java.lang.management.MemoryPoolMXBean#getUsage} or {@link java.lang.management.MemoryPoolMXBean#getCollectionUsage}. - * In some cases the total sum of memory usage of all heap memory pools is more than the maximum heap size. + * In some cases the total sum of memory usage of all heap memory pools is more than the maximum heap size. * This irregularity can be caused if data for each pool is collected between garbage collection cycles, * where objects have been moved or reclaimed. - * If you want to collect memory usage data that is synchronized across the memory pools, use the + * If you want to collect memory usage data that is synchronized across the memory pools, use the * {@link com.sun.management.GarbageCollectionNotificationInfo} or {@link com.sun.management.GarbageCollectorMXBean#getLastGcInfo} extensions. - * + * *

      3. Usage Threshold ({@link java.lang.management.MemoryPoolMXBean#getUsageThreshold}, {@link java.lang.management.MemoryPoolMXBean#setUsageThreshold}, {@link java.lang.management.MemoryPoolMXBean#isUsageThresholdExceeded})

      * The usage threshold attribute is designed for monitoring the increasing trend of memory usage and incurs only a low overhead. * This attribute is not appropriate for some memory pools. - * Use the {@link java.lang.management.MemoryPoolMXBean#isUsageThresholdSupported} method to determine + * Use the {@link java.lang.management.MemoryPoolMXBean#isUsageThresholdSupported} method to determine * if this functionality is supported by the memory pool to avoid an unexpected {@link java.lang.UnsupportedOperationException}. *
      * The following names are reported for heap memory pools that support the usage threshold attribute: @@ -93,11 +93,11 @@ *
    3. balanced-survivor *
    4. balanced-old * - * + * *

      4. Collection Usage Threshold ({@link java.lang.management.MemoryPoolMXBean#getCollectionUsageThreshold}, {@link java.lang.management.MemoryPoolMXBean#setCollectionUsageThreshold}, {@link java.lang.management.MemoryPoolMXBean#isCollectionUsageThresholdExceeded})

      - * The collection usage threshold is a manageable attribute that is applicable only to some garbage-collected memory pools. - * This attribute reports the amount of memory taken up by objects that are still in use after a garbage collection cycle. - * Use the {@link java.lang.management.MemoryPoolMXBean#isCollectionUsageThresholdSupported} method to determine + * The collection usage threshold is a manageable attribute that is applicable only to some garbage-collected memory pools. + * This attribute reports the amount of memory taken up by objects that are still in use after a garbage collection cycle. + * Use the {@link java.lang.management.MemoryPoolMXBean#isCollectionUsageThresholdSupported} method to determine * if this functionality is supported by the memory pool to avoid an unexpected {@link java.lang.UnsupportedOperationException}. *
      * The following names are reported for heap memory pools that support the collection usage threshold attribute: @@ -130,7 +130,7 @@ public interface MemoryPoolMXBean extends java.lang.management.MemoryPoolMXBean * The return value will be mapped to a * {@link javax.management.openmbean.CompositeData} with attributes as * specified in {@link java.lang.management.MemoryUsage}. - * + * * @return a {@link java.lang.management.MemoryUsage} containing the usage details for the memory * pool just before the most recent collection occurred. */ diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryUsage.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryUsage.java index 9e7872d02d3..4380d37a704 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryUsage.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryUsage.java @@ -29,8 +29,8 @@ /** * This represents a snapshot of the Operating System level Memory usage statistics. - * This is available on AIX, Linux, Windows and z/OS. - * + * This is available on AIX, Linux, Windows and z/OS. + * * @author sonchakr, dgunigun * @since 1.7.1 */ @@ -63,17 +63,17 @@ public MemoryUsage() { * @param cached The size of cache area in bytes; or -1 if undefined. * @param buffered The size of file buffer area in bytes; or -1 if undefined. * @param timestamp The timestamp when the snapshot was taken in microseconds. - * + * * @throws IllegalArgumentException if *
      • The values of total or free or timestamp are negative; or *
      • The values of swapTotal or swapFree or cached or buffered are negative but not -1; or *
      • The value of free is greater than total if defined; or *
      • The value of swapFree is greater than swapTotal if defined; or - *
      • The sum of values of cached, buffered and free are greater than total if defined. + *
      • The sum of values of cached, buffered and free are greater than total if defined. *
      */ private MemoryUsage(long total, long free, long swapTotal, long swapFree, - long cached, long buffered, long timestamp) throws IllegalArgumentException { + long cached, long buffered, long timestamp) throws IllegalArgumentException { super(); if ((total < 0) || (free < 0) || (timestamp < 0) || ((swapTotal < 0) && (swapTotal != -1)) || @@ -97,7 +97,7 @@ private MemoryUsage(long total, long free, long swapTotal, long swapFree, /** * The total amount of usable physical memory in bytes. - * + * * @return Total physical memory in bytes or -1 if info not available. */ public long getTotal() { @@ -106,7 +106,7 @@ public long getTotal() { /** * The total amount of free physical memory in bytes. - * + * * @return Free physical memory in bytes or -1 if info not available. */ public long getFree() { @@ -115,7 +115,7 @@ public long getFree() { /** * The amount of total swap space in bytes. - * + * * @return Total swap space in bytes or -1 if info not available. */ public long getSwapTotal() { @@ -124,7 +124,7 @@ public long getSwapTotal() { /** * The amount of free swap space in bytes. - * + * * @return Free swap space in bytes or -1 if info not available. */ public long getSwapFree() { @@ -147,7 +147,7 @@ public long getCached() { *
        *
      • Buffered memory is not available on AIX and Windows. *
      - * + * * @return Buffered memory in bytes or -1 if info not available. */ public long getBuffered() { @@ -156,7 +156,7 @@ public long getBuffered() { /** * The timestamp when the usage statistics were last sampled in microseconds. - * + * * @return Timestamp in microseconds. */ public long getTimestamp() { @@ -164,9 +164,9 @@ public long getTimestamp() { } /* (non-Javadoc) - * Setter method for updating the memory usage parameters into fields of a + * Setter method for updating the memory usage parameters into fields of a * {@link MemoryUsage} instance. - * + * * @param total The total Memory installed on the system in bytes. * @param free The amount of free memory in bytes. * @param swapTotal The configured swap memory size in bytes. @@ -240,7 +240,7 @@ public static MemoryUsage from(CompositeData cd) { buffered = ((Long) cd.get("buffered")).longValue(); //$NON-NLS-1$ timestamp = ((Long) cd.get("timestamp")).longValue(); //$NON-NLS-1$ } catch (InvalidKeyException e) { - /*[MSG "K05E6", "CompositeData object does not contain expected key."]*/ + /*[MSG "K05E6", "CompositeData object does not contain expected key."]*/ throw new IllegalArgumentException(com.ibm.oti.util.Msg.getString("K05E6")); //$NON-NLS-1$ } diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryUsageRetrievalException.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryUsageRetrievalException.java index 5767724b385..ea89f73d7aa 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryUsageRetrievalException.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/MemoryUsageRetrievalException.java @@ -24,10 +24,10 @@ package com.ibm.lang.management; /** - * Exception class whose instance is thrown when Memory usage sampling fails. + * Exception class whose instance is thrown when Memory usage sampling fails. * For exact cause one needs to inspect the exception string message capturing * the details by calling the toString() method. - * + * * @author sonchakr * @since 1.7.1 */ @@ -35,10 +35,10 @@ public class MemoryUsageRetrievalException extends Exception { private static final long serialVersionUID = -1503193846804870838L; /** - * Constructor for the exception class that takes a message string + * Constructor for the exception class that takes a message string * describing the exact nature of the exception. * - * @param msg The string that describes the exact nature of the exception + * @param msg The string that describes the exact nature of the exception * that occurred while sampling memory usage statistics. */ public MemoryUsageRetrievalException(String msg) diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessingCapacityNotificationInfo.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessingCapacityNotificationInfo.java index 00618eaf154..e2f683916fd 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessingCapacityNotificationInfo.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessingCapacityNotificationInfo.java @@ -42,51 +42,51 @@ public class ProcessingCapacityNotificationInfo { private final int newProcessingCapacity; - /** - * Constructs a new instance of this object. - * - * @param newProcessingCapacity - * the new processing capacity in units of 1% of a physical - * processor's capacity - */ + /** + * Constructs a new instance of this object. + * + * @param newProcessingCapacity + * the new processing capacity in units of 1% of a physical + * processor's capacity + */ public ProcessingCapacityNotificationInfo(int newProcessingCapacity) { super(); this.newProcessingCapacity = newProcessingCapacity; - } + } - /** - * Returns the new processing capacity after the change that this - * notification corresponds to. - * - * @return the new processing capacity in units of 1% of a physical - * processor's capacity. - */ - public int getNewProcessingCapacity() { - return this.newProcessingCapacity; - } + /** + * Returns the new processing capacity after the change that this + * notification corresponds to. + * + * @return the new processing capacity in units of 1% of a physical + * processor's capacity. + */ + public int getNewProcessingCapacity() { + return this.newProcessingCapacity; + } - /** - * Receives a {@link CompositeData} representing a - * ProcessingCapacityNotificationInfo object and attempts to - * return the root ProcessingCapacityNotificationInfo - * instance. - * - * @param cd - * a CompositeDate that represents a - * ProcessingCapacityNotificationInfo. - * @return if cd is non- null, returns a new - * instance of ProcessingCapacityNotificationInfo. - * If cd is null, returns - * null. - * @throws IllegalArgumentException - * if argument cd does not correspond to a - * ProcessingCapacityNotificationInfo with the - * following attribute: - *
        - *
      • newProcessingCapacity( - * java.lang.Integer) - *
      - */ + /** + * Receives a {@link CompositeData} representing a + * ProcessingCapacityNotificationInfo object and attempts to + * return the root ProcessingCapacityNotificationInfo + * instance. + * + * @param cd + * a CompositeDate that represents a + * ProcessingCapacityNotificationInfo. + * @return if cd is non- null, returns a new + * instance of ProcessingCapacityNotificationInfo. + * If cd is null, returns + * null. + * @throws IllegalArgumentException + * if argument cd does not correspond to a + * ProcessingCapacityNotificationInfo with the + * following attribute: + *
        + *
      • newProcessingCapacity( + * java.lang.Integer) + *
      + */ public static ProcessingCapacityNotificationInfo from(CompositeData cd) { ProcessingCapacityNotificationInfo result = null; @@ -96,7 +96,7 @@ public static ProcessingCapacityNotificationInfo from(CompositeData cd) { // following method invocations will exit on an // IllegalArgumentException... ManagementUtils.verifyFieldNumber(cd, 1); - String[] attributeNames = { "newProcessingCapacity" }; //$NON-NLS-1$ + String[] attributeNames = { "newProcessingCapacity" }; //$NON-NLS-1$ ManagementUtils.verifyFieldNames(cd, attributeNames); String[] attributeTypes = { "java.lang.Integer" }; //$NON-NLS-1$ ManagementUtils.verifyFieldTypes(cd, attributeNames, attributeTypes); diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessorUsage.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessorUsage.java index bba44218fdf..c505be94824 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessorUsage.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessorUsage.java @@ -69,16 +69,16 @@ public ProcessorUsage() { * @param online This Processor's online status (0 = offline, 1 = online) * or -1 for the global record or if not available. * @param timestamp The timestamp when usage statistics were last sampled in microseconds. - * + * * @throws IllegalArgumentException if *
      • The values of user or system or idle or wait or busy or id or online are negative but not -1; or *
      • The value of timestamp is negative; or *
      • The value of online is anything other than 0 or 1 or -1; or - *
      • The sum of values of user, system and wait are greater than busy if defined. + *
      • The sum of values of user, system and wait are greater than busy if defined. *
      */ private ProcessorUsage(long user, long system, long idle, long wait, - long busy, int id, int online, long timestamp) throws IllegalArgumentException { + long busy, int id, int online, long timestamp) throws IllegalArgumentException { super(); if (user < -1) { throw new IllegalArgumentException("For id(" + id + "), user(" + user + ") < -1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -120,7 +120,7 @@ private ProcessorUsage(long user, long system, long idle, long wait, /** * The time spent in user mode in microseconds. - * + * * @return The user times in microseconds or -1 if not available. */ public long getUser() { @@ -129,7 +129,7 @@ public long getUser() { /** * The time spent in system mode in microseconds. - * + * * @return The system times in microseconds or -1 if not available. */ public long getSystem() { @@ -138,7 +138,7 @@ public long getSystem() { /** * The time spent by the Processor sitting idle in microseconds. - * + * * @return The idle times in microseconds or -1 if not available. */ public long getIdle() { @@ -147,7 +147,7 @@ public long getIdle() { /** * The time spent by the Processor in Input/Output (IO) wait in microseconds. - * + * * @return The wait times in microseconds or -1 if not available. */ public long getWait() { @@ -156,7 +156,7 @@ public long getWait() { /** * The time spent by the Processor executing a non-idle thread in microseconds. - * + * * @return The busy times in microseconds or -1 if not available. */ public long getBusy() { @@ -166,7 +166,7 @@ public long getBusy() { /** * A unique identifier assigned to the this Processor. This is -1 if method * invoked on the global Processor record. - * + * * @return An identifier for this Processor or -1 for the global record or if not available. */ public int getId() { @@ -182,7 +182,7 @@ public int getId() { * even if it is currently offline. This is a limitation of the OS. Similarly offline * on AIX means that the Processor was never online. * - * + * * @return This Processor's online status (0 = offline, 1 = online) * or -1 for the global record or if not available. */ @@ -192,7 +192,7 @@ public int getOnline() { /** * The timestamp when usage statistics were last sampled in microseconds. - * + * * @return Timestamp in microseconds. */ public long getTimestamp() { @@ -200,9 +200,9 @@ public long getTimestamp() { } /** - * Setter method for updating the Processor usage parameters into fields + * Setter method for updating the Processor usage parameters into fields * of a {@link ProcessorUsage} instance. - * + * * @param user Time spent in User mode in microseconds. * @param system Time spent in System (or kernel or privileged) mode in microseconds. * @param idle Time spent in Idle mode in microseconds. @@ -237,7 +237,7 @@ void updateValues(long user, * instance. * * @param cd A {@link javax.management.openmbean.CompositeData} that represents a {@link ProcessorUsage} - * + * * @return if cd is non- null, returns a new instance of * {@link ProcessorUsage}, If cd * is null, returns null. diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessorUsageRetrievalException.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessorUsageRetrievalException.java index 5c7ee9b65c4..097fb50e4c9 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessorUsageRetrievalException.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ProcessorUsageRetrievalException.java @@ -27,7 +27,7 @@ * Exception class whose instance is thrown when Processor usage sampling fails. For exact * cause one needs to inspect the exception string message capturing the details by calling * the toString() method. - * + * * @author sonchakr * @since 1.7.1 */ diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/RuntimeMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/RuntimeMXBean.java index 7d0abe5437a..ea870fcac4b 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/RuntimeMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/RuntimeMXBean.java @@ -74,28 +74,28 @@ public String idleStateName() { * running on the available processors and the number of runnable entities * ready and queued to run on the available processors. The averaging * technique adopted can vary depending on the underlying operating system. - * + * * @return normally, the system load average as a double. If the system load * average is not obtainable (e.g. because the calculation may * involve an unacceptable performance impact) then a negative value * is returned. * @since 1.6 - * @see java.lang.management.OperatingSystemMXBean#getSystemLoadAverage() + * @see java.lang.management.OperatingSystemMXBean#getSystemLoadAverage() */ public double getCPULoad(); /*[IF JAVA_SPEC_VERSION < 19]*/ /** * Returns the native process identifier that identifies the current - * Java process to the operating system. The value is prone to being - * recycled over a period of time, as considered suitable by the + * Java process to the operating system. The value is prone to being + * recycled over a period of time, as considered suitable by the * operating system. - * - * @return A long representing the process ID (pid) on the underlying + * + * @return A long representing the process ID (pid) on the underlying * operating system. /*[IF JAVA_SPEC_VERSION >= 10] - * - * @deprecated As of Java 10. Use + * + * @deprecated As of Java 10. Use * {@link java.lang.management.RuntimeMXBean#getPid() getPid()} instead. */ @Deprecated(forRemoval=true, since="10") @@ -106,13 +106,13 @@ public String idleStateName() { /*[ENDIF] JAVA_SPEC_VERSION < 19*/ /** - * Returns a system load average calculated over the minute preceding + * Returns a system load average calculated over the minute preceding * the call averaged over the number of CPU available to Java virtual * machine process. - * + * * @return A double indicating the average system load per processor. * If the system load average is not available, it returns a negative - * value to indicate this. + * value to indicate this. */ public double getVMGeneratedCPULoad(); @@ -127,7 +127,7 @@ public String idleStateName() { * @return true if JVM state is idle. Otherwise returns false */ public boolean isVMIdle(); - + /** * Query the state of the Attach API. Return false if the Attach API is: * - still initializing @@ -151,9 +151,9 @@ public String idleStateName() { public boolean isAttachApiTerminated(); /** - * This is provided for the benefit of applications which use attach API to load JVMTI agents + * This is provided for the benefit of applications which use attach API to load JVMTI agents * into their own JVMs. - * + * * @return Attach API Virtual Machine ID of this VM * @since 1.8 diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ThreadMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ThreadMXBean.java index ee20ca910f0..7aef90f3938 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ThreadMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/ThreadMXBean.java @@ -31,57 +31,57 @@ public interface ThreadMXBean extends com.sun.management.ThreadMXBean { /** - * Fetches an array of the native (operating system assigned) identifiers - * corresponding to unique TIDs (as returned by java/lang/Thread.getId()) specified to it. - * @param threadIDs An array of thread identifiers that the user wishes to obtain - * native thread identifiers for. - * @return An array of operating system assigned native thread identifiers. If a thread among the - * given set of IDs is no longer alive or does not exist, a -1 is set in the corresponding - * element of the returned array. - * @throws IllegalArgumentException is thrown if any of the thread identifiers passed is invalid (<=0). - * @throws SecurityException is thrown if the caller does not have sufficient permissions - * (ManagementPermission("monitor")) - */ - public long[] getNativeThreadIds(long[] threadIDs) + * Fetches an array of the native (operating system assigned) identifiers + * corresponding to unique TIDs (as returned by java/lang/Thread.getId()) specified to it. + * @param threadIDs An array of thread identifiers that the user wishes to obtain + * native thread identifiers for. + * @return An array of operating system assigned native thread identifiers. If a thread among the + * given set of IDs is no longer alive or does not exist, a -1 is set in the corresponding + * element of the returned array. + * @throws IllegalArgumentException is thrown if any of the thread identifiers passed is invalid (<=0). + * @throws SecurityException is thrown if the caller does not have sufficient permissions + * (ManagementPermission("monitor")) + */ + public long[] getNativeThreadIds(long[] threadIDs) throws IllegalArgumentException, SecurityException; - /** - * Find the native (operating system assigned) thread identifiers corresponding - * to a unique TID (as returned by java/lang/Thread.getId()). When querying multiple threadIDs, - * consider using getNativeThreadIds(long[]) as it is more efficient than getNativeThreadId(). - * @param threadId The Java runtime allocated thread identifier. - * @return Operating system assigned native thread identifier. If the thread corresponding to the - * ID is no longer alive or does not exist, -1 is returned. - * @throws IllegalArgumentException is thrown if the thread identifier passed is invalid (<=0). - * @throws SecurityException is thrown if the caller does not have sufficient permissions - * (ManagementPermission("monitor")) - */ - public long getNativeThreadId(long threadId) - throws IllegalArgumentException, SecurityException; + /** + * Find the native (operating system assigned) thread identifiers corresponding + * to a unique TID (as returned by java/lang/Thread.getId()). When querying multiple threadIDs, + * consider using getNativeThreadIds(long[]) as it is more efficient than getNativeThreadId(). + * @param threadId The Java runtime allocated thread identifier. + * @return Operating system assigned native thread identifier. If the thread corresponding to the + * ID is no longer alive or does not exist, -1 is returned. + * @throws IllegalArgumentException is thrown if the thread identifier passed is invalid (<=0). + * @throws SecurityException is thrown if the caller does not have sufficient permissions + * (ManagementPermission("monitor")) + */ + public long getNativeThreadId(long threadId) + throws IllegalArgumentException, SecurityException; - /** - * API method that fetches an array of ExtendedThreadInfo objects corresponding to - * threads in the virtual machine during the time it is invoked. - * Fetches an array of ExtendedThreadInfo objects that provide native thread - * identifiers along with java.lang.management.ThreadInfo object representing the thread. - * Consider using dumpAllExtendedThreads() in place of dumpAllThreads() as it provides - * additional thread identification information in an efficient manner. - * @param lockedMonitors - * boolean indication of whether or not information on all - * currently locked object monitors is to be included in the - * returned array - * @param lockedSynchronizers - * boolean indication of whether or not information on all - * currently locked ownable synchronizers is to be included in - * the returned array - * @return Array of ExtendedThreadInfo objects. - * @throws SecurityException is thrown if the caller does not have sufficient permissions - * (ManagementPermission("monitor")) - * @throws UnsupportedOperationException is thrown if the JVM does not support monitoring - * object monitor usage or ownable synchronizer usage, even as it has been specified. - * @throws InternalError is thrown in case an error occurs while fetching thread information, - * typically, an internal error resulting from an inconsistency in the class library. - */ - public ExtendedThreadInfo[] dumpAllExtendedThreads(boolean lockedMonitors, boolean lockedSynchronizers) - throws SecurityException, UnsupportedOperationException, InternalError; + /** + * API method that fetches an array of ExtendedThreadInfo objects corresponding to + * threads in the virtual machine during the time it is invoked. + * Fetches an array of ExtendedThreadInfo objects that provide native thread + * identifiers along with java.lang.management.ThreadInfo object representing the thread. + * Consider using dumpAllExtendedThreads() in place of dumpAllThreads() as it provides + * additional thread identification information in an efficient manner. + * @param lockedMonitors + * boolean indication of whether or not information on all + * currently locked object monitors is to be included in the + * returned array + * @param lockedSynchronizers + * boolean indication of whether or not information on all + * currently locked ownable synchronizers is to be included in + * the returned array + * @return Array of ExtendedThreadInfo objects. + * @throws SecurityException is thrown if the caller does not have sufficient permissions + * (ManagementPermission("monitor")) + * @throws UnsupportedOperationException is thrown if the JVM does not support monitoring + * object monitor usage or ownable synchronizer usage, even as it has been specified. + * @throws InternalError is thrown in case an error occurs while fetching thread information, + * typically, an internal error resulting from an inconsistency in the class library. + */ + public ExtendedThreadInfo[] dumpAllExtendedThreads(boolean lockedMonitors, boolean lockedSynchronizers) + throws SecurityException, UnsupportedOperationException, InternalError; } diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/TotalPhysicalMemoryNotificationInfo.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/TotalPhysicalMemoryNotificationInfo.java index 1d6d8addf93..98bc3dee829 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/TotalPhysicalMemoryNotificationInfo.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/TotalPhysicalMemoryNotificationInfo.java @@ -42,7 +42,7 @@ public class TotalPhysicalMemoryNotificationInfo { /** * Constructs a new instance of this object. - * + * * @param newTotalPhysicalMemory * the new total bytes of physical memory */ @@ -58,29 +58,29 @@ public TotalPhysicalMemoryNotificationInfo(long newTotalPhysicalMemory) { */ public long getNewTotalPhysicalMemory() { return this.newTotalPhysicalMemory; - } + } - /** - * Receives a {@link CompositeData} representing a - * TotalPhysicalMemoryNotificationInfo object and attempts to - * return the root TotalPhysicalMemoryNotificationInfo - * instance. - * - * @param cd - * a CompositeDate that represents a - * TotalPhysicalMemoryNotificationInfo. - * @return if cd is non- null, returns a new - * instance of TotalPhysicalMemoryNotificationInfo. - * If cd is null, returns - * null. - * @throws IllegalArgumentException - * if argument cd does not correspond to a - * TotalPhysicalMemoryNotificationInfo with the - * following attribute: - *
        - *
      • newTotalPhysicalMemory( java.lang.Long) - *
      - */ + /** + * Receives a {@link CompositeData} representing a + * TotalPhysicalMemoryNotificationInfo object and attempts to + * return the root TotalPhysicalMemoryNotificationInfo + * instance. + * + * @param cd + * a CompositeDate that represents a + * TotalPhysicalMemoryNotificationInfo. + * @return if cd is non- null, returns a new + * instance of TotalPhysicalMemoryNotificationInfo. + * If cd is null, returns + * null. + * @throws IllegalArgumentException + * if argument cd does not correspond to a + * TotalPhysicalMemoryNotificationInfo with the + * following attribute: + *
        + *
      • newTotalPhysicalMemory( java.lang.Long) + *
      + */ public static TotalPhysicalMemoryNotificationInfo from(CompositeData cd) { TotalPhysicalMemoryNotificationInfo result = null; @@ -90,7 +90,7 @@ public static TotalPhysicalMemoryNotificationInfo from(CompositeData cd) { // following method invocations will exit on an // IllegalArgumentException... ManagementUtils.verifyFieldNumber(cd, 1); - String[] attributeNames = { "newTotalPhysicalMemory" }; //$NON-NLS-1$ + String[] attributeNames = { "newTotalPhysicalMemory" }; //$NON-NLS-1$ ManagementUtils.verifyFieldNames(cd, attributeNames); String[] attributeTypes = { "java.lang.Long" }; //$NON-NLS-1$ ManagementUtils.verifyFieldTypes(cd, attributeNames, attributeTypes); diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/UnixOperatingSystemMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/UnixOperatingSystemMXBean.java index c25292df9a1..8995530bba2 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/UnixOperatingSystemMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/UnixOperatingSystemMXBean.java @@ -25,28 +25,28 @@ /** * Interface provides platform-specific management utilities on Unix and Unix-like * operating systems. - * + * * @since 1.8 */ public interface UnixOperatingSystemMXBean extends com.sun.management.UnixOperatingSystemMXBean, OperatingSystemMXBean { /** * Returns the maximum number of file descriptors that can be opened in a process. - * + * * @return The maximum number of file descriptors that can be opened in a process or - * -1, if an error occurred while obtaining this. If the operating system doesn't have + * -1, if an error occurred while obtaining this. If the operating system doesn't have * any limits configured, Long.MAX_VALUE is returned. - * + * * @since 1.8 */ public long getMaxFileDescriptorCount(); /** * Returns the current number of file descriptors that are in opened state. - * + * * @return The current number of file descriptors that are in opened state or * -1, if an error occurred while obtaining this. - * + * * @since 1.8 */ public long getOpenFileDescriptorCount(); diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedRuntimeMXBeanImpl.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedRuntimeMXBeanImpl.java index f0c2b92c70d..3627ce69524 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedRuntimeMXBeanImpl.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedRuntimeMXBeanImpl.java @@ -39,7 +39,7 @@ public final class ExtendedRuntimeMXBeanImpl extends RuntimeMXBeanImpl implement /** * Singleton accessor method. - * + * * @return the RuntimeMXBeanImpl singleton. */ public static RuntimeMXBean getInstance() { diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/JvmCpuMonitor.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/JvmCpuMonitor.java index 350abd11348..4235f08e2f0 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/JvmCpuMonitor.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/JvmCpuMonitor.java @@ -38,7 +38,7 @@ public class JvmCpuMonitor implements JvmCpuMonitorMXBean { /** - * This is the default thread category of every application thread + * This is the default thread category of every application thread */ private enum Category { THREAD_CATEGORY_INVALID(-1, "Invalid"), //$NON-NLS-1$ @@ -112,10 +112,10 @@ public static Category fromString(String catName) { }; private static JvmCpuMonitor instance = new JvmCpuMonitor(); - + /** * Singleton accessor method. Returns an instance of {@link JvmCpuMonitor} - * + * * @return a static instance of {@link JvmCpuMonitor} */ public static JvmCpuMonitor getInstance() { @@ -124,7 +124,7 @@ public static JvmCpuMonitor getInstance() { /** * Returns the object name of the MXBean - * + * * @return objectName representing the MXBean */ public ObjectName getObjectName() { @@ -135,7 +135,7 @@ public ObjectName getObjectName() { return null; } } - + /** * {@inheritDoc} */ @@ -175,7 +175,7 @@ public int setThreadCategory(long id, String category) { default: throw new IllegalArgumentException(); } - + return setThreadCategoryImpl(id, catId.categoryValue()); } diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/JvmCpuMonitorInfoUtil.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/JvmCpuMonitorInfoUtil.java index 4e5243b9723..224eecbb037 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/JvmCpuMonitorInfoUtil.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/JvmCpuMonitorInfoUtil.java @@ -34,7 +34,7 @@ import com.ibm.lang.management.JvmCpuMonitorInfo; /** - * Support for the {@link JvmCpuMonitorInfo} class. + * Support for the {@link JvmCpuMonitorInfo} class. */ public final class JvmCpuMonitorInfoUtil { diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/MemoryNotificationThread.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/MemoryNotificationThread.java index 196bae85482..6a89d6fc8a3 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/MemoryNotificationThread.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/MemoryNotificationThread.java @@ -56,38 +56,38 @@ final class MemoryNotificationThread implements Runnable { } /** - * A helper used by processNotificationLoop to construct and dispatch - * garbage collection notification objects - * - * @param gcName - * the name of garbage collector which we are sending notifications on behalf of - * @param gcAction - * the action of the performed by the garbage collector - * @param gcCause - * the cause the garbage collection - * @param index - * the identifier of this garbage collection which is the number of collections that this collector has done - * @param startTime - * the start time of this GC in milliseconds since the Java virtual machine was started - * @param endTime - * the end time of this GC in milliseconds since the Java virtual machine was started - * @param initialSize - * the initial amount of memory of all memory pools - * @param preUsed - * the amounts of memory used of all memory pools before the garbage collection - * @param preCommitted - * the amounts of all memory pools that is guaranteed to be available for use before the garbage collection - * @param preMax - * the maximum amounts of memory pools that can be used before the garbage collection - * @param postUsed - * the amounts of memory used of all memory pools after the garbage collection - * @param postCommitted - * the amounts of all memory pools that is guaranteed to be available for use after the garbage collection - * @param postMax - * the maximum amounts of memory pools that can be used after the garbage collection - * @param sequenceNumber - * the sequence identifier of the current notification - */ + * A helper used by processNotificationLoop to construct and dispatch + * garbage collection notification objects + * + * @param gcName + * the name of garbage collector which we are sending notifications on behalf of + * @param gcAction + * the action of the performed by the garbage collector + * @param gcCause + * the cause the garbage collection + * @param index + * the identifier of this garbage collection which is the number of collections that this collector has done + * @param startTime + * the start time of this GC in milliseconds since the Java virtual machine was started + * @param endTime + * the end time of this GC in milliseconds since the Java virtual machine was started + * @param initialSize + * the initial amount of memory of all memory pools + * @param preUsed + * the amounts of memory used of all memory pools before the garbage collection + * @param preCommitted + * the amounts of all memory pools that is guaranteed to be available for use before the garbage collection + * @param preMax + * the maximum amounts of memory pools that can be used before the garbage collection + * @param postUsed + * the amounts of memory used of all memory pools after the garbage collection + * @param postCommitted + * the amounts of all memory pools that is guaranteed to be available for use after the garbage collection + * @param postMax + * the maximum amounts of memory pools that can be used after the garbage collection + * @param sequenceNumber + * the sequence identifier of the current notification + */ private void dispatchGCNotificationHelper(String gcName, String gcAction, String gcCause, long index, long startTime, long endTime, long[] initialSize, long[] preUsed, long[] preCommitted, long[] preMax, long[] postUsed, long[] postCommitted, long[] postMax, @@ -106,44 +106,44 @@ private void dispatchGCNotificationHelper(String gcName, String gcAction, String break; } } - } + } /** - * A helper used by processNotificationLoop to construct and dispatch - * memory threshold notification objects - * - * @param poolName - * the name of pool which we are sending notifications on behalf of - * @param min - * the initial amount in bytes of memory that can be allocated by - * this virtual machine - * @param used - * the number of bytes currently used for memory - * @param committed - * the number of bytes of committed memory - * @param max - * the maximum number of bytes that can be used for memory - * management purposes - * @param count - * the number of times that the memory usage of the memory pool - * in question has met or exceeded the relevant threshold - * @param sequenceNumber - * the sequence identifier of the current notification - * @param isCollectionUsageNotification - * a boolean indication of whether or not the new - * notification is as a result of the collection threshold being - * exceeded. If this value is false then the - * implication is that a memory threshold has been exceeded. - */ + * A helper used by processNotificationLoop to construct and dispatch + * memory threshold notification objects + * + * @param poolName + * the name of pool which we are sending notifications on behalf of + * @param min + * the initial amount in bytes of memory that can be allocated by + * this virtual machine + * @param used + * the number of bytes currently used for memory + * @param committed + * the number of bytes of committed memory + * @param max + * the maximum number of bytes that can be used for memory + * management purposes + * @param count + * the number of times that the memory usage of the memory pool + * in question has met or exceeded the relevant threshold + * @param sequenceNumber + * the sequence identifier of the current notification + * @param isCollectionUsageNotification + * a boolean indication of whether or not the new + * notification is as a result of the collection threshold being + * exceeded. If this value is false then the + * implication is that a memory threshold has been exceeded. + */ private void dispatchMemoryNotificationHelper(String poolName, long min, long used, long committed, long max, long count, long sequenceNumber, boolean isCollectionUsageNotification) { MemoryNotificationInfo info = new MemoryNotificationInfo(poolName, new MemoryUsage(min, used, committed, max), count); - Notification notification = new Notification( - isCollectionUsageNotification - ? MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED - : MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED, - "java.lang:type=Memory", //$NON-NLS-1$ - sequenceNumber); + Notification notification = new Notification( + isCollectionUsageNotification + ? MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED + : MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED, + "java.lang:type=Memory", //$NON-NLS-1$ + sequenceNumber); notification.setUserData(MemoryNotificationInfoUtil.toCompositeData(info)); memBean.sendNotification(notification); } diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/OperatingSystemNotificationThread.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/OperatingSystemNotificationThread.java index 53d4880739c..b55397bed27 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/OperatingSystemNotificationThread.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/OperatingSystemNotificationThread.java @@ -76,7 +76,7 @@ public Void run() { /** * Registers a signal handler for SIGRECONFIG, then processes notifications - * on an internal VM queue until a shutdown request is received. + * on an internal VM queue until a shutdown request is received. */ private native void processNotificationLoop(); diff --git a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSInfoRetrievalException.java b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSInfoRetrievalException.java index df6d6b2815e..d0cf1093183 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSInfoRetrievalException.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSInfoRetrievalException.java @@ -25,7 +25,7 @@ */ /** - * This exception class is thrown when retrieving + * This exception class is thrown when retrieving * Guest (Virtual Machine(VM)/Logical Partition(LPAR)) usage statistics fails. * It could be trying to retrieve either {@link GuestOSProcessorUsage} or * {@link GuestOSMemoryUsage}. For exact cause one needs to inspect the exception diff --git a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSMXBean.java index 40a76b93c36..cb9dfe4a711 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSMXBean.java @@ -63,7 +63,7 @@ * if (true != mbeanServer.isRegistered(mxbeanName)) { * // GuestOSMXBean not registered * } - * GuestOSMXBean guestBean = JMX.newMXBeanProxy(mbeanServer, mxbeanName, GuestOSMXBean.class); + * GuestOSMXBean guestBean = JMX.newMXBeanProxy(mbeanServer, mxbeanName, GuestOSMXBean.class); * } catch (Exception e) { * // Exception Handling * } @@ -94,7 +94,7 @@ public GuestOSProcessorUsage retrieveProcessorUsage(GuestOSProcessorUsage gpUsag /** * Function instantiates a {@link GuestOSProcessorUsage} object and populates it with the - * current snapshot of Processor Usage statistics of the Guest as seen by the Hypervisor. + * current snapshot of Processor Usage statistics of the Guest as seen by the Hypervisor. * The statistics are an aggregate across all physical CPUs assigned to the Guest by the Hypervisor. * * @return The new {@link GuestOSProcessorUsage} object. @@ -129,9 +129,9 @@ public GuestOSMemoryUsage retrieveMemoryUsage(GuestOSMemoryUsage gmUsage) * current snapshot of Memory Usage statistics of the Guest as seen by the Hypervisor. * * @return The new {@link GuestOSMemoryUsage} object. - * + * * @throws GuestOSInfoRetrievalException if it failed to obtain usage statistics. - * + * *

      In case of an exception, the handler code can use toString() on the exception code * to obtain a description of the exception. */ diff --git a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSMemoryUsage.java b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSMemoryUsage.java index e887fdac483..621bcccaea9 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSMemoryUsage.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSMemoryUsage.java @@ -60,12 +60,12 @@ public GuestOSMemoryUsage() { * @param memUsed The current used snapshot of Memory in MB or -1 if undefined. * @param timestamp The timestamp when the snapshot was taken in microseconds. * @param maxMemLimit The Max Memory limit if any set for this Guest or -1 if undefined. - * + * * @throws IllegalArgumentException if *

        *
      • The values of cpuTime or cpuEntitlement or hostCpuClockSpeed are negative but not -1; or *
      • memUsed is greater than maxMemLimit if defined. - *
      • The value of timestamp is negative. + *
      • The value of timestamp is negative. *
      */ private GuestOSMemoryUsage(long memUsed, long timestamp, long maxMemLimit) throws IllegalArgumentException { @@ -108,7 +108,7 @@ public long getMaxMemLimit() { /* (non-Javadoc) * Setter method for updating Guest Memory usage parameters for this instance. - * + * * @param used The current used snapshot of Memory in MB. * @param timestamp The timestamp when the snapshot was taken in microseconds. * @param limit The Max Memory limit if any set for this Guest. @@ -123,9 +123,9 @@ void updateValues(long used, long timestamp, long limit) { * Receives a {@link javax.management.openmbean.CompositeData} representing a {@link GuestOSMemoryUsage} * object and attempts to return the root {@link GuestOSMemoryUsage} instance. * - * @param cd A {@link javax.management.openmbean.CompositeData} that represents a + * @param cd A {@link javax.management.openmbean.CompositeData} that represents a * {@link GuestOSMemoryUsage}. - * + * * @return if cd is non- null, returns a new instance of * {@link GuestOSMemoryUsage}, If cd * is null, returns null. diff --git a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSProcessorUsage.java b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSProcessorUsage.java index 50858bc2f50..8be31c68d08 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSProcessorUsage.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/GuestOSProcessorUsage.java @@ -71,11 +71,11 @@ public GuestOSProcessorUsage() { * @throws IllegalArgumentException if *
        *
      • The values of cpuTime or cpuEntitlement or hostCpuClockSpeed are negative but not -1; or - *
      • The value of timestamp is negative. + *
      • The value of timestamp is negative. *
      */ private GuestOSProcessorUsage(long cpuTime, long timestamp, - float cpuEntitlement, long hostCpuClockSpeed) throws IllegalArgumentException { + float cpuEntitlement, long hostCpuClockSpeed) throws IllegalArgumentException { super(); if ((cpuTime < -1) || (cpuEntitlement < -1) || (hostCpuClockSpeed < -1) || (timestamp < 0)) { throw new IllegalArgumentException(); @@ -88,7 +88,7 @@ private GuestOSProcessorUsage(long cpuTime, long timestamp, /** * The total used time of the Guest as reported by the Hypervisor in microseconds. - *
        + *
          *
        • z/OS maintains CPU usage history only for the last 4 hours. The value might * not be monotonically increasing. *
        @@ -146,7 +146,7 @@ public float getCpuEntitlement() { /* (non-Javadoc) * Setter method for updating Guest Processor usage parameters for this instance - * + * * @param time The total used time for this Guest in microseconds. * @param timestamp The timestamp when the snapshot was taken in microseconds. * @param entitlement The total Processor entitlement for this Guest. @@ -164,13 +164,13 @@ void updateValues(long time, long timestamp, float entitlement, long cpuSpeed) { } /** - * Receives a {@link javax.management.openmbean.CompositeData} representing a + * Receives a {@link javax.management.openmbean.CompositeData} representing a * {@link GuestOSProcessorUsage} object and attempts to return the root * {@link GuestOSProcessorUsage} instance. * - * @param cd A {@link javax.management.openmbean.CompositeData} that represents a + * @param cd A {@link javax.management.openmbean.CompositeData} that represents a * {@link GuestOSProcessorUsage}. - * + * * @return if cd is non- null, returns a new instance of * {@link GuestOSProcessorUsage}, * If cd is null, returns null. @@ -285,11 +285,11 @@ public boolean equals(Object obj) { */ @Override public int hashCode() { - long gpHash = this.getCpuTime() + long gpHash = this.getCpuTime() + this.getTimestamp() + this.getHostCpuClockSpeed() + (long) this.getCpuEntitlement(); - + return (int) ((((gpHash >> 32) + gpHash) & HASHMASK) * 23); } diff --git a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/HypervisorMXBean.java b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/HypervisorMXBean.java index 3637eeef315..87db15d54e7 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/HypervisorMXBean.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/HypervisorMXBean.java @@ -67,7 +67,7 @@ * if (true != mbeanServer.isRegistered(mxbeanName)) { * // HypervisorMXBean not registered * } - * HypervisorMXBean hypBean = JMX.newMXBeanProxy(mbeanServer, mxbeanName, HypervisorMXBean.class); + * HypervisorMXBean hypBean = JMX.newMXBeanProxy(mbeanServer, mxbeanName, HypervisorMXBean.class); * } catch (Exception e) { * // Exception Handling * } @@ -80,7 +80,7 @@ public interface HypervisorMXBean extends PlatformManagedObject { /** * Indicates if the Operating System is running on a Hypervisor or not. - * + * * @return true if running on a Hypervisor, false otherwise. * @throws UnsupportedOperationException if the underlying Hypervisor is unsupported. @@ -90,7 +90,7 @@ public interface HypervisorMXBean extends PlatformManagedObject { /** * Returns the vendor of the Hypervisor if running in a virtualized environment. - * + * * @return string identifying the vendor of the Hypervisor if running under * Hypervisor, null otherwise. */ diff --git a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/internal/HypervisorMXBeanImpl.java b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/internal/HypervisorMXBeanImpl.java index 332e74c021f..9f75c68ef04 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/internal/HypervisorMXBeanImpl.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/virtualization/management/internal/HypervisorMXBeanImpl.java @@ -49,7 +49,7 @@ public final class HypervisorMXBeanImpl implements HypervisorMXBean { /** * Singleton accessor method. - * + * * @return the {@link HypervisorMXBeanImpl} singleton. */ public static HypervisorMXBeanImpl getInstance() { @@ -91,7 +91,7 @@ public boolean isEnvironmentVirtual() throws UnsupportedOperationException, Hype /** * Returns the object name of the MXBean. - * + * * @return objectName representing the MXBean. */ @Override @@ -106,14 +106,14 @@ public ObjectName getObjectName() { /** * Query whether the Environment is Virtual or not. - * + * * @return true if Operating System is running on a Hypervisor Host. */ private native int isEnvironmentVirtualImpl(); /** * Query the Hypervisor Vendor Name. - * + * * @return string identifying the vendor of the Hypervisor if running on a Hypervisor, null otherwise. */ private native String getVendorImpl(); diff --git a/jcl/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java b/jcl/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java index 0c442cfa91a..f895ebe35ef 100644 --- a/jcl/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java +++ b/jcl/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java @@ -110,7 +110,7 @@ public class GarbageCollectionNotificationInfo implements CompositeDataView { private final GcInfo gcInfo; private CompositeData cdata; - + private CompositeData getCompositeData() { if (null == cdata) { cdata = GarbageCollectionNotificationInfoUtil.toCompositeData(this); @@ -121,21 +121,21 @@ private CompositeData getCompositeData() { private void setCompositeData(CompositeData cd) { cdata = cd; } - + /** * Creates a new GarbageCollectionNotificationInfo instance. - * + * * @param gcName * the name of the garbage collector used to perform the collection * @param gcAction * the action of the performed by the garbage collector * @param gcCause * the cause the garbage collection - * @param gcInfo + * @param gcInfo * a GcInfo object providing statistics about the GC cycle - * + * */ - public GarbageCollectionNotificationInfo(String gcName, String gcAction, String gcCause, GcInfo gcInfo) { + public GarbageCollectionNotificationInfo(String gcName, String gcAction, String gcCause, GcInfo gcInfo) { super(); this.gcName = gcName; this.gcAction = gcAction; @@ -214,8 +214,8 @@ public GcInfo getGcInfo() { public static GarbageCollectionNotificationInfo from(CompositeData cd) { GarbageCollectionNotificationInfo result = null; - if (cd != null) { - /* Does cd meet the necessary criteria to create a new + if (cd != null) { + /* Does cd meet the necessary criteria to create a new * GarbageCollectionNotificationInfo? * If not then exit on an IllegalArgumentException. */ @@ -226,7 +226,7 @@ public static GarbageCollectionNotificationInfo from(CompositeData cd) { "java.lang.String", //$NON-NLS-1$ "java.lang.String", //$NON-NLS-1$ CompositeData.class.getName() }; - ManagementUtils.verifyFieldTypes(cd, attributeNames, attributeTypes); + ManagementUtils.verifyFieldTypes(cd, attributeNames, attributeTypes); /* Extract the values of the attributes and use them to construct * a new GarbageCollectionNotificationInfo. @@ -245,10 +245,10 @@ public static GarbageCollectionNotificationInfo from(CompositeData cd) { } /* Implementation of the CompositeDataView interface */ - + /** *

        Return the {@code CompositeData} representation of this - * {@code GarbageCollectionNotificationInfo}. + * {@code GarbageCollectionNotificationInfo}. * * @param ct the {@code CompositeType} that the caller expects. * This parameter is ignored and can be null. diff --git a/jcl/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotificationInfoUtil.java b/jcl/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotificationInfoUtil.java index 6111ddd27de..c0519ec8980 100644 --- a/jcl/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotificationInfoUtil.java +++ b/jcl/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotificationInfoUtil.java @@ -33,7 +33,7 @@ import com.sun.management.GarbageCollectionNotificationInfo; /** - * Support for the {@link GarbageCollectionNotificationInfo} class. + * Support for the {@link GarbageCollectionNotificationInfo} class. */ public final class GarbageCollectionNotificationInfoUtil { diff --git a/jcl/src/jdk.management/share/classes/com/sun/management/internal/GcInfoUtil.java b/jcl/src/jdk.management/share/classes/com/sun/management/internal/GcInfoUtil.java index 9ae5cd55498..046ad04f112 100644 --- a/jcl/src/jdk.management/share/classes/com/sun/management/internal/GcInfoUtil.java +++ b/jcl/src/jdk.management/share/classes/com/sun/management/internal/GcInfoUtil.java @@ -39,7 +39,7 @@ import com.sun.management.GcInfo; /** - * Support for the {@link GcInfo} class. + * Support for the {@link GcInfo} class. */ public final class GcInfoUtil { @@ -127,16 +127,16 @@ public static CompositeData toCompositeData(GcInfo info) { } /** - * @param index - * the identifier of this garbage collection which is the number of collections that this collector has done - * @param startTime - * the start time of the collection in milliseconds since the Java virtual machine was started. - * @param endTime - * the end time of the collection in milliseconds since the Java virtual machine was started. - * @param usageBeforeGc - * the memory usage of all memory pools at the beginning of this GC. - * @param usageAfterGc - * the memory usage of all memory pools at the end of this GC. + * @param index + * the identifier of this garbage collection which is the number of collections that this collector has done + * @param startTime + * the start time of the collection in milliseconds since the Java virtual machine was started. + * @param endTime + * the end time of the collection in milliseconds since the Java virtual machine was started. + * @param usageBeforeGc + * the memory usage of all memory pools at the beginning of this GC. + * @param usageAfterGc + * the memory usage of all memory pools at the end of this GC. * @return a GcInfo object */ public static GcInfo newGcInfoInstance(long index, long startTime, long endTime, Map usageBeforeGc, Map usageAfterGc) { diff --git a/jcl/src/jdk.management/share/classes/jdk/crac/management/CRaCMXBean.java b/jcl/src/jdk.management/share/classes/jdk/crac/management/CRaCMXBean.java index 663bb865461..d3f8d672cc8 100644 --- a/jcl/src/jdk.management/share/classes/jdk/crac/management/CRaCMXBean.java +++ b/jcl/src/jdk.management/share/classes/jdk/crac/management/CRaCMXBean.java @@ -28,28 +28,28 @@ * A management interface of the CRaC functionality in the Java virtual machine. */ public interface CRaCMXBean extends PlatformManagedObject { - public static final String CRAC_MXBEAN_NAME = "jdk.crac.management:type=CRaC"; //$NON-NLS-1$ + public static final String CRAC_MXBEAN_NAME = "jdk.crac.management:type=CRaC"; //$NON-NLS-1$ - /** - * Returns the time since the JVM restore was initiated. Returns -1 if restore has not occurred. - * - * @return the number of in millseconds since restore, returns -1 if restore has not occurred. - */ - public long getUptimeSinceRestore(); + /** + * Returns the time since the JVM restore was initiated. Returns -1 if restore has not occurred. + * + * @return the number of in millseconds since restore, returns -1 if restore has not occurred. + */ + public long getUptimeSinceRestore(); - /** - * Returns the time when the JVM restore was initiated. Returns -1 if restore has not occurred. - * - * @return the number of milliseconds since epoch, returns -1 if restore has not occurred. - */ - public long getRestoreTime(); + /** + * Returns the time when the JVM restore was initiated. Returns -1 if restore has not occurred. + * + * @return the number of milliseconds since epoch, returns -1 if restore has not occurred. + */ + public long getRestoreTime(); - /** - * Returns the implementation of CRaCMXBean. - * - * @return the implementation of CRaCMXBean. - */ - public static CRaCMXBean getCRaCMXBean() { - return CRaCMXBeanImpl.getInstance(); - } + /** + * Returns the implementation of CRaCMXBean. + * + * @return the implementation of CRaCMXBean. + */ + public static CRaCMXBean getCRaCMXBean() { + return CRaCMXBeanImpl.getInstance(); + } } diff --git a/jcl/src/jdk.management/share/classes/jdk/crac/management/CRaCMXBeanImpl.java b/jcl/src/jdk.management/share/classes/jdk/crac/management/CRaCMXBeanImpl.java index 3e3300fadb5..5addf07ec2a 100644 --- a/jcl/src/jdk.management/share/classes/jdk/crac/management/CRaCMXBeanImpl.java +++ b/jcl/src/jdk.management/share/classes/jdk/crac/management/CRaCMXBeanImpl.java @@ -31,51 +31,51 @@ * An implementation of the CRaCMXBean interface. */ public class CRaCMXBeanImpl implements CRaCMXBean { - private final static CRaCMXBean INSTANCE = createInstance(); + private final static CRaCMXBean INSTANCE = createInstance(); - private CRaCMXBeanImpl() { - } + private CRaCMXBeanImpl() { + } - private static CRaCMXBeanImpl createInstance() { - return new CRaCMXBeanImpl(); - } + private static CRaCMXBeanImpl createInstance() { + return new CRaCMXBeanImpl(); + } - /** - * Returns an instance of {@link CRaCMXBeanImpl}. - * - * @return an instance of {@link CRaCMXBeanImpl}. - */ - public static CRaCMXBean getInstance() { - return INSTANCE; - } + /** + * Returns an instance of {@link CRaCMXBeanImpl}. + * + * @return an instance of {@link CRaCMXBeanImpl}. + */ + public static CRaCMXBean getInstance() { + return INSTANCE; + } - /** - * {@inheritDoc} - */ - @Override - public long getUptimeSinceRestore() { - long restoreTime = getRestoreTime(); - return (restoreTime > 0) ? (System.currentTimeMillis() - restoreTime) : -1; - } + /** + * {@inheritDoc} + */ + @Override + public long getUptimeSinceRestore() { + long restoreTime = getRestoreTime(); + return (restoreTime > 0) ? (System.currentTimeMillis() - restoreTime) : -1; + } - /** - * {@inheritDoc} - */ - @Override - public long getRestoreTime() { - long processRestoreStartTime = InternalCRIUSupport.getProcessRestoreStartTime(); - return (processRestoreStartTime > 0) ? TimeUnit.NANOSECONDS.toMillis(processRestoreStartTime) : -1; - } + /** + * {@inheritDoc} + */ + @Override + public long getRestoreTime() { + long processRestoreStartTime = InternalCRIUSupport.getProcessRestoreStartTime(); + return (processRestoreStartTime > 0) ? TimeUnit.NANOSECONDS.toMillis(processRestoreStartTime) : -1; + } - /** - * {@inheritDoc} - */ - @Override - public ObjectName getObjectName() { - try { - return ObjectName.getInstance(CRAC_MXBEAN_NAME); - } catch (MalformedObjectNameException e) { - throw new InternalError(e); - } - } + /** + * {@inheritDoc} + */ + @Override + public ObjectName getObjectName() { + try { + return ObjectName.getInstance(CRAC_MXBEAN_NAME); + } catch (MalformedObjectNameException e) { + throw new InternalError(e); + } + } } diff --git a/jcl/src/jdk.management/share/classes/openj9/lang/management/ConfigurationUnavailableException.java b/jcl/src/jdk.management/share/classes/openj9/lang/management/ConfigurationUnavailableException.java index c73979d8023..46314563cc3 100644 --- a/jcl/src/jdk.management/share/classes/openj9/lang/management/ConfigurationUnavailableException.java +++ b/jcl/src/jdk.management/share/classes/openj9/lang/management/ConfigurationUnavailableException.java @@ -37,5 +37,5 @@ public class ConfigurationUnavailableException extends Exception { public ConfigurationUnavailableException(String message, Throwable cause) { super(message, cause); - } + } } diff --git a/jcl/src/jdk.management/share/classes/openj9/lang/management/InvalidOptionException.java b/jcl/src/jdk.management/share/classes/openj9/lang/management/InvalidOptionException.java index 1380dea9720..204ccafe396 100644 --- a/jcl/src/jdk.management/share/classes/openj9/lang/management/InvalidOptionException.java +++ b/jcl/src/jdk.management/share/classes/openj9/lang/management/InvalidOptionException.java @@ -33,5 +33,5 @@ public class InvalidOptionException extends Exception { public InvalidOptionException(String message, Throwable cause) { super(message, cause); - } + } } diff --git a/jcl/src/jdk.management/share/classes/openj9/lang/management/OpenJ9DiagnosticsMXBean.java b/jcl/src/jdk.management/share/classes/openj9/lang/management/OpenJ9DiagnosticsMXBean.java index 872723224e6..4c7b1f73ed1 100644 --- a/jcl/src/jdk.management/share/classes/openj9/lang/management/OpenJ9DiagnosticsMXBean.java +++ b/jcl/src/jdk.management/share/classes/openj9/lang/management/OpenJ9DiagnosticsMXBean.java @@ -21,7 +21,6 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 */ - package openj9.lang.management; import java.lang.management.PlatformManagedObject; @@ -57,8 +56,8 @@ public interface OpenJ9DiagnosticsMXBean extends PlatformManagedObject { /** * Reset the JVM dump options to the settings specified when the JVM was started removing any additional - * configuration done since then. This method may throw a ConfigurationUnavailableException if the dump - * configuration cannot be altered. If this occurs it will usually be because a dump event is currently being + * configuration done since then. This method may throw a ConfigurationUnavailableException if the dump + * configuration cannot be altered. If this occurs it will usually be because a dump event is currently being * handled. * * @throws ConfigurationUnavailableException if the configuration cannot be changed because a dump is already in progress @@ -78,8 +77,8 @@ public interface OpenJ9DiagnosticsMXBean extends PlatformManagedObject { /** * This function sets options for the dump subsystem. - * The dump option is passed in as a String. Use the same syntax as the -Xdump command-line option, with the - * initial -Xdump: omitted. See the -Xdump option section on dump agents in the + * The dump option is passed in as a String. Use the same syntax as the -Xdump command-line option, with the + * initial -Xdump: omitted. See the -Xdump option section on dump agents in the * documentation for the OpenJ9 JVM. This method may throw a ConfigurationUnavailableException if the dump * configuration cannot be altered. * @@ -96,7 +95,7 @@ public interface OpenJ9DiagnosticsMXBean extends PlatformManagedObject { * A java dump is in a human-readable format, and summarizes the state of the JVM. * The default heap dump format (a phd file) is not human-readable. * A system dump is a platform-specific file that contains information about the active processes, threads, and - * system memory. System dumps are usually large. + * system memory. System dumps are usually large. * The snap dump format is not human-readable and must be processed using the trace formatting tool supplied with the OpenJ9 JVM. * * @param dumpAgent the dump agent to be triggered @@ -112,7 +111,7 @@ public interface OpenJ9DiagnosticsMXBean extends PlatformManagedObject { * The JVM will attempt to write the file to the specified file name. This may * include replacement tokens as documented in the section on dump agents * in the documentation for the OpenJ9 JVM. - * + * * A string containing the actual filename written to is returned. This may not * be the same as the requested filename for several reasons: *

          @@ -127,11 +126,11 @@ public interface OpenJ9DiagnosticsMXBean extends PlatformManagedObject { * to write the dump to another location, unless -Xdump:nofailover was specified on * the command line. *
        - * + * * If a security manager exists a permission check for com.ibm.jvm.DumpPermission will be * made, if this fails a SecurityException will be thrown. * - * @return the file name that the dump was actually written to + * @return the file name that the dump was actually written to * @param dumpAgent the dump agent to be triggered * @param fileNamePattern the filename to write to, which may be null, empty or include replacement tokens * @throws InvalidOptionException if the fileNamePattern was invalid From 65475d82a09c0a277f1600f7f7f6cc598215207c Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 14:12:40 -0400 Subject: [PATCH 09/16] Tidy up whitespace in openj9.dataaccess * remove trailing whitespace * indent with tabs consistently Signed-off-by: Keith W. Campbell --- .../ibm/dataaccess/ByteArrayMarshaller.java | 1077 ++-- .../ibm/dataaccess/ByteArrayUnmarshaller.java | 1225 ++-- .../com/ibm/dataaccess/CommonData.java | 536 +- .../com/ibm/dataaccess/DecimalData.java | 5124 ++++++++--------- .../com/ibm/dataaccess/ExternalDecimal.java | 265 +- .../com/ibm/dataaccess/PackedDecimal.java | 4078 +++++++------ 6 files changed, 6147 insertions(+), 6158 deletions(-) diff --git a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayMarshaller.java b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayMarshaller.java index 21daec8a104..b1a191a028b 100644 --- a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayMarshaller.java +++ b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayMarshaller.java @@ -28,556 +28,555 @@ * double) to byte arrays. * * @author IBM - * @version $Revision$ on $Date$ + * @version $Revision$ on $Date$ */ public class ByteArrayMarshaller { - private ByteArrayMarshaller() { - } + private ByteArrayMarshaller() { + } - /** - * Copies the short value into two consecutive bytes of the byte array - * starting at the offset. - * - * @param value - * the short value to marshall - * @param byteArray - * destination - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void writeShort(short value, byte[] byteArray, int offset, - boolean bigEndian) { - if ((offset + 2 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "writeShort is trying to access byteArray[" + offset + "] and byteArray[" + (offset + 1) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - if (bigEndian) - { - writeShort_(value, byteArray, offset, true); - } - else - { - writeShort_(value, byteArray, offset, false); - } - } - - private static void writeShort_(short value, byte[] byteArray, int offset, - boolean bigEndian) - { - if (bigEndian) { - byteArray[offset] = (byte) (value >> 8); - byteArray[offset + 1] = (byte) (value); - } else { - byteArray[offset + 1] = (byte) (value >> 8); - byteArray[offset] = (byte) (value); - } - } - - - /** - * Copies zero to two bytes of the short value into the byte array starting - * at the offset. - * - * @param value - * the short value to marshall - * @param byteArray - * destination - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * @param numBytes - * the number of bytes to marshal, must be 0-2 inclusive - * - * @throws NullPointerException - * if byteArray is null - * @throws IllegalArgumentException - * if numBytes < 0 or - * numBytes > 2 - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void writeShort(short value, byte[] byteArray, int offset, - boolean bigEndian, int numBytes) { - if ((offset + numBytes > byteArray.length) && (numBytes > 0) && (numBytes <= 2)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "writeShort is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - if (offset < 0) - throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero."); - - if (numBytes < 0 || numBytes > 2) - throw new IllegalArgumentException("numBytes == " + numBytes); - - if (bigEndian) - writeShort_(value, byteArray, offset, true, numBytes); - else - writeShort_(value, byteArray, offset, false, numBytes); - } - - private static void writeShort_(short value, byte[] byteArray, int offset, - boolean bigEndian, int numBytes) { - int i = offset; - switch (numBytes) { - case 0: - break; - case 1: - byteArray[i] = (byte) value; - break; - case 2: - if (bigEndian) { - byteArray[i] = (byte) (value >> 8); - byteArray[i + 1] = (byte) (value); - } else { - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - } - } + /** + * Copies the short value into two consecutive bytes of the byte array + * starting at the offset. + * + * @param value + * the short value to marshall + * @param byteArray + * destination + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void writeShort(short value, byte[] byteArray, int offset, + boolean bigEndian) { + if ((offset + 2 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "writeShort is trying to access byteArray[" + offset + "] and byteArray[" + (offset + 1) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - /** - * Copies an int value into four consecutive bytes of the byte array - * starting at the offset. - * - * @param value - * the int value to marshall - * @param byteArray - * destination - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void writeInt(int value, byte[] byteArray, int offset, - boolean bigEndian) { - if ((offset + 4 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "writeInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - if (bigEndian) - { - writeInt_(value, byteArray, offset, true); - } - else - { - writeInt_(value, byteArray, offset, false); - } - } + if (bigEndian) + { + writeShort_(value, byteArray, offset, true); + } + else + { + writeShort_(value, byteArray, offset, false); + } + } - private static void writeInt_(int value, byte[] byteArray, int offset, - boolean bigEndian) { - if (bigEndian) { - byteArray[offset] = (byte) (value >> 24); - byteArray[offset + 1] = (byte) (value >> 16); - byteArray[offset + 2] = (byte) (value >> 8); - byteArray[offset + 3] = (byte) (value); - } else { - byteArray[offset + 3] = (byte) (value >> 24); - byteArray[offset + 2] = (byte) (value >> 16); - byteArray[offset + 1] = (byte) (value >> 8); - byteArray[offset] = (byte) (value); - } - } - - /** - * Copies zero to four bytes of the int value into the byte array starting - * at the offset. - * - * @param value - * the int value to marshall - * @param byteArray - * destination - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * @param numBytes - * the number of bytes to marshall, must be 0-4 inclusive - * - * @throws NullPointerException - * if byteArray is null - * @throws IllegalArgumentException - * if numBytes < 0 or - * numBytes > 4 - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void writeInt(int value, byte[] byteArray, int offset, - boolean bigEndian, int numBytes) { - if ((offset + numBytes > byteArray.length) && (numBytes <= 4) && (numBytes > 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "writeInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - if (offset < 0) - throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero."); - if (numBytes < 0 || numBytes > 4) - throw new IllegalArgumentException("numBytes == " + numBytes); - - if (bigEndian) - { - writeInt_(value, byteArray, offset, true, numBytes); - } - else - { - writeInt_(value, byteArray, offset, false, numBytes); - } - } - - private static void writeInt_(int value, byte[] byteArray, int offset, - boolean bigEndian, int numBytes) { - int i = offset; - switch (numBytes) { - case 0: - break; - case 1: - byteArray[i] = (byte) value; - break; - case 2: - if (bigEndian) { - byteArray[i] = (byte) (value >> 8); - byteArray[i + 1] = (byte) (value); - } else { - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - case 3: - if (bigEndian) { - byteArray[i] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i + 2] = (byte) (value); - } else { - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - case 4: - if (bigEndian) { - byteArray[i] = (byte) (value >> 24); - byteArray[i + 1] = (byte) (value >> 16); - byteArray[i + 2] = (byte) (value >> 8); - byteArray[i + 3] = (byte) (value); - } else { - byteArray[i + 3] = (byte) (value >> 24); - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - } - } + private static void writeShort_(short value, byte[] byteArray, int offset, + boolean bigEndian) + { + if (bigEndian) { + byteArray[offset] = (byte) (value >> 8); + byteArray[offset + 1] = (byte) (value); + } else { + byteArray[offset + 1] = (byte) (value >> 8); + byteArray[offset] = (byte) (value); + } + } - /** - * Copies the long value into eight consecutive bytes of the byte array - * starting at the offset. - * - * @param value - * the long value to marshall - * @param byteArray - * destination - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void writeLong(long value, byte[] byteArray, int offset, - boolean bigEndian) { - if ((offset + 8 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "writeLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - if (bigEndian) - { - writeLong_(value, byteArray, offset, true); - } - else - { - writeLong_(value, byteArray, offset, false); - } - } - - private static void writeLong_(long value, byte[] byteArray, int offset, - boolean bigEndian) { - if (bigEndian) { - byteArray[offset] = (byte) (value >> 56); - byteArray[offset + 1] = (byte) (value >> 48); - byteArray[offset + 2] = (byte) (value >> 40); - byteArray[offset + 3] = (byte) (value >> 32); - byteArray[offset + 4] = (byte) (value >> 24); - byteArray[offset + 5] = (byte) (value >> 16); - byteArray[offset + 6] = (byte) (value >> 8); - byteArray[offset + 7] = (byte) (value); - } else { - byteArray[offset + 7] = (byte) (value >> 56); - byteArray[offset + 6] = (byte) (value >> 48); - byteArray[offset + 5] = (byte) (value >> 40); - byteArray[offset + 4] = (byte) (value >> 32); - byteArray[offset + 3] = (byte) (value >> 24); - byteArray[offset + 2] = (byte) (value >> 16); - byteArray[offset + 1] = (byte) (value >> 8); - byteArray[offset] = (byte) (value); - } - } + /** + * Copies zero to two bytes of the short value into the byte array starting + * at the offset. + * + * @param value + * the short value to marshall + * @param byteArray + * destination + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * @param numBytes + * the number of bytes to marshal, must be 0-2 inclusive + * + * @throws NullPointerException + * if byteArray is null + * @throws IllegalArgumentException + * if numBytes < 0 or + * numBytes > 2 + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void writeShort(short value, byte[] byteArray, int offset, + boolean bigEndian, int numBytes) { + if ((offset + numBytes > byteArray.length) && (numBytes > 0) && (numBytes <= 2)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "writeShort is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + if (offset < 0) + throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero."); - /** - * Copies zero to eight bytes of the long value into the byte array starting - * at the offset. - * - * @param value - * the long value to marshall - * @param byteArray - * destination - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * @param numBytes - * the number of bytes to marshal, must be 0-8 inclusive - * - * @throws NullPointerException - * if byteArray is null - * @throws IllegalArgumentException - * if numBytes < 0 or - * numBytes > 8 - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void writeLong(long value, byte[] byteArray, int offset, - boolean bigEndian, int numBytes) { - if ((offset + numBytes > byteArray.length) && (numBytes > 0) && (numBytes <=8)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "writeLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - if (offset < 0) - throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero."); - - if (numBytes < 0 || numBytes > 8) - throw new IllegalArgumentException("numBytes == " + numBytes); - - if (bigEndian) - writeLong_(value, byteArray, offset, true, numBytes); - else - writeLong_(value, byteArray, offset, false, numBytes); - } + if (numBytes < 0 || numBytes > 2) + throw new IllegalArgumentException("numBytes == " + numBytes); - private static void writeLong_(long value, byte[] byteArray, int offset, - boolean bigEndian, int numBytes) { - int i = offset; - switch (numBytes) { - case 0: - break; - case 1: - byteArray[i] = (byte) value; - break; - case 2: - if (bigEndian) { - byteArray[i] = (byte) (value >> 8); - byteArray[i + 1] = (byte) (value); - } else { - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - case 3: - if (bigEndian) { - byteArray[i] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i + 2] = (byte) (value); - } else { - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - case 4: - if (bigEndian) { - byteArray[i] = (byte) (value >> 24); - byteArray[i + 1] = (byte) (value >> 16); - byteArray[i + 2] = (byte) (value >> 8); - byteArray[i + 3] = (byte) (value); - } else { - byteArray[i + 3] = (byte) (value >> 24); - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - case 5: - if (bigEndian) { - byteArray[i] = (byte) (value >> 32); - byteArray[i + 1] = (byte) (value >> 24); - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 3] = (byte) (value >> 8); - byteArray[i + 4] = (byte) (value); - } else { - byteArray[i + 4] = (byte) (value >> 32); - byteArray[i + 3] = (byte) (value >> 24); - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - case 6: - if (bigEndian) { - byteArray[i] = (byte) (value >> 40); - byteArray[i + 1] = (byte) (value >> 32); - byteArray[i + 2] = (byte) (value >> 24); - byteArray[i + 3] = (byte) (value >> 16); - byteArray[i + 4] = (byte) (value >> 8); - byteArray[i + 5] = (byte) (value); - } else { - byteArray[i + 5] = (byte) (value >> 40); - byteArray[i + 4] = (byte) (value >> 32); - byteArray[i + 3] = (byte) (value >> 24); - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - case 7: - if (bigEndian) { - byteArray[i] = (byte) (value >> 48); - byteArray[i + 1] = (byte) (value >> 40); - byteArray[i + 2] = (byte) (value >> 32); - byteArray[i + 3] = (byte) (value >> 24); - byteArray[i + 4] = (byte) (value >> 16); - byteArray[i + 5] = (byte) (value >> 8); - byteArray[i + 6] = (byte) (value); - } else { - byteArray[i + 6] = (byte) (value >> 48); - byteArray[i + 5] = (byte) (value >> 40); - byteArray[i + 4] = (byte) (value >> 32); - byteArray[i + 3] = (byte) (value >> 24); - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - case 8: - if (bigEndian) { - byteArray[i] = (byte) (value >> 56); - byteArray[i + 1] = (byte) (value >> 48); - byteArray[i + 2] = (byte) (value >> 40); - byteArray[i + 3] = (byte) (value >> 32); - byteArray[i + 4] = (byte) (value >> 24); - byteArray[i + 5] = (byte) (value >> 16); - byteArray[i + 6] = (byte) (value >> 8); - byteArray[i + 7] = (byte) (value); - } else { - byteArray[i + 7] = (byte) (value >> 56); - byteArray[i + 6] = (byte) (value >> 48); - byteArray[i + 5] = (byte) (value >> 40); - byteArray[i + 4] = (byte) (value >> 32); - byteArray[i + 3] = (byte) (value >> 24); - byteArray[i + 2] = (byte) (value >> 16); - byteArray[i + 1] = (byte) (value >> 8); - byteArray[i] = (byte) (value); - } - break; - } + if (bigEndian) + writeShort_(value, byteArray, offset, true, numBytes); + else + writeShort_(value, byteArray, offset, false, numBytes); + } - } - - /** - * Copies the float value into four consecutive bytes of the byte array - * starting at the offset. - * - * @param value - * the float value to marshall - * @param byteArray - * destination - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void writeFloat(float value, byte[] byteArray, int offset, - boolean bigEndian) { - if ((offset + 4 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "writeFloat is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - if (bigEndian) - writeFloat_(value, byteArray, offset, true); - else - writeFloat_(value, byteArray, offset, false); - } - - private static void writeFloat_(float value, byte[] byteArray, int offset, - boolean bigEndian) { - writeInt(Float.floatToIntBits(value), byteArray, offset, bigEndian); - } + private static void writeShort_(short value, byte[] byteArray, int offset, + boolean bigEndian, int numBytes) { + int i = offset; + switch (numBytes) { + case 0: + break; + case 1: + byteArray[i] = (byte) value; + break; + case 2: + if (bigEndian) { + byteArray[i] = (byte) (value >> 8); + byteArray[i + 1] = (byte) (value); + } else { + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + } + } - /** - * Copies the double value into eight consecutive bytes of the byte array - * starting at the offset. - * - * @param value - * the double value to marshall - * @param byteArray - * destination - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void writeDouble(double value, byte[] byteArray, int offset, - boolean bigEndian) { - if ((offset + 8 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "writeDouble is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + /** + * Copies an int value into four consecutive bytes of the byte array + * starting at the offset. + * + * @param value + * the int value to marshall + * @param byteArray + * destination + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void writeInt(int value, byte[] byteArray, int offset, + boolean bigEndian) { + if ((offset + 4 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "writeInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - if (bigEndian) - writeDouble_(value, byteArray, offset, true); - else - writeDouble_(value, byteArray, offset, false); - } - - private static void writeDouble_(double value, byte[] byteArray, int offset, - boolean bigEndian) { - writeLong(Double.doubleToLongBits(value), byteArray, offset, bigEndian); - } + if (bigEndian) + { + writeInt_(value, byteArray, offset, true); + } + else + { + writeInt_(value, byteArray, offset, false); + } + } + + private static void writeInt_(int value, byte[] byteArray, int offset, + boolean bigEndian) { + if (bigEndian) { + byteArray[offset] = (byte) (value >> 24); + byteArray[offset + 1] = (byte) (value >> 16); + byteArray[offset + 2] = (byte) (value >> 8); + byteArray[offset + 3] = (byte) (value); + } else { + byteArray[offset + 3] = (byte) (value >> 24); + byteArray[offset + 2] = (byte) (value >> 16); + byteArray[offset + 1] = (byte) (value >> 8); + byteArray[offset] = (byte) (value); + } + } + + /** + * Copies zero to four bytes of the int value into the byte array starting + * at the offset. + * + * @param value + * the int value to marshall + * @param byteArray + * destination + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * @param numBytes + * the number of bytes to marshall, must be 0-4 inclusive + * + * @throws NullPointerException + * if byteArray is null + * @throws IllegalArgumentException + * if numBytes < 0 or + * numBytes > 4 + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void writeInt(int value, byte[] byteArray, int offset, + boolean bigEndian, int numBytes) { + if ((offset + numBytes > byteArray.length) && (numBytes <= 4) && (numBytes > 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "writeInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + if (offset < 0) + throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero."); + if (numBytes < 0 || numBytes > 4) + throw new IllegalArgumentException("numBytes == " + numBytes); + + if (bigEndian) + { + writeInt_(value, byteArray, offset, true, numBytes); + } + else + { + writeInt_(value, byteArray, offset, false, numBytes); + } + } + + private static void writeInt_(int value, byte[] byteArray, int offset, + boolean bigEndian, int numBytes) { + int i = offset; + switch (numBytes) { + case 0: + break; + case 1: + byteArray[i] = (byte) value; + break; + case 2: + if (bigEndian) { + byteArray[i] = (byte) (value >> 8); + byteArray[i + 1] = (byte) (value); + } else { + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + case 3: + if (bigEndian) { + byteArray[i] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i + 2] = (byte) (value); + } else { + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + case 4: + if (bigEndian) { + byteArray[i] = (byte) (value >> 24); + byteArray[i + 1] = (byte) (value >> 16); + byteArray[i + 2] = (byte) (value >> 8); + byteArray[i + 3] = (byte) (value); + } else { + byteArray[i + 3] = (byte) (value >> 24); + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + } + } + + /** + * Copies the long value into eight consecutive bytes of the byte array + * starting at the offset. + * + * @param value + * the long value to marshall + * @param byteArray + * destination + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void writeLong(long value, byte[] byteArray, int offset, + boolean bigEndian) { + if ((offset + 8 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "writeLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + + if (bigEndian) + { + writeLong_(value, byteArray, offset, true); + } + else + { + writeLong_(value, byteArray, offset, false); + } + } + + private static void writeLong_(long value, byte[] byteArray, int offset, + boolean bigEndian) { + if (bigEndian) { + byteArray[offset] = (byte) (value >> 56); + byteArray[offset + 1] = (byte) (value >> 48); + byteArray[offset + 2] = (byte) (value >> 40); + byteArray[offset + 3] = (byte) (value >> 32); + byteArray[offset + 4] = (byte) (value >> 24); + byteArray[offset + 5] = (byte) (value >> 16); + byteArray[offset + 6] = (byte) (value >> 8); + byteArray[offset + 7] = (byte) (value); + } else { + byteArray[offset + 7] = (byte) (value >> 56); + byteArray[offset + 6] = (byte) (value >> 48); + byteArray[offset + 5] = (byte) (value >> 40); + byteArray[offset + 4] = (byte) (value >> 32); + byteArray[offset + 3] = (byte) (value >> 24); + byteArray[offset + 2] = (byte) (value >> 16); + byteArray[offset + 1] = (byte) (value >> 8); + byteArray[offset] = (byte) (value); + } + } + + /** + * Copies zero to eight bytes of the long value into the byte array starting + * at the offset. + * + * @param value + * the long value to marshall + * @param byteArray + * destination + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * @param numBytes + * the number of bytes to marshal, must be 0-8 inclusive + * + * @throws NullPointerException + * if byteArray is null + * @throws IllegalArgumentException + * if numBytes < 0 or + * numBytes > 8 + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void writeLong(long value, byte[] byteArray, int offset, + boolean bigEndian, int numBytes) { + if ((offset + numBytes > byteArray.length) && (numBytes > 0) && (numBytes <=8)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "writeLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + if (offset < 0) + throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero."); + + if (numBytes < 0 || numBytes > 8) + throw new IllegalArgumentException("numBytes == " + numBytes); + + if (bigEndian) + writeLong_(value, byteArray, offset, true, numBytes); + else + writeLong_(value, byteArray, offset, false, numBytes); + } + + private static void writeLong_(long value, byte[] byteArray, int offset, + boolean bigEndian, int numBytes) { + int i = offset; + switch (numBytes) { + case 0: + break; + case 1: + byteArray[i] = (byte) value; + break; + case 2: + if (bigEndian) { + byteArray[i] = (byte) (value >> 8); + byteArray[i + 1] = (byte) (value); + } else { + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + case 3: + if (bigEndian) { + byteArray[i] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i + 2] = (byte) (value); + } else { + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + case 4: + if (bigEndian) { + byteArray[i] = (byte) (value >> 24); + byteArray[i + 1] = (byte) (value >> 16); + byteArray[i + 2] = (byte) (value >> 8); + byteArray[i + 3] = (byte) (value); + } else { + byteArray[i + 3] = (byte) (value >> 24); + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + case 5: + if (bigEndian) { + byteArray[i] = (byte) (value >> 32); + byteArray[i + 1] = (byte) (value >> 24); + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 3] = (byte) (value >> 8); + byteArray[i + 4] = (byte) (value); + } else { + byteArray[i + 4] = (byte) (value >> 32); + byteArray[i + 3] = (byte) (value >> 24); + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + case 6: + if (bigEndian) { + byteArray[i] = (byte) (value >> 40); + byteArray[i + 1] = (byte) (value >> 32); + byteArray[i + 2] = (byte) (value >> 24); + byteArray[i + 3] = (byte) (value >> 16); + byteArray[i + 4] = (byte) (value >> 8); + byteArray[i + 5] = (byte) (value); + } else { + byteArray[i + 5] = (byte) (value >> 40); + byteArray[i + 4] = (byte) (value >> 32); + byteArray[i + 3] = (byte) (value >> 24); + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + case 7: + if (bigEndian) { + byteArray[i] = (byte) (value >> 48); + byteArray[i + 1] = (byte) (value >> 40); + byteArray[i + 2] = (byte) (value >> 32); + byteArray[i + 3] = (byte) (value >> 24); + byteArray[i + 4] = (byte) (value >> 16); + byteArray[i + 5] = (byte) (value >> 8); + byteArray[i + 6] = (byte) (value); + } else { + byteArray[i + 6] = (byte) (value >> 48); + byteArray[i + 5] = (byte) (value >> 40); + byteArray[i + 4] = (byte) (value >> 32); + byteArray[i + 3] = (byte) (value >> 24); + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + case 8: + if (bigEndian) { + byteArray[i] = (byte) (value >> 56); + byteArray[i + 1] = (byte) (value >> 48); + byteArray[i + 2] = (byte) (value >> 40); + byteArray[i + 3] = (byte) (value >> 32); + byteArray[i + 4] = (byte) (value >> 24); + byteArray[i + 5] = (byte) (value >> 16); + byteArray[i + 6] = (byte) (value >> 8); + byteArray[i + 7] = (byte) (value); + } else { + byteArray[i + 7] = (byte) (value >> 56); + byteArray[i + 6] = (byte) (value >> 48); + byteArray[i + 5] = (byte) (value >> 40); + byteArray[i + 4] = (byte) (value >> 32); + byteArray[i + 3] = (byte) (value >> 24); + byteArray[i + 2] = (byte) (value >> 16); + byteArray[i + 1] = (byte) (value >> 8); + byteArray[i] = (byte) (value); + } + break; + } + + } + + /** + * Copies the float value into four consecutive bytes of the byte array + * starting at the offset. + * + * @param value + * the float value to marshall + * @param byteArray + * destination + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void writeFloat(float value, byte[] byteArray, int offset, + boolean bigEndian) { + if ((offset + 4 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "writeFloat is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + if (bigEndian) + writeFloat_(value, byteArray, offset, true); + else + writeFloat_(value, byteArray, offset, false); + } + + private static void writeFloat_(float value, byte[] byteArray, int offset, + boolean bigEndian) { + writeInt(Float.floatToIntBits(value), byteArray, offset, bigEndian); + } + + /** + * Copies the double value into eight consecutive bytes of the byte array + * starting at the offset. + * + * @param value + * the double value to marshall + * @param byteArray + * destination + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void writeDouble(double value, byte[] byteArray, int offset, + boolean bigEndian) { + if ((offset + 8 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "writeDouble is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + + if (bigEndian) + writeDouble_(value, byteArray, offset, true); + else + writeDouble_(value, byteArray, offset, false); + } + + private static void writeDouble_(double value, byte[] byteArray, int offset, + boolean bigEndian) { + writeLong(Double.doubleToLongBits(value), byteArray, offset, bigEndian); + } } diff --git a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayUnmarshaller.java b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayUnmarshaller.java index d893919d372..c70ba153f13 100644 --- a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayUnmarshaller.java +++ b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayUnmarshaller.java @@ -25,626 +25,627 @@ /** * Conversion routines to unmarshall Java binary types (short, int, long, float, * double) from byte arrays. - * + * *

        * With sign extensions enabled, the marshalled data is interpreted as signed * and the data will be appropriately converted into the return type container. * With sign extensions disabled, unfilled bits in the container will be set to - * zero. For example, -1 as one signed byte is 0xFF. - * Using readShort with signExtend true, the resultant - * short will contain 0xFFFF, which is -1 in Java's - * signed format. With signExtend false, the resultant short will + * zero. For example, -1 as one signed byte is 0xFF. + * Using readShort with signExtend true, the resultant + * short will contain 0xFFFF, which is -1 in Java's + * signed format. With signExtend false, the resultant short will * contain 0x00FF, which is 255. *

        - * + * * @author IBM - * @version $Revision$ on $Date$ + * @version $Revision$ on $Date$ */ public final class ByteArrayUnmarshaller { - // private constructor, class contains only static methods. - private ByteArrayUnmarshaller() { - super(); - } - - /** - * Returns a short value copied from two consecutive bytes of the byte array - * starting at the offset. - * - * @param byteArray - * source - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @return short - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static short readShort(byte[] byteArray, int offset, - boolean bigEndian) { - if ((offset + 2 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "readShort is trying to access byteArray[" + offset + "] and byteArray[" + (offset + 1) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - if (bigEndian) - return readShort_(byteArray, offset, true); - else - return readShort_(byteArray, offset, false); - } - - private static short readShort_(byte[] byteArray, int offset, - boolean bigEndian) { - if (bigEndian) { - return (short) (((byteArray[offset] & 0xFF) << 8) | ((byteArray[offset + 1] & 0xFF))); - } else { - return (short) (((byteArray[offset + 1] & 0xFF) << 8) | ((byteArray[offset] & 0xFF))); - } - } - - /** - * Returns a short value copied from zero to two consecutive bytes of the - * byte array starting at the offset. - * - * @param byteArray - * source - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * @param numBytes - * the number of bytes to unmarshall, must be 0-2 inclusive - * @param signExtend - * if true and numBytes < 2 then the topmost - * bytes of the returned short will be sign extended - * - * @return long - * - * @throws NullPointerException - * if byteArray is null - * @throws IllegalArgumentException - * if numBytes < 0 or - * numBytes > 2 - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static short readShort(byte[] byteArray, int offset, - boolean bigEndian, int numBytes, boolean signExtend) - { - if ((offset + numBytes > byteArray.length) || offset < 0) - throw new ArrayIndexOutOfBoundsException("Access offset must be positive or zero and last byte must be in range."); - if (numBytes < 0 || numBytes > 2) - throw new IllegalArgumentException("numBytes == " + numBytes); - - if (bigEndian) - { - if (signExtend) - return readShort_(byteArray, offset, true, numBytes, true); - else - return readShort_(byteArray, offset, true, numBytes, false); - } - else - { - if (signExtend) - return readShort_(byteArray, offset, false, numBytes, true); - else - return readShort_(byteArray, offset, false, numBytes, false); - } - } - - private static short readShort_(byte[] byteArray, int offset, - boolean bigEndian, int numBytes, boolean signExtend) { - int i = offset; - switch (numBytes) { - case 0: - return 0; - case 1: - if (signExtend) - return byteArray[i]; - else - return (short) (byteArray[i] & 0x00FF); - case 2: - if (bigEndian) { - return (short) (((byteArray[i] & 0xFF) << 8) | ((byteArray[i + 1] & 0xFF))); - } else { - return (short) (((byteArray[i + 1] & 0xFF) << 8) | ((byteArray[i] & 0xFF))); - } - default: - return 0; - } - } - - /** - * Returns an int value copied from four consecutive bytes starting at the - * offset. - * - * @param byteArray - * source - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @return int - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static int readInt(byte[] byteArray, int offset, boolean bigEndian) { - if ((offset + 4 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "readInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - if (bigEndian) - { - return readInt_(byteArray, offset, true); - } - else - { - return readInt_(byteArray, offset, false); - } - } - - private static int readInt_(byte[] byteArray, int offset, boolean bigEndian) { - if (bigEndian) { - return ((byteArray[offset] & 0xFF) << 24) - | ((byteArray[offset + 1] & 0xFF) << 16) - | ((byteArray[offset + 2] & 0xFF) << 8) - | ((byteArray[offset + 3] & 0xFF)); - } else { - return ((byteArray[offset + 3] & 0xFF) << 24) - | ((byteArray[offset + 2] & 0xFF) << 16) - | ((byteArray[offset + 1] & 0xFF) << 8) - | ((byteArray[offset] & 0xFF)); - } - } - - /** - * Returns an int value copied from zero to four consecutive bytes of the - * byte array starting at the offset. - * - * @param byteArray - * source - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * @param numBytes - * the number of bytes to unmarshall, must be 0-4 inclusive - * @param signExtend - * if true and numBytes < 4 then the topmost - * bytes of the returned int will be sign extended - * - * @return int - * - * @throws NullPointerException - * if byteArray is null - * @throws IllegalArgumentException - * if numBytes < 0 or - * numBytes > 4 - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static int readInt(byte[] byteArray, int offset, boolean bigEndian, - int numBytes, boolean signExtend) - { - if ((offset + numBytes > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Access offset must be positive or zero and last byte must be in range."); - if (numBytes < 0 || numBytes > 4) - throw new IllegalArgumentException("numBytes == " + numBytes); - - if (bigEndian) - { - if (signExtend) - return readInt_(byteArray, offset, true, numBytes, true); - else - return readInt_(byteArray, offset, true, numBytes, false); - } - else - { - if (signExtend) - return readInt_(byteArray, offset, false, numBytes, true); - else - return readInt_(byteArray, offset, false, numBytes, false); - } - } - - private static int readInt_(byte[] byteArray, int offset, boolean bigEndian, - int numBytes, boolean signExtend) { - int i = offset; - int answer; - switch (numBytes) { - case 0: - return 0; - case 1: - if (signExtend) - return byteArray[i]; - else - return byteArray[i] & 0x000000FF; - case 2: - if (bigEndian) { - answer = (((byteArray[i] & 0xFF) << 8) | (byteArray[i + 1] & 0xFF)); - } else { - answer = (((byteArray[i + 1] & 0xFF) << 8) | (byteArray[i] & 0xFF)); - } - if (signExtend) - return (short) answer; - else - return answer & 0x0000FFFF; - case 3: - if (bigEndian) { - answer = ((byteArray[i] & 0xFF) << 16) - | ((byteArray[i + 1] & 0xFF) << 8) - | ((byteArray[i + 2] & 0xFF)); - } else { - answer = ((byteArray[i + 2] & 0xFF) << 16) - | ((byteArray[i + 1] & 0xFF) << 8) - | ((byteArray[i] & 0xFF)); - } - /* if the most significant bit is 1, we need to do sign extension */ - if (signExtend && (answer & (1 << (3 * 8 - 1))) != 0) { - answer |= 0xFF000000; - } - return answer; - case 4: - if (bigEndian) { - return ((byteArray[i] & 0xFF) << 24) - | ((byteArray[i + 1] & 0xFF) << 16) - | ((byteArray[i + 2] & 0xFF) << 8) - | ((byteArray[i + 3] & 0xFF)); - } else { - return ((byteArray[i + 3] & 0xFF) << 24) - | ((byteArray[i + 2] & 0xFF) << 16) - | ((byteArray[i + 1] & 0xFF) << 8) - | ((byteArray[i] & 0xFF)); - } - default: - return 0; - } - } - - /** - * Returns a long value copied from eight consecutive bytes of the byte - * array starting at the offset. - * - * @param byteArray - * source - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @return long - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static long readLong(byte[] byteArray, int offset, boolean bigEndian) { - if ((offset + 8 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "readLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - if (bigEndian) - { - return readLong_(byteArray, offset, true); - } - else - { - return readLong_(byteArray, offset, false); - } - } - - private static long readLong_(byte[] byteArray, int offset, boolean bigEndian) { - if (bigEndian) { - return (((long) (byteArray[offset] & 0xFF)) << 56) - | (((long) (byteArray[offset + 1] & 0xFF)) << 48) - | (((long) (byteArray[offset + 2] & 0xFF)) << 40) - | (((long) (byteArray[offset + 3] & 0xFF)) << 32) - | (((long) (byteArray[offset + 4] & 0xFF)) << 24) - | (((byteArray[offset + 5] & 0xFF)) << 16) - | (((byteArray[offset + 6] & 0xFF)) << 8) - | (((byteArray[offset + 7] & 0xFF))); - } else { - return (((long) (byteArray[offset + 7] & 0xFF)) << 56) - | (((long) (byteArray[offset + 6] & 0xFF)) << 48) - | (((long) (byteArray[offset + 5] & 0xFF)) << 40) - | (((long) (byteArray[offset + 4] & 0xFF)) << 32) - | (((long) (byteArray[offset + 3] & 0xFF)) << 24) - | (((byteArray[offset + 2] & 0xFF)) << 16) - | (((byteArray[offset + 1] & 0xFF)) << 8) - | (((byteArray[offset] & 0xFF))); - } - } - - /** - * Returns a long value copied from zero to eight consecutive bytes of the - * byte array starting at the offset. - * - * @param byteArray - * source - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * @param numBytes - * the number of bytes to unmarshall, must be 0-8 inclusive - * @param signExtend - * if true and numBytes < 8 then the topmost - * bytes of the returned long will be sign extended - * - * @return long - * - * @throws NullPointerException - * if byteArray is null - * @throws IllegalArgumentException - * if numBytes < 0 or - * numBytes > 8 - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static long readLong(byte[] byteArray, int offset, - boolean bigEndian, int numBytes, boolean signExtend) { - if ((offset + numBytes > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Access offset must be positive or zero and last byte must be in range."); - if (numBytes < 0 || numBytes > 8) - throw new IllegalArgumentException("numBytes == " + numBytes); - - if (bigEndian) - { - if (signExtend) - return readLong_(byteArray, offset, true, numBytes, true); - else - return readLong_(byteArray, offset, true, numBytes, false); - } - else - { - if (signExtend) - return readLong_(byteArray, offset, false, numBytes, true); - else - return readLong_(byteArray, offset, false, numBytes, false); - } - } - private static long readLong_(byte[] byteArray, int offset, - boolean bigEndian, int numBytes, boolean signExtend) { - int i = offset; - long answer; - switch (numBytes) { - case 0: - return 0; - case 1: - if (signExtend) - return byteArray[i]; - else - return byteArray[i] & 0x00000000000000FFl; - case 2: - if (bigEndian) { - answer = (((byteArray[i] & 0xFF) << 8) | (byteArray[i + 1] & 0xFF)); - } else { - answer = (((byteArray[i + 1] & 0xFF) << 8) | (byteArray[i] & 0xFF)); - } - if (signExtend) - return (short) answer; - else - return answer & 0x000000000000FFFFl; - case 3: - if (bigEndian) { - answer = (((byteArray[i]) & 0xFF) << 16) - | (((byteArray[i + 1]) & 0xFF) << 8) - | (((byteArray[i + 2]) & 0xFF)); - - } else { - answer = (((byteArray[i + 2]) & 0xFF) << 16) - | (((byteArray[i + 1]) & 0xFF) << 8) - | (((byteArray[i]) & 0xFF)); - - } - - if (signExtend) { - answer = (answer << 40) >> 40; - } - - return answer; - case 4: - if (bigEndian) { - answer = ((((long) byteArray[i]) & 0xFF) << 24) - | (((byteArray[i + 1]) & 0xFF) << 16) - | (((byteArray[i + 2]) & 0xFF) << 8) - | (((byteArray[i + 3]) & 0xFF)); - - } else { - answer = ((((long) byteArray[i + 3]) & 0xFF) << 24) - | (((byteArray[i + 2]) & 0xFF) << 16) - | (((byteArray[i + 1]) & 0xFF) << 8) - | (((byteArray[i]) & 0xFF)); - - } - - if (signExtend) { - answer = (answer << 32) >> 32; - } - - return answer; - case 5: - if (bigEndian) { - answer = ((((long) byteArray[i]) & 0xFF) << 32) - | ((((long) byteArray[i + 1]) & 0xFF) << 24) - | (((byteArray[i + 2]) & 0xFF) << 16) - | (((byteArray[i + 3]) & 0xFF) << 8) - | (((byteArray[i + 4]) & 0xFF)); - - } else { - answer = ((((long) byteArray[i + 4]) & 0xFF) << 32) - | ((((long) byteArray[i + 3]) & 0xFF) << 24) - | (((byteArray[i + 2]) & 0xFF) << 16) - | (((byteArray[i + 1]) & 0xFF) << 8) - | (((byteArray[i]) & 0xFF)); - - } - - if (signExtend) { - answer = (answer << 24) >> 24; - } - return answer; - case 6: - if (bigEndian) { - answer = ((((long) byteArray[i]) & 0xFF) << 40) - | ((((long) byteArray[i + 1]) & 0xFF) << 32) - | ((((long) byteArray[i + 2]) & 0xFF) << 24) - | (((byteArray[i + 3]) & 0xFF) << 16) - | (((byteArray[i + 4]) & 0xFF) << 8) - | (((byteArray[i + 5]) & 0xFF)); - - } else { - answer = ((((long) byteArray[i + 5]) & 0xFF) << 40) - | ((((long) byteArray[i + 4]) & 0xFF) << 32) - | ((((long) byteArray[i + 3]) & 0xFF) << 24) - | (((byteArray[i + 2]) & 0xFF) << 16) - | (((byteArray[i + 1]) & 0xFF) << 8) - | (((byteArray[i]) & 0xFF)); - } - - if (signExtend) { - answer = (answer << 16) >> 16; - } - return answer; - case 7: - if (bigEndian) { - answer = ((((long) byteArray[i]) & 0xFF) << 48) - | ((((long) byteArray[i + 1]) & 0xFF) << 40) - | ((((long) byteArray[i + 2]) & 0xFF) << 32) - | ((((long) byteArray[i + 3]) & 0xFF) << 24) - | (((byteArray[i + 4]) & 0xFF) << 16) - | (((byteArray[i + 5]) & 0xFF) << 8) - | (((byteArray[i + 6]) & 0xFF)); - - } else { - answer = ((((long) byteArray[i + 6]) & 0xFF) << 48) - | ((((long) byteArray[i + 5]) & 0xFF) << 40) - | ((((long) byteArray[i + 4]) & 0xFF) << 32) - | ((((long) byteArray[i + 3]) & 0xFF) << 24) - | (((byteArray[i + 2]) & 0xFF) << 16) - | (((byteArray[i + 1]) & 0xFF) << 8) - | (((byteArray[i]) & 0xFF)); - - } - - if (signExtend) { - answer = (answer << 8) >> 8; - } - - return answer; - case 8: - if (bigEndian) { - return ((((long) byteArray[i]) & 0xFF) << 56) - | ((((long) byteArray[i + 1]) & 0xFF) << 48) - | ((((long) byteArray[i + 2]) & 0xFF) << 40) - | ((((long) byteArray[i + 3]) & 0xFF) << 32) - | ((((long) byteArray[i + 4]) & 0xFF) << 24) - | (((byteArray[i + 5]) & 0xFF) << 16) - | (((byteArray[i + 6]) & 0xFF) << 8) - | (((byteArray[i + 7]) & 0xFF)); - } else { - return ((((long) byteArray[i + 7]) & 0xFF) << 56) - | ((((long) byteArray[i + 6]) & 0xFF) << 48) - | ((((long) byteArray[i + 5]) & 0xFF) << 40) - | ((((long) byteArray[i + 4]) & 0xFF) << 32) - | ((((long) byteArray[i + 3]) & 0xFF) << 24) - | (((byteArray[i + 2]) & 0xFF) << 16) - | (((byteArray[i + 1]) & 0xFF) << 8) - | (((byteArray[i]) & 0xFF)); - } - default: - return 0; - } - } - - /** - * Returns a float value copied from four consecutive bytes of the byte - * array starting at the offset. - * - * @param byteArray - * source - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @return float - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static float readFloat(byte[] byteArray, int offset, - boolean bigEndian) { - if ((offset + 4 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "readFloat is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - if (bigEndian) - return readFloat_(byteArray, offset, true); - else - return readFloat_(byteArray, offset, false); - } - - private static float readFloat_(byte[] byteArray, int offset, - boolean bigEndian) { - return Float.intBitsToFloat(readInt(byteArray, offset, bigEndian)); - } - - /** - * Returns a double value copied from eight consecutive bytes of the byte - * array starting at the offset. - * - * @param byteArray - * source - * @param offset - * offset in the byte array - * @param bigEndian - * if false the bytes will be copied in reverse (little endian) - * order - * - * @return double - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static double readDouble(byte[] byteArray, int offset, - boolean bigEndian) { - if ((offset + 8 > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "readDouble is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - if (bigEndian) - return readDouble_(byteArray, offset, true); - else - return readDouble_(byteArray, offset, false); - } - private static double readDouble_(byte[] byteArray, int offset, - boolean bigEndian) { - return Double.longBitsToDouble(readLong(byteArray, offset, bigEndian)); - } + // private constructor, class contains only static methods. + private ByteArrayUnmarshaller() { + super(); + } + + /** + * Returns a short value copied from two consecutive bytes of the byte array + * starting at the offset. + * + * @param byteArray + * source + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @return short + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static short readShort(byte[] byteArray, int offset, + boolean bigEndian) { + if ((offset + 2 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "readShort is trying to access byteArray[" + offset + "] and byteArray[" + (offset + 1) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + + if (bigEndian) + return readShort_(byteArray, offset, true); + else + return readShort_(byteArray, offset, false); + } + + private static short readShort_(byte[] byteArray, int offset, + boolean bigEndian) { + if (bigEndian) { + return (short) (((byteArray[offset] & 0xFF) << 8) | ((byteArray[offset + 1] & 0xFF))); + } else { + return (short) (((byteArray[offset + 1] & 0xFF) << 8) | ((byteArray[offset] & 0xFF))); + } + } + + /** + * Returns a short value copied from zero to two consecutive bytes of the + * byte array starting at the offset. + * + * @param byteArray + * source + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * @param numBytes + * the number of bytes to unmarshall, must be 0-2 inclusive + * @param signExtend + * if true and numBytes < 2 then the topmost + * bytes of the returned short will be sign extended + * + * @return long + * + * @throws NullPointerException + * if byteArray is null + * @throws IllegalArgumentException + * if numBytes < 0 or + * numBytes > 2 + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static short readShort(byte[] byteArray, int offset, + boolean bigEndian, int numBytes, boolean signExtend) + { + if ((offset + numBytes > byteArray.length) || offset < 0) + throw new ArrayIndexOutOfBoundsException("Access offset must be positive or zero and last byte must be in range."); + if (numBytes < 0 || numBytes > 2) + throw new IllegalArgumentException("numBytes == " + numBytes); + + if (bigEndian) + { + if (signExtend) + return readShort_(byteArray, offset, true, numBytes, true); + else + return readShort_(byteArray, offset, true, numBytes, false); + } + else + { + if (signExtend) + return readShort_(byteArray, offset, false, numBytes, true); + else + return readShort_(byteArray, offset, false, numBytes, false); + } + } + + private static short readShort_(byte[] byteArray, int offset, + boolean bigEndian, int numBytes, boolean signExtend) { + int i = offset; + switch (numBytes) { + case 0: + return 0; + case 1: + if (signExtend) + return byteArray[i]; + else + return (short) (byteArray[i] & 0x00FF); + case 2: + if (bigEndian) { + return (short) (((byteArray[i] & 0xFF) << 8) | ((byteArray[i + 1] & 0xFF))); + } else { + return (short) (((byteArray[i + 1] & 0xFF) << 8) | ((byteArray[i] & 0xFF))); + } + default: + return 0; + } + } + + /** + * Returns an int value copied from four consecutive bytes starting at the + * offset. + * + * @param byteArray + * source + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @return int + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static int readInt(byte[] byteArray, int offset, boolean bigEndian) { + if ((offset + 4 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "readInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + + if (bigEndian) + { + return readInt_(byteArray, offset, true); + } + else + { + return readInt_(byteArray, offset, false); + } + } + + private static int readInt_(byte[] byteArray, int offset, boolean bigEndian) { + if (bigEndian) { + return ((byteArray[offset] & 0xFF) << 24) + | ((byteArray[offset + 1] & 0xFF) << 16) + | ((byteArray[offset + 2] & 0xFF) << 8) + | ((byteArray[offset + 3] & 0xFF)); + } else { + return ((byteArray[offset + 3] & 0xFF) << 24) + | ((byteArray[offset + 2] & 0xFF) << 16) + | ((byteArray[offset + 1] & 0xFF) << 8) + | ((byteArray[offset] & 0xFF)); + } + } + + /** + * Returns an int value copied from zero to four consecutive bytes of the + * byte array starting at the offset. + * + * @param byteArray + * source + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * @param numBytes + * the number of bytes to unmarshall, must be 0-4 inclusive + * @param signExtend + * if true and numBytes < 4 then the topmost + * bytes of the returned int will be sign extended + * + * @return int + * + * @throws NullPointerException + * if byteArray is null + * @throws IllegalArgumentException + * if numBytes < 0 or + * numBytes > 4 + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static int readInt(byte[] byteArray, int offset, boolean bigEndian, + int numBytes, boolean signExtend) + { + if ((offset + numBytes > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Access offset must be positive or zero and last byte must be in range."); + if (numBytes < 0 || numBytes > 4) + throw new IllegalArgumentException("numBytes == " + numBytes); + + if (bigEndian) + { + if (signExtend) + return readInt_(byteArray, offset, true, numBytes, true); + else + return readInt_(byteArray, offset, true, numBytes, false); + } + else + { + if (signExtend) + return readInt_(byteArray, offset, false, numBytes, true); + else + return readInt_(byteArray, offset, false, numBytes, false); + } + } + + private static int readInt_(byte[] byteArray, int offset, boolean bigEndian, + int numBytes, boolean signExtend) { + int i = offset; + int answer; + switch (numBytes) { + case 0: + return 0; + case 1: + if (signExtend) + return byteArray[i]; + else + return byteArray[i] & 0x000000FF; + case 2: + if (bigEndian) { + answer = (((byteArray[i] & 0xFF) << 8) | (byteArray[i + 1] & 0xFF)); + } else { + answer = (((byteArray[i + 1] & 0xFF) << 8) | (byteArray[i] & 0xFF)); + } + if (signExtend) + return (short) answer; + else + return answer & 0x0000FFFF; + case 3: + if (bigEndian) { + answer = ((byteArray[i] & 0xFF) << 16) + | ((byteArray[i + 1] & 0xFF) << 8) + | ((byteArray[i + 2] & 0xFF)); + } else { + answer = ((byteArray[i + 2] & 0xFF) << 16) + | ((byteArray[i + 1] & 0xFF) << 8) + | ((byteArray[i] & 0xFF)); + } + /* if the most significant bit is 1, we need to do sign extension */ + if (signExtend && (answer & (1 << (3 * 8 - 1))) != 0) { + answer |= 0xFF000000; + } + return answer; + case 4: + if (bigEndian) { + return ((byteArray[i] & 0xFF) << 24) + | ((byteArray[i + 1] & 0xFF) << 16) + | ((byteArray[i + 2] & 0xFF) << 8) + | ((byteArray[i + 3] & 0xFF)); + } else { + return ((byteArray[i + 3] & 0xFF) << 24) + | ((byteArray[i + 2] & 0xFF) << 16) + | ((byteArray[i + 1] & 0xFF) << 8) + | ((byteArray[i] & 0xFF)); + } + default: + return 0; + } + } + + /** + * Returns a long value copied from eight consecutive bytes of the byte + * array starting at the offset. + * + * @param byteArray + * source + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @return long + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static long readLong(byte[] byteArray, int offset, boolean bigEndian) { + if ((offset + 8 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "readLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + + if (bigEndian) + { + return readLong_(byteArray, offset, true); + } + else + { + return readLong_(byteArray, offset, false); + } + } + + private static long readLong_(byte[] byteArray, int offset, boolean bigEndian) { + if (bigEndian) { + return (((long) (byteArray[offset] & 0xFF)) << 56) + | (((long) (byteArray[offset + 1] & 0xFF)) << 48) + | (((long) (byteArray[offset + 2] & 0xFF)) << 40) + | (((long) (byteArray[offset + 3] & 0xFF)) << 32) + | (((long) (byteArray[offset + 4] & 0xFF)) << 24) + | (((byteArray[offset + 5] & 0xFF)) << 16) + | (((byteArray[offset + 6] & 0xFF)) << 8) + | (((byteArray[offset + 7] & 0xFF))); + } else { + return (((long) (byteArray[offset + 7] & 0xFF)) << 56) + | (((long) (byteArray[offset + 6] & 0xFF)) << 48) + | (((long) (byteArray[offset + 5] & 0xFF)) << 40) + | (((long) (byteArray[offset + 4] & 0xFF)) << 32) + | (((long) (byteArray[offset + 3] & 0xFF)) << 24) + | (((byteArray[offset + 2] & 0xFF)) << 16) + | (((byteArray[offset + 1] & 0xFF)) << 8) + | (((byteArray[offset] & 0xFF))); + } + } + + /** + * Returns a long value copied from zero to eight consecutive bytes of the + * byte array starting at the offset. + * + * @param byteArray + * source + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * @param numBytes + * the number of bytes to unmarshall, must be 0-8 inclusive + * @param signExtend + * if true and numBytes < 8 then the topmost + * bytes of the returned long will be sign extended + * + * @return long + * + * @throws NullPointerException + * if byteArray is null + * @throws IllegalArgumentException + * if numBytes < 0 or + * numBytes > 8 + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static long readLong(byte[] byteArray, int offset, + boolean bigEndian, int numBytes, boolean signExtend) { + if ((offset + numBytes > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Access offset must be positive or zero and last byte must be in range."); + if (numBytes < 0 || numBytes > 8) + throw new IllegalArgumentException("numBytes == " + numBytes); + + if (bigEndian) + { + if (signExtend) + return readLong_(byteArray, offset, true, numBytes, true); + else + return readLong_(byteArray, offset, true, numBytes, false); + } + else + { + if (signExtend) + return readLong_(byteArray, offset, false, numBytes, true); + else + return readLong_(byteArray, offset, false, numBytes, false); + } + } + private static long readLong_(byte[] byteArray, int offset, + boolean bigEndian, int numBytes, boolean signExtend) { + int i = offset; + long answer; + switch (numBytes) { + case 0: + return 0; + case 1: + if (signExtend) + return byteArray[i]; + else + return byteArray[i] & 0x00000000000000FFl; + case 2: + if (bigEndian) { + answer = (((byteArray[i] & 0xFF) << 8) | (byteArray[i + 1] & 0xFF)); + } else { + answer = (((byteArray[i + 1] & 0xFF) << 8) | (byteArray[i] & 0xFF)); + } + if (signExtend) + return (short) answer; + else + return answer & 0x000000000000FFFFl; + case 3: + if (bigEndian) { + answer = (((byteArray[i]) & 0xFF) << 16) + | (((byteArray[i + 1]) & 0xFF) << 8) + | (((byteArray[i + 2]) & 0xFF)); + + } else { + answer = (((byteArray[i + 2]) & 0xFF) << 16) + | (((byteArray[i + 1]) & 0xFF) << 8) + | (((byteArray[i]) & 0xFF)); + + } + + if (signExtend) { + answer = (answer << 40) >> 40; + } + + return answer; + case 4: + if (bigEndian) { + answer = ((((long) byteArray[i]) & 0xFF) << 24) + | (((byteArray[i + 1]) & 0xFF) << 16) + | (((byteArray[i + 2]) & 0xFF) << 8) + | (((byteArray[i + 3]) & 0xFF)); + + } else { + answer = ((((long) byteArray[i + 3]) & 0xFF) << 24) + | (((byteArray[i + 2]) & 0xFF) << 16) + | (((byteArray[i + 1]) & 0xFF) << 8) + | (((byteArray[i]) & 0xFF)); + + } + + if (signExtend) { + answer = (answer << 32) >> 32; + } + + return answer; + case 5: + if (bigEndian) { + answer = ((((long) byteArray[i]) & 0xFF) << 32) + | ((((long) byteArray[i + 1]) & 0xFF) << 24) + | (((byteArray[i + 2]) & 0xFF) << 16) + | (((byteArray[i + 3]) & 0xFF) << 8) + | (((byteArray[i + 4]) & 0xFF)); + + } else { + answer = ((((long) byteArray[i + 4]) & 0xFF) << 32) + | ((((long) byteArray[i + 3]) & 0xFF) << 24) + | (((byteArray[i + 2]) & 0xFF) << 16) + | (((byteArray[i + 1]) & 0xFF) << 8) + | (((byteArray[i]) & 0xFF)); + + } + + if (signExtend) { + answer = (answer << 24) >> 24; + } + return answer; + case 6: + if (bigEndian) { + answer = ((((long) byteArray[i]) & 0xFF) << 40) + | ((((long) byteArray[i + 1]) & 0xFF) << 32) + | ((((long) byteArray[i + 2]) & 0xFF) << 24) + | (((byteArray[i + 3]) & 0xFF) << 16) + | (((byteArray[i + 4]) & 0xFF) << 8) + | (((byteArray[i + 5]) & 0xFF)); + + } else { + answer = ((((long) byteArray[i + 5]) & 0xFF) << 40) + | ((((long) byteArray[i + 4]) & 0xFF) << 32) + | ((((long) byteArray[i + 3]) & 0xFF) << 24) + | (((byteArray[i + 2]) & 0xFF) << 16) + | (((byteArray[i + 1]) & 0xFF) << 8) + | (((byteArray[i]) & 0xFF)); + } + + if (signExtend) { + answer = (answer << 16) >> 16; + } + return answer; + case 7: + if (bigEndian) { + answer = ((((long) byteArray[i]) & 0xFF) << 48) + | ((((long) byteArray[i + 1]) & 0xFF) << 40) + | ((((long) byteArray[i + 2]) & 0xFF) << 32) + | ((((long) byteArray[i + 3]) & 0xFF) << 24) + | (((byteArray[i + 4]) & 0xFF) << 16) + | (((byteArray[i + 5]) & 0xFF) << 8) + | (((byteArray[i + 6]) & 0xFF)); + + } else { + answer = ((((long) byteArray[i + 6]) & 0xFF) << 48) + | ((((long) byteArray[i + 5]) & 0xFF) << 40) + | ((((long) byteArray[i + 4]) & 0xFF) << 32) + | ((((long) byteArray[i + 3]) & 0xFF) << 24) + | (((byteArray[i + 2]) & 0xFF) << 16) + | (((byteArray[i + 1]) & 0xFF) << 8) + | (((byteArray[i]) & 0xFF)); + + } + + if (signExtend) { + answer = (answer << 8) >> 8; + } + + return answer; + case 8: + if (bigEndian) { + return ((((long) byteArray[i]) & 0xFF) << 56) + | ((((long) byteArray[i + 1]) & 0xFF) << 48) + | ((((long) byteArray[i + 2]) & 0xFF) << 40) + | ((((long) byteArray[i + 3]) & 0xFF) << 32) + | ((((long) byteArray[i + 4]) & 0xFF) << 24) + | (((byteArray[i + 5]) & 0xFF) << 16) + | (((byteArray[i + 6]) & 0xFF) << 8) + | (((byteArray[i + 7]) & 0xFF)); + } else { + return ((((long) byteArray[i + 7]) & 0xFF) << 56) + | ((((long) byteArray[i + 6]) & 0xFF) << 48) + | ((((long) byteArray[i + 5]) & 0xFF) << 40) + | ((((long) byteArray[i + 4]) & 0xFF) << 32) + | ((((long) byteArray[i + 3]) & 0xFF) << 24) + | (((byteArray[i + 2]) & 0xFF) << 16) + | (((byteArray[i + 1]) & 0xFF) << 8) + | (((byteArray[i]) & 0xFF)); + } + default: + return 0; + } + } + + /** + * Returns a float value copied from four consecutive bytes of the byte + * array starting at the offset. + * + * @param byteArray + * source + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @return float + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static float readFloat(byte[] byteArray, int offset, + boolean bigEndian) { + if ((offset + 4 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "readFloat is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + + if (bigEndian) + return readFloat_(byteArray, offset, true); + else + return readFloat_(byteArray, offset, false); + } + + private static float readFloat_(byte[] byteArray, int offset, + boolean bigEndian) { + return Float.intBitsToFloat(readInt(byteArray, offset, bigEndian)); + } + + /** + * Returns a double value copied from eight consecutive bytes of the byte + * array starting at the offset. + * + * @param byteArray + * source + * @param offset + * offset in the byte array + * @param bigEndian + * if false the bytes will be copied in reverse (little endian) + * order + * + * @return double + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static double readDouble(byte[] byteArray, int offset, + boolean bigEndian) { + if ((offset + 8 > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "readDouble is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + + if (bigEndian) + return readDouble_(byteArray, offset, true); + else + return readDouble_(byteArray, offset, false); + } + + private static double readDouble_(byte[] byteArray, int offset, + boolean bigEndian) { + return Double.longBitsToDouble(readLong(byteArray, offset, bigEndian)); + } } diff --git a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/CommonData.java b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/CommonData.java index 1a30e8bfa9e..7ab4151b47b 100644 --- a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/CommonData.java +++ b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/CommonData.java @@ -30,278 +30,278 @@ * decimal representations and arithmetic operations on packed decimals. * * * @author IBM - * @version $Revision$ on $Date$ + * @version $Revision$ on $Date$ */ class CommonData { public final static int HIGHER_NIBBLE_MASK = 0xF0; - public final static int LOWER_NIBBLE_MASK = 0x0F; - public final static int INTEGER_MASK = 0xFF; // used for converting byte to - // integer - /** Constant representing a packed zero */ - final static byte PACKED_ZERO = (byte) (0x00); - - final static byte PACKED_SIGNED_ZERO = (byte) 0x0C; - final static byte PACKED_PLUS = (byte) 0x0C; - final static byte PACKED_MINUS = (byte) 0x0D; - private static final byte PACKED_ALT_PLUS = (byte) 0x0F; - private static final byte PACKED_ALT_PLUS1 = (byte) 0x0E; - private static final byte PACKED_ALT_PLUS2 = (byte) 0x0A; - private static final byte PACKED_ALT_MINUS = (byte) 0x0B; - protected static final byte EXTERNAL_SIGN_PLUS = (byte)0x4e; - protected static final byte EXTERNAL_SIGN_MINUS = (byte)0x60; - protected static final byte EXTERNAL_EMBEDDED_SIGN_PLUS = (byte)0xC0; - protected static final byte EXTERNAL_EMBEDDED_SIGN_MINUS = (byte)0xD0; - - protected static final byte EXTERNAL_EMBEDDED_SIGN_PLUS_ALTERNATE_A = (byte) 0xA0; - protected static final byte EXTERNAL_EMBEDDED_SIGN_PLUS_ALTERNATE_E = (byte) 0xE0; - protected static final byte EXTERNAL_EMBEDDED_SIGN_PLUS_ALTERNATE_F = (byte) 0xF0; - protected static final byte EXTERNAL_EMBEDDED_SIGN_MINUS_ALTERNATE_B = (byte) 0xB0; - - protected final static byte PACKED_INVALID_DIGIT = (byte) (0xff); - - /** - * The map table's for calculating byte arithmetics. sized to be 2^10 as we - * need to consider carries/borrows. - */ - private static final int BYTE_ARITHMETICS_TABLE_LENGTH = 1024; - - /** - * Outputs the sum of two bytes - */ - public static int getPackedSumValues(int input) { - return packedSumValues[input] & INTEGER_MASK; - } - - /** - * counts how many bytes are there in an external decimal. - */ - public static int getExternalByteCounts(int precision, int decimalType) - { - switch (decimalType) - { - case DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING: - case DecimalData.EBCDIC_SIGN_EMBEDDED_LEADING: - return precision; - case DecimalData.EBCDIC_SIGN_SEPARATE_TRAILING: - case DecimalData.EBCDIC_SIGN_SEPARATE_LEADING: - return precision+1; - default: - throw new IllegalArgumentException("illegal decimalType."); - } - } - - /** - * Outputs the sum of two bytes plus one - */ - public static byte getPackedSumPlusOneValues(int input) { - return packedSumPlusOneValues[input]; - } - - /** - * Outputs the difference of two bytes - */ - public static byte getPackedDifferenceValues(int input) { - return packedDifferenceValues[input]; - } - - /** - * Outputs the difference of two bytes minus one - */ - public static byte getPackedDifferenceMinusOneValues(int input) { - return packedDifferenceMinusOneValues[input]; - } - - /** - * Outputs the sum of the input and one - */ - public static byte getPackedAddOneValues(byte input) { - int carryHighDigit = ((input & CommonData.HIGHER_NIBBLE_MASK) >> 4); - int carryLowDigit = (input & CommonData.LOWER_NIBBLE_MASK) + 1; - if (carryLowDigit == 10) { - carryLowDigit = 0; - carryHighDigit = carryHighDigit + 1; - if (carryHighDigit == 10) { - carryHighDigit = 0; - } - } - return (byte) ((carryHighDigit << 4) + carryLowDigit); - } - - /** - * Outputs the difference of two bytes - */ - public static byte getPackedBorrowOneValues(byte input) { - int borrowHighDigit = ((input & CommonData.HIGHER_NIBBLE_MASK) >> 4); - int borrowLowDigit = (input & CommonData.LOWER_NIBBLE_MASK) - 1; - if (borrowLowDigit < 0) { - borrowLowDigit = 9; - borrowHighDigit = borrowHighDigit - 1; - if (borrowHighDigit < 0) { - borrowHighDigit = 9; - } - } - return (byte) ((borrowHighDigit << 4) + borrowLowDigit); - } - - /** - * Converts a packed byte to binary value - */ - public static int getPackedToBinaryValues(int input) { - return (((input & CommonData.HIGHER_NIBBLE_MASK) >> 4) * 10) + - (input & CommonData.LOWER_NIBBLE_MASK); - } - - /** - * Converts a binary value to a packed byte - */ - public static byte getBinaryToPackedValues(int input) { - int value = ((input/10) << 4) + (input % 10); - return (byte)value; - } - - /** - * Normalizes the input sign code to the preferred sign code. - * - * @return PACKED_MINUS if and only if the input is PACKED_MINUS or PACKED_ALT_MINUS, otherwise PACKED_PLUS - */ - public static byte getSign(int i) { - return (i == PACKED_MINUS || i == PACKED_ALT_MINUS) ? PACKED_MINUS : PACKED_PLUS; - } - - /** - * Returns the number of bytes required for storing a packed decimal of a - * given precision - * - * @param precision - * number of packed decimal digits - * @return number of bytes required for storing the packed decimal - * - * @throws ArrayIndexOutOfBoundsException - * if the precision value is invalid - */ - public static int getPackedByteCount(int precision) { - return ((precision / 2) + 1); - } - - /** - * Outputs the sum of the input and one taking into consideration the sign - * of the input - */ - public static byte getPackedAddOneSignValues(byte input) { - int digit = (input & CommonData.HIGHER_NIBBLE_MASK) >> 4; - digit++; - if (digit == 10) - digit = 0; - return (byte) (digit << 4 | (input & CommonData.LOWER_NIBBLE_MASK)); - } - /** - * Byte array of single byte packed decimals. Each packed decimal is the sum - * of two packed decimals operands. The index is a function of the operand - * values. - */ - private static final byte[] packedSumValues = new byte[BYTE_ARITHMETICS_TABLE_LENGTH]; - - /** - * Byte array of single byte packed decimals. Each packed decimal is the sum - * of two packed decimals operands and a carry from the previous byte. The - * index is a function of the operand values. - */ - private static final byte[] packedSumPlusOneValues = new byte[BYTE_ARITHMETICS_TABLE_LENGTH]; - - /** - * Byte array of single byte packed decimals. Each packed decimal is the - * difference of two packed decimal operands. The index is a function of the - * operand values. - */ - private static final byte[] packedDifferenceValues = new byte[BYTE_ARITHMETICS_TABLE_LENGTH]; - - /** - * Byte array of single byte packed decimals. Each packed decimal is the - * difference of two packed decimal operands and a borrow from the previous - * byte. The index is a function of the operand values. - */ - private static final byte[] packedDifferenceMinusOneValues = new byte[BYTE_ARITHMETICS_TABLE_LENGTH]; - - static { - int i, j, m, n; - - Arrays.fill(packedSumValues, PACKED_INVALID_DIGIT); - Arrays.fill(packedSumPlusOneValues, PACKED_INVALID_DIGIT); - Arrays.fill(packedDifferenceValues, PACKED_INVALID_DIGIT); - Arrays.fill(packedDifferenceMinusOneValues, PACKED_INVALID_DIGIT); - // setting valid elements - for (i = 0; i < 10; i++) { - for (j = 0; j < 10; j++) { - for (m = 0; m < 10; m++) { - for (n = 0; n < 10; n++) { - setPackedSumArrays(i, j, m, n); - } - } - } - } - } - - /** - * Creates arrays holding results of simple operations on bytes comprising - * packed decimal digits. - * - * @param i - * first nibble (digit) of the first byte - * @param j - * second nibble (digit) of the first byte - * @param m - * first nibble (digit) of the second byte - * @param n - * second nibble (digit) of the second byte - */ - public static void setPackedSumArrays(int i, int j, int m, int n) { - int opAIndexValue, opBIndexValue; - int valueIdx, onesValue, tensValue; - byte byteValue; - // allow 5 bits for both tens sum and ones sum to get unique index - opAIndexValue = (i << 5) + j; - opBIndexValue = (m << 5) + n; - valueIdx = opAIndexValue + opBIndexValue; - // a + b or b + a values - onesValue = (j + n) % 10; - if (onesValue < j) - tensValue = (i + m + 1) % 10; - else - tensValue = (i + m) % 10; - byteValue = (byte) ((tensValue << 4) + onesValue); - packedSumValues[valueIdx] = byteValue; - - // a + b + 1(carry to previous byte) values - onesValue = (j + n + 1) % 10; - if (onesValue <= j) - tensValue = (i + m + 1) % 10; - else - tensValue = (i + m) % 10; - byteValue = (byte) ((tensValue << 4) + onesValue); - packedSumPlusOneValues[valueIdx] = byteValue; - - valueIdx = (opAIndexValue - opBIndexValue) & 0x3FF; - // a - b values - onesValue = (j - n + 10) % 10; - if (onesValue > j) // borrow required; - tensValue = (i - m - 1 + 10) % 10; - else - tensValue = (i - m + 10) % 10; - byteValue = (byte) ((tensValue << 4) + onesValue); - - if (packedDifferenceValues[valueIdx] == PACKED_INVALID_DIGIT) - packedDifferenceValues[valueIdx] = byteValue; - - // a - b - 1 (borrow from previous byte) values - onesValue = (j - n - 1 + 10) % 10; - if (onesValue >= j) // borrow required; - tensValue = (i - m - 1 + 10) % 10; - else - tensValue = (i - m + 10) % 10; - byteValue = (byte) ((tensValue << 4) + onesValue); - packedDifferenceMinusOneValues[valueIdx] = byteValue; - } + public final static int LOWER_NIBBLE_MASK = 0x0F; + public final static int INTEGER_MASK = 0xFF; // used for converting byte to + // integer + /** Constant representing a packed zero */ + final static byte PACKED_ZERO = (byte) (0x00); + + final static byte PACKED_SIGNED_ZERO = (byte) 0x0C; + final static byte PACKED_PLUS = (byte) 0x0C; + final static byte PACKED_MINUS = (byte) 0x0D; + private static final byte PACKED_ALT_PLUS = (byte) 0x0F; + private static final byte PACKED_ALT_PLUS1 = (byte) 0x0E; + private static final byte PACKED_ALT_PLUS2 = (byte) 0x0A; + private static final byte PACKED_ALT_MINUS = (byte) 0x0B; + protected static final byte EXTERNAL_SIGN_PLUS = (byte)0x4e; + protected static final byte EXTERNAL_SIGN_MINUS = (byte)0x60; + protected static final byte EXTERNAL_EMBEDDED_SIGN_PLUS = (byte)0xC0; + protected static final byte EXTERNAL_EMBEDDED_SIGN_MINUS = (byte)0xD0; + + protected static final byte EXTERNAL_EMBEDDED_SIGN_PLUS_ALTERNATE_A = (byte) 0xA0; + protected static final byte EXTERNAL_EMBEDDED_SIGN_PLUS_ALTERNATE_E = (byte) 0xE0; + protected static final byte EXTERNAL_EMBEDDED_SIGN_PLUS_ALTERNATE_F = (byte) 0xF0; + protected static final byte EXTERNAL_EMBEDDED_SIGN_MINUS_ALTERNATE_B = (byte) 0xB0; + + protected final static byte PACKED_INVALID_DIGIT = (byte) (0xff); + + /** + * The map table's for calculating byte arithmetics. sized to be 2^10 as we + * need to consider carries/borrows. + */ + private static final int BYTE_ARITHMETICS_TABLE_LENGTH = 1024; + + /** + * Outputs the sum of two bytes + */ + public static int getPackedSumValues(int input) { + return packedSumValues[input] & INTEGER_MASK; + } + + /** + * counts how many bytes are there in an external decimal. + */ + public static int getExternalByteCounts(int precision, int decimalType) + { + switch (decimalType) + { + case DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING: + case DecimalData.EBCDIC_SIGN_EMBEDDED_LEADING: + return precision; + case DecimalData.EBCDIC_SIGN_SEPARATE_TRAILING: + case DecimalData.EBCDIC_SIGN_SEPARATE_LEADING: + return precision+1; + default: + throw new IllegalArgumentException("illegal decimalType."); + } + } + + /** + * Outputs the sum of two bytes plus one + */ + public static byte getPackedSumPlusOneValues(int input) { + return packedSumPlusOneValues[input]; + } + + /** + * Outputs the difference of two bytes + */ + public static byte getPackedDifferenceValues(int input) { + return packedDifferenceValues[input]; + } + + /** + * Outputs the difference of two bytes minus one + */ + public static byte getPackedDifferenceMinusOneValues(int input) { + return packedDifferenceMinusOneValues[input]; + } + + /** + * Outputs the sum of the input and one + */ + public static byte getPackedAddOneValues(byte input) { + int carryHighDigit = ((input & CommonData.HIGHER_NIBBLE_MASK) >> 4); + int carryLowDigit = (input & CommonData.LOWER_NIBBLE_MASK) + 1; + if (carryLowDigit == 10) { + carryLowDigit = 0; + carryHighDigit = carryHighDigit + 1; + if (carryHighDigit == 10) { + carryHighDigit = 0; + } + } + return (byte) ((carryHighDigit << 4) + carryLowDigit); + } + + /** + * Outputs the difference of two bytes + */ + public static byte getPackedBorrowOneValues(byte input) { + int borrowHighDigit = ((input & CommonData.HIGHER_NIBBLE_MASK) >> 4); + int borrowLowDigit = (input & CommonData.LOWER_NIBBLE_MASK) - 1; + if (borrowLowDigit < 0) { + borrowLowDigit = 9; + borrowHighDigit = borrowHighDigit - 1; + if (borrowHighDigit < 0) { + borrowHighDigit = 9; + } + } + return (byte) ((borrowHighDigit << 4) + borrowLowDigit); + } + + /** + * Converts a packed byte to binary value + */ + public static int getPackedToBinaryValues(int input) { + return (((input & CommonData.HIGHER_NIBBLE_MASK) >> 4) * 10) + + (input & CommonData.LOWER_NIBBLE_MASK); + } + + /** + * Converts a binary value to a packed byte + */ + public static byte getBinaryToPackedValues(int input) { + int value = ((input/10) << 4) + (input % 10); + return (byte)value; + } + + /** + * Normalizes the input sign code to the preferred sign code. + * + * @return PACKED_MINUS if and only if the input is PACKED_MINUS or PACKED_ALT_MINUS, otherwise PACKED_PLUS + */ + public static byte getSign(int i) { + return (i == PACKED_MINUS || i == PACKED_ALT_MINUS) ? PACKED_MINUS : PACKED_PLUS; + } + + /** + * Returns the number of bytes required for storing a packed decimal of a + * given precision + * + * @param precision + * number of packed decimal digits + * @return number of bytes required for storing the packed decimal + * + * @throws ArrayIndexOutOfBoundsException + * if the precision value is invalid + */ + public static int getPackedByteCount(int precision) { + return ((precision / 2) + 1); + } + + /** + * Outputs the sum of the input and one taking into consideration the sign + * of the input + */ + public static byte getPackedAddOneSignValues(byte input) { + int digit = (input & CommonData.HIGHER_NIBBLE_MASK) >> 4; + digit++; + if (digit == 10) + digit = 0; + return (byte) (digit << 4 | (input & CommonData.LOWER_NIBBLE_MASK)); + } + /** + * Byte array of single byte packed decimals. Each packed decimal is the sum + * of two packed decimals operands. The index is a function of the operand + * values. + */ + private static final byte[] packedSumValues = new byte[BYTE_ARITHMETICS_TABLE_LENGTH]; + + /** + * Byte array of single byte packed decimals. Each packed decimal is the sum + * of two packed decimals operands and a carry from the previous byte. The + * index is a function of the operand values. + */ + private static final byte[] packedSumPlusOneValues = new byte[BYTE_ARITHMETICS_TABLE_LENGTH]; + + /** + * Byte array of single byte packed decimals. Each packed decimal is the + * difference of two packed decimal operands. The index is a function of the + * operand values. + */ + private static final byte[] packedDifferenceValues = new byte[BYTE_ARITHMETICS_TABLE_LENGTH]; + + /** + * Byte array of single byte packed decimals. Each packed decimal is the + * difference of two packed decimal operands and a borrow from the previous + * byte. The index is a function of the operand values. + */ + private static final byte[] packedDifferenceMinusOneValues = new byte[BYTE_ARITHMETICS_TABLE_LENGTH]; + + static { + int i, j, m, n; + + Arrays.fill(packedSumValues, PACKED_INVALID_DIGIT); + Arrays.fill(packedSumPlusOneValues, PACKED_INVALID_DIGIT); + Arrays.fill(packedDifferenceValues, PACKED_INVALID_DIGIT); + Arrays.fill(packedDifferenceMinusOneValues, PACKED_INVALID_DIGIT); + // setting valid elements + for (i = 0; i < 10; i++) { + for (j = 0; j < 10; j++) { + for (m = 0; m < 10; m++) { + for (n = 0; n < 10; n++) { + setPackedSumArrays(i, j, m, n); + } + } + } + } + } + + /** + * Creates arrays holding results of simple operations on bytes comprising + * packed decimal digits. + * + * @param i + * first nibble (digit) of the first byte + * @param j + * second nibble (digit) of the first byte + * @param m + * first nibble (digit) of the second byte + * @param n + * second nibble (digit) of the second byte + */ + public static void setPackedSumArrays(int i, int j, int m, int n) { + int opAIndexValue, opBIndexValue; + int valueIdx, onesValue, tensValue; + byte byteValue; + // allow 5 bits for both tens sum and ones sum to get unique index + opAIndexValue = (i << 5) + j; + opBIndexValue = (m << 5) + n; + valueIdx = opAIndexValue + opBIndexValue; + // a + b or b + a values + onesValue = (j + n) % 10; + if (onesValue < j) + tensValue = (i + m + 1) % 10; + else + tensValue = (i + m) % 10; + byteValue = (byte) ((tensValue << 4) + onesValue); + packedSumValues[valueIdx] = byteValue; + + // a + b + 1(carry to previous byte) values + onesValue = (j + n + 1) % 10; + if (onesValue <= j) + tensValue = (i + m + 1) % 10; + else + tensValue = (i + m) % 10; + byteValue = (byte) ((tensValue << 4) + onesValue); + packedSumPlusOneValues[valueIdx] = byteValue; + + valueIdx = (opAIndexValue - opBIndexValue) & 0x3FF; + // a - b values + onesValue = (j - n + 10) % 10; + if (onesValue > j) // borrow required; + tensValue = (i - m - 1 + 10) % 10; + else + tensValue = (i - m + 10) % 10; + byteValue = (byte) ((tensValue << 4) + onesValue); + + if (packedDifferenceValues[valueIdx] == PACKED_INVALID_DIGIT) + packedDifferenceValues[valueIdx] = byteValue; + + // a - b - 1 (borrow from previous byte) values + onesValue = (j - n - 1 + 10) % 10; + if (onesValue >= j) // borrow required; + tensValue = (i - m - 1 + 10) % 10; + else + tensValue = (i - m + 10) % 10; + byteValue = (byte) ((tensValue << 4) + onesValue); + packedDifferenceMinusOneValues[valueIdx] = byteValue; + } } diff --git a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/DecimalData.java b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/DecimalData.java index b2e5b43f26e..efa6f69b8ee 100644 --- a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/DecimalData.java +++ b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/DecimalData.java @@ -33,17 +33,17 @@ /** * Routines to convert between decimal data types stored in byte arrays and Java binary types. - * + * *

        * All the converter routines require the precision of the decimal value to convert, which represents the number of * decimal digits in the decimal value, not including the sign. *

        - * + * *

        * Unicode Decimal values can be represented as either a char array or as a byte array where every Unicode character is * represented by a pair of adjacent bytes. *

        - * + * *

        * For embedded sign nibbles (4 bit integers representing values between 0x0 and 0xF * inclusive) in External Decimal or Packed Decimal data, 0xB and 0xD represent a negative @@ -52,7 +52,7 @@ * 0xC if the result is positive, and a preferred negative sign code of 0xD if the result is * negative. All values between 0x0 and 0xF inclusive are interpreted as valid sign codes. *

        - * + * *

        * This library has full support for signed integers but only limited support for scale points (decimals). Scale points * and other unrecognized characters found in input External, Unicode, or Packed Decimal byte arrays are not supported, @@ -60,2571 +60,2565 @@ * -1.23 will be interpreted as -123). When converting to BigDecimal (as output), a scale value may be explicitly * specified as a separate parameter. *

        - * + * * @author IBM * @version $Revision$ on $Date$ */ public final class DecimalData { - /** - * External Decimal data format where each byte is an EBCDIC character representing a decimal digit, the sign is - * encoded in the top nibble of the last byte. - */ - public static final int EBCDIC_SIGN_EMBEDDED_TRAILING = 1; - - /** - * External Decimal data format where each byte is an EBCDIC character representing a decimal digit, the sign is - * encoded in the top nibble of the first byte. - */ - public static final int EBCDIC_SIGN_EMBEDDED_LEADING = 2; - - /** - * External Decimal data format where each byte is an EBCDIC character representing a decimal digit, the sign is - * encoded in a separate byte that comes after the last byte of the number. - */ - public static final int EBCDIC_SIGN_SEPARATE_TRAILING = 3; - - /** - * External Decimal data format where each byte is an EBCDIC character representing a decimal digit, the sign is - * encoded in a separate byte that comes before the first byte of the number. - */ - public static final int EBCDIC_SIGN_SEPARATE_LEADING = 4; - - /** - * Unicode Decimal data format where each digit is a Unicode character, there is no sign. - */ - public static final int UNICODE_UNSIGNED = 5; - - /** - * Unicode Decimal data format where each digit is a Unicode character, the sign is stored in the first character. - */ - public static final int UNICODE_SIGN_SEPARATE_LEADING = 6; - - /** - * Unicode Decimal data format where each digit is a Unicode character, the sign is stored in the last character. - */ - public static final int UNICODE_SIGN_SEPARATE_TRAILING = 7; - - /** - * External Decimal format for positive separate sign - */ - private static final byte EBCDIC_SIGN_POSITIVE = 0x4E; - - /** - * External Decimal format for negative separate sign - */ - private static final byte EBCDIC_SIGN_NEGATIVE = 0x60; - - /** - * External Decimal High Nibble Mask - */ - private static final byte EXTERNAL_HIGH_MASK = (byte) 0xF0; - - private static final byte UNICODE_HIGH_MASK = (byte) 0x30; - - static final int EXTERNAL_DECIMAL_MIN = 1; - - static final int EXTERNAL_DECIMAL_MAX = 4; - - private static final int EBCDIC_MIN = 1; - - private static final int EBCDIC_MAX = 4; - - private static final int UNICODE_MIN = 5; - - private static final int UNICODE_MAX = 7; - - private static byte[] PD2EDTranslationTable; - private static byte[] ED2UDTranslationTable; - - private static char UNICODE_SIGN_MINUS = '-'; - private static char UNICODE_SIGN_PLUS = '+'; - private static char UNICODE_ZERO = '0'; - - private static final boolean JIT_INTRINSICS_ENABLED = false; - - static { - PD2EDTranslationTable = new byte[512]; - ED2UDTranslationTable = new byte[256]; - - Arrays.fill(PD2EDTranslationTable, (byte) 0); - Arrays.fill(ED2UDTranslationTable, (byte) 0); - - for (int tenDigit = 0; tenDigit < 10; ++tenDigit) - for (int oneDigit = 0; oneDigit < 10; ++oneDigit) - { - int pdValue = tenDigit * 16 + oneDigit; - // ED tenDigit - PD2EDTranslationTable[pdValue*2 ] = (byte)(0xF0 | tenDigit); - PD2EDTranslationTable[pdValue*2+1] = (byte)(0xF0 | oneDigit); - } - - for (int digit = 0; digit < 10; ++digit) - { - int edValue = (0xF0 | digit); - ED2UDTranslationTable[edValue + 1] = (byte)(0x30 | digit); - } - - BigDecimal dummy = new BigDecimal("0"); - - - } - - // Private constructor, class contains only static methods. - private DecimalData() { - } - - private static final int PACKED_BYTES_LENGTH = 33; - // Pre-compute all of the possible values for one byte of a Packed Decimal - private static final byte[] PACKED_BYTES = new byte[200]; - static { - int i = 100; - for (int j = 0; j < 100; j++, i--) { - int low = i % 10; - int high = (i / 10) % 10; - PACKED_BYTES[j] = (byte) ((high << 4) + low); - } - i = 0; - for (int j = 100; j < 200; j++, i++) { - int low = i % 10; - int high = (i / 10) % 10; - PACKED_BYTES[j] = (byte) ((high << 4) + low); - } - } - - /** - * This method is recognized by the JIT. The ILGenerator and Walker will replace this method with an appropriate - * iconst bytecode value corresponding to whether or not the architecture supports DAA JIT intrinsics. Currently - * the JIT will generate an iconst 1 if and only if we are executing under zOS. - * - * @return true if DAA JIT intrinsics are enabled on the current platform, false otherwise - * - */ - private final static boolean JITIntrinsicsEnabled() - { - return JIT_INTRINSICS_ENABLED; - } - - // Binary search on the number of digits in value - private static int numDigits(int value) - { - value = (value == Integer.MIN_VALUE) ? Integer.MAX_VALUE : Math.abs(value); - - return (value >= 10000) ? - (value >= 10000000) ? - (value >= 100000000) ? - (value >= 1000000000) ? 10 : 9 : 8 : - (value >= 100000) ? - (value >= 1000000) ? 7 : 6 : 5 : - (value >= 100) ? - (value >= 1000) ? 4 : 3 : - (value >= 10) ? 2 : 1; - } - - // Binary search on the number of digits in value - private static int numDigits(long value) - { - value = value == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(value); - - return (value >= 1000000000L) ? - (value >= 100000000000000L) ? - (value >= 10000000000000000L) ? - (value >= 100000000000000000L) ? - (value >= 1000000000000000000L) ? 19 : 18 : 17 : - (value >= 1000000000000000L) ? 16 : 15 : - (value >= 100000000000L) ? - (value >= 1000000000000L) ? - (value >= 10000000000000L) ? 14 : 13 : 12 : - (value >= 10000000000L) ? 11 : 10 : - (value >= 10000L) ? - (value >= 1000000L) ? - (value >= 10000000L) ? - (value >= 100000000L) ? 9 : 8 : 7 : - (value >= 100000L) ? 6 : 5 : - (value >= 100L) ? - (value >= 1000L) ? 4 : 3 : - (value >= 10L) ? 2 : 1; - } - - /** - * Converts a binary integer value into a signed Packed Decimal format. The Packed Decimal will be padded with zeros - * on the left if necessary. - * - * Overflow can happen if the resulting Packed Decimal does not fit into the result byte array, given the offset and - * precision. In this case, when checkOverflow is true an ArithmeticException is thrown, - * when false a truncated or invalid result is returned. - * - * @param integerValue - * the binary integer value to convert - * @param packedDecimal - * byte array that will store the resulting Packed Decimal value - * @param offset - * offset of the first byte of the Packed Decimal in packedDecimal - * @param precision - * number of Packed Decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if packedDecimal is null - * @throws ArithmeticException - * if the checkOverflow parameter is true and overflow occurs - */ - public static void convertIntegerToPackedDecimal(int integerValue, - byte[] packedDecimal, int offset, int precision, - boolean checkOverflow) { - if ((offset + ((precision/ 2) + 1) > packedDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertIntegerToPackedDecimal is trying to access packedDecimal[" + offset + "] to packedDecimal[" + (offset + (precision/ 2)) + "], " + - " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); - - convertIntegerToPackedDecimal_(integerValue, packedDecimal, offset, precision, checkOverflow); - } - - private static void convertIntegerToPackedDecimal_(int integerValue, - byte[] packedDecimal, int offset, int precision, - boolean checkOverflow) { - int value; - int bytes = CommonData.getPackedByteCount(precision); - int last = offset + bytes - 1; - int i; - boolean evenPrecision = (precision % 2 == 0) ? true : false; - - // avoid invalid precision - if (checkOverflow) { - if (precision < 1) - throw new ArithmeticException( - "Decimal overflow - Packed Decimal precision lesser than 1"); - - if (numDigits(integerValue) > precision) - throw new ArithmeticException( - "Decimal overflow - Packed Decimal precision insufficient"); - } - if (integerValue < 0) { - packedDecimal[last] = (byte) ((Math.abs(integerValue) % 10) << 4 | CommonData.PACKED_MINUS); - value = Math.abs(integerValue / 10); - } else { - value = integerValue; - packedDecimal[last] = (byte) ((value % 10) << 4 | CommonData.PACKED_PLUS); - value = value / 10; - } - - // fill in high/low nibble pairs from next-to-last up to first - for (i = last - 1; i > offset && value != 0; i--) { - packedDecimal[i] = CommonData.getBinaryToPackedValues(value % 100); - value = value / 100; - } - - if (i == offset && value != 0) { - if (evenPrecision) - packedDecimal[i] = (byte) (CommonData.getBinaryToPackedValues(value % 100) & CommonData.LOWER_NIBBLE_MASK); - else - packedDecimal[i] = CommonData.getBinaryToPackedValues(value % 100); - value = value / 100; - i--; - } - - if (checkOverflow && value != 0) { - throw new ArithmeticException( - "Decimal overflow - Packed Decimal precision insufficient"); - } - if (i >= offset) { - for (int j = 0; j < i - offset + 1; ++j) - packedDecimal[j+offset] = CommonData.PACKED_ZERO; - } - } - - /** - * Converts an integer to an External Decimal in a byte array. The External Decimal will be padded with zeros on the - * left if necessary. - * - * Overflow can happen if the resulting External Decimal value does not fit into the byte array, given the precision - * and offset. In this case, when checkOverflow is true an ArithmeticException is thrown, - * when false a truncated or invalid result is returned. - * - * @param integerValue - * the value to convert - * @param externalDecimal - * the byte array which will hold the External Decimal on a successful return - * @param offset - * the offset in the byte array at which the External Decimal should be located - * @param precision - * the number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticExceptionwill be thrown if the designated array cannot hold the - * External Decimal. - * @param decimalType - * constant value indicating the type of External Decimal - * - * @throws NullPointerException - * if externalDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if the checkOverflow parameter is true and overflow occurs - * @throws IllegalArgumentException - * if decimalType or precision is invalid - */ - public static void convertIntegerToExternalDecimal(int integerValue, - byte[] externalDecimal, int offset, int precision, - boolean checkOverflow, int decimalType) { - if ((offset < 0) - || (offset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " - + "convertIntegerToExternalDecimal is trying to access externalDecimal[" + offset - + "] to externalDecimal[" + (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1) - + "], " + " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); - if (JITIntrinsicsEnabled()) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertIntegerToPackedDecimal_(integerValue, packedDecimal, 0, precision, checkOverflow); - convertPackedDecimalToExternalDecimal_(packedDecimal, 0, externalDecimal, offset, precision, decimalType); - } else { - convertIntegerToExternalDecimal_(integerValue, externalDecimal, offset, precision, checkOverflow, decimalType); - } - } - - private static void convertIntegerToExternalDecimal_(int integerValue, byte[] externalDecimal, int offset, - int precision, boolean checkOverflow, int decimalType) { - int i; - byte zoneVal = EXTERNAL_HIGH_MASK; - - int externalSignOffset = offset; - if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) - offset++; - int end = offset + precision - 1; - - if (decimalType < EXTERNAL_DECIMAL_MIN || decimalType > EXTERNAL_DECIMAL_MAX) - throw new IllegalArgumentException("invalid decimalType"); - - if (checkOverflow) { - if (precision < 1) - throw new ArithmeticException("Decimal overflow - External Decimal precision lesser than 1"); - - if (numDigits(integerValue) > precision) - throw new ArithmeticException("Decimal overflow - External Decimal precision insufficient"); - } - - externalDecimal[end] = (byte) (zoneVal | Math.abs(integerValue % 10)); - int value = Math.abs(integerValue / 10); - // fill in high/low nibble pairs from next-to-last up to first - for (i = end - 1; i >= offset && value != 0; i--) { - externalDecimal[i] = (byte) (zoneVal | (value % 10)); - value = value / 10; - } - - if (i >= offset) { - for (int j = offset; j <= i; j++) { - externalDecimal[j] = (byte) (zoneVal | CommonData.PACKED_ZERO); - } - } - - switch (decimalType) { - case EBCDIC_SIGN_EMBEDDED_TRAILING: - case EBCDIC_SIGN_EMBEDDED_LEADING: - if (decimalType == EBCDIC_SIGN_EMBEDDED_TRAILING) { - externalSignOffset += precision - 1; - } - byte sign; - if (integerValue >= 0) { - sign = (byte) (CommonData.PACKED_PLUS << 4); - } else { - sign = (byte) (CommonData.PACKED_MINUS << 4); - } - externalDecimal[externalSignOffset] = (byte) ((externalDecimal[externalSignOffset] & CommonData.LOWER_NIBBLE_MASK) | sign); - break; - case EBCDIC_SIGN_SEPARATE_TRAILING: - case EBCDIC_SIGN_SEPARATE_LEADING: - if (decimalType == EBCDIC_SIGN_SEPARATE_TRAILING) { - externalSignOffset += precision; - } - if (integerValue >= 0) - externalDecimal[externalSignOffset] = EBCDIC_SIGN_POSITIVE; - else - externalDecimal[externalSignOffset] = EBCDIC_SIGN_NEGATIVE; - break; - } - } - - /** - * Converts an integer to a Unicode Decimal in a char array - * - * Overflow can happen if the resulting External Decimal value does not fit into the char array, given the offset and - * precision. In this case, when checkOverflow is true an ArithmeticException is thrown, - * when false a truncated or invalid result is returned. - * - * @param integerValue - * the long value to convert - * @param unicodeDecimal - * the char array which will hold the Unicode Decimal on a successful return - * @param offset - * the offset in the char array where the Unicode Decimal would be located - * @param precision - * the number of decimal digits. Maximum valid precision is 253 - * @param checkoverflow - * if true, when the designated an ArithmeticException - * @param unicodeType - * constant value indicating the type of Unicode Decimal - * - * @throws NullPointerException - * if unicodeDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * - * @throws ArithmeticException - * if the checkOverflow parameter is true and overflow occurs - * @throws IllegalArgumentException - * if the decimalType or precision is invalid - */ - public static void convertIntegerToUnicodeDecimal(int integerValue, - char[] unicodeDecimal, int offset, int precision, - boolean checkoverflow, int unicodeType) { - int size = unicodeType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; - if ((offset + size > unicodeDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertIntegerToUnicodeDecimal is trying to access unicodeDecimal[" + offset + "] to unicodeDecimal[" + (offset + size - 1) + "], " + - " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); - - if (JITIntrinsicsEnabled()) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertIntegerToPackedDecimal_(integerValue, packedDecimal, 0, precision, checkoverflow); - convertPackedDecimalToUnicodeDecimal_(packedDecimal, 0, unicodeDecimal, offset, precision, unicodeType); - } else { - convertIntegerToUnicodeDecimal_(integerValue, unicodeDecimal, offset, precision, checkoverflow, unicodeType); - } - } - - private static void convertIntegerToUnicodeDecimal_(int integerValue, char[] unicodeDecimal, int offset, int precision, boolean checkOverflow, int unicodeType) - { - // Avoid invalid precisions - if (checkOverflow) { - if (precision < 1) - throw new ArithmeticException("Decimal overflow - Unicode Decimal precision lesser than 1"); - - if (precision < numDigits(integerValue)) - throw new ArithmeticException("Decimal overflow - Unicode Decimal precision insufficient"); - } - - switch (unicodeType) - { - case UNICODE_UNSIGNED: break; - - case UNICODE_SIGN_SEPARATE_LEADING: - unicodeDecimal[offset++] = integerValue < 0 ? UNICODE_SIGN_MINUS : UNICODE_SIGN_PLUS; - break; - - case UNICODE_SIGN_SEPARATE_TRAILING: - unicodeDecimal[offset + precision] = integerValue < 0 ? UNICODE_SIGN_MINUS : UNICODE_SIGN_PLUS; - break; - - default: throw new IllegalArgumentException("Invalid decimalType"); - } - - unicodeDecimal[offset + precision - 1] = (char) (UNICODE_HIGH_MASK | (Math.abs(integerValue) % 10)); - - // Normalize the value - integerValue = Math.abs(integerValue / 10); - - int i; - - // fill in high/low nibble pairs from next-to-last up to first - for (i = offset + precision - 2; i >= offset && integerValue != 0; i--) { - unicodeDecimal[i] = (char) (UNICODE_HIGH_MASK | (integerValue % 10)); - - integerValue = integerValue / 10; - } - - if (checkOverflow && integerValue != 0) { - throw new ArithmeticException("Decimal overflow - Unicode Decimal precision insufficient"); - } - - for (; i >= offset; i--) { - unicodeDecimal[i] = (char) UNICODE_HIGH_MASK; - } - } - - /** - * Converts a binary long value into signed Packed Decimal format. The Packed Decimal will be padded with zeros on - * the left if necessary. - * - * Overflow can happen if the resulting Packed Decimal does not fit into the result byte array, given the offset and - * precision . In this case, when checkOverflow is true an ArithmeticException is thrown, - * when false a truncated or invalid result is returned. - * - * @param longValue - * the binary long value to convert - * @param packedDecimal - * byte array that will store the resulting Packed Decimal value - * @param offset - * offset of the first byte of the Packed Decimal in packedDecimal - * @param precision - * number of Packed Decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow), otherwise a truncated value is returned - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if packedDecimal is null - * @throws ArithmeticException - * the checkOverflow parameter is true and overflow occurs - */ - public static void convertLongToPackedDecimal(long longValue, - byte[] packedDecimal, int offset, int precision, - boolean checkOverflow) { - if ((offset + ((precision/ 2) + 1) > packedDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertLongToPackedDecimal is trying to access packedDecimal[" + offset + "] to packedDecimal[" + (offset + (precision/ 2)) + "], " + - " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); - - convertLongToPackedDecimal_(longValue, packedDecimal, offset, precision, checkOverflow); - } - private static void convertLongToPackedDecimal_(long longValue, - byte[] packedDecimal, int offset, int precision, - boolean checkOverflow) { - long value; - int bytes = CommonData.getPackedByteCount(precision); - int last = offset + bytes - 1; - int i; - boolean evenPrecision = (precision % 2 == 0) ? true : false; - - if (checkOverflow) { - if (precision < 1) - throw new ArithmeticException( - "Decimal overflow - Packed Decimal precision lesser than 1"); - - if (numDigits(longValue) > precision) - throw new ArithmeticException( - "Decimal overflow - Packed Decimal precision insufficient"); - } - - if (longValue < 0) { - packedDecimal[last] = (byte) ((Math.abs(longValue) % 10) << 4 | CommonData.PACKED_MINUS); - value = Math.abs(longValue / 10); - } else { - value = longValue; - packedDecimal[last] = (byte) ((value % 10) << 4 | CommonData.PACKED_PLUS); - value = value / 10; - } - - // fill in high/low nibble pairs from next-to-last up to first - for (i = last - 1; i > offset && value != 0; i--) { - packedDecimal[i] = CommonData - .getBinaryToPackedValues((int) (value % 100)); - value = value / 100; - } - - if (i == offset && value != 0) { - if (evenPrecision) - packedDecimal[i] = (byte) (CommonData - .getBinaryToPackedValues((int) (value % 100)) & CommonData.LOWER_NIBBLE_MASK); - else - packedDecimal[i] = CommonData - .getBinaryToPackedValues((int) (value % 100)); - value = value / 100; - i--; - } - - if (checkOverflow && value != 0) { - throw new ArithmeticException( - "Decimal overflow - Packed Decimal precision insufficient"); - } - if (i >= offset) { - for (int j = 0; j < i - offset + 1; ++j) - packedDecimal[j+offset] = CommonData.PACKED_ZERO; - } - } - - /** - * Converts a long into an External Decimal in a byte array. The External Decimal will be padded with zeros on the - * left if necessary. - * - * Overflow can happen if the External Decimal value does not fit into the byte array, given its precision and offset. - * In this case, when checkOverflow is true an ArithmeticException is thrown, when false a - * truncated or invalid result is returned. - * - * @param longValue - * the value to convert - * @param externalDecimal - * the byte array which will hold the External Decimal on a successful return - * @param offset - * the offset into externalDecimal where External Decimal should be located - * @param precision - * the number of decimal digits to convert. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException or IllegalArgumentException may be thrown - * @param decimalType - * constant value indicating the type of External Decimal - * - * @throws NullPointerException - * if externalDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if the checkOverflow parameter is true and overflow occurs - * @throws IllegalArgumentException - * if the decimalType or precision is invalid - */ - public static void convertLongToExternalDecimal(long longValue, byte[] externalDecimal, int offset, int precision, - boolean checkOverflow, int decimalType) { - if ((offset < 0) - || (offset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " - + "convertLongToExternalDecimal is trying to access externalDecimal[" + offset - + "] to externalDecimal[" + (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1) - + "], " + " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); - if (JITIntrinsicsEnabled()) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertLongToPackedDecimal_(longValue, packedDecimal, 0, precision, checkOverflow); - convertPackedDecimalToExternalDecimal_(packedDecimal, 0, externalDecimal, offset, precision, decimalType); - } else { - convertLongToExternalDecimal_(longValue, externalDecimal, offset, precision, checkOverflow, decimalType); - } - } - - private static void convertLongToExternalDecimal_(long longValue, byte[] externalDecimal, int offset, - int precision, boolean checkOverflow, int decimalType) { - int i; - byte zoneVal = EXTERNAL_HIGH_MASK; - - int externalSignOffset = offset; - if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) - offset++; - int end = offset + precision - 1; - - if (decimalType < EXTERNAL_DECIMAL_MIN || decimalType > EXTERNAL_DECIMAL_MAX) - throw new IllegalArgumentException("invalid decimalType"); - - if (checkOverflow) { - if (precision < 1) - throw new ArithmeticException("Decimal overflow - External Decimal precision lesser than 1"); - - if (numDigits(longValue) > precision) - throw new ArithmeticException("Decimal overflow - External Decimal precision insufficient"); - } - - externalDecimal[end] = (byte) (zoneVal | Math.abs(longValue % 10)); - long value = Math.abs(longValue / 10); - // fill in high/low nibble pairs from next-to-last up to first - for (i = end - 1; i >= offset && value != 0; i--) { - externalDecimal[i] = (byte) (zoneVal | (value % 10)); - value = value / 10; - } - - if (i >= offset) { - for (int j = offset; j <= i; j++) { - externalDecimal[j] = (byte) (zoneVal | CommonData.PACKED_ZERO); - } - } - - switch (decimalType) { - case EBCDIC_SIGN_EMBEDDED_TRAILING: - case EBCDIC_SIGN_EMBEDDED_LEADING: - if (decimalType == EBCDIC_SIGN_EMBEDDED_TRAILING) { - externalSignOffset += precision - 1; - } - byte sign; - if (longValue >= 0) { - sign = (byte) (CommonData.PACKED_PLUS << 4); - } else { - sign = (byte) (CommonData.PACKED_MINUS << 4); - } - externalDecimal[externalSignOffset] = (byte) ((externalDecimal[externalSignOffset] & CommonData.LOWER_NIBBLE_MASK) | sign); - break; - case EBCDIC_SIGN_SEPARATE_TRAILING: - case EBCDIC_SIGN_SEPARATE_LEADING: - if (decimalType == EBCDIC_SIGN_SEPARATE_TRAILING) { - externalSignOffset += precision; - } - if (longValue >= 0) - externalDecimal[externalSignOffset] = EBCDIC_SIGN_POSITIVE; - else - externalDecimal[externalSignOffset] = EBCDIC_SIGN_NEGATIVE; - break; - } - } - - /** - * Converts a long to a Unicode Decimal in a char array - * - * Overflow can happen if the resulting Unicode Decimal value does not fit into the char array, given its precision - * and offset . In this case, when checkOverflow is true an ArithmeticException is thrown, - * when false a truncated or invalid result is returned. - * - * @param longValue - * the long value to convert - * @param unicodeDecimal - * the char array which will hold the Unicode Decimal on a successful return - * @param offset - * the offset in the char array where the Unicode Decimal would be located - * @param precision - * the number of Unicode Decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException or IllegalArgumentException may be thrown - * @param decimalType - * constant value indicating the type of External Decimal - * - * @throws NullPointerException - * if unicodeDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if the checkOverflow parameter is true and overflow occurs - * @throws IllegalArgumentException - * if decimalType or precision is invalid - */ - public static void convertLongToUnicodeDecimal(long longValue, - char[] unicodeDecimal, int offset, int precision, - boolean checkOverflow, int decimalType) { - int size = decimalType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; - if ((offset + size > unicodeDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertIntegerToUnicodeDecimal is trying to access unicodeDecimal[" + offset + "] to unicodeDecimal[" + (offset + size - 1) + "], " + - " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); - - if (JITIntrinsicsEnabled()) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertLongToPackedDecimal_(longValue, packedDecimal, 0, precision, checkOverflow); - convertPackedDecimalToUnicodeDecimal_(packedDecimal, 0, unicodeDecimal, offset, precision, decimalType); - } else { - convertLongToUnicodeDecimal_(longValue, unicodeDecimal, offset, precision, checkOverflow, decimalType); - } - } - - private static void convertLongToUnicodeDecimal_(long longValue, char[] unicodeDecimal, int offset, int precision, boolean checkOverflow, int unicodeType) - { - // Avoid invalid precisions - if (checkOverflow) { - if (precision < 1) - throw new ArithmeticException("Decimal overflow - Unicode Decimal precision lesser than 1"); - - if (precision < numDigits(longValue)) - throw new ArithmeticException("Decimal overflow - Unicode Decimal precision insufficient"); - } - - switch (unicodeType) - { - case UNICODE_UNSIGNED: break; - - case UNICODE_SIGN_SEPARATE_LEADING: - unicodeDecimal[offset++] = longValue < 0 ? UNICODE_SIGN_MINUS : UNICODE_SIGN_PLUS; - break; - - case UNICODE_SIGN_SEPARATE_TRAILING: - unicodeDecimal[offset + precision] = longValue < 0 ? UNICODE_SIGN_MINUS : UNICODE_SIGN_PLUS; - break; - - default: throw new IllegalArgumentException("Invalid decimalType"); - } - - unicodeDecimal[offset + precision - 1] = (char) (UNICODE_HIGH_MASK | (Math.abs(longValue) % 10)); - - // Normalize the value - longValue = Math.abs(longValue / 10); - - int i; - - // fill in high/low nibble pairs from next-to-last up to first - for (i = offset + precision - 2; i >= offset && longValue != 0; i--) { - unicodeDecimal[i] = (char) (UNICODE_HIGH_MASK | (longValue % 10)); - - longValue = longValue / 10; - } - - if (checkOverflow && longValue != 0) { - throw new ArithmeticException("Decimal overflow - Unicode Decimal precision insufficient"); - } - - for (; i >= offset; i--) { - unicodeDecimal[i] = (char) UNICODE_HIGH_MASK; - } - } - - /** - * Converts a Packed Decimal value in a byte array into a binary integer. If the digital part of the input Packed - * Decimal is not valid then the digital part of the output will not be valid. The sign of the input Packed Decimal - * is assumed to be positive unless the sign nibble contains one of the negative sign codes, in which case the - * sign of the input Packed Decimal is interpreted as negative. - * - * Overflow can happen if the Packed Decimal value does not fit into a binary integer. When - * checkOverflow is true overflow results in an ArithmeticException, when false a - * truncated or invalid result is returned. - * - * @param packedDecimal - * byte array which contains the Packed Decimal value - * @param offset - * offset of the first byte of the Packed Decimal in packedDecimal - * @param precision - * number of Packed Decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException may be thrown - * - * @return int the resulting binary integer value - * - * @throws NullPointerException - * if packedDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result does not fit into an int (overflow) - */ - public static int convertPackedDecimalToInteger(byte[] packedDecimal, - int offset, int precision, boolean checkOverflow) { - if ((offset + ((precision/ 2) + 1) > packedDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertPackedDecimalToInteger is trying to access packedDecimal[" + offset + "] to packedDecimal[" + (offset + (precision/ 2)) + "], " + - " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); - - return convertPackedDecimalToInteger_(packedDecimal, offset, precision, checkOverflow); - } - - private static int convertPackedDecimalToInteger_(byte[] packedDecimal, - int offset, int precision, boolean checkOverflow) { - int bytes = CommonData.getPackedByteCount(precision); - int end = offset + bytes - 1; - long value = 0;// = (packedDecimal[end] & CommonData.INTEGER_MASK) >> 4; - - byte sign = CommonData.getSign((byte) (packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK)); - - // Skip the first byte if the precision is even and the low-order nibble is zero - if (precision % 2 == 0 && (packedDecimal[offset] & CommonData.LOWER_NIBBLE_MASK) == 0x00) - { - precision--; - offset++; - } - - // Skip consecutive zero bytes - for (; offset < end && packedDecimal[offset] == CommonData.PACKED_ZERO; offset++) - { - precision -= 2; - } - - if (checkOverflow) - { - // Skip high-order zero if and only if precision is odd - if (precision % 2 == 1 && (packedDecimal[offset] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) - { - precision--; - } - - // At this point we are guaranteed that the nibble pointed by a non-zero precision value is non-zero - if (precision > 10) - throw new ArithmeticException( - "Decimal overflow - Packed Decimal too large for an int"); - } - - // For checkOverflow == true at this point we are guaranteed that precision <= 10. The following loop - // will never overflow because the long value can always contain an integer of precision 10. - - for (int pos = offset; pos <= end - 1; ++pos) - { - value = value * 100 + CommonData.getPackedToBinaryValues(packedDecimal[pos]); - } - - value = value * 10 + ((packedDecimal[end] & CommonData.HIGHER_NIBBLE_MASK) >> 4); - - if (sign == CommonData.PACKED_MINUS) - value = -1 * value; - - if (checkOverflow && (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE)) - { - throw new ArithmeticException( - "Decimal overflow - Packed Decimal too large for a int"); - } - - return (int)value; - } - - /** - * Converts a Packed Decimal value in a byte array into a binary long. If the digital part of the input Packed - * Decimal is not valid then the digital part of the output will not be valid. The sign of the input Packed Decimal - * is assumed to be positive unless the sign nibble contains one of the negative sign codes, in which case the - * sign of the input Packed Decimal is interpreted as negative. - * - * Overflow can happen if the Packed Decimal value does not fit into a binary long. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param packedDecimal - * byte array which contains the Packed Decimal value - * @param offset - * offset of the first byte of the Packed Decimal in packedDecimal - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException may be thrown - * - * @return long the resulting binary long value - * - * @throws NullPointerException - * if packedDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result does not fit into a long (overflow) - */ - public static long convertPackedDecimalToLong(byte[] packedDecimal, - int offset, int precision, boolean checkOverflow) { - if ((offset + ((precision/ 2) + 1) > packedDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertPackedDecimalToLong is trying to access packedDecimal[" + offset + "] to packedDecimal[" + (offset + (precision/ 2)) + "], " + - " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); - - return convertPackedDecimalToLong_(packedDecimal, offset, precision, checkOverflow); - } - - private static long convertPackedDecimalToLong_(byte[] packedDecimal, - int offset, int precision, boolean checkOverflow) { - long value = 0; - int bytes = CommonData.getPackedByteCount(precision); - int end = offset + bytes - 1; - int last = packedDecimal[end] & CommonData.INTEGER_MASK; - byte sign = CommonData.getSign((byte) (last & CommonData.LOWER_NIBBLE_MASK)); - - // Skip the first byte if the precision is even and the low-order nibble is zero - if (precision % 2 == 0 && (packedDecimal[offset] & CommonData.LOWER_NIBBLE_MASK) == 0x00) - { - precision--; - offset++; - } - - // Skip consecutive zero bytes - for (; offset < end && packedDecimal[offset] == CommonData.PACKED_ZERO; offset++) - { - precision -= 2; - } - - if (checkOverflow) - { - // Skip high-order zero if and only if precision is odd - if (precision % 2 == 1 && (packedDecimal[offset] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) - { - precision--; - } - - // At this point we are guaranteed that the nibble pointed by a non-zero precision value is non-zero - if (precision > 19) - throw new ArithmeticException( - "Decimal overflow - Packed Decimal too large for a long"); - } - - // For checkOverflow == true at this point we are guaranteed that precision <= 19. The following loop - // may cause the signed long value to overflow. Because the first digit of Long.MAX_VALUE is a 9 the - // overflowed signed long value cannot overflow an unsigned long. This guarantees that if an overflow - // occurs, value will be negative. We will use this fact along with the sign code calculated earlier - // to determine whether overflow occurred. - - for (int pos = offset; pos <= end - 1; ++pos) - { - value = value * 100 + CommonData.getPackedToBinaryValues(packedDecimal[pos]); - } - - value = value * 10 + ((last & CommonData.HIGHER_NIBBLE_MASK) >> 4); - - - if (sign == CommonData.PACKED_MINUS) - value = -value; - - if (checkOverflow) - { - if (sign == CommonData.PACKED_PLUS && value < 0) - throw new ArithmeticException( - "Decimal overflow - Packed Decimal too large for a long"); - else if (sign == CommonData.PACKED_MINUS && value > 0) - throw new ArithmeticException( - "Decimal overflow - Packed Decimal too large for a long"); - } - - return value; - } - - /** - * Converts a Packed Decimal in a byte array into an External Decimal in another byte array. If the digital part of - * the input Packed Decimal is not valid then the digital part of the output will not be valid. The sign of the - * input Packed Decimal is assumed to be positive unless the sign nibble contains one of the negative sign codes, - * in which case the sign of the input Packed Decimal is interpreted as negative. - * - * @param packedDecimal - * byte array that holds the Packed Decimal to be converted - * @param packedOffset - * offset in packedDecimal where the Packed Decimal is located - * @param externalDecimal - * byte array that will hold the External Decimal on a successful return - * @param externalOffset - * offset in externalOffset where the External Decimal is expected to be located - * @param precision - * number of decimal digits - * @param decimalType - * constant indicating the type of the decimal - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if packedDecimal or externalDecimal are null - * @throws IllegalArgumentException - * if precision or decimalType is invalid - */ - public static void convertPackedDecimalToExternalDecimal( - byte[] packedDecimal, int packedOffset, byte[] externalDecimal, - int externalOffset, int precision, int decimalType) { - if ((packedOffset + ((precision/ 2) + 1) > packedDecimal.length) || (packedOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertPackedDecimalToExternalDecimal is trying to access packedDecimal[" + packedOffset + "] to packedDecimal[" + (packedOffset + (precision/ 2)) + "], " + - " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); - if ((externalOffset < 0) || (externalOffset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertPackedDecimalToExternalDecimal is trying to access externalDecimal[" + externalOffset + "] to externalDecimal[" + (externalOffset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + "], " + - " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); - - convertPackedDecimalToExternalDecimal_(packedDecimal, packedOffset, externalDecimal, - externalOffset, precision, decimalType); - } - - private static void convertPackedDecimalToExternalDecimal_( - byte[] packedDecimal, int packedOffset, byte[] externalDecimal, - int externalOffset, int precision, int decimalType) { - - if (decimalType < EXTERNAL_DECIMAL_MIN - || decimalType > EXTERNAL_DECIMAL_MAX) - throw new IllegalArgumentException("invalid decimalType"); - if (precision <= 0) - throw new IllegalArgumentException("negative precision"); - - int externalSignOffset = externalOffset; - if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) - externalOffset++; - - int end = packedOffset + precision / 2; - int edEnd = externalOffset + precision - 1; - - byte zoneVal = EXTERNAL_HIGH_MASK; - - // handle even precision - if (precision % 2 == 0) { - externalDecimal[externalOffset++] = (byte) (zoneVal | (packedDecimal[packedOffset++] & CommonData.LOWER_NIBBLE_MASK)); - } - - // compute all the intermediate digits - for (int i = packedOffset; i < end; i++) { - externalDecimal[externalOffset++] = (byte) (zoneVal | (((packedDecimal[i] & CommonData.HIGHER_NIBBLE_MASK) >> 4) & CommonData.LOWER_NIBBLE_MASK)); - externalDecimal[externalOffset++] = (byte) (zoneVal | (packedDecimal[i] & CommonData.LOWER_NIBBLE_MASK)); - } - - - // deal with the last digit - externalDecimal[edEnd] = (byte) (zoneVal | (((packedDecimal[end] & 0xF0) >> 4) & CommonData.LOWER_NIBBLE_MASK)); - - //byte sign = (byte)((packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK) << 4); - byte sign = (byte)(CommonData.getSign(packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK) << 4); - - switch (decimalType) { - case EBCDIC_SIGN_SEPARATE_LEADING: - if (sign == (byte) 0xC0) - externalDecimal[externalSignOffset] = EBCDIC_SIGN_POSITIVE; - else - externalDecimal[externalSignOffset] = EBCDIC_SIGN_NEGATIVE; - break; - case EBCDIC_SIGN_EMBEDDED_LEADING: - externalDecimal[externalSignOffset] = (byte) ((externalDecimal[externalSignOffset] & CommonData.LOWER_NIBBLE_MASK) | sign); - break; - case EBCDIC_SIGN_EMBEDDED_TRAILING: - externalSignOffset += precision - 1; - externalDecimal[externalSignOffset] = (byte) ((externalDecimal[externalSignOffset] & CommonData.LOWER_NIBBLE_MASK) | sign); - break; - case EBCDIC_SIGN_SEPARATE_TRAILING: - externalSignOffset += precision; - if (sign == (byte) 0xC0) - externalDecimal[externalSignOffset] = EBCDIC_SIGN_POSITIVE; - else - externalDecimal[externalSignOffset] = EBCDIC_SIGN_NEGATIVE; - break; - default: - //unreachable code - //throw new IllegalArgumentException("invalid decimalType"); - } - } - - /** - * Convert a Packed Decimal in a byte array to a Unicode Decimal in a char array. If the digital part of the input - * Packed Decimal is not valid then the digital part of the output will not be valid. The sign of the input Packed - * Decimal is assumed to be positive unless the sign nibble contains one of the negative sign codes, in which - * case the sign of the input Packed Decimal is interpreted as negative. - * - * @param packedDecimal - * byte array that holds a Packed Decimal to be converted - * @param packedOffset - * offset in packedDecimal where the Packed Decimal is located - * @param unicodeDecimal - * char array that will hold the Unicode Decimal on a successful return - * @param unicodeOffset - * offset in the byte array where the Unicode Decimal is expected to be located - * @param precision - * number of decimal digits - * @param decimalType - * constant value indicating the type of the External Decimal - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if packedDecimal or unicodeDecimal are null - * @throws IllegalArgumentException - * if precision or decimalType is invalid - */ - public static void convertPackedDecimalToUnicodeDecimal( - byte[] packedDecimal, int packedOffset, char[] unicodeDecimal, - int unicodeOffset, int precision, int decimalType) { - int size = decimalType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; - if ((unicodeOffset + size > unicodeDecimal.length) || (unicodeOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertPackedDecimalToUnicodeDecimal is trying to access unicodeDecimal[" + unicodeOffset + "] to unicodeDecimal[" + (unicodeOffset + size - 1) + "], " + - " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); - if ((packedOffset < 0) || (packedOffset + ((precision/ 2) + 1) > packedDecimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertPackedDecimalToUnicodeDecimal is trying to access packedDecimal[" + packedOffset + "] to packedDecimal[" + (packedOffset + (precision/ 2)) + "], " + - " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); - - convertPackedDecimalToUnicodeDecimal_(packedDecimal, packedOffset, unicodeDecimal, - unicodeOffset, precision, decimalType); - } - - private static void convertPackedDecimalToUnicodeDecimal_( - byte[] packedDecimal, int packedOffset, char[] unicodeDecimal, - int unicodeOffset, int precision, int decimalType) { - - if (precision <= 0) - throw new IllegalArgumentException("negative precision"); - - int externalSignOffset = -1; - switch (decimalType) { - case UNICODE_UNSIGNED: - break; - case UNICODE_SIGN_SEPARATE_LEADING: - externalSignOffset = unicodeOffset++; - break; - case UNICODE_SIGN_SEPARATE_TRAILING: - externalSignOffset = unicodeOffset + precision; - break; - default: - throw new IllegalArgumentException("invalid decimalType"); - } - - byte zoneVal = UNICODE_HIGH_MASK; - - // Get sign from Packed Decimal - int end = packedOffset + precision / 2; - byte sign = (byte) (packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK); - sign = CommonData.getSign(sign); - - // handle even precision - if (precision % 2 == 0) { - unicodeDecimal[unicodeOffset] = (char) (zoneVal | (packedDecimal[packedOffset++] & CommonData.LOWER_NIBBLE_MASK)); - unicodeOffset++; - } - - // compute all the intermediate digits - for (int i = packedOffset; i < end; i++) { - unicodeDecimal[unicodeOffset] = (char) (zoneVal | (((packedDecimal[i] & CommonData.HIGHER_NIBBLE_MASK) >> 4) & CommonData.LOWER_NIBBLE_MASK)); - unicodeOffset++; - unicodeDecimal[unicodeOffset] = (char) (zoneVal | (packedDecimal[i] & CommonData.LOWER_NIBBLE_MASK)); - unicodeOffset++; - } - - // deal with the last digit - unicodeDecimal[unicodeOffset] = (char) (zoneVal | (((packedDecimal[end] & 0xF0) >> 4) & CommonData.LOWER_NIBBLE_MASK)); - - // put the sign - if (decimalType != UNICODE_UNSIGNED) { - if (sign == CommonData.PACKED_PLUS) { - // put 2B for positive - unicodeDecimal[externalSignOffset] = 0x2B; - } else { - // put 2D for negative - unicodeDecimal[externalSignOffset] = 0x2D; - } - } - } - - /** - * Convert a Packed Decimal in a byte array to a BigInteger. If the digital part of the input Packed Decimal is not - * valid then the digital part of the output will not be valid. The sign of the input Packed Decimal is assumed to - * to be positive unless the sign nibble contains one of the negative sign codes, in which case the sign of the - * input Packed Decimal is interpreted as negative. - * - * Overflow can happen if the Packed Decimal value does not fit into the BigInteger. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param packedDecimal - * byte array that holds the Packed Decimal to be converted - * @param offset - * offset in packedDecimal where the Packed Decimal is located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @return BigInteger the resulting BigInteger - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if packedDecimal is null - */ - public static BigInteger convertPackedDecimalToBigInteger( - byte[] packedDecimal, int offset, int precision, - boolean checkOverflow) { - return convertPackedDecimalToBigDecimal(packedDecimal, offset, - precision, 0, checkOverflow).toBigInteger(); - } - - /** - * Convert a Packed Decimal in a byte array to a BigDecimal. If the digital part of the input Packed Decimal is not - * valid then the digital part of the output will not be valid. The sign of the input Packed Decimal is assumed to - * to be positive unless the sign nibble contains one of the negative sign codes, in which case the sign of the - * input Packed Decimal is interpreted as negative. - * - * Overflow can happen if the Packed Decimal value does not fit into the BigDecimal. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param packedDecimal - * byte array that holds the Packed Decimal to be converted - * @param offset - * offset in packedDecimal where the Packed Decimal is located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param scale - * scale of the BigDecimal to be returned - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * - * @return BigDecimal the resulting BigDecimal - * - * @throws NullPointerException - * if packedDecimal is null - * @throws ArrayIndexOutOfBoundsException - * /requires rounding if an invalid array access occurs - */ - public static BigDecimal convertPackedDecimalToBigDecimal( - byte[] packedDecimal, int offset, int precision, int scale, - boolean checkOverflow) { - - if (precision <= 9) { - return BigDecimal.valueOf( - convertPackedDecimalToInteger(packedDecimal, offset, precision, - checkOverflow), scale); - } else if (precision <= 18) { - return BigDecimal.valueOf( - convertPackedDecimalToLong(packedDecimal, offset, precision, - checkOverflow), scale); - } - - return slowSignedPackedToBigDecimal(packedDecimal, offset, precision, - scale, checkOverflow); - } - - /** - * Converts an External Decimal value in a byte array into a binary integer. If the digital part of the input - * External Decimal is not valid then the digital part of the output will not be valid. The sign of the input - * External Decimal is assumed to be positive unless the sign nibble or byte (depending on - * decimalType) contains one of the negative sign codes, in which case the sign of the input External - * Decimal is interpreted as negative. - * - * Overflow can happen if the External Decimal value does not fit into a binary integer. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false the resulting number - * will be wrapped around starting at the minimum/maximum possible integer value. - * - * @param externalDecimal - * byte array which contains the External Decimal value - * @param offset - * the offset where the External Decimal value is located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException or IllegalArgumentException may be thrown. If - * false and there is an overflow, the result is undefined. - * @param decimalType - * constant value indicating the type of External Decimal - * - * @return int the resulting binary integer - * - * @throws NullPointerException - * if externalDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result does not fit into a int (overflow) - * @throws IllegalArgumentException - * if precision or decimalType is invalid - */ - public static int convertExternalDecimalToInteger(byte[] externalDecimal, - int offset, int precision, boolean checkOverflow, int decimalType) { - if ((offset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertExternalDecimalToInteger is trying to access externalDecimal[" + offset + "] to externalDecimal[" + (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + "], " + - " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); - - if (precision <= 0) - throw new IllegalArgumentException("Precision can't be negative."); - - if (JITIntrinsicsEnabled()) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertExternalDecimalToPackedDecimal_(externalDecimal, offset, packedDecimal, 0, precision, decimalType); - return convertPackedDecimalToInteger_(packedDecimal, 0, precision, checkOverflow); - } else { - return convertExternalDecimalToInteger_(externalDecimal, offset, precision, checkOverflow, decimalType); - } - } - - private static int convertExternalDecimalToInteger_(byte[] externalDecimal, - int offset, int precision, boolean checkOverflow, int decimalType) { - int end = (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1); - boolean isNegative = isExternalDecimalSignNegative(externalDecimal, offset, precision, decimalType); - - - if (decimalType == EBCDIC_SIGN_SEPARATE_TRAILING) { - end--; - } else if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) { - offset++; - } - - int value = 0; - if (isNegative) - { - if (precision < 10 || (checkOverflow == false)) //max/min values are -2,147,483,648 and 2,147,483,647, so no overflow possible - { - for (int i = offset; i <= end; i++) - { - value = value * 10 - (externalDecimal[i] & 0x0F); - } - } - else //checkOverflow true, precision >= 10 - { - int tenthOffset = end-9; //location of 10th digit if existent - int offsetMod = offset > tenthOffset ? offset : tenthOffset; //only read last 10 digits - for (int i = offsetMod; i <= end; i++) - { - value = value * 10 - (externalDecimal[i] & 0x0F); - } - //need value>0 for cases like 2,900,000,000 and digit>2 for 5,000,000,000 - if (value > 0 || (tenthOffset >= offset && (externalDecimal[tenthOffset] & 0x0F) > 2)) //check 10th digit - { - throw new ArithmeticException( - "Decimal overflow - External Decimal too small for an int"); - } - - //any more digits are overflow - for (int i = offset; i < offsetMod; i++) - { - if ((externalDecimal[i] & 0x0F) > 0) - { - throw new ArithmeticException( - "Decimal overflow - External Decimal too small for an int"); - } - } - } - } - else - { - if (precision < 10 || (checkOverflow == false)) //max/min values are -2,147,483,648 and 2,147,483,647, so no overflow possible - { - for (int i = offset; i <= end; i++) - { - value = value * 10 + (externalDecimal[i] & 0x0F); - } - } - else //checkOverflow true, precision >= 10 - { - int tenthOffset = end-9; //location of 10th digit if existent - int offsetMod = offset > tenthOffset ? offset : tenthOffset; //only read last 10 digits - for (int i = offsetMod; i <= end; i++) - { - value = value * 10 + (externalDecimal[i] & 0x0F); - } - //need value<0 for cases like 2,900,000,000 and digit>2 for 5,000,000,000 - if (value < 0 || (tenthOffset >= offset && (externalDecimal[tenthOffset] & 0x0F) > 2)) //check 10th digit - { - throw new ArithmeticException( - "Decimal overflow - External Decimal too large for an int"); - } - - //any more digits are overflow - for (int i = offset; i < offsetMod; i++) - { - if ((externalDecimal[i] & 0x0F) > 0) - { - throw new ArithmeticException( - "Decimal overflow - External Decimal too large for an int"); - } - } - } - } - return value; - } - - /** - * Converts an External Decimal value in a byte array into a long. If the digital part of the input External Decimal - * is not valid then the digital part of the output will not be valid. The sign of the input External Decimal is - * assumed to be positive unless the sign nibble or byte (depending on decimalType) contains one of - * the negative sign codes, in which case the sign of the input External Decimal is interpreted as negative. - * - * Overflow can happen if the External Decimal value does not fit into a binary long. When - * checkOverflow is true overflow results in an ArithmeticException, when false the - * resulting number will be wrapped around starting at the minimum/maximum possible long value. - * - * @param externalDecimal - * byte array which contains the External Decimal value - * @param offset - * offset of the first byte of the Packed Decimal in the externalDecimal - * @param precision - * number of External Decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown when the converted value cannot fit into - * designated External Decimal array. If false and there is an overflow, the result is undefined. - * @param decimalType - * constant value indicating the type of External Decimal - * - * @return long the resulting binary long value - * - * @throws NullPointerException - * if externalDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result does not fit into a long (overflow) - * @throws IllegalArgumentException - * if precision or decimalType is invalid - */ - public static long convertExternalDecimalToLong(byte[] externalDecimal, - int offset, int precision, boolean checkOverflow, int decimalType) { - if ((offset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertExternalDecimalToLong is trying to access externalDecimal[" + offset + "] to externalDecimal[" + (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + "], " + - " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); - - if (precision <= 0) - throw new IllegalArgumentException("Precision can't be negative."); - - if (JITIntrinsicsEnabled()) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertExternalDecimalToPackedDecimal_(externalDecimal, offset, packedDecimal, 0, precision, decimalType); - return convertPackedDecimalToLong_(packedDecimal, 0, precision, checkOverflow); - } else { - return convertExternalDecimalToLong_(externalDecimal, offset, precision, checkOverflow, decimalType); - } - } - - private static long convertExternalDecimalToLong_(byte[] externalDecimal, - int offset, int precision, boolean checkOverflow, int decimalType) { - int end = (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1); - boolean isNegative = isExternalDecimalSignNegative(externalDecimal, offset, precision, decimalType); - - if (decimalType == EBCDIC_SIGN_SEPARATE_TRAILING) { - end--; - } else if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) { - offset++; - } - - long value = 0; - if (isNegative) - { - if (precision < 19 || (checkOverflow == false)) //max/min values are -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807, so no overflow possible - { - for (int i = offset; i <= end; i++) - { - value = value * 10 - (externalDecimal[i] & 0x0F); - } - } - else //checkOverflow true, precision >= 19 - { - int offsetMod = offset > end-18 ? offset : end-18; //only read last 19 digits - for (int i = offsetMod; i <= end; i++) - { - value = value * 10 - (externalDecimal[i] & 0x0F); - } - if (value > 0) //check 19th digit - { - throw new ArithmeticException( - "Decimal overflow - External Decimal too small for a long"); - } - - //any more digits are overflow - for (int i = offset; i < offsetMod; i++) - { - if ((externalDecimal[i] & 0x0F) > 0) - { - throw new ArithmeticException( - "Decimal overflow - External Decimal too small for a long"); - } - } - } - } - else - { - if (precision < 19 || (checkOverflow == false)) //max/min values are -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807, so no overflow possible - { - for (int i = offset; i <= end; i++) - { - value = value * 10 + (externalDecimal[i] & 0x0F); - } - } - else //checkOverflow true, precision >= 19 - { - int offsetMod = offset > end-18 ? offset : end-18; //only read last 19 digits - for (int i = offsetMod; i <= end; i++) - { - value = value * 10 + (externalDecimal[i] & 0x0F); - } - if (value < 0) //check 19th digit - { - throw new ArithmeticException( - "Decimal overflow - External Decimal too large for a long"); - } - - //any more digits are overflow - for (int i = offset; i < offsetMod; i++) - { - if ((externalDecimal[i] & 0x0F) > 0) - { - throw new ArithmeticException( - "Decimal overflow - External Decimal too large for a long"); - } - } - } - } - return value; - } - - /** - * Converts an External Decimal in a byte array to a Packed Decimal in another byte array. If the digital part of - * the input External Decimal is not valid then the digital part of the output will not be valid. The sign of the - * input External Decimal is assumed to be positive unless the sign nibble or byte (depending on - * decimalType) contains one of the negative sign codes, in which case the sign of the input External - * Decimal is interpreted as negative. - * - * @param externalDecimal - * byte array holding the External Decimal to be converted - * @param externalOffset - * offset in externalDecimal where the External Decimal is located - * @param packedDecimal - * byte array which will hold the Packed Decimal on a successful return - * @param packedOffset - * offset in packedDecimal where the Packed Decimal is expected to be located - * @param precision - * the number of decimal digits - * @param decimalType - * constant value indicating the type of External Decimal - * - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if packedDecimal or externalDecimal is null - * @throws IllegalArgumentException - * if precision or decimalType is invalid - */ - public static void convertExternalDecimalToPackedDecimal( - byte[] externalDecimal, int externalOffset, byte[] packedDecimal, - int packedOffset, int precision, int decimalType) { - if ((externalOffset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length) || (externalOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertExternalDecimalToPackedDecimal is trying to access externalDecimal[" + externalOffset + "] to externalDecimal[" + (externalOffset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + "], " + - " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); - - if ((packedOffset < 0) || (packedOffset + ((precision/ 2) + 1) > packedDecimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertExternalDecimalToPackedDecimal is trying to access packedDecimal[" + packedOffset + "] to packedDecimal[" + (packedOffset + (precision/ 2)) + "], " + - " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); - - convertExternalDecimalToPackedDecimal_(externalDecimal, externalOffset, packedDecimal, - packedOffset, precision, decimalType); - } - - private static void convertExternalDecimalToPackedDecimal_( - byte[] externalDecimal, int externalOffset, byte[] packedDecimal, - int packedOffset, int precision, int decimalType) { - - boolean isNegative = isExternalDecimalSignNegative(externalDecimal, externalOffset, precision, decimalType); - - if (decimalType < EXTERNAL_DECIMAL_MIN - || decimalType > EXTERNAL_DECIMAL_MAX) - throw new IllegalArgumentException("invalid decimalType"); - if (precision <= 0) - throw new IllegalArgumentException("negative precision"); - - int end = packedOffset + precision / 2; - - // deal with sign leading - if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) { - externalOffset++; - } - - // handle even precision - if (precision % 2 == 0) { - packedDecimal[packedOffset++] = (byte) (externalDecimal[externalOffset++] & CommonData.LOWER_NIBBLE_MASK); - } - - for (int i = packedOffset; i < end; i++) { - byte top = (byte) ((externalDecimal[externalOffset++] & CommonData.LOWER_NIBBLE_MASK) << 4); - byte bottom = (byte) (externalDecimal[externalOffset++] & CommonData.LOWER_NIBBLE_MASK); - packedDecimal[i] = (byte) (top | bottom); - } - - // deal with the last digit - packedDecimal[end] = (byte) ((externalDecimal[externalOffset] & CommonData.LOWER_NIBBLE_MASK) << 4); - - // Compute the sign - if (isNegative) - packedDecimal[end] |= CommonData.PACKED_MINUS; - else - packedDecimal[end] |= CommonData.PACKED_PLUS; - } - - /** - * Convert an External Decimal in a byte array to a BigInteger. The sign of the input External Decimal is assumed to - * to be positive unless the sign nibble or byte (depending on decimalType) contains one of the - * negative sign codes, in which case the sign of the input External Decimal is interpreted as negative. - * - * Overflow can happen if the External Decimal value does not fit into the BigInteger. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param externalDecimal - * byte array that holds the Packed Decimal to be converted - * @param offset - * offset in externalDecimal where the Packed Decimal is located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @param decimalType - * constant value indicating the type of External Decimal - * - * @return BigInteger the resulting BigInteger - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if externalDecimal is null - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - * @throws IllegalArgumentException - * if decimalType or precision is invalid, or the digital part of the input is - * invalid. - */ - public static BigInteger convertExternalDecimalToBigInteger( - byte[] externalDecimal, int offset, int precision, - boolean checkOverflow, int decimalType) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertExternalDecimalToPackedDecimal(externalDecimal, offset, - packedDecimal, 0, precision, decimalType); - - int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); - if (cc != 0) - throw new IllegalArgumentException("The input External Decimal is not valid."); - - return convertPackedDecimalToBigDecimal(packedDecimal, 0, precision, 0, - checkOverflow).toBigInteger(); - } - - /** - * Converts an External Decimal in a byte array to a BigDecimal. The sign of the input External Decimal is assumed - * to be positive unless the sign nibble or byte (depending on decimalType) contains one of the - * negative sign codes, in which case the sign of the input External Decimal is interpreted as negative. - * - * Overflow can happen if the External Decimal value does not fit into the BigDecimal. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param externalDecimal - * byte array holding the External Decimal to be converted - * @param offset - * offset in externalDecimal where the External Decimal is located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param scale - * scale of the BigDecimal - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @param decimalType - * constant value that indicates the type of External Decimal - * - * @return BigDecimal the resulting BigDecimal - * - * @throws NullPointerException - * if externalDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - * @throws IllegalArgumentException - * if checkOverflow is true and the Packed Decimal is in an invalid format, or the digital - * part of the input is invalid. - */ - public static BigDecimal convertExternalDecimalToBigDecimal( - byte[] externalDecimal, int offset, int precision, int scale, - boolean checkOverflow, int decimalType) { - if (precision <= 9) { - return BigDecimal.valueOf( - convertExternalDecimalToInteger(externalDecimal, offset, precision, - checkOverflow, decimalType), scale); - } else if (precision <= 18) { - return BigDecimal.valueOf( - convertExternalDecimalToLong(externalDecimal, offset, precision, - checkOverflow, decimalType), scale); - } - - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertExternalDecimalToPackedDecimal(externalDecimal, offset, - packedDecimal, 0, precision, decimalType); - - int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); - if (cc != 0) - throw new IllegalArgumentException("The input External Decimal is not valid."); - - return convertPackedDecimalToBigDecimal(packedDecimal, 0, precision, - scale, checkOverflow); - } - - private static boolean isExternalDecimalSignNegative(byte[] externalDecimal, int externalOffset, - int precision, int decimalType) - { - byte signByte = 0; - switch (decimalType) - { - case EBCDIC_SIGN_EMBEDDED_LEADING: - signByte = (byte) (externalDecimal[externalOffset] & EXTERNAL_HIGH_MASK); - if (signByte == CommonData.EXTERNAL_EMBEDDED_SIGN_MINUS || - signByte == CommonData.EXTERNAL_EMBEDDED_SIGN_MINUS_ALTERNATE_B) - return true; - break; - - case EBCDIC_SIGN_EMBEDDED_TRAILING: - signByte = (byte)(externalDecimal[externalOffset + precision - 1] & EXTERNAL_HIGH_MASK); - if (signByte == CommonData.EXTERNAL_EMBEDDED_SIGN_MINUS || - signByte == CommonData.EXTERNAL_EMBEDDED_SIGN_MINUS_ALTERNATE_B) - return true; - break; - - case EBCDIC_SIGN_SEPARATE_LEADING: - signByte = externalDecimal[externalOffset]; - if (signByte == CommonData.EXTERNAL_SIGN_MINUS) - return true; - break; - - case EBCDIC_SIGN_SEPARATE_TRAILING: - signByte = externalDecimal[externalOffset + precision]; - if (signByte == CommonData.EXTERNAL_SIGN_MINUS) - return true; - break; - - default: - throw new IllegalArgumentException("Invalid decimal sign type."); - } - - return false; - } - - /** - * Converts a Unicode Decimal value in a char array into a binary integer. The sign of the input Unicode Decimal is - * assumed to be positive unless the sign char contains the negative sign code, in which case the sign of the - * input Unicode Decimal is interpreted as negative. - * - * Overflow can happen if the Unicode Decimal value does not fit into a binary int. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param unicodeDecimal - * char array which contains the Unicode Decimal value - * @param offset - * the offset where the Unicode Decimal value is located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException or IllegalArgumentException may be thrown - * @param unicodeType - * constant value indicating the type of External Decimal - * - * @return int the resulting binary integer - * - * @throws NullPointerException - * if unicodeDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result does not fit into a long (overflow) - * @throws IllegalArgumentException - * if precision or decimalType is invalid, or the digital part of the input is - * invalid. - */ - public static int convertUnicodeDecimalToInteger(char[] unicodeDecimal, - int offset, int precision, boolean checkOverflow, int unicodeType) { - int size = unicodeType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; - if ((offset + size > unicodeDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertUnicodeDecimalToInteger is trying to access unicodeDecimal[" + offset + "] to unicodeDecimal[" + (offset + size - 1) + "], " + - " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); - - if (JITIntrinsicsEnabled()) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertUnicodeDecimalToPackedDecimal_(unicodeDecimal, offset, - packedDecimal, 0, precision, unicodeType); - int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, - precision, true, true); - if (cc != 0) - throw new IllegalArgumentException( - "The input Unicode is not valid"); - - return convertPackedDecimalToInteger_(packedDecimal, 0, precision, - checkOverflow); - } else { - return convertUnicodeDecimalToInteger_(unicodeDecimal, offset, - precision, checkOverflow, unicodeType); - } - } - - private static int convertUnicodeDecimalToInteger_(char[] unicodeDecimal, - int offset, int precision, boolean checkOverflow, int unicodeType) { - // Validate precision - if (precision <= 0) - throw new IllegalArgumentException("invalid precision"); - - // Validate decimalType and determine sign - boolean positive = true; - switch (unicodeType) { - case UNICODE_UNSIGNED: - break; - case UNICODE_SIGN_SEPARATE_LEADING: - positive = unicodeDecimal[offset++] == UNICODE_SIGN_PLUS; - break; - case UNICODE_SIGN_SEPARATE_TRAILING: - positive = unicodeDecimal[offset + precision] == UNICODE_SIGN_PLUS; - break; - default: - throw new IllegalArgumentException("invalid decimalType"); - } - - int end = offset + precision; - long val = 0; - - // Trim leading 0s - for (; offset < end && unicodeDecimal[offset] == UNICODE_ZERO; offset++) { - precision--; - } - - // Preemptive check overflow: 10 digits in Integer.MAX_VALUE - if (checkOverflow && precision > 10) { - throw new ArithmeticException( - "Decimal overflow - Unicode Decimal too large for an int"); - } - - // Working in negatives as Integer.MIN_VALUE has a greater - // distance from 0 than Integer.MAX_VALUE - for ( ; offset < end; ++offset) { - val *= 10; - val -= unicodeDecimal[offset] & CommonData.LOWER_NIBBLE_MASK; - } - - // Normalize result - val = positive ? -val : val; - - // Check overflow - if (checkOverflow && (val > Integer.MAX_VALUE || val < Integer.MIN_VALUE)) { - throw new ArithmeticException( - "Decimal overflow - Unicode Decimal too large for a int"); - } - - return (int) val; - } - - /** - * Converts a Unicode Decimal value in a char array into a binary long. The sign of the input Unicode Decimal is - * assumed to be positive unless the sign char contains the negative sign code, in which case the sign of the - * input Unicode Decimal is interpreted as negative. - * - * Overflow can happen if the Unicode Decimal value does not fit into a binary long. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param unicodeDecimal - * char array which contains the External Decimal value - * @param offset - * offset of the first byte of the Unicode Decimal in unicodeDecimal - * @param precision - * number of Unicode Decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown when - * @param unicodeType - * constant value indicating the type of External Decimal - * - * @return long the resulting binary long value - * - * @throws NullPointerException - * if unicodeDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result does not fit into a long (overflow) - * @throws IllegalArgumentException - * if unicodeType or precision is invalid, or the digital part of the input is - * invalid. - */ - public static long convertUnicodeDecimalToLong(char[] unicodeDecimal, - int offset, int precision, boolean checkOverflow, int unicodeType) { - int size = unicodeType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; - if ((offset + size > unicodeDecimal.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertUnicodeDecimalToLong is trying to access unicodeDecimal[" + offset + "] to unicodeDecimal[" + (offset + size - 1) + "], " + - " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); - - if (JITIntrinsicsEnabled()) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertUnicodeDecimalToPackedDecimal_(unicodeDecimal, offset, - packedDecimal, 0, precision, unicodeType); - - int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); - if (cc != 0) - throw new IllegalArgumentException("The input Unicode is not valid"); - - return convertPackedDecimalToLong_(packedDecimal, 0, precision, - checkOverflow); - } else { - return convertUnicodeDecimalToLong_(unicodeDecimal, offset, precision, checkOverflow, unicodeType); - } - } - - private static long convertUnicodeDecimalToLong_(char[] unicodeDecimal, - int offset, int precision, boolean checkOverflow, int unicodeType) { - // Validate precision - if (precision <= 0) - throw new IllegalArgumentException("invalid precision"); - - // Validate decimalType and determine sign - boolean positive = true; - switch (unicodeType) { - case UNICODE_UNSIGNED: - break; - case UNICODE_SIGN_SEPARATE_LEADING: - positive = unicodeDecimal[offset++] == UNICODE_SIGN_PLUS; - break; - case UNICODE_SIGN_SEPARATE_TRAILING: - positive = unicodeDecimal[offset + precision] == UNICODE_SIGN_PLUS; - break; - default: - throw new IllegalArgumentException("invalid decimalType"); - } - - int end = offset + precision; - long val = 0; - - // Trim leading 0s - for (; offset < end && unicodeDecimal[offset] == UNICODE_ZERO; offset++) { - precision--; - } - - // Preemptive check overflow: 19 digits in Long.MAX_VALUE - if (checkOverflow && precision > 19) { - throw new ArithmeticException( - "Decimal overflow - Unicode Decimal too large for a long"); - } - - // Working in negatives as Long.MIN_VALUE has a greater - // distance from 0 than Long.MAX_VALUE - for ( ; offset < end; ++offset) { - val *= 10; - val -= unicodeDecimal[offset] & CommonData.LOWER_NIBBLE_MASK; - } - - // Normalize result - val = positive ? -val : val; - - // Check overflow - if (checkOverflow) { - if (positive && val < 0) { - throw new ArithmeticException( - "Decimal overflow - Unicode Decimal too large for a long"); - } else if (!positive && val > 0) { - throw new ArithmeticException( - "Decimal overflow - Unicode Decimal too small for a long"); - } - } - - return val; - } - - /** - * Converts an Unicode Decimal in a char array to a Packed Decimal in a byte array. If the digital part of the input - * Unicode Decimal is not valid then the digital part of the output will not be valid. The sign of the input Unicode - * Decimal is assumed to be positive unless the sign byte contains the negative sign code, in which case the sign - * of the input Unicode Decimal is interpreted as negative. - * - * @param unicodeDecimal - * char array that holds the Unicode Decimal to be converted - * @param unicodeOffset - * offset in unicodeDecimal at which the Unicode Decimal is located - * @param packedDecimal - * byte array that will hold the Packed Decimal on a successful return - * @param packedOffset - * offset in packedDecimal where the Packed Decimal is expected to be located - * @param precision - * number of decimal digits - * @param decimalType - * constant value indicating the type of External Decimal - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if packedDecimal or unicodeDecimal are null - * @throws IllegalArgumentException - * if precision or decimalType is invalid - */ - public static void convertUnicodeDecimalToPackedDecimal( - char[] unicodeDecimal, int unicodeOffset, byte[] packedDecimal, - int packedOffset, int precision, int decimalType) { - int size = decimalType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; - if ((unicodeOffset + size > unicodeDecimal.length) || (unicodeOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertUnicodeDecimalToPackedDecimal is trying to access unicodeDecimal[" + unicodeOffset + "] to unicodeDecimal[" + (unicodeOffset + size - 1) + "], " + - " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); - if ((packedOffset < 0) || (packedOffset + ((precision/ 2) + 1) > packedDecimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "convertUnicodeDecimalToPackedDecimal is trying to access packedDecimal[" + packedOffset + "] to packedDecimal[" + (packedOffset + (precision/ 2)) + "], " + - " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); - - convertUnicodeDecimalToPackedDecimal_(unicodeDecimal, unicodeOffset, - packedDecimal, packedOffset, precision, decimalType); - } - - private static void convertUnicodeDecimalToPackedDecimal_( - char[] unicodeDecimal, int unicodeOffset, byte[] packedDecimal, - int packedOffset, int precision, int decimalType) { - - if (precision <= 0) - throw new IllegalArgumentException("invalid precision"); - - int end = packedOffset + precision / 2; - int signOffset = unicodeOffset; - if (decimalType == UNICODE_SIGN_SEPARATE_LEADING) { - unicodeOffset++; - } - // handle even precision - if (precision % 2 == 0) { - packedDecimal[packedOffset++] = (byte) (unicodeDecimal[unicodeOffset++] & CommonData.LOWER_NIBBLE_MASK); - } - - // compute all the intermediate digits - for (int i = packedOffset; i < end; i++) { - byte top = (byte) ((unicodeDecimal[unicodeOffset++] & CommonData.LOWER_NIBBLE_MASK) << 4); - byte bottom = (byte) (unicodeDecimal[unicodeOffset++] & CommonData.LOWER_NIBBLE_MASK); - packedDecimal[i] = (byte) (top | bottom); - } - packedDecimal[end] = (byte) ((unicodeDecimal[unicodeOffset++] & CommonData.LOWER_NIBBLE_MASK) << 4); - - switch (decimalType) - { - case UNICODE_SIGN_SEPARATE_LEADING: - if (unicodeDecimal[signOffset] == '-') - packedDecimal[end] |= CommonData.PACKED_MINUS; - else - packedDecimal[end] |= CommonData.PACKED_PLUS; - break; - - case UNICODE_SIGN_SEPARATE_TRAILING: - if (unicodeDecimal[unicodeOffset] == '-') - packedDecimal[end] |= CommonData.PACKED_MINUS; - else - packedDecimal[end] |= CommonData.PACKED_PLUS; - break; - - case UNICODE_UNSIGNED: - packedDecimal[end] |= CommonData.PACKED_PLUS; - break; - - default: - throw new IllegalArgumentException("invalid decimalType"); - } - } - - /** - * Convert a Unicode Decimal in a char array to a BigInteger. The sign of the input Unicode Decimal is assumed to - * be positive unless the sign byte contains the negative sign code, in which case the sign of the input Unicode - * Decimal is interpreted as negative. - * - * Overflow can happen if the Unicode Decimal value does not fit into a binary long. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param unicodeDecimal - * char array that holds the Packed Decimal to be converted - * @param offset - * offset into unicodeDecimal where the Packed Decimal is located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @param decimalType - * constant value indicating the type of External Decimal - * - * @return BigInteger the resulting BigInteger - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws NullPointerException - * if unicodeDecimal is null - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - * @throws IllegalArgumentException - * if decimalType or precision is invalid, or the digital part of the input is - * invalid. - */ - public static BigInteger convertUnicodeDecimalToBigInteger( - char[] unicodeDecimal, int offset, int precision, - boolean checkOverflow, int decimalType) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertUnicodeDecimalToPackedDecimal(unicodeDecimal, offset, - packedDecimal, 0, precision, decimalType); - - int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); - if (cc != 0) - throw new IllegalArgumentException("The input Unicode is not valid"); - - return convertPackedDecimalToBigDecimal(packedDecimal, 0, precision, 0, - checkOverflow).toBigInteger(); - } - - /** - * Converts a Unicode Decimal in a char array to a BigDecimal. The sign of the input Unicode Decimal is assumed to - * to be positive unless the sign byte contains the negative sign code, in which case the sign of the input Unicode - * Decimal is interpreted as negative. - * - * Overflow can happen if the Unicode Decimal value does not fit into the BigDecimal. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param unicodeDecimal - * char array that holds the Unicode Decimal - * @param offset - * offset in unicodeDecimal where the Unicode Decimal is located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param scale - * scale of the returned BigDecimal - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @param decimalType - * constant value indicating the type of External Decimal - * - * @return BigDecimal - * - * @throws NullPointerException - * if unicodeDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - * @throws IllegalArgumentException - * if checkOverflow is true and the Packed Decimal is in an invalid format, or the digital - * part of the input is invalid. - */ - public static BigDecimal convertUnicodeDecimalToBigDecimal( - char[] unicodeDecimal, int offset, int precision, int scale, - boolean checkOverflow, int decimalType) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertUnicodeDecimalToPackedDecimal(unicodeDecimal, offset, - packedDecimal, 0, precision, decimalType); - - - int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); - if (cc != 0) - throw new IllegalArgumentException("The input Unicode is not valid"); - - return convertPackedDecimalToBigDecimal(packedDecimal, 0, precision, - scale, checkOverflow); - } - - /** - * Converts a BigInteger value into a Packed Decimal in a byte array - * - * Overflow can happen if the BigInteger does not fit into the byte array. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param bigIntegerValue - * BigInteger value to be converted - * @param packedDecimal - * byte array which will hold the Packed Decimal on a successful return - * @param offset - * offset into packedDecimal where the Packed Decimal is expected to be located - * @param precision - * number of decimal digits. Maximum valid precision is 253s - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * - * @throws NullPointerException - * if packedDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - */ - public static void convertBigIntegerToPackedDecimal( - BigInteger bigIntegerValue, byte[] packedDecimal, int offset, - int precision, boolean checkOverflow) { - convertBigDecimalToPackedDecimal(new BigDecimal(bigIntegerValue), - packedDecimal, offset, precision, checkOverflow); - } - - /** - * Converts a BigInteger value into an External Decimal in a byte array - * - * Overflow can happen if the BigInteger does not fit into the byte array. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param bigIntegerValue - * BigInteger value to be converted - * @param externalDecimal - * byte array which will hold the External Decimal on a successful return - * @param offset - * offset into externalDecimal where the External Decimal is expected to be located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @param decimalType - * constant value that indicates the type of External Decimal - * - * @throws NullPointerException - * if externalDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - * @throws IllegalArgumentException - * if decimalType or precision is invalid - */ - public static void convertBigIntegerToExternalDecimal( - BigInteger bigIntegerValue, byte[] externalDecimal, int offset, - int precision, boolean checkOverflow, int decimalType) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertBigDecimalToPackedDecimal(new BigDecimal(bigIntegerValue), - packedDecimal, 0, precision, checkOverflow); - convertPackedDecimalToExternalDecimal(packedDecimal, 0, - externalDecimal, offset, precision, decimalType); - } - - /** - * Converts a BigInteger value to a Unicode Decimal in a char array - * - * Overflow can happen if the BigInteger does not fit into the char array. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param bigIntegerValue - * BigInteger value to be converted - * @param unicodeDecimal - * char array that will hold the Unicode decimal on a successful return - * @param offset - * offset into unicodeDecimal where the Unicode Decimal is expected to be located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @param decimalType - * constant indicating the type of External Decimal - * - * @throws NullPointerException - * if unicodeDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - * @throws IllegalArgumentException - * if decimalType or precision is invalid - */ - public static void convertBigIntegerToUnicodeDecimal( - BigInteger bigIntegerValue, char[] unicodeDecimal, int offset, - int precision, boolean checkOverflow, int decimalType) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertBigDecimalToPackedDecimal(new BigDecimal(bigIntegerValue), - packedDecimal, 0, precision, checkOverflow); - convertPackedDecimalToUnicodeDecimal(packedDecimal, 0, unicodeDecimal, - offset, precision, decimalType); - } - - /** - * Converts a BigDecimal into a Packed Decimal in a byte array - * - * Overflow can happen if the BigDecimal does not fit into the result byte array. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param bigDecimalValue - * the BigDecimal value to be converted - * @param packedDecimal - * byte array which will hold the Packed Decimal on a successful return - * @param offset - * desired offset in packedDecimal where the Packed Decimal is expected to be located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * - * @throws NullPointerException - * if packedDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - */ - public static void convertBigDecimalToPackedDecimal( - BigDecimal bigDecimalValue, byte[] packedDecimal, int offset, - int precision, boolean checkOverflow) { - - int bdprec = bigDecimalValue.precision(); - if (bdprec <=9) - { - convertIntegerToPackedDecimal((int) bigDecimalValue.unscaledValue().longValue(), - packedDecimal, offset, precision, checkOverflow); - return; - } - if (bdprec <= 18) - { - convertLongToPackedDecimal(bigDecimalValue.unscaledValue().longValue(), - packedDecimal, offset, precision, checkOverflow); - return; - } - - slowBigDecimalToSignedPacked(bigDecimalValue, packedDecimal, offset, - precision, checkOverflow); - } - - /** - * Converts a BigDecimal value to an External Decimal in a byte array - * - * Overflow can happen if the BigDecimal does not fit into the result byte array. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param bigDecimalValue - * BigDecimal value to be converted - * @param externalDecimal - * byte array that will hold the External Decimal on a successful return - * @param offset - * offset in externalDecimal where the External Decimal is expected to be located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @param decimalType - * constant value indicating the External Decimal type - * - * @throws NullPointerException - * if externalDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - * @throws IllegalArgumentException - * if precision or decimalType is invalid - */ - public static void convertBigDecimalToExternalDecimal( - BigDecimal bigDecimalValue, byte[] externalDecimal, int offset, - int precision, boolean checkOverflow, int decimalType) { - - int bdprec = bigDecimalValue.precision(); - if (bdprec <=9) - { - convertIntegerToExternalDecimal((int) bigDecimalValue.unscaledValue().longValue(), - externalDecimal, offset, precision, checkOverflow, decimalType); - return; - } - if (bdprec <= 18) - { - convertLongToExternalDecimal(bigDecimalValue.unscaledValue().longValue(), - externalDecimal, offset, precision, checkOverflow, decimalType); - return; - } - - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertBigDecimalToPackedDecimal(bigDecimalValue, packedDecimal, 0, - precision, checkOverflow); - convertPackedDecimalToExternalDecimal(packedDecimal, 0, - externalDecimal, offset, precision, decimalType); - } - - /** - * Converts a BigDecimal value to a Unicode Decimal in a char array - * - * Overflow can happen if the BigDecimal does not fit into the result char array. In this case, when - * checkOverflow is true an ArithmeticException is thrown, when false a truncated or - * invalid result is returned. - * - * @param bigDecimalValue - * BigDecimal value to be converted - * @param unicodeDecimal - * char array which will hold the Unicode Decimal on a successful return - * @param offset - * offset in unicodeDecimal where the Unicode Decimal is expected to be located - * @param precision - * number of decimal digits. Maximum valid precision is 253 - * @param checkOverflow - * if true an ArithmeticException will be thrown if the decimal value does not fit in the - * specified precision (overflow) - * @param decimalType - * constant value that indicates the type of External Decimal - * - * @throws NullPointerException - * if unicodeDecimal is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if checkOverflow is true and the result overflows - * @throws IllegalArgumentException - * if decimalType or precision is invalid - */ - public static void convertBigDecimalToUnicodeDecimal( - BigDecimal bigDecimalValue, char[] unicodeDecimal, int offset, - int precision, boolean checkOverflow, int decimalType) { - byte[] packedDecimal = new byte[precision / 2 + 1]; - convertBigDecimalToPackedDecimal(bigDecimalValue, packedDecimal, 0, - precision, checkOverflow); - convertPackedDecimalToUnicodeDecimal(packedDecimal, 0, unicodeDecimal, - offset, precision, decimalType); - } - - // below is code taken from BigDecimalConverters - // these are special functions recognized by the jit - private static boolean DFPFacilityAvailable() { - return false; - } - - private static boolean DFPUseDFP() { - return false; - } - - private static BigDecimal createZeroBigDecimal() { - return new BigDecimal(0); // don't use BigDecimal.ZERO, need a new - // object every time - } - - private static boolean DFPConvertPackedToDFP(BigDecimal bd, long pack, - int scale, boolean signed) { - return false; - } - - private static long DFPConvertDFPToPacked(long dfpValue, boolean signed) { - return Long.MAX_VALUE; - } - - private final static int getflags() { - return 0x3; - } - - private final static long getlaside(BigDecimal bd) { - return Long.MIN_VALUE; - } - - private static BigDecimal slowSignedPackedToBigDecimal(byte[] byteArray, - int offset, int precision, int scale, boolean exceptions) { - - - int length = (precision + 2) / 2; - - int sn = byteArray[offset + length - 1] & CommonData.LOWER_NIBBLE_MASK; - - char[] temp = new char[length * 2]; - temp[0] = (sn == 0x0D || sn == 0x0B) ? '-' : '0'; - for (int i = 0; i < length - 1; i++) { - temp[2 * i + 1] = (char) ('0' + (byteArray[i + offset] >>> 4 & CommonData.LOWER_NIBBLE_MASK)); - temp[2 * i + 2] = (char) ('0' + (byteArray[i + offset] & CommonData.LOWER_NIBBLE_MASK)); - } - temp[length * 2 - 1] = (char) ('0' + (byteArray[offset + length - 1] >>> 4 & CommonData.LOWER_NIBBLE_MASK)); - - return new BigDecimal(new BigInteger(new String(temp)), scale); - } - - private static void slowBigDecimalToSignedPacked(BigDecimal bd, - byte[] byteArray, int offset, int precision, boolean checkOverflow) { - - // digits are right justified in the return byte array - if (checkOverflow && precision < bd.precision()) - throw new ArithmeticException( - "Decimal overflow - precision of result Packed Decimal lesser than BigDecimal precision"); - - BigInteger value = bd.unscaledValue(); - char[] buffer = value.abs().toString().toCharArray(); - int numDigitsLeft = buffer.length - 1; - int endPosition = numDigitsLeft % 2; - int length = (precision + 2) / 2; - int index = length - 2; - - // take care of the sign nibble and the right most digit - byteArray[offset + length - 1] = (byte) ((buffer[numDigitsLeft] - '0') << 4); - byteArray[offset + length - 1] |= (byte) ((value.signum() == -1) ? 0x0D : 0x0C); - - // compact 2 digits into each byte - for (int i = numDigitsLeft - 1; i >= endPosition - && (offset + index >= 0); i -= 2, --index) { - byteArray[offset + index] = (byte) (buffer[i] - '0'); - byteArray[offset + index] |= (byte) ((buffer[i - 1] - '0') << 4); - } - - // if there's a left over digit, put it in the last byte - if (endPosition > 0 && (offset + index >= 0)) { - byteArray[offset + index] = (byte) (buffer[0] - '0'); - } - } - - /* - * Converts the Packed Decimal to equivalent long (in hex). - */ - private static long convertPackedToLong(byte[] byteArray, int offset, - int length) { - if (length == 8) { - return ByteArrayUnmarshaller.readLong(byteArray, offset, true); - } else if (length == 4) { - // We need to zero extend the int to long. - return ((long) ByteArrayUnmarshaller.readInt(byteArray, offset, - true)) & 0xFFFFFFFFl; - } - - else { - // slow way to load value into dfp - long value = 0; - for (int i = 0; i < length; ++i) { - value = value << 8; - value += ((long) (byteArray[offset + i] & 0xFF)); - } - return value; - } - } - - private static void convertLongToPacked(long value, byte[] byteArray, - int offset, int length) { - if (length == 8) { - ByteArrayMarshaller.writeLong(value, byteArray, offset, true); - } else if (length == 4) { - ByteArrayMarshaller.writeInt((int) value, byteArray, offset, true); - } else { - for (int i = length - 1; i <= 0; i--) { - byteArray[offset + i] = (byte) ((value) & 0xFF); - value = value >> 8; - } - } - } + /** + * External Decimal data format where each byte is an EBCDIC character representing a decimal digit, the sign is + * encoded in the top nibble of the last byte. + */ + public static final int EBCDIC_SIGN_EMBEDDED_TRAILING = 1; + + /** + * External Decimal data format where each byte is an EBCDIC character representing a decimal digit, the sign is + * encoded in the top nibble of the first byte. + */ + public static final int EBCDIC_SIGN_EMBEDDED_LEADING = 2; + + /** + * External Decimal data format where each byte is an EBCDIC character representing a decimal digit, the sign is + * encoded in a separate byte that comes after the last byte of the number. + */ + public static final int EBCDIC_SIGN_SEPARATE_TRAILING = 3; + + /** + * External Decimal data format where each byte is an EBCDIC character representing a decimal digit, the sign is + * encoded in a separate byte that comes before the first byte of the number. + */ + public static final int EBCDIC_SIGN_SEPARATE_LEADING = 4; + + /** + * Unicode Decimal data format where each digit is a Unicode character, there is no sign. + */ + public static final int UNICODE_UNSIGNED = 5; + + /** + * Unicode Decimal data format where each digit is a Unicode character, the sign is stored in the first character. + */ + public static final int UNICODE_SIGN_SEPARATE_LEADING = 6; + + /** + * Unicode Decimal data format where each digit is a Unicode character, the sign is stored in the last character. + */ + public static final int UNICODE_SIGN_SEPARATE_TRAILING = 7; + + /** + * External Decimal format for positive separate sign + */ + private static final byte EBCDIC_SIGN_POSITIVE = 0x4E; + + /** + * External Decimal format for negative separate sign + */ + private static final byte EBCDIC_SIGN_NEGATIVE = 0x60; + + /** + * External Decimal High Nibble Mask + */ + private static final byte EXTERNAL_HIGH_MASK = (byte) 0xF0; + + private static final byte UNICODE_HIGH_MASK = (byte) 0x30; + + static final int EXTERNAL_DECIMAL_MIN = 1; + + static final int EXTERNAL_DECIMAL_MAX = 4; + + private static final int EBCDIC_MIN = 1; + + private static final int EBCDIC_MAX = 4; + + private static final int UNICODE_MIN = 5; + + private static final int UNICODE_MAX = 7; + + private static byte[] PD2EDTranslationTable; + private static byte[] ED2UDTranslationTable; + + private static char UNICODE_SIGN_MINUS = '-'; + private static char UNICODE_SIGN_PLUS = '+'; + private static char UNICODE_ZERO = '0'; + + private static final boolean JIT_INTRINSICS_ENABLED = false; + + static { + PD2EDTranslationTable = new byte[512]; + ED2UDTranslationTable = new byte[256]; + + Arrays.fill(PD2EDTranslationTable, (byte) 0); + Arrays.fill(ED2UDTranslationTable, (byte) 0); + + for (int tenDigit = 0; tenDigit < 10; ++tenDigit) + for (int oneDigit = 0; oneDigit < 10; ++oneDigit) + { + int pdValue = tenDigit * 16 + oneDigit; + // ED tenDigit + PD2EDTranslationTable[pdValue*2 ] = (byte)(0xF0 | tenDigit); + PD2EDTranslationTable[pdValue*2+1] = (byte)(0xF0 | oneDigit); + } + + for (int digit = 0; digit < 10; ++digit) + { + int edValue = (0xF0 | digit); + ED2UDTranslationTable[edValue + 1] = (byte)(0x30 | digit); + } + + BigDecimal dummy = new BigDecimal("0"); + } + + // Private constructor, class contains only static methods. + private DecimalData() { + } + + private static final int PACKED_BYTES_LENGTH = 33; + // Pre-compute all of the possible values for one byte of a Packed Decimal + private static final byte[] PACKED_BYTES = new byte[200]; + static { + int i = 100; + for (int j = 0; j < 100; j++, i--) { + int low = i % 10; + int high = (i / 10) % 10; + PACKED_BYTES[j] = (byte) ((high << 4) + low); + } + i = 0; + for (int j = 100; j < 200; j++, i++) { + int low = i % 10; + int high = (i / 10) % 10; + PACKED_BYTES[j] = (byte) ((high << 4) + low); + } + } + + /** + * This method is recognized by the JIT. The ILGenerator and Walker will replace this method with an appropriate + * iconst bytecode value corresponding to whether or not the architecture supports DAA JIT intrinsics. Currently + * the JIT will generate an iconst 1 if and only if we are executing under zOS. + * + * @return true if DAA JIT intrinsics are enabled on the current platform, false otherwise + * + */ + private final static boolean JITIntrinsicsEnabled() + { + return JIT_INTRINSICS_ENABLED; + } + + // Binary search on the number of digits in value + private static int numDigits(int value) + { + value = (value == Integer.MIN_VALUE) ? Integer.MAX_VALUE : Math.abs(value); + + return (value >= 10000) ? + (value >= 10000000) ? + (value >= 100000000) ? + (value >= 1000000000) ? 10 : 9 : 8 : + (value >= 100000) ? + (value >= 1000000) ? 7 : 6 : 5 : + (value >= 100) ? + (value >= 1000) ? 4 : 3 : + (value >= 10) ? 2 : 1; + } + + // Binary search on the number of digits in value + private static int numDigits(long value) + { + value = value == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(value); + + return (value >= 1000000000L) ? + (value >= 100000000000000L) ? + (value >= 10000000000000000L) ? + (value >= 100000000000000000L) ? + (value >= 1000000000000000000L) ? 19 : 18 : 17 : + (value >= 1000000000000000L) ? 16 : 15 : + (value >= 100000000000L) ? + (value >= 1000000000000L) ? + (value >= 10000000000000L) ? 14 : 13 : 12 : + (value >= 10000000000L) ? 11 : 10 : + (value >= 10000L) ? + (value >= 1000000L) ? + (value >= 10000000L) ? + (value >= 100000000L) ? 9 : 8 : 7 : + (value >= 100000L) ? 6 : 5 : + (value >= 100L) ? + (value >= 1000L) ? 4 : 3 : + (value >= 10L) ? 2 : 1; + } + + /** + * Converts a binary integer value into a signed Packed Decimal format. The Packed Decimal will be padded with zeros + * on the left if necessary. + * + * Overflow can happen if the resulting Packed Decimal does not fit into the result byte array, given the offset and + * precision. In this case, when checkOverflow is true an ArithmeticException is thrown, + * when false a truncated or invalid result is returned. + * + * @param integerValue + * the binary integer value to convert + * @param packedDecimal + * byte array that will store the resulting Packed Decimal value + * @param offset + * offset of the first byte of the Packed Decimal in packedDecimal + * @param precision + * number of Packed Decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if packedDecimal is null + * @throws ArithmeticException + * if the checkOverflow parameter is true and overflow occurs + */ + public static void convertIntegerToPackedDecimal(int integerValue, + byte[] packedDecimal, int offset, int precision, + boolean checkOverflow) { + if ((offset + ((precision/ 2) + 1) > packedDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertIntegerToPackedDecimal is trying to access packedDecimal[" + offset + "] to packedDecimal[" + (offset + (precision/ 2)) + "], " + + " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); + + convertIntegerToPackedDecimal_(integerValue, packedDecimal, offset, precision, checkOverflow); + } + + private static void convertIntegerToPackedDecimal_(int integerValue, + byte[] packedDecimal, int offset, int precision, + boolean checkOverflow) { + int value; + int bytes = CommonData.getPackedByteCount(precision); + int last = offset + bytes - 1; + int i; + boolean evenPrecision = (precision % 2 == 0) ? true : false; + + // avoid invalid precision + if (checkOverflow) { + if (precision < 1) + throw new ArithmeticException( + "Decimal overflow - Packed Decimal precision lesser than 1"); + + if (numDigits(integerValue) > precision) + throw new ArithmeticException( + "Decimal overflow - Packed Decimal precision insufficient"); + } + if (integerValue < 0) { + packedDecimal[last] = (byte) ((Math.abs(integerValue) % 10) << 4 | CommonData.PACKED_MINUS); + value = Math.abs(integerValue / 10); + } else { + value = integerValue; + packedDecimal[last] = (byte) ((value % 10) << 4 | CommonData.PACKED_PLUS); + value = value / 10; + } + + // fill in high/low nibble pairs from next-to-last up to first + for (i = last - 1; i > offset && value != 0; i--) { + packedDecimal[i] = CommonData.getBinaryToPackedValues(value % 100); + value = value / 100; + } + + if (i == offset && value != 0) { + if (evenPrecision) + packedDecimal[i] = (byte) (CommonData.getBinaryToPackedValues(value % 100) & CommonData.LOWER_NIBBLE_MASK); + else + packedDecimal[i] = CommonData.getBinaryToPackedValues(value % 100); + value = value / 100; + i--; + } + + if (checkOverflow && value != 0) { + throw new ArithmeticException( + "Decimal overflow - Packed Decimal precision insufficient"); + } + if (i >= offset) { + for (int j = 0; j < i - offset + 1; ++j) + packedDecimal[j+offset] = CommonData.PACKED_ZERO; + } + } + + /** + * Converts an integer to an External Decimal in a byte array. The External Decimal will be padded with zeros on the + * left if necessary. + * + * Overflow can happen if the resulting External Decimal value does not fit into the byte array, given the precision + * and offset. In this case, when checkOverflow is true an ArithmeticException is thrown, + * when false a truncated or invalid result is returned. + * + * @param integerValue + * the value to convert + * @param externalDecimal + * the byte array which will hold the External Decimal on a successful return + * @param offset + * the offset in the byte array at which the External Decimal should be located + * @param precision + * the number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticExceptionwill be thrown if the designated array cannot hold the + * External Decimal. + * @param decimalType + * constant value indicating the type of External Decimal + * + * @throws NullPointerException + * if externalDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if the checkOverflow parameter is true and overflow occurs + * @throws IllegalArgumentException + * if decimalType or precision is invalid + */ + public static void convertIntegerToExternalDecimal(int integerValue, + byte[] externalDecimal, int offset, int precision, + boolean checkOverflow, int decimalType) { + if ((offset < 0) + || (offset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertIntegerToExternalDecimal is trying to access externalDecimal[" + offset + + "] to externalDecimal[" + (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + + "], " + " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); + if (JITIntrinsicsEnabled()) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertIntegerToPackedDecimal_(integerValue, packedDecimal, 0, precision, checkOverflow); + convertPackedDecimalToExternalDecimal_(packedDecimal, 0, externalDecimal, offset, precision, decimalType); + } else { + convertIntegerToExternalDecimal_(integerValue, externalDecimal, offset, precision, checkOverflow, decimalType); + } + } + + private static void convertIntegerToExternalDecimal_(int integerValue, byte[] externalDecimal, int offset, + int precision, boolean checkOverflow, int decimalType) { + int i; + byte zoneVal = EXTERNAL_HIGH_MASK; + + int externalSignOffset = offset; + if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) + offset++; + int end = offset + precision - 1; + + if (decimalType < EXTERNAL_DECIMAL_MIN || decimalType > EXTERNAL_DECIMAL_MAX) + throw new IllegalArgumentException("invalid decimalType"); + + if (checkOverflow) { + if (precision < 1) + throw new ArithmeticException("Decimal overflow - External Decimal precision lesser than 1"); + + if (numDigits(integerValue) > precision) + throw new ArithmeticException("Decimal overflow - External Decimal precision insufficient"); + } + + externalDecimal[end] = (byte) (zoneVal | Math.abs(integerValue % 10)); + int value = Math.abs(integerValue / 10); + // fill in high/low nibble pairs from next-to-last up to first + for (i = end - 1; i >= offset && value != 0; i--) { + externalDecimal[i] = (byte) (zoneVal | (value % 10)); + value = value / 10; + } + + if (i >= offset) { + for (int j = offset; j <= i; j++) { + externalDecimal[j] = (byte) (zoneVal | CommonData.PACKED_ZERO); + } + } + + switch (decimalType) { + case EBCDIC_SIGN_EMBEDDED_TRAILING: + case EBCDIC_SIGN_EMBEDDED_LEADING: + if (decimalType == EBCDIC_SIGN_EMBEDDED_TRAILING) { + externalSignOffset += precision - 1; + } + byte sign; + if (integerValue >= 0) { + sign = (byte) (CommonData.PACKED_PLUS << 4); + } else { + sign = (byte) (CommonData.PACKED_MINUS << 4); + } + externalDecimal[externalSignOffset] = (byte) ((externalDecimal[externalSignOffset] & CommonData.LOWER_NIBBLE_MASK) | sign); + break; + case EBCDIC_SIGN_SEPARATE_TRAILING: + case EBCDIC_SIGN_SEPARATE_LEADING: + if (decimalType == EBCDIC_SIGN_SEPARATE_TRAILING) { + externalSignOffset += precision; + } + if (integerValue >= 0) + externalDecimal[externalSignOffset] = EBCDIC_SIGN_POSITIVE; + else + externalDecimal[externalSignOffset] = EBCDIC_SIGN_NEGATIVE; + break; + } + } + + /** + * Converts an integer to a Unicode Decimal in a char array + * + * Overflow can happen if the resulting External Decimal value does not fit into the char array, given the offset and + * precision. In this case, when checkOverflow is true an ArithmeticException is thrown, + * when false a truncated or invalid result is returned. + * + * @param integerValue + * the long value to convert + * @param unicodeDecimal + * the char array which will hold the Unicode Decimal on a successful return + * @param offset + * the offset in the char array where the Unicode Decimal would be located + * @param precision + * the number of decimal digits. Maximum valid precision is 253 + * @param checkoverflow + * if true, when the designated an ArithmeticException + * @param unicodeType + * constant value indicating the type of Unicode Decimal + * + * @throws NullPointerException + * if unicodeDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * + * @throws ArithmeticException + * if the checkOverflow parameter is true and overflow occurs + * @throws IllegalArgumentException + * if the decimalType or precision is invalid + */ + public static void convertIntegerToUnicodeDecimal(int integerValue, + char[] unicodeDecimal, int offset, int precision, + boolean checkoverflow, int unicodeType) { + int size = unicodeType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; + if ((offset + size > unicodeDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertIntegerToUnicodeDecimal is trying to access unicodeDecimal[" + offset + "] to unicodeDecimal[" + (offset + size - 1) + "], " + + " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); + + if (JITIntrinsicsEnabled()) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertIntegerToPackedDecimal_(integerValue, packedDecimal, 0, precision, checkoverflow); + convertPackedDecimalToUnicodeDecimal_(packedDecimal, 0, unicodeDecimal, offset, precision, unicodeType); + } else { + convertIntegerToUnicodeDecimal_(integerValue, unicodeDecimal, offset, precision, checkoverflow, unicodeType); + } + } + + private static void convertIntegerToUnicodeDecimal_(int integerValue, char[] unicodeDecimal, int offset, int precision, boolean checkOverflow, int unicodeType) + { + // Avoid invalid precisions + if (checkOverflow) { + if (precision < 1) + throw new ArithmeticException("Decimal overflow - Unicode Decimal precision lesser than 1"); + + if (precision < numDigits(integerValue)) + throw new ArithmeticException("Decimal overflow - Unicode Decimal precision insufficient"); + } + + switch (unicodeType) + { + case UNICODE_UNSIGNED: break; + + case UNICODE_SIGN_SEPARATE_LEADING: + unicodeDecimal[offset++] = integerValue < 0 ? UNICODE_SIGN_MINUS : UNICODE_SIGN_PLUS; + break; + + case UNICODE_SIGN_SEPARATE_TRAILING: + unicodeDecimal[offset + precision] = integerValue < 0 ? UNICODE_SIGN_MINUS : UNICODE_SIGN_PLUS; + break; + + default: throw new IllegalArgumentException("Invalid decimalType"); + } + + unicodeDecimal[offset + precision - 1] = (char) (UNICODE_HIGH_MASK | (Math.abs(integerValue) % 10)); + + // Normalize the value + integerValue = Math.abs(integerValue / 10); + + int i; + + // fill in high/low nibble pairs from next-to-last up to first + for (i = offset + precision - 2; i >= offset && integerValue != 0; i--) { + unicodeDecimal[i] = (char) (UNICODE_HIGH_MASK | (integerValue % 10)); + + integerValue = integerValue / 10; + } + + if (checkOverflow && integerValue != 0) { + throw new ArithmeticException("Decimal overflow - Unicode Decimal precision insufficient"); + } + + for (; i >= offset; i--) { + unicodeDecimal[i] = (char) UNICODE_HIGH_MASK; + } + } + + /** + * Converts a binary long value into signed Packed Decimal format. The Packed Decimal will be padded with zeros on + * the left if necessary. + * + * Overflow can happen if the resulting Packed Decimal does not fit into the result byte array, given the offset and + * precision . In this case, when checkOverflow is true an ArithmeticException is thrown, + * when false a truncated or invalid result is returned. + * + * @param longValue + * the binary long value to convert + * @param packedDecimal + * byte array that will store the resulting Packed Decimal value + * @param offset + * offset of the first byte of the Packed Decimal in packedDecimal + * @param precision + * number of Packed Decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow), otherwise a truncated value is returned + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if packedDecimal is null + * @throws ArithmeticException + * the checkOverflow parameter is true and overflow occurs + */ + public static void convertLongToPackedDecimal(long longValue, + byte[] packedDecimal, int offset, int precision, + boolean checkOverflow) { + if ((offset + ((precision/ 2) + 1) > packedDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertLongToPackedDecimal is trying to access packedDecimal[" + offset + "] to packedDecimal[" + (offset + (precision/ 2)) + "], " + + " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); + + convertLongToPackedDecimal_(longValue, packedDecimal, offset, precision, checkOverflow); + } + + private static void convertLongToPackedDecimal_(long longValue, + byte[] packedDecimal, int offset, int precision, + boolean checkOverflow) { + long value; + int bytes = CommonData.getPackedByteCount(precision); + int last = offset + bytes - 1; + int i; + boolean evenPrecision = (precision % 2 == 0) ? true : false; + + if (checkOverflow) { + if (precision < 1) + throw new ArithmeticException( + "Decimal overflow - Packed Decimal precision lesser than 1"); + + if (numDigits(longValue) > precision) + throw new ArithmeticException( + "Decimal overflow - Packed Decimal precision insufficient"); + } + + if (longValue < 0) { + packedDecimal[last] = (byte) ((Math.abs(longValue) % 10) << 4 | CommonData.PACKED_MINUS); + value = Math.abs(longValue / 10); + } else { + value = longValue; + packedDecimal[last] = (byte) ((value % 10) << 4 | CommonData.PACKED_PLUS); + value = value / 10; + } + + // fill in high/low nibble pairs from next-to-last up to first + for (i = last - 1; i > offset && value != 0; i--) { + packedDecimal[i] = CommonData + .getBinaryToPackedValues((int) (value % 100)); + value = value / 100; + } + + if (i == offset && value != 0) { + if (evenPrecision) + packedDecimal[i] = (byte) (CommonData + .getBinaryToPackedValues((int) (value % 100)) & CommonData.LOWER_NIBBLE_MASK); + else + packedDecimal[i] = CommonData + .getBinaryToPackedValues((int) (value % 100)); + value = value / 100; + i--; + } + + if (checkOverflow && value != 0) { + throw new ArithmeticException( + "Decimal overflow - Packed Decimal precision insufficient"); + } + if (i >= offset) { + for (int j = 0; j < i - offset + 1; ++j) + packedDecimal[j+offset] = CommonData.PACKED_ZERO; + } + } + + /** + * Converts a long into an External Decimal in a byte array. The External Decimal will be padded with zeros on the + * left if necessary. + * + * Overflow can happen if the External Decimal value does not fit into the byte array, given its precision and offset. + * In this case, when checkOverflow is true an ArithmeticException is thrown, when false a + * truncated or invalid result is returned. + * + * @param longValue + * the value to convert + * @param externalDecimal + * the byte array which will hold the External Decimal on a successful return + * @param offset + * the offset into externalDecimal where External Decimal should be located + * @param precision + * the number of decimal digits to convert. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException or IllegalArgumentException may be thrown + * @param decimalType + * constant value indicating the type of External Decimal + * + * @throws NullPointerException + * if externalDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if the checkOverflow parameter is true and overflow occurs + * @throws IllegalArgumentException + * if the decimalType or precision is invalid + */ + public static void convertLongToExternalDecimal(long longValue, byte[] externalDecimal, int offset, int precision, + boolean checkOverflow, int decimalType) { + if ((offset < 0) + || (offset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertLongToExternalDecimal is trying to access externalDecimal[" + offset + + "] to externalDecimal[" + (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + + "], " + " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); + if (JITIntrinsicsEnabled()) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertLongToPackedDecimal_(longValue, packedDecimal, 0, precision, checkOverflow); + convertPackedDecimalToExternalDecimal_(packedDecimal, 0, externalDecimal, offset, precision, decimalType); + } else { + convertLongToExternalDecimal_(longValue, externalDecimal, offset, precision, checkOverflow, decimalType); + } + } + + private static void convertLongToExternalDecimal_(long longValue, byte[] externalDecimal, int offset, + int precision, boolean checkOverflow, int decimalType) { + int i; + byte zoneVal = EXTERNAL_HIGH_MASK; + + int externalSignOffset = offset; + if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) + offset++; + int end = offset + precision - 1; + + if (decimalType < EXTERNAL_DECIMAL_MIN || decimalType > EXTERNAL_DECIMAL_MAX) + throw new IllegalArgumentException("invalid decimalType"); + + if (checkOverflow) { + if (precision < 1) + throw new ArithmeticException("Decimal overflow - External Decimal precision lesser than 1"); + + if (numDigits(longValue) > precision) + throw new ArithmeticException("Decimal overflow - External Decimal precision insufficient"); + } + + externalDecimal[end] = (byte) (zoneVal | Math.abs(longValue % 10)); + long value = Math.abs(longValue / 10); + // fill in high/low nibble pairs from next-to-last up to first + for (i = end - 1; i >= offset && value != 0; i--) { + externalDecimal[i] = (byte) (zoneVal | (value % 10)); + value = value / 10; + } + + if (i >= offset) { + for (int j = offset; j <= i; j++) { + externalDecimal[j] = (byte) (zoneVal | CommonData.PACKED_ZERO); + } + } + + switch (decimalType) { + case EBCDIC_SIGN_EMBEDDED_TRAILING: + case EBCDIC_SIGN_EMBEDDED_LEADING: + if (decimalType == EBCDIC_SIGN_EMBEDDED_TRAILING) { + externalSignOffset += precision - 1; + } + byte sign; + if (longValue >= 0) { + sign = (byte) (CommonData.PACKED_PLUS << 4); + } else { + sign = (byte) (CommonData.PACKED_MINUS << 4); + } + externalDecimal[externalSignOffset] = (byte) ((externalDecimal[externalSignOffset] & CommonData.LOWER_NIBBLE_MASK) | sign); + break; + case EBCDIC_SIGN_SEPARATE_TRAILING: + case EBCDIC_SIGN_SEPARATE_LEADING: + if (decimalType == EBCDIC_SIGN_SEPARATE_TRAILING) { + externalSignOffset += precision; + } + if (longValue >= 0) + externalDecimal[externalSignOffset] = EBCDIC_SIGN_POSITIVE; + else + externalDecimal[externalSignOffset] = EBCDIC_SIGN_NEGATIVE; + break; + } + } + + /** + * Converts a long to a Unicode Decimal in a char array + * + * Overflow can happen if the resulting Unicode Decimal value does not fit into the char array, given its precision + * and offset . In this case, when checkOverflow is true an ArithmeticException is thrown, + * when false a truncated or invalid result is returned. + * + * @param longValue + * the long value to convert + * @param unicodeDecimal + * the char array which will hold the Unicode Decimal on a successful return + * @param offset + * the offset in the char array where the Unicode Decimal would be located + * @param precision + * the number of Unicode Decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException or IllegalArgumentException may be thrown + * @param decimalType + * constant value indicating the type of External Decimal + * + * @throws NullPointerException + * if unicodeDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if the checkOverflow parameter is true and overflow occurs + * @throws IllegalArgumentException + * if decimalType or precision is invalid + */ + public static void convertLongToUnicodeDecimal(long longValue, + char[] unicodeDecimal, int offset, int precision, + boolean checkOverflow, int decimalType) { + int size = decimalType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; + if ((offset + size > unicodeDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertIntegerToUnicodeDecimal is trying to access unicodeDecimal[" + offset + "] to unicodeDecimal[" + (offset + size - 1) + "], " + + " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); + + if (JITIntrinsicsEnabled()) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertLongToPackedDecimal_(longValue, packedDecimal, 0, precision, checkOverflow); + convertPackedDecimalToUnicodeDecimal_(packedDecimal, 0, unicodeDecimal, offset, precision, decimalType); + } else { + convertLongToUnicodeDecimal_(longValue, unicodeDecimal, offset, precision, checkOverflow, decimalType); + } + } + + private static void convertLongToUnicodeDecimal_(long longValue, char[] unicodeDecimal, int offset, int precision, boolean checkOverflow, int unicodeType) + { + // Avoid invalid precisions + if (checkOverflow) { + if (precision < 1) + throw new ArithmeticException("Decimal overflow - Unicode Decimal precision lesser than 1"); + + if (precision < numDigits(longValue)) + throw new ArithmeticException("Decimal overflow - Unicode Decimal precision insufficient"); + } + + switch (unicodeType) + { + case UNICODE_UNSIGNED: break; + + case UNICODE_SIGN_SEPARATE_LEADING: + unicodeDecimal[offset++] = longValue < 0 ? UNICODE_SIGN_MINUS : UNICODE_SIGN_PLUS; + break; + + case UNICODE_SIGN_SEPARATE_TRAILING: + unicodeDecimal[offset + precision] = longValue < 0 ? UNICODE_SIGN_MINUS : UNICODE_SIGN_PLUS; + break; + + default: throw new IllegalArgumentException("Invalid decimalType"); + } + + unicodeDecimal[offset + precision - 1] = (char) (UNICODE_HIGH_MASK | (Math.abs(longValue) % 10)); + + // Normalize the value + longValue = Math.abs(longValue / 10); + + int i; + + // fill in high/low nibble pairs from next-to-last up to first + for (i = offset + precision - 2; i >= offset && longValue != 0; i--) { + unicodeDecimal[i] = (char) (UNICODE_HIGH_MASK | (longValue % 10)); + + longValue = longValue / 10; + } + + if (checkOverflow && longValue != 0) { + throw new ArithmeticException("Decimal overflow - Unicode Decimal precision insufficient"); + } + + for (; i >= offset; i--) { + unicodeDecimal[i] = (char) UNICODE_HIGH_MASK; + } + } + + /** + * Converts a Packed Decimal value in a byte array into a binary integer. If the digital part of the input Packed + * Decimal is not valid then the digital part of the output will not be valid. The sign of the input Packed Decimal + * is assumed to be positive unless the sign nibble contains one of the negative sign codes, in which case the + * sign of the input Packed Decimal is interpreted as negative. + * + * Overflow can happen if the Packed Decimal value does not fit into a binary integer. When + * checkOverflow is true overflow results in an ArithmeticException, when false a + * truncated or invalid result is returned. + * + * @param packedDecimal + * byte array which contains the Packed Decimal value + * @param offset + * offset of the first byte of the Packed Decimal in packedDecimal + * @param precision + * number of Packed Decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException may be thrown + * + * @return int the resulting binary integer value + * + * @throws NullPointerException + * if packedDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result does not fit into an int (overflow) + */ + public static int convertPackedDecimalToInteger(byte[] packedDecimal, + int offset, int precision, boolean checkOverflow) { + if ((offset + ((precision/ 2) + 1) > packedDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertPackedDecimalToInteger is trying to access packedDecimal[" + offset + "] to packedDecimal[" + (offset + (precision/ 2)) + "], " + + " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); + + return convertPackedDecimalToInteger_(packedDecimal, offset, precision, checkOverflow); + } + + private static int convertPackedDecimalToInteger_(byte[] packedDecimal, + int offset, int precision, boolean checkOverflow) { + int bytes = CommonData.getPackedByteCount(precision); + int end = offset + bytes - 1; + long value = 0;// = (packedDecimal[end] & CommonData.INTEGER_MASK) >> 4; + + byte sign = CommonData.getSign((byte) (packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK)); + + // Skip the first byte if the precision is even and the low-order nibble is zero + if (precision % 2 == 0 && (packedDecimal[offset] & CommonData.LOWER_NIBBLE_MASK) == 0x00) + { + precision--; + offset++; + } + + // Skip consecutive zero bytes + for (; offset < end && packedDecimal[offset] == CommonData.PACKED_ZERO; offset++) + { + precision -= 2; + } + + if (checkOverflow) + { + // Skip high-order zero if and only if precision is odd + if (precision % 2 == 1 && (packedDecimal[offset] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) + { + precision--; + } + + // At this point we are guaranteed that the nibble pointed by a non-zero precision value is non-zero + if (precision > 10) + throw new ArithmeticException( + "Decimal overflow - Packed Decimal too large for an int"); + } + + // For checkOverflow == true at this point we are guaranteed that precision <= 10. The following loop + // will never overflow because the long value can always contain an integer of precision 10. + + for (int pos = offset; pos <= end - 1; ++pos) + { + value = value * 100 + CommonData.getPackedToBinaryValues(packedDecimal[pos]); + } + + value = value * 10 + ((packedDecimal[end] & CommonData.HIGHER_NIBBLE_MASK) >> 4); + + if (sign == CommonData.PACKED_MINUS) + value = -1 * value; + + if (checkOverflow && (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE)) + { + throw new ArithmeticException( + "Decimal overflow - Packed Decimal too large for a int"); + } + + return (int)value; + } + + /** + * Converts a Packed Decimal value in a byte array into a binary long. If the digital part of the input Packed + * Decimal is not valid then the digital part of the output will not be valid. The sign of the input Packed Decimal + * is assumed to be positive unless the sign nibble contains one of the negative sign codes, in which case the + * sign of the input Packed Decimal is interpreted as negative. + * + * Overflow can happen if the Packed Decimal value does not fit into a binary long. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param packedDecimal + * byte array which contains the Packed Decimal value + * @param offset + * offset of the first byte of the Packed Decimal in packedDecimal + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException may be thrown + * + * @return long the resulting binary long value + * + * @throws NullPointerException + * if packedDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result does not fit into a long (overflow) + */ + public static long convertPackedDecimalToLong(byte[] packedDecimal, + int offset, int precision, boolean checkOverflow) { + if ((offset + ((precision/ 2) + 1) > packedDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertPackedDecimalToLong is trying to access packedDecimal[" + offset + "] to packedDecimal[" + (offset + (precision/ 2)) + "], " + + " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); + + return convertPackedDecimalToLong_(packedDecimal, offset, precision, checkOverflow); + } + + private static long convertPackedDecimalToLong_(byte[] packedDecimal, + int offset, int precision, boolean checkOverflow) { + long value = 0; + int bytes = CommonData.getPackedByteCount(precision); + int end = offset + bytes - 1; + int last = packedDecimal[end] & CommonData.INTEGER_MASK; + byte sign = CommonData.getSign((byte) (last & CommonData.LOWER_NIBBLE_MASK)); + + // Skip the first byte if the precision is even and the low-order nibble is zero + if (precision % 2 == 0 && (packedDecimal[offset] & CommonData.LOWER_NIBBLE_MASK) == 0x00) + { + precision--; + offset++; + } + + // Skip consecutive zero bytes + for (; offset < end && packedDecimal[offset] == CommonData.PACKED_ZERO; offset++) + { + precision -= 2; + } + + if (checkOverflow) + { + // Skip high-order zero if and only if precision is odd + if (precision % 2 == 1 && (packedDecimal[offset] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) + { + precision--; + } + + // At this point we are guaranteed that the nibble pointed by a non-zero precision value is non-zero + if (precision > 19) + throw new ArithmeticException( + "Decimal overflow - Packed Decimal too large for a long"); + } + + // For checkOverflow == true at this point we are guaranteed that precision <= 19. The following loop + // may cause the signed long value to overflow. Because the first digit of Long.MAX_VALUE is a 9 the + // overflowed signed long value cannot overflow an unsigned long. This guarantees that if an overflow + // occurs, value will be negative. We will use this fact along with the sign code calculated earlier + // to determine whether overflow occurred. + + for (int pos = offset; pos <= end - 1; ++pos) + { + value = value * 100 + CommonData.getPackedToBinaryValues(packedDecimal[pos]); + } + + value = value * 10 + ((last & CommonData.HIGHER_NIBBLE_MASK) >> 4); + + if (sign == CommonData.PACKED_MINUS) + value = -value; + + if (checkOverflow) + { + if (sign == CommonData.PACKED_PLUS && value < 0) + throw new ArithmeticException( + "Decimal overflow - Packed Decimal too large for a long"); + else if (sign == CommonData.PACKED_MINUS && value > 0) + throw new ArithmeticException( + "Decimal overflow - Packed Decimal too large for a long"); + } + + return value; + } + + /** + * Converts a Packed Decimal in a byte array into an External Decimal in another byte array. If the digital part of + * the input Packed Decimal is not valid then the digital part of the output will not be valid. The sign of the + * input Packed Decimal is assumed to be positive unless the sign nibble contains one of the negative sign codes, + * in which case the sign of the input Packed Decimal is interpreted as negative. + * + * @param packedDecimal + * byte array that holds the Packed Decimal to be converted + * @param packedOffset + * offset in packedDecimal where the Packed Decimal is located + * @param externalDecimal + * byte array that will hold the External Decimal on a successful return + * @param externalOffset + * offset in externalOffset where the External Decimal is expected to be located + * @param precision + * number of decimal digits + * @param decimalType + * constant indicating the type of the decimal + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if packedDecimal or externalDecimal are null + * @throws IllegalArgumentException + * if precision or decimalType is invalid + */ + public static void convertPackedDecimalToExternalDecimal( + byte[] packedDecimal, int packedOffset, byte[] externalDecimal, + int externalOffset, int precision, int decimalType) { + if ((packedOffset + ((precision/ 2) + 1) > packedDecimal.length) || (packedOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertPackedDecimalToExternalDecimal is trying to access packedDecimal[" + packedOffset + "] to packedDecimal[" + (packedOffset + (precision/ 2)) + "], " + + " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); + if ((externalOffset < 0) || (externalOffset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertPackedDecimalToExternalDecimal is trying to access externalDecimal[" + externalOffset + "] to externalDecimal[" + (externalOffset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + "], " + + " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); + + convertPackedDecimalToExternalDecimal_(packedDecimal, packedOffset, externalDecimal, + externalOffset, precision, decimalType); + } + + private static void convertPackedDecimalToExternalDecimal_( + byte[] packedDecimal, int packedOffset, byte[] externalDecimal, + int externalOffset, int precision, int decimalType) { + + if (decimalType < EXTERNAL_DECIMAL_MIN + || decimalType > EXTERNAL_DECIMAL_MAX) + throw new IllegalArgumentException("invalid decimalType"); + if (precision <= 0) + throw new IllegalArgumentException("negative precision"); + + int externalSignOffset = externalOffset; + if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) + externalOffset++; + + int end = packedOffset + precision / 2; + int edEnd = externalOffset + precision - 1; + + byte zoneVal = EXTERNAL_HIGH_MASK; + + // handle even precision + if (precision % 2 == 0) { + externalDecimal[externalOffset++] = (byte) (zoneVal | (packedDecimal[packedOffset++] & CommonData.LOWER_NIBBLE_MASK)); + } + + // compute all the intermediate digits + for (int i = packedOffset; i < end; i++) { + externalDecimal[externalOffset++] = (byte) (zoneVal | (((packedDecimal[i] & CommonData.HIGHER_NIBBLE_MASK) >> 4) & CommonData.LOWER_NIBBLE_MASK)); + externalDecimal[externalOffset++] = (byte) (zoneVal | (packedDecimal[i] & CommonData.LOWER_NIBBLE_MASK)); + } + + // deal with the last digit + externalDecimal[edEnd] = (byte) (zoneVal | (((packedDecimal[end] & 0xF0) >> 4) & CommonData.LOWER_NIBBLE_MASK)); + + //byte sign = (byte)((packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK) << 4); + byte sign = (byte)(CommonData.getSign(packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK) << 4); + + switch (decimalType) { + case EBCDIC_SIGN_SEPARATE_LEADING: + if (sign == (byte) 0xC0) + externalDecimal[externalSignOffset] = EBCDIC_SIGN_POSITIVE; + else + externalDecimal[externalSignOffset] = EBCDIC_SIGN_NEGATIVE; + break; + case EBCDIC_SIGN_EMBEDDED_LEADING: + externalDecimal[externalSignOffset] = (byte) ((externalDecimal[externalSignOffset] & CommonData.LOWER_NIBBLE_MASK) | sign); + break; + case EBCDIC_SIGN_EMBEDDED_TRAILING: + externalSignOffset += precision - 1; + externalDecimal[externalSignOffset] = (byte) ((externalDecimal[externalSignOffset] & CommonData.LOWER_NIBBLE_MASK) | sign); + break; + case EBCDIC_SIGN_SEPARATE_TRAILING: + externalSignOffset += precision; + if (sign == (byte) 0xC0) + externalDecimal[externalSignOffset] = EBCDIC_SIGN_POSITIVE; + else + externalDecimal[externalSignOffset] = EBCDIC_SIGN_NEGATIVE; + break; + default: + //unreachable code + //throw new IllegalArgumentException("invalid decimalType"); + } + } + + /** + * Convert a Packed Decimal in a byte array to a Unicode Decimal in a char array. If the digital part of the input + * Packed Decimal is not valid then the digital part of the output will not be valid. The sign of the input Packed + * Decimal is assumed to be positive unless the sign nibble contains one of the negative sign codes, in which + * case the sign of the input Packed Decimal is interpreted as negative. + * + * @param packedDecimal + * byte array that holds a Packed Decimal to be converted + * @param packedOffset + * offset in packedDecimal where the Packed Decimal is located + * @param unicodeDecimal + * char array that will hold the Unicode Decimal on a successful return + * @param unicodeOffset + * offset in the byte array where the Unicode Decimal is expected to be located + * @param precision + * number of decimal digits + * @param decimalType + * constant value indicating the type of the External Decimal + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if packedDecimal or unicodeDecimal are null + * @throws IllegalArgumentException + * if precision or decimalType is invalid + */ + public static void convertPackedDecimalToUnicodeDecimal( + byte[] packedDecimal, int packedOffset, char[] unicodeDecimal, + int unicodeOffset, int precision, int decimalType) { + int size = decimalType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; + if ((unicodeOffset + size > unicodeDecimal.length) || (unicodeOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertPackedDecimalToUnicodeDecimal is trying to access unicodeDecimal[" + unicodeOffset + "] to unicodeDecimal[" + (unicodeOffset + size - 1) + "], " + + " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); + if ((packedOffset < 0) || (packedOffset + ((precision/ 2) + 1) > packedDecimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertPackedDecimalToUnicodeDecimal is trying to access packedDecimal[" + packedOffset + "] to packedDecimal[" + (packedOffset + (precision/ 2)) + "], " + + " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); + + convertPackedDecimalToUnicodeDecimal_(packedDecimal, packedOffset, unicodeDecimal, + unicodeOffset, precision, decimalType); + } + + private static void convertPackedDecimalToUnicodeDecimal_( + byte[] packedDecimal, int packedOffset, char[] unicodeDecimal, + int unicodeOffset, int precision, int decimalType) { + + if (precision <= 0) + throw new IllegalArgumentException("negative precision"); + + int externalSignOffset = -1; + switch (decimalType) { + case UNICODE_UNSIGNED: + break; + case UNICODE_SIGN_SEPARATE_LEADING: + externalSignOffset = unicodeOffset++; + break; + case UNICODE_SIGN_SEPARATE_TRAILING: + externalSignOffset = unicodeOffset + precision; + break; + default: + throw new IllegalArgumentException("invalid decimalType"); + } + + byte zoneVal = UNICODE_HIGH_MASK; + + // Get sign from Packed Decimal + int end = packedOffset + precision / 2; + byte sign = (byte) (packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK); + sign = CommonData.getSign(sign); + + // handle even precision + if (precision % 2 == 0) { + unicodeDecimal[unicodeOffset] = (char) (zoneVal | (packedDecimal[packedOffset++] & CommonData.LOWER_NIBBLE_MASK)); + unicodeOffset++; + } + + // compute all the intermediate digits + for (int i = packedOffset; i < end; i++) { + unicodeDecimal[unicodeOffset] = (char) (zoneVal | (((packedDecimal[i] & CommonData.HIGHER_NIBBLE_MASK) >> 4) & CommonData.LOWER_NIBBLE_MASK)); + unicodeOffset++; + unicodeDecimal[unicodeOffset] = (char) (zoneVal | (packedDecimal[i] & CommonData.LOWER_NIBBLE_MASK)); + unicodeOffset++; + } + + // deal with the last digit + unicodeDecimal[unicodeOffset] = (char) (zoneVal | (((packedDecimal[end] & 0xF0) >> 4) & CommonData.LOWER_NIBBLE_MASK)); + + // put the sign + if (decimalType != UNICODE_UNSIGNED) { + if (sign == CommonData.PACKED_PLUS) { + // put 2B for positive + unicodeDecimal[externalSignOffset] = 0x2B; + } else { + // put 2D for negative + unicodeDecimal[externalSignOffset] = 0x2D; + } + } + } + + /** + * Convert a Packed Decimal in a byte array to a BigInteger. If the digital part of the input Packed Decimal is not + * valid then the digital part of the output will not be valid. The sign of the input Packed Decimal is assumed to + * to be positive unless the sign nibble contains one of the negative sign codes, in which case the sign of the + * input Packed Decimal is interpreted as negative. + * + * Overflow can happen if the Packed Decimal value does not fit into the BigInteger. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param packedDecimal + * byte array that holds the Packed Decimal to be converted + * @param offset + * offset in packedDecimal where the Packed Decimal is located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @return BigInteger the resulting BigInteger + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if packedDecimal is null + */ + public static BigInteger convertPackedDecimalToBigInteger( + byte[] packedDecimal, int offset, int precision, + boolean checkOverflow) { + return convertPackedDecimalToBigDecimal(packedDecimal, offset, + precision, 0, checkOverflow).toBigInteger(); + } + + /** + * Convert a Packed Decimal in a byte array to a BigDecimal. If the digital part of the input Packed Decimal is not + * valid then the digital part of the output will not be valid. The sign of the input Packed Decimal is assumed to + * to be positive unless the sign nibble contains one of the negative sign codes, in which case the sign of the + * input Packed Decimal is interpreted as negative. + * + * Overflow can happen if the Packed Decimal value does not fit into the BigDecimal. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param packedDecimal + * byte array that holds the Packed Decimal to be converted + * @param offset + * offset in packedDecimal where the Packed Decimal is located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param scale + * scale of the BigDecimal to be returned + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * + * @return BigDecimal the resulting BigDecimal + * + * @throws NullPointerException + * if packedDecimal is null + * @throws ArrayIndexOutOfBoundsException + * /requires rounding if an invalid array access occurs + */ + public static BigDecimal convertPackedDecimalToBigDecimal( + byte[] packedDecimal, int offset, int precision, int scale, + boolean checkOverflow) { + + if (precision <= 9) { + return BigDecimal.valueOf( + convertPackedDecimalToInteger(packedDecimal, offset, precision, + checkOverflow), scale); + } else if (precision <= 18) { + return BigDecimal.valueOf( + convertPackedDecimalToLong(packedDecimal, offset, precision, + checkOverflow), scale); + } + + return slowSignedPackedToBigDecimal(packedDecimal, offset, precision, + scale, checkOverflow); + } + + /** + * Converts an External Decimal value in a byte array into a binary integer. If the digital part of the input + * External Decimal is not valid then the digital part of the output will not be valid. The sign of the input + * External Decimal is assumed to be positive unless the sign nibble or byte (depending on + * decimalType) contains one of the negative sign codes, in which case the sign of the input External + * Decimal is interpreted as negative. + * + * Overflow can happen if the External Decimal value does not fit into a binary integer. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false the resulting number + * will be wrapped around starting at the minimum/maximum possible integer value. + * + * @param externalDecimal + * byte array which contains the External Decimal value + * @param offset + * the offset where the External Decimal value is located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException or IllegalArgumentException may be thrown. If + * false and there is an overflow, the result is undefined. + * @param decimalType + * constant value indicating the type of External Decimal + * + * @return int the resulting binary integer + * + * @throws NullPointerException + * if externalDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result does not fit into a int (overflow) + * @throws IllegalArgumentException + * if precision or decimalType is invalid + */ + public static int convertExternalDecimalToInteger(byte[] externalDecimal, + int offset, int precision, boolean checkOverflow, int decimalType) { + if ((offset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertExternalDecimalToInteger is trying to access externalDecimal[" + offset + "] to externalDecimal[" + (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + "], " + + " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); + + if (precision <= 0) + throw new IllegalArgumentException("Precision can't be negative."); + + if (JITIntrinsicsEnabled()) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertExternalDecimalToPackedDecimal_(externalDecimal, offset, packedDecimal, 0, precision, decimalType); + return convertPackedDecimalToInteger_(packedDecimal, 0, precision, checkOverflow); + } else { + return convertExternalDecimalToInteger_(externalDecimal, offset, precision, checkOverflow, decimalType); + } + } + + private static int convertExternalDecimalToInteger_(byte[] externalDecimal, + int offset, int precision, boolean checkOverflow, int decimalType) { + int end = (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1); + boolean isNegative = isExternalDecimalSignNegative(externalDecimal, offset, precision, decimalType); + + if (decimalType == EBCDIC_SIGN_SEPARATE_TRAILING) { + end--; + } else if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) { + offset++; + } + + int value = 0; + if (isNegative) + { + if (precision < 10 || (checkOverflow == false)) //max/min values are -2,147,483,648 and 2,147,483,647, so no overflow possible + { + for (int i = offset; i <= end; i++) + { + value = value * 10 - (externalDecimal[i] & 0x0F); + } + } + else //checkOverflow true, precision >= 10 + { + int tenthOffset = end-9; //location of 10th digit if existent + int offsetMod = offset > tenthOffset ? offset : tenthOffset; //only read last 10 digits + for (int i = offsetMod; i <= end; i++) + { + value = value * 10 - (externalDecimal[i] & 0x0F); + } + //need value>0 for cases like 2,900,000,000 and digit>2 for 5,000,000,000 + if (value > 0 || (tenthOffset >= offset && (externalDecimal[tenthOffset] & 0x0F) > 2)) //check 10th digit + { + throw new ArithmeticException( + "Decimal overflow - External Decimal too small for an int"); + } + + //any more digits are overflow + for (int i = offset; i < offsetMod; i++) + { + if ((externalDecimal[i] & 0x0F) > 0) + { + throw new ArithmeticException( + "Decimal overflow - External Decimal too small for an int"); + } + } + } + } + else + { + if (precision < 10 || (checkOverflow == false)) //max/min values are -2,147,483,648 and 2,147,483,647, so no overflow possible + { + for (int i = offset; i <= end; i++) + { + value = value * 10 + (externalDecimal[i] & 0x0F); + } + } + else //checkOverflow true, precision >= 10 + { + int tenthOffset = end-9; //location of 10th digit if existent + int offsetMod = offset > tenthOffset ? offset : tenthOffset; //only read last 10 digits + for (int i = offsetMod; i <= end; i++) + { + value = value * 10 + (externalDecimal[i] & 0x0F); + } + //need value<0 for cases like 2,900,000,000 and digit>2 for 5,000,000,000 + if (value < 0 || (tenthOffset >= offset && (externalDecimal[tenthOffset] & 0x0F) > 2)) //check 10th digit + { + throw new ArithmeticException( + "Decimal overflow - External Decimal too large for an int"); + } + + //any more digits are overflow + for (int i = offset; i < offsetMod; i++) + { + if ((externalDecimal[i] & 0x0F) > 0) + { + throw new ArithmeticException( + "Decimal overflow - External Decimal too large for an int"); + } + } + } + } + return value; + } + + /** + * Converts an External Decimal value in a byte array into a long. If the digital part of the input External Decimal + * is not valid then the digital part of the output will not be valid. The sign of the input External Decimal is + * assumed to be positive unless the sign nibble or byte (depending on decimalType) contains one of + * the negative sign codes, in which case the sign of the input External Decimal is interpreted as negative. + * + * Overflow can happen if the External Decimal value does not fit into a binary long. When + * checkOverflow is true overflow results in an ArithmeticException, when false the + * resulting number will be wrapped around starting at the minimum/maximum possible long value. + * + * @param externalDecimal + * byte array which contains the External Decimal value + * @param offset + * offset of the first byte of the Packed Decimal in the externalDecimal + * @param precision + * number of External Decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown when the converted value cannot fit into + * designated External Decimal array. If false and there is an overflow, the result is undefined. + * @param decimalType + * constant value indicating the type of External Decimal + * + * @return long the resulting binary long value + * + * @throws NullPointerException + * if externalDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result does not fit into a long (overflow) + * @throws IllegalArgumentException + * if precision or decimalType is invalid + */ + public static long convertExternalDecimalToLong(byte[] externalDecimal, + int offset, int precision, boolean checkOverflow, int decimalType) { + if ((offset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertExternalDecimalToLong is trying to access externalDecimal[" + offset + "] to externalDecimal[" + (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + "], " + + " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); + + if (precision <= 0) + throw new IllegalArgumentException("Precision can't be negative."); + + if (JITIntrinsicsEnabled()) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertExternalDecimalToPackedDecimal_(externalDecimal, offset, packedDecimal, 0, precision, decimalType); + return convertPackedDecimalToLong_(packedDecimal, 0, precision, checkOverflow); + } else { + return convertExternalDecimalToLong_(externalDecimal, offset, precision, checkOverflow, decimalType); + } + } + + private static long convertExternalDecimalToLong_(byte[] externalDecimal, + int offset, int precision, boolean checkOverflow, int decimalType) { + int end = (offset + CommonData.getExternalByteCounts(precision, decimalType) - 1); + boolean isNegative = isExternalDecimalSignNegative(externalDecimal, offset, precision, decimalType); + + if (decimalType == EBCDIC_SIGN_SEPARATE_TRAILING) { + end--; + } else if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) { + offset++; + } + + long value = 0; + if (isNegative) + { + if (precision < 19 || (checkOverflow == false)) //max/min values are -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807, so no overflow possible + { + for (int i = offset; i <= end; i++) + { + value = value * 10 - (externalDecimal[i] & 0x0F); + } + } + else //checkOverflow true, precision >= 19 + { + int offsetMod = offset > end-18 ? offset : end-18; //only read last 19 digits + for (int i = offsetMod; i <= end; i++) + { + value = value * 10 - (externalDecimal[i] & 0x0F); + } + if (value > 0) //check 19th digit + { + throw new ArithmeticException( + "Decimal overflow - External Decimal too small for a long"); + } + + //any more digits are overflow + for (int i = offset; i < offsetMod; i++) + { + if ((externalDecimal[i] & 0x0F) > 0) + { + throw new ArithmeticException( + "Decimal overflow - External Decimal too small for a long"); + } + } + } + } + else + { + if (precision < 19 || (checkOverflow == false)) //max/min values are -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807, so no overflow possible + { + for (int i = offset; i <= end; i++) + { + value = value * 10 + (externalDecimal[i] & 0x0F); + } + } + else //checkOverflow true, precision >= 19 + { + int offsetMod = offset > end-18 ? offset : end-18; //only read last 19 digits + for (int i = offsetMod; i <= end; i++) + { + value = value * 10 + (externalDecimal[i] & 0x0F); + } + if (value < 0) //check 19th digit + { + throw new ArithmeticException( + "Decimal overflow - External Decimal too large for a long"); + } + + //any more digits are overflow + for (int i = offset; i < offsetMod; i++) + { + if ((externalDecimal[i] & 0x0F) > 0) + { + throw new ArithmeticException( + "Decimal overflow - External Decimal too large for a long"); + } + } + } + } + return value; + } + + /** + * Converts an External Decimal in a byte array to a Packed Decimal in another byte array. If the digital part of + * the input External Decimal is not valid then the digital part of the output will not be valid. The sign of the + * input External Decimal is assumed to be positive unless the sign nibble or byte (depending on + * decimalType) contains one of the negative sign codes, in which case the sign of the input External + * Decimal is interpreted as negative. + * + * @param externalDecimal + * byte array holding the External Decimal to be converted + * @param externalOffset + * offset in externalDecimal where the External Decimal is located + * @param packedDecimal + * byte array which will hold the Packed Decimal on a successful return + * @param packedOffset + * offset in packedDecimal where the Packed Decimal is expected to be located + * @param precision + * the number of decimal digits + * @param decimalType + * constant value indicating the type of External Decimal + * + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if packedDecimal or externalDecimal is null + * @throws IllegalArgumentException + * if precision or decimalType is invalid + */ + public static void convertExternalDecimalToPackedDecimal( + byte[] externalDecimal, int externalOffset, byte[] packedDecimal, + int packedOffset, int precision, int decimalType) { + if ((externalOffset + CommonData.getExternalByteCounts(precision, decimalType) > externalDecimal.length) || (externalOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertExternalDecimalToPackedDecimal is trying to access externalDecimal[" + externalOffset + "] to externalDecimal[" + (externalOffset + CommonData.getExternalByteCounts(precision, decimalType) - 1) + "], " + + " but valid indices are from 0 to " + (externalDecimal.length - 1) + "."); + + if ((packedOffset < 0) || (packedOffset + ((precision/ 2) + 1) > packedDecimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertExternalDecimalToPackedDecimal is trying to access packedDecimal[" + packedOffset + "] to packedDecimal[" + (packedOffset + (precision/ 2)) + "], " + + " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); + + convertExternalDecimalToPackedDecimal_(externalDecimal, externalOffset, packedDecimal, + packedOffset, precision, decimalType); + } + + private static void convertExternalDecimalToPackedDecimal_( + byte[] externalDecimal, int externalOffset, byte[] packedDecimal, + int packedOffset, int precision, int decimalType) { + + boolean isNegative = isExternalDecimalSignNegative(externalDecimal, externalOffset, precision, decimalType); + + if (decimalType < EXTERNAL_DECIMAL_MIN + || decimalType > EXTERNAL_DECIMAL_MAX) + throw new IllegalArgumentException("invalid decimalType"); + if (precision <= 0) + throw new IllegalArgumentException("negative precision"); + + int end = packedOffset + precision / 2; + + // deal with sign leading + if (decimalType == EBCDIC_SIGN_SEPARATE_LEADING) { + externalOffset++; + } + + // handle even precision + if (precision % 2 == 0) { + packedDecimal[packedOffset++] = (byte) (externalDecimal[externalOffset++] & CommonData.LOWER_NIBBLE_MASK); + } + + for (int i = packedOffset; i < end; i++) { + byte top = (byte) ((externalDecimal[externalOffset++] & CommonData.LOWER_NIBBLE_MASK) << 4); + byte bottom = (byte) (externalDecimal[externalOffset++] & CommonData.LOWER_NIBBLE_MASK); + packedDecimal[i] = (byte) (top | bottom); + } + + // deal with the last digit + packedDecimal[end] = (byte) ((externalDecimal[externalOffset] & CommonData.LOWER_NIBBLE_MASK) << 4); + + // Compute the sign + if (isNegative) + packedDecimal[end] |= CommonData.PACKED_MINUS; + else + packedDecimal[end] |= CommonData.PACKED_PLUS; + } + + /** + * Convert an External Decimal in a byte array to a BigInteger. The sign of the input External Decimal is assumed to + * to be positive unless the sign nibble or byte (depending on decimalType) contains one of the + * negative sign codes, in which case the sign of the input External Decimal is interpreted as negative. + * + * Overflow can happen if the External Decimal value does not fit into the BigInteger. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param externalDecimal + * byte array that holds the Packed Decimal to be converted + * @param offset + * offset in externalDecimal where the Packed Decimal is located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @param decimalType + * constant value indicating the type of External Decimal + * + * @return BigInteger the resulting BigInteger + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if externalDecimal is null + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + * @throws IllegalArgumentException + * if decimalType or precision is invalid, or the digital part of the input is + * invalid. + */ + public static BigInteger convertExternalDecimalToBigInteger( + byte[] externalDecimal, int offset, int precision, + boolean checkOverflow, int decimalType) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertExternalDecimalToPackedDecimal(externalDecimal, offset, + packedDecimal, 0, precision, decimalType); + + int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); + if (cc != 0) + throw new IllegalArgumentException("The input External Decimal is not valid."); + + return convertPackedDecimalToBigDecimal(packedDecimal, 0, precision, 0, + checkOverflow).toBigInteger(); + } + + /** + * Converts an External Decimal in a byte array to a BigDecimal. The sign of the input External Decimal is assumed + * to be positive unless the sign nibble or byte (depending on decimalType) contains one of the + * negative sign codes, in which case the sign of the input External Decimal is interpreted as negative. + * + * Overflow can happen if the External Decimal value does not fit into the BigDecimal. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param externalDecimal + * byte array holding the External Decimal to be converted + * @param offset + * offset in externalDecimal where the External Decimal is located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param scale + * scale of the BigDecimal + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @param decimalType + * constant value that indicates the type of External Decimal + * + * @return BigDecimal the resulting BigDecimal + * + * @throws NullPointerException + * if externalDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + * @throws IllegalArgumentException + * if checkOverflow is true and the Packed Decimal is in an invalid format, or the digital + * part of the input is invalid. + */ + public static BigDecimal convertExternalDecimalToBigDecimal( + byte[] externalDecimal, int offset, int precision, int scale, + boolean checkOverflow, int decimalType) { + if (precision <= 9) { + return BigDecimal.valueOf( + convertExternalDecimalToInteger(externalDecimal, offset, precision, + checkOverflow, decimalType), scale); + } else if (precision <= 18) { + return BigDecimal.valueOf( + convertExternalDecimalToLong(externalDecimal, offset, precision, + checkOverflow, decimalType), scale); + } + + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertExternalDecimalToPackedDecimal(externalDecimal, offset, + packedDecimal, 0, precision, decimalType); + + int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); + if (cc != 0) + throw new IllegalArgumentException("The input External Decimal is not valid."); + + return convertPackedDecimalToBigDecimal(packedDecimal, 0, precision, + scale, checkOverflow); + } + + private static boolean isExternalDecimalSignNegative(byte[] externalDecimal, int externalOffset, + int precision, int decimalType) + { + byte signByte = 0; + switch (decimalType) + { + case EBCDIC_SIGN_EMBEDDED_LEADING: + signByte = (byte) (externalDecimal[externalOffset] & EXTERNAL_HIGH_MASK); + if (signByte == CommonData.EXTERNAL_EMBEDDED_SIGN_MINUS || + signByte == CommonData.EXTERNAL_EMBEDDED_SIGN_MINUS_ALTERNATE_B) + return true; + break; + + case EBCDIC_SIGN_EMBEDDED_TRAILING: + signByte = (byte)(externalDecimal[externalOffset + precision - 1] & EXTERNAL_HIGH_MASK); + if (signByte == CommonData.EXTERNAL_EMBEDDED_SIGN_MINUS || + signByte == CommonData.EXTERNAL_EMBEDDED_SIGN_MINUS_ALTERNATE_B) + return true; + break; + + case EBCDIC_SIGN_SEPARATE_LEADING: + signByte = externalDecimal[externalOffset]; + if (signByte == CommonData.EXTERNAL_SIGN_MINUS) + return true; + break; + + case EBCDIC_SIGN_SEPARATE_TRAILING: + signByte = externalDecimal[externalOffset + precision]; + if (signByte == CommonData.EXTERNAL_SIGN_MINUS) + return true; + break; + + default: + throw new IllegalArgumentException("Invalid decimal sign type."); + } + + return false; + } + + /** + * Converts a Unicode Decimal value in a char array into a binary integer. The sign of the input Unicode Decimal is + * assumed to be positive unless the sign char contains the negative sign code, in which case the sign of the + * input Unicode Decimal is interpreted as negative. + * + * Overflow can happen if the Unicode Decimal value does not fit into a binary int. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param unicodeDecimal + * char array which contains the Unicode Decimal value + * @param offset + * the offset where the Unicode Decimal value is located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException or IllegalArgumentException may be thrown + * @param unicodeType + * constant value indicating the type of External Decimal + * + * @return int the resulting binary integer + * + * @throws NullPointerException + * if unicodeDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result does not fit into a long (overflow) + * @throws IllegalArgumentException + * if precision or decimalType is invalid, or the digital part of the input is + * invalid. + */ + public static int convertUnicodeDecimalToInteger(char[] unicodeDecimal, + int offset, int precision, boolean checkOverflow, int unicodeType) { + int size = unicodeType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; + if ((offset + size > unicodeDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertUnicodeDecimalToInteger is trying to access unicodeDecimal[" + offset + "] to unicodeDecimal[" + (offset + size - 1) + "], " + + " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); + + if (JITIntrinsicsEnabled()) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertUnicodeDecimalToPackedDecimal_(unicodeDecimal, offset, + packedDecimal, 0, precision, unicodeType); + int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, + precision, true, true); + if (cc != 0) + throw new IllegalArgumentException( + "The input Unicode is not valid"); + + return convertPackedDecimalToInteger_(packedDecimal, 0, precision, + checkOverflow); + } else { + return convertUnicodeDecimalToInteger_(unicodeDecimal, offset, + precision, checkOverflow, unicodeType); + } + } + + private static int convertUnicodeDecimalToInteger_(char[] unicodeDecimal, + int offset, int precision, boolean checkOverflow, int unicodeType) { + // Validate precision + if (precision <= 0) + throw new IllegalArgumentException("invalid precision"); + + // Validate decimalType and determine sign + boolean positive = true; + switch (unicodeType) { + case UNICODE_UNSIGNED: + break; + case UNICODE_SIGN_SEPARATE_LEADING: + positive = unicodeDecimal[offset++] == UNICODE_SIGN_PLUS; + break; + case UNICODE_SIGN_SEPARATE_TRAILING: + positive = unicodeDecimal[offset + precision] == UNICODE_SIGN_PLUS; + break; + default: + throw new IllegalArgumentException("invalid decimalType"); + } + + int end = offset + precision; + long val = 0; + + // Trim leading 0s + for (; offset < end && unicodeDecimal[offset] == UNICODE_ZERO; offset++) { + precision--; + } + + // Preemptive check overflow: 10 digits in Integer.MAX_VALUE + if (checkOverflow && precision > 10) { + throw new ArithmeticException( + "Decimal overflow - Unicode Decimal too large for an int"); + } + + // Working in negatives as Integer.MIN_VALUE has a greater + // distance from 0 than Integer.MAX_VALUE + for ( ; offset < end; ++offset) { + val *= 10; + val -= unicodeDecimal[offset] & CommonData.LOWER_NIBBLE_MASK; + } + + // Normalize result + val = positive ? -val : val; + + // Check overflow + if (checkOverflow && (val > Integer.MAX_VALUE || val < Integer.MIN_VALUE)) { + throw new ArithmeticException( + "Decimal overflow - Unicode Decimal too large for a int"); + } + + return (int) val; + } + + /** + * Converts a Unicode Decimal value in a char array into a binary long. The sign of the input Unicode Decimal is + * assumed to be positive unless the sign char contains the negative sign code, in which case the sign of the + * input Unicode Decimal is interpreted as negative. + * + * Overflow can happen if the Unicode Decimal value does not fit into a binary long. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param unicodeDecimal + * char array which contains the External Decimal value + * @param offset + * offset of the first byte of the Unicode Decimal in unicodeDecimal + * @param precision + * number of Unicode Decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown when + * @param unicodeType + * constant value indicating the type of External Decimal + * + * @return long the resulting binary long value + * + * @throws NullPointerException + * if unicodeDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result does not fit into a long (overflow) + * @throws IllegalArgumentException + * if unicodeType or precision is invalid, or the digital part of the input is + * invalid. + */ + public static long convertUnicodeDecimalToLong(char[] unicodeDecimal, + int offset, int precision, boolean checkOverflow, int unicodeType) { + int size = unicodeType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; + if ((offset + size > unicodeDecimal.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertUnicodeDecimalToLong is trying to access unicodeDecimal[" + offset + "] to unicodeDecimal[" + (offset + size - 1) + "], " + + " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); + + if (JITIntrinsicsEnabled()) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertUnicodeDecimalToPackedDecimal_(unicodeDecimal, offset, + packedDecimal, 0, precision, unicodeType); + + int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); + if (cc != 0) + throw new IllegalArgumentException("The input Unicode is not valid"); + + return convertPackedDecimalToLong_(packedDecimal, 0, precision, + checkOverflow); + } else { + return convertUnicodeDecimalToLong_(unicodeDecimal, offset, precision, checkOverflow, unicodeType); + } + } + + private static long convertUnicodeDecimalToLong_(char[] unicodeDecimal, + int offset, int precision, boolean checkOverflow, int unicodeType) { + // Validate precision + if (precision <= 0) + throw new IllegalArgumentException("invalid precision"); + + // Validate decimalType and determine sign + boolean positive = true; + switch (unicodeType) { + case UNICODE_UNSIGNED: + break; + case UNICODE_SIGN_SEPARATE_LEADING: + positive = unicodeDecimal[offset++] == UNICODE_SIGN_PLUS; + break; + case UNICODE_SIGN_SEPARATE_TRAILING: + positive = unicodeDecimal[offset + precision] == UNICODE_SIGN_PLUS; + break; + default: + throw new IllegalArgumentException("invalid decimalType"); + } + + int end = offset + precision; + long val = 0; + + // Trim leading 0s + for (; offset < end && unicodeDecimal[offset] == UNICODE_ZERO; offset++) { + precision--; + } + + // Preemptive check overflow: 19 digits in Long.MAX_VALUE + if (checkOverflow && precision > 19) { + throw new ArithmeticException( + "Decimal overflow - Unicode Decimal too large for a long"); + } + + // Working in negatives as Long.MIN_VALUE has a greater + // distance from 0 than Long.MAX_VALUE + for ( ; offset < end; ++offset) { + val *= 10; + val -= unicodeDecimal[offset] & CommonData.LOWER_NIBBLE_MASK; + } + + // Normalize result + val = positive ? -val : val; + + // Check overflow + if (checkOverflow) { + if (positive && val < 0) { + throw new ArithmeticException( + "Decimal overflow - Unicode Decimal too large for a long"); + } else if (!positive && val > 0) { + throw new ArithmeticException( + "Decimal overflow - Unicode Decimal too small for a long"); + } + } + + return val; + } + + /** + * Converts an Unicode Decimal in a char array to a Packed Decimal in a byte array. If the digital part of the input + * Unicode Decimal is not valid then the digital part of the output will not be valid. The sign of the input Unicode + * Decimal is assumed to be positive unless the sign byte contains the negative sign code, in which case the sign + * of the input Unicode Decimal is interpreted as negative. + * + * @param unicodeDecimal + * char array that holds the Unicode Decimal to be converted + * @param unicodeOffset + * offset in unicodeDecimal at which the Unicode Decimal is located + * @param packedDecimal + * byte array that will hold the Packed Decimal on a successful return + * @param packedOffset + * offset in packedDecimal where the Packed Decimal is expected to be located + * @param precision + * number of decimal digits + * @param decimalType + * constant value indicating the type of External Decimal + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if packedDecimal or unicodeDecimal are null + * @throws IllegalArgumentException + * if precision or decimalType is invalid + */ + public static void convertUnicodeDecimalToPackedDecimal( + char[] unicodeDecimal, int unicodeOffset, byte[] packedDecimal, + int packedOffset, int precision, int decimalType) { + int size = decimalType == DecimalData.UNICODE_UNSIGNED ? precision : precision + 1; + if ((unicodeOffset + size > unicodeDecimal.length) || (unicodeOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertUnicodeDecimalToPackedDecimal is trying to access unicodeDecimal[" + unicodeOffset + "] to unicodeDecimal[" + (unicodeOffset + size - 1) + "], " + + " but valid indices are from 0 to " + (unicodeDecimal.length - 1) + "."); + if ((packedOffset < 0) || (packedOffset + ((precision/ 2) + 1) > packedDecimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "convertUnicodeDecimalToPackedDecimal is trying to access packedDecimal[" + packedOffset + "] to packedDecimal[" + (packedOffset + (precision/ 2)) + "], " + + " but valid indices are from 0 to " + (packedDecimal.length - 1) + "."); + + convertUnicodeDecimalToPackedDecimal_(unicodeDecimal, unicodeOffset, + packedDecimal, packedOffset, precision, decimalType); + } + + private static void convertUnicodeDecimalToPackedDecimal_( + char[] unicodeDecimal, int unicodeOffset, byte[] packedDecimal, + int packedOffset, int precision, int decimalType) { + + if (precision <= 0) + throw new IllegalArgumentException("invalid precision"); + + int end = packedOffset + precision / 2; + int signOffset = unicodeOffset; + if (decimalType == UNICODE_SIGN_SEPARATE_LEADING) { + unicodeOffset++; + } + // handle even precision + if (precision % 2 == 0) { + packedDecimal[packedOffset++] = (byte) (unicodeDecimal[unicodeOffset++] & CommonData.LOWER_NIBBLE_MASK); + } + + // compute all the intermediate digits + for (int i = packedOffset; i < end; i++) { + byte top = (byte) ((unicodeDecimal[unicodeOffset++] & CommonData.LOWER_NIBBLE_MASK) << 4); + byte bottom = (byte) (unicodeDecimal[unicodeOffset++] & CommonData.LOWER_NIBBLE_MASK); + packedDecimal[i] = (byte) (top | bottom); + } + packedDecimal[end] = (byte) ((unicodeDecimal[unicodeOffset++] & CommonData.LOWER_NIBBLE_MASK) << 4); + + switch (decimalType) + { + case UNICODE_SIGN_SEPARATE_LEADING: + if (unicodeDecimal[signOffset] == '-') + packedDecimal[end] |= CommonData.PACKED_MINUS; + else + packedDecimal[end] |= CommonData.PACKED_PLUS; + break; + + case UNICODE_SIGN_SEPARATE_TRAILING: + if (unicodeDecimal[unicodeOffset] == '-') + packedDecimal[end] |= CommonData.PACKED_MINUS; + else + packedDecimal[end] |= CommonData.PACKED_PLUS; + break; + + case UNICODE_UNSIGNED: + packedDecimal[end] |= CommonData.PACKED_PLUS; + break; + + default: + throw new IllegalArgumentException("invalid decimalType"); + } + } + + /** + * Convert a Unicode Decimal in a char array to a BigInteger. The sign of the input Unicode Decimal is assumed to + * be positive unless the sign byte contains the negative sign code, in which case the sign of the input Unicode + * Decimal is interpreted as negative. + * + * Overflow can happen if the Unicode Decimal value does not fit into a binary long. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param unicodeDecimal + * char array that holds the Packed Decimal to be converted + * @param offset + * offset into unicodeDecimal where the Packed Decimal is located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @param decimalType + * constant value indicating the type of External Decimal + * + * @return BigInteger the resulting BigInteger + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws NullPointerException + * if unicodeDecimal is null + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + * @throws IllegalArgumentException + * if decimalType or precision is invalid, or the digital part of the input is + * invalid. + */ + public static BigInteger convertUnicodeDecimalToBigInteger( + char[] unicodeDecimal, int offset, int precision, + boolean checkOverflow, int decimalType) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertUnicodeDecimalToPackedDecimal(unicodeDecimal, offset, + packedDecimal, 0, precision, decimalType); + + int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); + if (cc != 0) + throw new IllegalArgumentException("The input Unicode is not valid"); + + return convertPackedDecimalToBigDecimal(packedDecimal, 0, precision, 0, + checkOverflow).toBigInteger(); + } + + /** + * Converts a Unicode Decimal in a char array to a BigDecimal. The sign of the input Unicode Decimal is assumed to + * to be positive unless the sign byte contains the negative sign code, in which case the sign of the input Unicode + * Decimal is interpreted as negative. + * + * Overflow can happen if the Unicode Decimal value does not fit into the BigDecimal. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param unicodeDecimal + * char array that holds the Unicode Decimal + * @param offset + * offset in unicodeDecimal where the Unicode Decimal is located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param scale + * scale of the returned BigDecimal + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @param decimalType + * constant value indicating the type of External Decimal + * + * @return BigDecimal + * + * @throws NullPointerException + * if unicodeDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + * @throws IllegalArgumentException + * if checkOverflow is true and the Packed Decimal is in an invalid format, or the digital + * part of the input is invalid. + */ + public static BigDecimal convertUnicodeDecimalToBigDecimal( + char[] unicodeDecimal, int offset, int precision, int scale, + boolean checkOverflow, int decimalType) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertUnicodeDecimalToPackedDecimal(unicodeDecimal, offset, + packedDecimal, 0, precision, decimalType); + + int cc = PackedDecimal.checkPackedDecimal(packedDecimal, 0, precision,true, true); + if (cc != 0) + throw new IllegalArgumentException("The input Unicode is not valid"); + + return convertPackedDecimalToBigDecimal(packedDecimal, 0, precision, + scale, checkOverflow); + } + + /** + * Converts a BigInteger value into a Packed Decimal in a byte array + * + * Overflow can happen if the BigInteger does not fit into the byte array. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param bigIntegerValue + * BigInteger value to be converted + * @param packedDecimal + * byte array which will hold the Packed Decimal on a successful return + * @param offset + * offset into packedDecimal where the Packed Decimal is expected to be located + * @param precision + * number of decimal digits. Maximum valid precision is 253s + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * + * @throws NullPointerException + * if packedDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + */ + public static void convertBigIntegerToPackedDecimal( + BigInteger bigIntegerValue, byte[] packedDecimal, int offset, + int precision, boolean checkOverflow) { + convertBigDecimalToPackedDecimal(new BigDecimal(bigIntegerValue), + packedDecimal, offset, precision, checkOverflow); + } + + /** + * Converts a BigInteger value into an External Decimal in a byte array + * + * Overflow can happen if the BigInteger does not fit into the byte array. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param bigIntegerValue + * BigInteger value to be converted + * @param externalDecimal + * byte array which will hold the External Decimal on a successful return + * @param offset + * offset into externalDecimal where the External Decimal is expected to be located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @param decimalType + * constant value that indicates the type of External Decimal + * + * @throws NullPointerException + * if externalDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + * @throws IllegalArgumentException + * if decimalType or precision is invalid + */ + public static void convertBigIntegerToExternalDecimal( + BigInteger bigIntegerValue, byte[] externalDecimal, int offset, + int precision, boolean checkOverflow, int decimalType) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertBigDecimalToPackedDecimal(new BigDecimal(bigIntegerValue), + packedDecimal, 0, precision, checkOverflow); + convertPackedDecimalToExternalDecimal(packedDecimal, 0, + externalDecimal, offset, precision, decimalType); + } + + /** + * Converts a BigInteger value to a Unicode Decimal in a char array + * + * Overflow can happen if the BigInteger does not fit into the char array. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param bigIntegerValue + * BigInteger value to be converted + * @param unicodeDecimal + * char array that will hold the Unicode decimal on a successful return + * @param offset + * offset into unicodeDecimal where the Unicode Decimal is expected to be located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @param decimalType + * constant indicating the type of External Decimal + * + * @throws NullPointerException + * if unicodeDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + * @throws IllegalArgumentException + * if decimalType or precision is invalid + */ + public static void convertBigIntegerToUnicodeDecimal( + BigInteger bigIntegerValue, char[] unicodeDecimal, int offset, + int precision, boolean checkOverflow, int decimalType) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertBigDecimalToPackedDecimal(new BigDecimal(bigIntegerValue), + packedDecimal, 0, precision, checkOverflow); + convertPackedDecimalToUnicodeDecimal(packedDecimal, 0, unicodeDecimal, + offset, precision, decimalType); + } + + /** + * Converts a BigDecimal into a Packed Decimal in a byte array + * + * Overflow can happen if the BigDecimal does not fit into the result byte array. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param bigDecimalValue + * the BigDecimal value to be converted + * @param packedDecimal + * byte array which will hold the Packed Decimal on a successful return + * @param offset + * desired offset in packedDecimal where the Packed Decimal is expected to be located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * + * @throws NullPointerException + * if packedDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + */ + public static void convertBigDecimalToPackedDecimal( + BigDecimal bigDecimalValue, byte[] packedDecimal, int offset, + int precision, boolean checkOverflow) { + + int bdprec = bigDecimalValue.precision(); + if (bdprec <=9) + { + convertIntegerToPackedDecimal((int) bigDecimalValue.unscaledValue().longValue(), + packedDecimal, offset, precision, checkOverflow); + return; + } + if (bdprec <= 18) + { + convertLongToPackedDecimal(bigDecimalValue.unscaledValue().longValue(), + packedDecimal, offset, precision, checkOverflow); + return; + } + + slowBigDecimalToSignedPacked(bigDecimalValue, packedDecimal, offset, + precision, checkOverflow); + } + + /** + * Converts a BigDecimal value to an External Decimal in a byte array + * + * Overflow can happen if the BigDecimal does not fit into the result byte array. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param bigDecimalValue + * BigDecimal value to be converted + * @param externalDecimal + * byte array that will hold the External Decimal on a successful return + * @param offset + * offset in externalDecimal where the External Decimal is expected to be located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @param decimalType + * constant value indicating the External Decimal type + * + * @throws NullPointerException + * if externalDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + * @throws IllegalArgumentException + * if precision or decimalType is invalid + */ + public static void convertBigDecimalToExternalDecimal( + BigDecimal bigDecimalValue, byte[] externalDecimal, int offset, + int precision, boolean checkOverflow, int decimalType) { + + int bdprec = bigDecimalValue.precision(); + if (bdprec <=9) + { + convertIntegerToExternalDecimal((int) bigDecimalValue.unscaledValue().longValue(), + externalDecimal, offset, precision, checkOverflow, decimalType); + return; + } + if (bdprec <= 18) + { + convertLongToExternalDecimal(bigDecimalValue.unscaledValue().longValue(), + externalDecimal, offset, precision, checkOverflow, decimalType); + return; + } + + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertBigDecimalToPackedDecimal(bigDecimalValue, packedDecimal, 0, + precision, checkOverflow); + convertPackedDecimalToExternalDecimal(packedDecimal, 0, + externalDecimal, offset, precision, decimalType); + } + + /** + * Converts a BigDecimal value to a Unicode Decimal in a char array + * + * Overflow can happen if the BigDecimal does not fit into the result char array. In this case, when + * checkOverflow is true an ArithmeticException is thrown, when false a truncated or + * invalid result is returned. + * + * @param bigDecimalValue + * BigDecimal value to be converted + * @param unicodeDecimal + * char array which will hold the Unicode Decimal on a successful return + * @param offset + * offset in unicodeDecimal where the Unicode Decimal is expected to be located + * @param precision + * number of decimal digits. Maximum valid precision is 253 + * @param checkOverflow + * if true an ArithmeticException will be thrown if the decimal value does not fit in the + * specified precision (overflow) + * @param decimalType + * constant value that indicates the type of External Decimal + * + * @throws NullPointerException + * if unicodeDecimal is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if checkOverflow is true and the result overflows + * @throws IllegalArgumentException + * if decimalType or precision is invalid + */ + public static void convertBigDecimalToUnicodeDecimal( + BigDecimal bigDecimalValue, char[] unicodeDecimal, int offset, + int precision, boolean checkOverflow, int decimalType) { + byte[] packedDecimal = new byte[precision / 2 + 1]; + convertBigDecimalToPackedDecimal(bigDecimalValue, packedDecimal, 0, + precision, checkOverflow); + convertPackedDecimalToUnicodeDecimal(packedDecimal, 0, unicodeDecimal, + offset, precision, decimalType); + } + + // below is code taken from BigDecimalConverters + // these are special functions recognized by the jit + private static boolean DFPFacilityAvailable() { + return false; + } + + private static boolean DFPUseDFP() { + return false; + } + + private static BigDecimal createZeroBigDecimal() { + return new BigDecimal(0); // don't use BigDecimal.ZERO, need a new + // object every time + } + + private static boolean DFPConvertPackedToDFP(BigDecimal bd, long pack, + int scale, boolean signed) { + return false; + } + + private static long DFPConvertDFPToPacked(long dfpValue, boolean signed) { + return Long.MAX_VALUE; + } + + private final static int getflags() { + return 0x3; + } + + private final static long getlaside(BigDecimal bd) { + return Long.MIN_VALUE; + } + + private static BigDecimal slowSignedPackedToBigDecimal(byte[] byteArray, + int offset, int precision, int scale, boolean exceptions) { + + int length = (precision + 2) / 2; + + int sn = byteArray[offset + length - 1] & CommonData.LOWER_NIBBLE_MASK; + + char[] temp = new char[length * 2]; + temp[0] = (sn == 0x0D || sn == 0x0B) ? '-' : '0'; + for (int i = 0; i < length - 1; i++) { + temp[2 * i + 1] = (char) ('0' + (byteArray[i + offset] >>> 4 & CommonData.LOWER_NIBBLE_MASK)); + temp[2 * i + 2] = (char) ('0' + (byteArray[i + offset] & CommonData.LOWER_NIBBLE_MASK)); + } + temp[length * 2 - 1] = (char) ('0' + (byteArray[offset + length - 1] >>> 4 & CommonData.LOWER_NIBBLE_MASK)); + + return new BigDecimal(new BigInteger(new String(temp)), scale); + } + + private static void slowBigDecimalToSignedPacked(BigDecimal bd, + byte[] byteArray, int offset, int precision, boolean checkOverflow) { + + // digits are right justified in the return byte array + if (checkOverflow && precision < bd.precision()) + throw new ArithmeticException( + "Decimal overflow - precision of result Packed Decimal lesser than BigDecimal precision"); + + BigInteger value = bd.unscaledValue(); + char[] buffer = value.abs().toString().toCharArray(); + int numDigitsLeft = buffer.length - 1; + int endPosition = numDigitsLeft % 2; + int length = (precision + 2) / 2; + int index = length - 2; + + // take care of the sign nibble and the right most digit + byteArray[offset + length - 1] = (byte) ((buffer[numDigitsLeft] - '0') << 4); + byteArray[offset + length - 1] |= (byte) ((value.signum() == -1) ? 0x0D : 0x0C); + + // compact 2 digits into each byte + for (int i = numDigitsLeft - 1; i >= endPosition + && (offset + index >= 0); i -= 2, --index) { + byteArray[offset + index] = (byte) (buffer[i] - '0'); + byteArray[offset + index] |= (byte) ((buffer[i - 1] - '0') << 4); + } + + // if there's a left over digit, put it in the last byte + if (endPosition > 0 && (offset + index >= 0)) { + byteArray[offset + index] = (byte) (buffer[0] - '0'); + } + } + + /* + * Converts the Packed Decimal to equivalent long (in hex). + */ + private static long convertPackedToLong(byte[] byteArray, int offset, + int length) { + if (length == 8) { + return ByteArrayUnmarshaller.readLong(byteArray, offset, true); + } else if (length == 4) { + // We need to zero extend the int to long. + return ((long) ByteArrayUnmarshaller.readInt(byteArray, offset, + true)) & 0xFFFFFFFFl; + } + + else { + // slow way to load value into dfp + long value = 0; + for (int i = 0; i < length; ++i) { + value = value << 8; + value += ((long) (byteArray[offset + i] & 0xFF)); + } + return value; + } + } + + private static void convertLongToPacked(long value, byte[] byteArray, + int offset, int length) { + if (length == 8) { + ByteArrayMarshaller.writeLong(value, byteArray, offset, true); + } else if (length == 4) { + ByteArrayMarshaller.writeInt((int) value, byteArray, offset, true); + } else { + for (int i = length - 1; i <= 0; i--) { + byteArray[offset + i] = (byte) ((value) & 0xFF); + value = value >> 8; + } + } + } } diff --git a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ExternalDecimal.java b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ExternalDecimal.java index 295e983b941..f818a897432 100644 --- a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ExternalDecimal.java +++ b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ExternalDecimal.java @@ -23,150 +23,149 @@ package com.ibm.dataaccess; public class ExternalDecimal { - /** - * Private constructor, class contains only static methods. - */ - private ExternalDecimal() { - super(); - } + /** + * Private constructor, class contains only static methods. + */ + private ExternalDecimal() { + super(); + } + private static byte EXTERNAL_DECIMAL_SPACE_SYMBOL = (byte)0x40; + private static int EXTERNAL_DECIMAL_INVALID_DIGIT = 2; + private static int EXTERNAL_DECIMAL_INVALID_SIGN = 1; - private static byte EXTERNAL_DECIMAL_SPACE_SYMBOL = (byte)0x40; - private static int EXTERNAL_DECIMAL_INVALID_DIGIT = 2; - private static int EXTERNAL_DECIMAL_INVALID_SIGN = 1; + /** + * Checks the validity of a External Decimal, returns an integer indicating the status of the External Decimal. + * + * @param byteArray + * source array. + * @param offset + * starting offset of the External Decimal. + * @param precision + * number of digits to be verified. + * @param decimalType + * constant indicating the type of the decimal. Supported values are + * DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING, DecimalData.EBCDIC_SIGN_EMBEDDED_LEADING, + * DecimalData.EBCDIC_SIGN_SEPARATE_TRAILING, DecimalData.EBCDIC_SIGN_SEPARATE_LEADING. + * @param bytesWithSpaces + * represents number of left most bytes containing EBCDIC space character if sign is + * embedded, ignored otherwise. + * + * @return the condition code: + * 0 if all digit codes and the sign are valid, + * 1 if the sign is invalid, + * 2 if at least one digit code is invalid, + * 3 if sign and at least one digit code is invalid. + * + * @throws NullPointerException + * if byteArray is null. + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs. + * @throws IllegalArgumentException + * if the precision is less than 1. + * @throws IllegalArgumentException + * if the offset is less than 0. + * @throws IllegalArgumentException + * if decimalType is invalid. + * @throws IllegalArgumentException + * if bytesWithSpaces is less than 0 when sign is embedded. + */ + public static int checkExternalDecimal(byte[] byteArray, int offset, + int precision, int decimalType, int bytesWithSpaces) { + if (precision < 1) + throw new IllegalArgumentException("Precision must be greater than 0."); - /** - * Checks the validity of a External Decimal, returns an integer indicating the status of the External Decimal. - * - * @param byteArray - * source array. - * @param offset - * starting offset of the External Decimal. - * @param precision - * number of digits to be verified. - * @param decimalType - * constant indicating the type of the decimal. Supported values are - * DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING, DecimalData.EBCDIC_SIGN_EMBEDDED_LEADING, - * DecimalData.EBCDIC_SIGN_SEPARATE_TRAILING, DecimalData.EBCDIC_SIGN_SEPARATE_LEADING. - * @param bytesWithSpaces - * represents number of left most bytes containing EBCDIC space character if sign is - * embedded, ignored otherwise. - * - * @return the condition code: - * 0 if all digit codes and the sign are valid, - * 1 if the sign is invalid, - * 2 if at least one digit code is invalid, - * 3 if sign and at least one digit code is invalid. - * - * @throws NullPointerException - * if byteArray is null. - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs. - * @throws IllegalArgumentException - * if the precision is less than 1. - * @throws IllegalArgumentException - * if the offset is less than 0. - * @throws IllegalArgumentException - * if decimalType is invalid. - * @throws IllegalArgumentException - * if bytesWithSpaces is less than 0 when sign is embedded. - */ - public static int checkExternalDecimal(byte[] byteArray, int offset, - int precision, int decimalType, int bytesWithSpaces) { - if (precision < 1) - throw new IllegalArgumentException("Precision must be greater than 0."); + if (offset < 0) + throw new IllegalArgumentException("Offset must be non-negative integer."); - if (offset < 0) - throw new IllegalArgumentException("Offset must be non-negative integer."); + if (decimalType < DecimalData.EXTERNAL_DECIMAL_MIN || decimalType > DecimalData.EXTERNAL_DECIMAL_MAX) + throw new IllegalArgumentException("Invalid decimalType."); - if (decimalType < DecimalData.EXTERNAL_DECIMAL_MIN || decimalType > DecimalData.EXTERNAL_DECIMAL_MAX) - throw new IllegalArgumentException("Invalid decimalType."); + final int lengthNeeded = offset + CommonData.getExternalByteCounts(precision, decimalType); + if (lengthNeeded > byteArray.length) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "checkExternalDecimal is trying to access byteArray[" + offset + "] to byteArray[" + (lengthNeeded - 1) + "]" + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - final int lengthNeeded = offset + CommonData.getExternalByteCounts(precision, decimalType); - if (lengthNeeded > byteArray.length) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "checkExternalDecimal is trying to access byteArray[" + offset + "] to byteArray[" + (lengthNeeded - 1) + "]" + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + return checkExternalDecimal_(byteArray, offset, precision, decimalType, bytesWithSpaces); + } - return checkExternalDecimal_(byteArray, offset, precision, decimalType, bytesWithSpaces); - } + private static int checkExternalDecimal_(byte[] byteArray, int offset, + int precision, int decimalType, int bytesWithSpaces) { - private static int checkExternalDecimal_(byte[] byteArray, int offset, - int precision, int decimalType, int bytesWithSpaces) { + // Digit is invalid if: + // - number of non space digits is equal to 0 (precision == bytesWithSpaces) + // - number of non space digits is greater than precision (bytesWithSpaces < 0) + if (decimalType == DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING + && (precision == bytesWithSpaces || bytesWithSpaces < 0)) { + return 3; + } - // Digit is invalid if: - // - number of non space digits is equal to 0 (precision == bytesWithSpaces) - // - number of non space digits is greater than precision (bytesWithSpaces < 0) - if (decimalType == DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING - && (precision == bytesWithSpaces || bytesWithSpaces < 0)) { - return 3; - } + int startIndex = offset; // start of sign-digit/zone-digit bytes + int endIndex = startIndex + CommonData.getExternalByteCounts(precision, decimalType) - 1; + boolean isSignEmbedded = false; + byte signByte; + switch (decimalType) { + case DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING: + isSignEmbedded = true; + signByte = byteArray[endIndex]; + --endIndex; + startIndex += bytesWithSpaces; + break; + case DecimalData.EBCDIC_SIGN_SEPARATE_TRAILING: + signByte = byteArray[endIndex]; + --endIndex; + break; + case DecimalData.EBCDIC_SIGN_EMBEDDED_LEADING: + isSignEmbedded = true; + signByte = byteArray[startIndex]; + ++startIndex; + break; + case DecimalData.EBCDIC_SIGN_SEPARATE_LEADING: + signByte = byteArray[startIndex]; + ++startIndex; + break; + default: + signByte = (byte)0x9F; // random invalid sign byte + break; + } - int startIndex = offset; // start of sign-digit/zone-digit bytes - int endIndex = startIndex + CommonData.getExternalByteCounts(precision, decimalType) - 1; - boolean isSignEmbedded = false; - byte signByte; - switch (decimalType) { - case DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING: - isSignEmbedded = true; - signByte = byteArray[endIndex]; - --endIndex; - startIndex += bytesWithSpaces; - break; - case DecimalData.EBCDIC_SIGN_SEPARATE_TRAILING: - signByte = byteArray[endIndex]; - --endIndex; - break; - case DecimalData.EBCDIC_SIGN_EMBEDDED_LEADING: - isSignEmbedded = true; - signByte = byteArray[startIndex]; - ++startIndex; - break; - case DecimalData.EBCDIC_SIGN_SEPARATE_LEADING: - signByte = byteArray[startIndex]; - ++startIndex; - break; - default: - signByte = (byte)0x9F; // random invalid sign byte - break; - } + int returnCode = 0; + if (decimalType == DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING && bytesWithSpaces > 0) { + // Validate bytes before digits + for (int index = offset; index < startIndex; ++index) { + // Only EXTERNAL_DECIMAL_SPACE_SYMBOL and F[0-9] are considered valid + if (byteArray[index] != EXTERNAL_DECIMAL_SPACE_SYMBOL + && (((byteArray[index] & (byte)CommonData.HIGHER_NIBBLE_MASK) & 0xF0) != 0xF0 // zone nibble + || (byteArray[index] & (byte)CommonData.LOWER_NIBBLE_MASK) > 0x09)) { // digit nibble + returnCode = EXTERNAL_DECIMAL_INVALID_DIGIT; + } + } + } - int returnCode = 0; - if (decimalType == DecimalData.EBCDIC_SIGN_EMBEDDED_TRAILING && bytesWithSpaces > 0) { - // Validate bytes before digits - for (int index = offset; index < startIndex; ++index) { - // Only EXTERNAL_DECIMAL_SPACE_SYMBOL and F[0-9] are considered valid - if (byteArray[index] != EXTERNAL_DECIMAL_SPACE_SYMBOL - && (((byteArray[index] & (byte)CommonData.HIGHER_NIBBLE_MASK) & 0xF0) != 0xF0 // zone nibble - || (byteArray[index] & (byte)CommonData.LOWER_NIBBLE_MASK) > 0x09)) { // digit nibble - returnCode = EXTERNAL_DECIMAL_INVALID_DIGIT; - } - } - } + // Validate digits + for (int index = startIndex; index <= endIndex && returnCode < EXTERNAL_DECIMAL_INVALID_DIGIT; ++index) { + // Only valid digits are F[0-9] + if (byteArray[index] == EXTERNAL_DECIMAL_SPACE_SYMBOL + || ((byteArray[index] & (byte)CommonData.HIGHER_NIBBLE_MASK) & 0xF0) != 0xF0 // zone nibble + || (byteArray[index] & (byte)CommonData.LOWER_NIBBLE_MASK) > 0x09) { // digit nibble + returnCode = EXTERNAL_DECIMAL_INVALID_DIGIT; + } + } - // Validate digits - for (int index = startIndex; index <= endIndex && returnCode < EXTERNAL_DECIMAL_INVALID_DIGIT; ++index) { - // Only valid digits are F[0-9] - if (byteArray[index] == EXTERNAL_DECIMAL_SPACE_SYMBOL - || ((byteArray[index] & (byte)CommonData.HIGHER_NIBBLE_MASK) & 0xF0) != 0xF0 // zone nibble - || (byteArray[index] & (byte)CommonData.LOWER_NIBBLE_MASK) > 0x09) { // digit nibble - returnCode = EXTERNAL_DECIMAL_INVALID_DIGIT; - } - } + // Validate sign byte + if (isSignEmbedded) { + // Check digit nibble embedded in sign byte + if ((signByte & (byte)CommonData.LOWER_NIBBLE_MASK) > 0x09) returnCode = EXTERNAL_DECIMAL_INVALID_DIGIT; - // Validate sign byte - if (isSignEmbedded) { - // Check digit nibble embedded in sign byte - if ((signByte & (byte)CommonData.LOWER_NIBBLE_MASK) > 0x09) returnCode = EXTERNAL_DECIMAL_INVALID_DIGIT; - - // Check sign nibble for preferred and alternate representations - if (((signByte & (byte)CommonData.HIGHER_NIBBLE_MASK) & 0xF0) < 0xA0) returnCode |= EXTERNAL_DECIMAL_INVALID_SIGN; - } - else if (!isSignEmbedded - && signByte != CommonData.EXTERNAL_SIGN_MINUS - && signByte != CommonData.EXTERNAL_SIGN_PLUS) { - returnCode |= EXTERNAL_DECIMAL_INVALID_SIGN; - } - return returnCode; - } + // Check sign nibble for preferred and alternate representations + if (((signByte & (byte)CommonData.HIGHER_NIBBLE_MASK) & 0xF0) < 0xA0) returnCode |= EXTERNAL_DECIMAL_INVALID_SIGN; + } + else if (!isSignEmbedded + && signByte != CommonData.EXTERNAL_SIGN_MINUS + && signByte != CommonData.EXTERNAL_SIGN_PLUS) { + returnCode |= EXTERNAL_DECIMAL_INVALID_SIGN; + } + return returnCode; + } } diff --git a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/PackedDecimal.java b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/PackedDecimal.java index d491bc001e3..c27dc8c7a9f 100644 --- a/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/PackedDecimal.java +++ b/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/PackedDecimal.java @@ -29,2050 +29,2046 @@ /** * Arithmetic, copying and shifting operations for Packed Decimal data. - * + * * @author IBM - * @version $Revision$ on $Date$ + * @version $Revision$ on $Date$ */ public final class PackedDecimal { - /** - * Private constructor, class contains only static methods. - */ - private PackedDecimal() { - super(); - } - - private static final ThreadLocal op1_threadLocal = new ThreadLocal() { - protected PackedDecimalOperand initialValue() - { - return new PackedDecimalOperand(); - } - }; - private static final ThreadLocal op2_threadLocal = new ThreadLocal() { - protected PackedDecimalOperand initialValue() - { - return new PackedDecimalOperand(); - } - }; - private static final ThreadLocal sum_threadLocal = new ThreadLocal() { - protected PackedDecimalOperand initialValue() - { - return new PackedDecimalOperand(); - } - }; - - /** - * Checks the validity of a Packed Decimal, return code indicating the status of the Packed Decimal. - * - * @param byteArray - * the source container array - * @param offset - * starting offset of the Packed Decimal - * @param precision - * precision of the Packed Decimal. Maximum valid precision is 253 - * @param ignoreHighNibbleForEvenPrecision - * if true, ignore to check if the top nibble (first 4 bits) of the input is an invalid sign value in the - * case of even precision - * @param canOverwriteHighNibbleForEvenPrecision - * if true, change the high nibble to a zero in case of even precision - * @return the condition code: 0 All digit codes and the sign valid 1 Sign invalid 2 At least one digit code invalid - * 3 Sign invalid and at least one digit code invalid - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static int checkPackedDecimal(byte[] byteArray, int offset, - int precision, boolean ignoreHighNibbleForEvenPrecision, - boolean canOverwriteHighNibbleForEvenPrecision) { - if ((offset + ((precision / 2) + 1) > byteArray.length) || (offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "checkPackedDecimal is trying to access byteArray[" + offset + "] to byteArray[" + (offset + (precision / 2)) + "]" + - " but valid indices are from 0 to " + (byteArray.length - 1) + "."); - - return checkPackedDecimal_(byteArray, offset, precision, - ignoreHighNibbleForEvenPrecision, canOverwriteHighNibbleForEvenPrecision); - } - - private static int checkPackedDecimal_(byte[] byteArray, int offset, - int precision, boolean ignoreHighNibbleForEvenPrecision, - boolean canOverwriteHighNibbleForEvenPrecision) { - - if (precision < 1) - throw new IllegalArgumentException("Illegal Precision."); - - boolean evenPrecision = precision % 2 == 0 ? true : false; - int signOffset = offset + CommonData.getPackedByteCount(precision) - 1; - - int returnCode = 0; - - if (canOverwriteHighNibbleForEvenPrecision && evenPrecision) { - byteArray[offset] = (byte) (byteArray[offset] & CommonData.LOWER_NIBBLE_MASK); - } - - if (evenPrecision && ignoreHighNibbleForEvenPrecision) - { - if ((byteArray[offset] & CommonData.LOWER_NIBBLE_MASK) > 0x09) - returnCode = 2; - offset++; - } - - - // ordinary checking places here: - int i; - for (i = offset; i < signOffset && byteArray[i] == CommonData.PACKED_ZERO; i++) - ; - - for (; i < signOffset; i++) - { - if ((byteArray[i] & CommonData.LOWER_NIBBLE_MASK) > 0x09 || - (byteArray[i] & CommonData.HIGHER_NIBBLE_MASK & 0xFF) > 0x90) - { - returnCode = 2; - break; - } - } - - if (i == signOffset && (byteArray[signOffset] & CommonData.HIGHER_NIBBLE_MASK & 0xFF) > 0x90) - returnCode = 2; - - // Check sign nibble - if ((byteArray[signOffset] & CommonData.LOWER_NIBBLE_MASK) < 0x0A) - { - returnCode++; - } - return returnCode; - } - - // Assuming canOverwriteMostSignificantEvenNibble == false - /** - * Checks the validity of a Packed Decimal, return code indicating the status of the Packed Decimal. The most - * significant nibble cannot be overwritten. - * - * @param byteArray - * the source container array - * @param offset - * starting offset of the Packed Decimal - * @param precision - * precision of the Packed Decimal - * @param ignoreHighNibbleForEvenPrecision - * if true, ignore the high nibble in the case of even precision - * @return the condition code: 0 All digit codes and the sign valid 1 Sign invalid 2 At least one digit code invalid - * 3 Sign invalid and at least one digit code invalid - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static int checkPackedDecimal(byte[] byteArray, int offset, - int precision, boolean ignoreHighNibbleForEvenPrecision) { - return checkPackedDecimal(byteArray, offset, precision, - ignoreHighNibbleForEvenPrecision, false); - } - - // Assuming canOverwriteMostSignificantEvenNibble == false - /** - * Checks the validity of a Packed Decimal, return code indicating the status of the Packed Decimal. Don't ignore - * the most significant nibble. The most significant nibble cannot be overwritten. - * - * @param byteArray - * the source container array - * @param offset - * starting offset of the Packed Decimal - * @param precision - * precision of the Packed Decimal - * @return the condition code: 0 All digit codes and the sign valid 1 Sign invalid 2 At least one digit code invalid - * 3 Sign invalid and at least one digit code invalid - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static int checkPackedDecimal(byte[] byteArray, int offset, - int precision) { - return checkPackedDecimal(byteArray, offset, precision, false, false); - } - - private static void copyRemainingDigits(PackedDecimalOperand op1, - PackedDecimalOperand op2, boolean checkOverflow) - throws ArithmeticException { - PackedDecimalOperand sum = sum_threadLocal.get(); - - int bytes; - // copy any high order digits left in larger value to result - if (op1.currentOffset >= op1.offset) { - - bytes = op1.currentOffset - op1.offset + 1; - int sumBytes = sum.currentOffset - sum.offset + 1; - if (bytes >= sumBytes) { - if (checkOverflow && bytes > sumBytes) - throw new ArithmeticException( - "Decimal overflow during addition/subtraction."); - else - bytes = sum.currentOffset - sum.offset + 1; - sum.currentOffset = sum.currentOffset - bytes + 1; - op1.currentOffset += -bytes + 1; - System.arraycopy(op1.byteArray, op1.currentOffset, - sum.byteArray, sum.currentOffset, bytes); - if (sum.precision % 2 == 0) { - byte highNibble = (byte) (sum.byteArray[sum.currentOffset] & CommonData.HIGHER_NIBBLE_MASK); - if (checkOverflow && bytes == sumBytes - && highNibble != 0x00) - throw new ArithmeticException( - "Decimal overflow during addition/subtraction."); - else - sum.byteArray[sum.currentOffset] &= CommonData.LOWER_NIBBLE_MASK; - } - } else { - sum.currentOffset = sum.currentOffset - bytes + 1; - System.arraycopy(op1.byteArray, op1.offset, sum.byteArray, - sum.currentOffset, bytes); - } - sum.currentOffset--; - - } - // pad high order result bytes with zeros - if (sum.currentOffset >= sum.offset) { - bytes = sum.currentOffset - sum.offset + 1; - Arrays.fill(sum.byteArray, sum.offset, sum.offset + bytes, CommonData.PACKED_ZERO); - } - } - - /** - * Add two Packed Decimals in byte arrays. The sign of an input Packed Decimal is assumed to be positive unless - * the sign nibble contains one of the negative sign codes, in which case the sign of the respective input Packed - * Decimal is interpreted as negative. - * - * @param result - * byte array that will hold the sum of the two operand Packed Decimals - * @param resultOffset - * offset into result where the sum Packed Decimal begins - * @param resultPrecision - * number of Packed Decimal digits for the sum. Maximum valid precision is 253 - * @param op1Decimal - * byte array that holds the first operand Packed Decimal. - * @param op1Offset - * offset into op1Decimal where the Packed Decimal. is located - * @param op1Precision - * number of Packed Decimal digits for the first operand. Maximum valid precision is 253 - * @param op2Decimal - * byte array that holds the second operand Packed Decimal - * @param op2Offset - * offset into op2Decimal where the Packed Decimal is located - * @param op2Precision - * number of Packed Decimal digits for the second operand. Maximum valid precision is 253 - * @param checkOverflow - * check for overflow - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if an overflow occurs during the computation of the sum - */ - public static void addPackedDecimal(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision, boolean checkOverflow) throws ArithmeticException { - if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "addPackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + - " but valid indices are from 0 to " + (result.length - 1) + "."); - - if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "addPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "addPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - addPackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, - op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); - } - - private static void addPackedDecimal_(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision, boolean checkOverflow) throws ArithmeticException { - // capture result type information - sum_threadLocal.get().setSumOperand(result, resultOffset, - resultPrecision); - // ignore leading zeros in operand values - op1_threadLocal.get().setOperand(op1Decimal, op1Offset, op1Precision); - op2_threadLocal.get().setOperand(op2Decimal, op2Offset, op2Precision); - // add values - computeValue(checkOverflow); - } - - /** - * Subtracts two Packed Decimals in byte arrays. The sign of an input Packed Decimal is assumed to be positive - * unless the sign nibble contains one of the negative sign codes, in which case the sign of the respective input - * Packed Decimal is interpreted as negative. - * - * @param result - * byte array that will hold the difference of the two operand Packed Decimals - * @param resultOffset - * offset into result where the result Packed Decimal is located - * @param resultPrecision - * number of Packed Decimal digits for the result. Maximum valid precision is 253 - * @param op1Decimal - * byte array that holds the first Packed Decimal operand - * @param op1Offset - * offset into op1Decimal where the first operand is located - * @param op1Precision - * number of Packed Decimal digits for the first operand. Maximum valid precision is 253 - * @param op2Decimal - * byte array that holds the second Packed Decimal operand - * @param op2Offset - * offset into op2Decimal where the second operand is located - * @param op2Precision - * number of Packed Decimal digits for the second operand. Maximum valid precision is 253 - * @param checkOverflow - * check for overflow - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if an overflow occurs during the computation of the difference - */ - public static void subtractPackedDecimal(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision, boolean checkOverflow) throws ArithmeticException { - if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "subtractPackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + - " but valid indices are from 0 to " + (result.length - 1) + "."); - - if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "subtractPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "subtractPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - subtractPackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, - op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); - } - - private static void subtractPackedDecimal_(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision, boolean checkOverflow) throws ArithmeticException { - - PackedDecimalOperand sum = sum_threadLocal.get(); - PackedDecimalOperand op1 = op1_threadLocal.get(); - PackedDecimalOperand op2 = op2_threadLocal.get(); - - // capture result type information - sum.setSumOperand(result, resultOffset, resultPrecision); - // ignore leading zeros in operand values - op1.setOperand(op1Decimal, op1Offset, op1Precision); - op2.setOperand(op2Decimal, op2Offset, op2Precision); - // change op2 sign for subtraction - if ((op2.sign & CommonData.LOWER_NIBBLE_MASK) == CommonData.PACKED_PLUS) - op2.sign = (op2.sign & CommonData.HIGHER_NIBBLE_MASK) - | CommonData.PACKED_MINUS; - else - op2.sign = (op2.sign & CommonData.HIGHER_NIBBLE_MASK) - | CommonData.PACKED_PLUS; - // add values - computeValue(checkOverflow); - } - - /** - * Create a positive Packed Decimal representation of zero. - * - * @param byteArray - * byte array which will hold the packed zero - * @param offset - * offset into toBytes where the packed zero begins - * @param len - * length of the packed zero. Maximum valid length is 253 - * - * @throws NullPointerException - * if toBytes is null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static void setPackedZero(byte[] byteArray, int offset, int len) { - int byteLen = CommonData.getPackedByteCount(len); - Arrays.fill(byteArray, offset, offset + byteLen - 1, CommonData.PACKED_ZERO); - byteArray[offset + byteLen - 1] = CommonData.PACKED_PLUS; - } - - private static void computeSum(PackedDecimalOperand op1, - PackedDecimalOperand op2, boolean checkOverflow) - throws ArithmeticException { - - PackedDecimalOperand sum = sum_threadLocal.get(); - - boolean carry;// add op2 sign digit to op1 sign digit - sum.indexValue = ((op1.signDigit + op2.signDigit) << 1) & 0x3FF; - sum.byteValue = CommonData.getPackedSumValues(sum.indexValue); - carry = sum.byteValue < op1.signDigit; - sum.byteArray[sum.signOffset] = (byte) (sum.byteValue | (op1.sign & CommonData.LOWER_NIBBLE_MASK)); - - // add op2 digits to op1 digits - for (; op2.currentOffset >= op2.offset - && sum.currentOffset >= sum.offset; op2.currentOffset -= 1, op1.currentOffset -= 1, sum.currentOffset -= 1) { - if (checkOverflow && sum.currentOffset < sum.offset) { - throw new ArithmeticException( - "Decimal overflow in addPackedDecimal."); - } - ; - op1.byteValue = op1.byteArray[op1.currentOffset] - & CommonData.INTEGER_MASK; - op2.byteValue = op2.byteArray[op2.currentOffset] - & CommonData.INTEGER_MASK; - op1.indexValue = op1.byteValue - + (op1.byteValue & CommonData.HIGHER_NIBBLE_MASK); - op2.indexValue = op2.byteValue - + (op2.byteValue & CommonData.HIGHER_NIBBLE_MASK); - sum.indexValue = op1.indexValue + op2.indexValue; - if (carry) - sum.byteValue = CommonData - .getPackedSumPlusOneValues(sum.indexValue); - else - sum.byteValue = CommonData.getPackedSumValues(sum.indexValue); - carry = (sum.byteValue & CommonData.INTEGER_MASK) < ((op1.byteValue & CommonData.INTEGER_MASK) + (op2.byteValue & CommonData.INTEGER_MASK)); - sum.byteArray[sum.currentOffset] = (byte) (sum.byteValue); - } - // if carry, add one to remaining high order digits from op1 - for (; carry && op1.currentOffset >= op1.offset - && sum.currentOffset >= sum.offset; op1.currentOffset -= 1, sum.currentOffset -= 1) { - if (checkOverflow && sum.currentOffset < sum.offset) { - throw new ArithmeticException( - "Decimal overflow in addPackedDecimal"); - } - sum.byteValue = CommonData - .getPackedAddOneValues(op1.byteArray[op1.currentOffset]) - & CommonData.INTEGER_MASK; - carry = (sum.byteValue == 0x00); - sum.byteArray[sum.currentOffset] = (byte) (sum.byteValue); - } - if (sum.currentOffset < sum.offset) // reached the end - { - if ((carry && checkOverflow) - || (checkOverflow && op1.currentOffset >= op1.offset)) - throw new ArithmeticException( - "Decimal overflow in addPackedDecimal"); - else if (sum.precision % 2 == 0) { - if ((byte) (sum.byteArray[sum.offset] & CommonData.HIGHER_NIBBLE_MASK) > (byte) 0x00 - && checkOverflow) - throw new ArithmeticException( - "Decimal overflow in addPackedDecimal"); - sum.byteArray[sum.offset] &= CommonData.LOWER_NIBBLE_MASK; - } - return; - } - // if still carry, add high order one to sum - if (carry) { // carry - sum.byteArray[sum.currentOffset] = 1; - sum.currentOffset -= 1; - } - // copy any remaining digits - copyRemainingDigits(op1, op2, checkOverflow); - } - - private static void computeDifference(PackedDecimalOperand op1, - PackedDecimalOperand op2, boolean checkOverflow) - throws ArithmeticException { - - PackedDecimalOperand sum = sum_threadLocal.get(); - - boolean borrow; - // compute difference from sign byte - borrow = op1.signDigit < op2.signDigit; - - sum.byteValue = Math.abs((op1.signDigit >> 4) - (op2.signDigit >> 4) - + 10) % 10; - sum.byteArray[sum.signOffset] = (byte) ((sum.byteValue << 4) | (op1.sign & CommonData.LOWER_NIBBLE_MASK)); - - // compute op1 digit values - op2 digit values ; - for (op2.currentOffset = op2.signOffset - 1, op1.currentOffset = op1.signOffset - 1; op2.currentOffset >= op2.offset - && sum.currentOffset >= sum.offset; op2.currentOffset -= 1, op1.currentOffset -= 1, sum.currentOffset -= 1) { - if (checkOverflow && sum.currentOffset < sum.offset) { - throw new ArithmeticException( - "Decimal overflow in subtractPackedDecimal"); - } - - op1.byteValue = op1.byteArray[op1.currentOffset] - & CommonData.INTEGER_MASK; - op2.byteValue = op2.byteArray[op2.currentOffset] - & CommonData.INTEGER_MASK; - op1.indexValue = op1.byteValue - + (op1.byteValue & CommonData.HIGHER_NIBBLE_MASK); - op2.indexValue = op2.byteValue - + (op2.byteValue & CommonData.HIGHER_NIBBLE_MASK); - sum.indexValue = (op1.indexValue - op2.indexValue) & 0x3FF; - if (borrow) - sum.byteValue = CommonData - .getPackedDifferenceMinusOneValues(sum.indexValue); - else - sum.byteValue = CommonData - .getPackedDifferenceValues(sum.indexValue); - borrow = (sum.byteValue & CommonData.INTEGER_MASK) > ((op1.byteValue & CommonData.INTEGER_MASK) - (op2.byteValue & CommonData.INTEGER_MASK)); - if (sum.currentOffset >= sum.offset) - sum.byteArray[sum.currentOffset] = (byte) (sum.byteValue); - } - // if borrow, subtract one from remaining high order digits - for (; borrow && op1.currentOffset >= op1.offset - && sum.currentOffset >= sum.offset; op1.currentOffset -= 1, sum.currentOffset -= 1) { - if (checkOverflow && sum.currentOffset < sum.offset) { - throw new ArithmeticException( - "Decimal overflow in subtractPackedDecimal"); - } - sum.byteValue = CommonData - .getPackedBorrowOneValues(op1.byteArray[op1.currentOffset]) - & CommonData.INTEGER_MASK; - borrow = (sum.byteValue == 0x99); - if (sum.currentOffset >= sum.offset) - sum.byteArray[sum.currentOffset] = (byte) (sum.byteValue); - } - - copyRemainingDigits(op1, op2, checkOverflow); - } - - private static void computeValue(boolean checkOverflow) - throws ArithmeticException { - - PackedDecimalOperand sum = sum_threadLocal.get(); - PackedDecimalOperand op1 = op1_threadLocal.get(); - PackedDecimalOperand op2 = op2_threadLocal.get(); - - if ((op1.sign & CommonData.LOWER_NIBBLE_MASK) == (op2.sign & CommonData.LOWER_NIBBLE_MASK)) { - // signs are same, compute sum of values - // add less bytes to more bytes - if (op1.bytes < op2.bytes) - computeSum(op2, op1, checkOverflow); - else - computeSum(op1, op2, checkOverflow); - } else { // signs are different, compute difference of values - // subtract smaller value from larger value so we will always - // have one to borrow - if (op1.bytes < op2.bytes) - computeDifference(op2, op1, checkOverflow); // op2 has more - // non-zero bytes - else if (op1.bytes > op2.bytes) - computeDifference(op1, op2, checkOverflow); // op2 has more - // non-zero bytes - else { - // compare values to find which is larger. - // adjust offsets at same time - difference between equal bytes - // is 0 - findDifference: { - for (; op1.offset < op1.signOffset; op1.offset += 1, op2.offset += 1) { - op1.byteValue = op1.byteArray[op1.offset]; - op2.byteValue = op2.byteArray[op2.offset]; - if (op1.byteValue != op2.byteValue) - break findDifference; - } - op1.byteValue = op1.byteArray[op1.offset] - & CommonData.HIGHER_NIBBLE_MASK; - op2.byteValue = op2.byteArray[op2.offset] - & CommonData.HIGHER_NIBBLE_MASK; - if (op1.byteValue == op2.byteValue) { - // values are equal, difference is zero - setPackedZero(sum.byteArray, sum.offset, sum.precision); - return; - } - } - if ((op1.byteValue & CommonData.INTEGER_MASK) > (op2.byteValue & CommonData.INTEGER_MASK)) - computeDifference(op1, op2, checkOverflow); - else - computeDifference(op2, op1, checkOverflow); - } - } - } - - // The implementations of multiply, divide and remainder are based on - // BigDecimal - // for simplicity and also because it has been shown that they have - // acceptable performance. - - private static final int MULTIPLY = 1, DIVIDE = 2, REMAINDER = 3; - - /** - * Multiplies two Packed Decimals in byte arrays. The sign of an input Packed Decimal is assumed to be positive - * unless the sign nibble contains one of the negative sign codes, in which case the sign of the respective input - * Packed Decimal is interpreted as negative. - * - * @param result - * byte array that will hold the product Packed Decimal - * @param resultOffset - * offset into result where the product Packed Decimal is located - * @param resultPrecision - * the length (number of digits) of the product Packed Decimal. Maximum valid precision is 253 - * @param op1Decimal - * byte array that will hold the multiplicand Packed Decimal - * @param op1Offset - * offset into op1Decimal where the multiplicand is located - * @param op1Precision - * the length (number of digits) of the multiplicand Packed Decimal. Maximum valid precision is 253 - * @param op2Decimal - * byte array that will hold the multiplier - * @param op2Offset - * offset into op2Decimal where the multiplier is located - * @param op2Precision - * the length (number of digits) of the multiplier Packed Decimal. Maximum valid precision is 253 - * @param checkOverflow - * if set to true, Packed Decimals are validated before multiplication and an - * IllegalArgumentException or ArithmeticException may be thrown. If not, the - * result can be invalid - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws IllegalArgumentException - * if an overflow occurs during multiplication - * @throws ArithmeticException - * if any of the Packed Decimal operands are invalid - */ - public static void multiplyPackedDecimal(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, // multiplicand - byte[] op2Decimal, int op2Offset, int op2Precision, // multiplier - boolean checkOverflow) { - if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "multiplyPackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + - " but valid indices are from 0 to " + (result.length - 1) + "."); - - if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "multiplyPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "multiplyPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - multiplyPackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, - op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); - } - - private static void multiplyPackedDecimal_(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, // multiplicand - byte[] op2Decimal, int op2Offset, int op2Precision, // multiplier - boolean checkOverflow) { - packedDecimalBinaryOp(MULTIPLY, result, resultOffset, resultPrecision, - op1Decimal, op1Offset, op1Precision, op2Decimal, op2Offset, - op2Precision, checkOverflow); - } - - /** - * Divides two Packed Decimals is byte arrays. The sign of an input Packed Decimal is assumed to be positive - * unless the sign nibble contains one of the negative sign codes, in which case the sign of the respective input - * Packed Decimal is interpreted as negative. - * - * @param result - * byte array that will hold the quotient Packed Decimal - * @param resultOffset - * offset into result where the quotient Packed Decimal is located - * @param resultPrecision - * the length (number of digits) of the quotient Packed Decimal. Maximum valid precision is 253 - * @param op1Decimal - * byte array that will hold the dividend Packed Decimal - * @param op1Offset - * offset into op1Decimal where the dividend is located - * @param op1Precision - * the length (number of digits) of the dividend Packed Decimal. Maximum valid precision is 253 - * @param op2Decimal - * byte array that will hold the divisor - * @param op2Offset - * offset into op2Decimal where the divisor is located - * @param op2Precision - * the length (number of digits) of the divisor Packed Decimal. Maximum valid precision is 253 - * @param checkOverflow - * if set to true, Packed Decimals are validated before division and an - * IllegalArgumentException or ArithmeticException may be thrown. If not, the - * result can be invalid - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws IllegalArgumentException - * if an overflow occurs during division - * @throws ArithmeticException - * if any of the Packed Decimal operands are invalid - */ - public static void dividePackedDecimal(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision, boolean checkOverflow) { - if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "dividePackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + - " but valid indices are from 0 to " + (result.length - 1) + "."); - - if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "dividePackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "dividePackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - dividePackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, - op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); - } - - private static void dividePackedDecimal_(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision, boolean checkOverflow) { - packedDecimalBinaryOp(DIVIDE, result, resultOffset, resultPrecision, - op1Decimal, op1Offset, op1Precision, op2Decimal, op2Offset, - op2Precision, checkOverflow); - - } - - /** - * Calculates the remainder resulting from the division of two Packed Decimals in byte arrays. The sign of an input - * Packed Decimal is assumed to be positive unless the sign nibble contains one of the negative sign codes, in - * which case the sign of the respective input Packed Decimal is interpreted as negative. - * - * @param result - * byte array that will hold the remainder Packed Decimal - * @param resultOffset - * offset into result where the remainder Packed Decimal is located - * @param resultPrecision - * number of Packed Decimal digits for the remainder. Maximum valid precision is 253 - * @param op1Decimal - * byte array that will hold the dividend Packed Decimal - * @param op1Offset - * offset into op1Decimal where the dividend is located - * @param op1Precision - * number of Packed Decimal digits for the dividend. Maximum valid precision is 253 - * @param op2Decimal - * byte array that will hold the divisor - * @param op2Offset - * offset into op2Decimal where the divisor is located - * @param op2Precision - * number of Packed Decimal digits for the divisor. Maximum valid precision is 253 - * @param checkOverflow - * if set to true, Packed Decimals are validated before division and an - * IllegalArgumentException or ArithmeticException may be thrown. If not, the - * result can be invalid - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws IllegalArgumentException - * if an overflow occurs during division - * @throws ArithmeticException - * if any of the Packed Decimal operands are invalid - */ - public static void remainderPackedDecimal(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision, boolean checkOverflow) { - if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "remainderPackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + - " but valid indices are from 0 to " + (result.length - 1) + "."); - - if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "remainderPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "remainderPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - remainderPackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, - op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); - } - private static void remainderPackedDecimal_(byte[] result, int resultOffset, - int resultPrecision, byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision, boolean checkOverflow) { - packedDecimalBinaryOp(REMAINDER, result, resultOffset, resultPrecision, - op1Decimal, op1Offset, op1Precision, op2Decimal, op2Offset, - op2Precision, checkOverflow); - } - - private static BigInteger getBigInteger(byte[] pd, int offset, int length) { - int end = offset + length - 1; - StringBuilder sb = new StringBuilder(); - - if ((pd[end] & CommonData.LOWER_NIBBLE_MASK) == 0x0B - || (pd[end] & CommonData.LOWER_NIBBLE_MASK) == 0x0D) - sb.append('-'); - - for (int i = offset; i < end; i++) { - sb.append((char) ('0' + (pd[i] >> 4 & CommonData.LOWER_NIBBLE_MASK))); - sb.append((char) ('0' + (pd[i] & CommonData.LOWER_NIBBLE_MASK))); - } - sb.append((char) ('0' + (pd[end] >> 4 & CommonData.LOWER_NIBBLE_MASK))); - return new BigInteger(sb.toString()); - } - - private static void putBigInteger(byte[] pd, int offset, int length, - BigInteger bigInt, boolean checkOverflow) - throws ArithmeticException { - int end = offset + length - 1; - - // could use abs(), but want to avoid creating another BigInteger object - char[] chars = bigInt.toString().toCharArray(); - boolean neg = chars[0] == '-'; - - int charStart = neg ? 1 : 0; - int charEnd = chars.length - 1; - - pd[end--] = (byte) ((neg ? 0x0D : 0x0C) | ((chars[charEnd--] - '0') << 4)); - - while (end >= offset) { - byte b = 0; - if (charEnd >= charStart) { - b = (byte) (chars[charEnd--] - '0'); - if (charEnd >= charStart) { - b |= (byte) ((chars[charEnd--] - '0') << 4); - } - } - pd[end--] = b; - } - - if (checkOverflow && charEnd < charStart) { - while (charEnd >= charStart) { - if (chars[charEnd--] != '0') { - throw new ArithmeticException( - "Packed Decimal overflow during multiplication/division, non-zero digits lost"); - } - } - } - } - - private static void zeroTopNibbleIfEven(byte[] bytes, int offset, int prec) { - if (prec % 2 == 0) - bytes[offset] &= CommonData.LOWER_NIBBLE_MASK; - } - - private static void packedDecimalBinaryOp(int op, byte[] result, - int offsetResult, int precResult, byte[] op1, int op1Offset, - int precOp1, byte[] op2, int op2Offset, int precOp2, - boolean checkOverflow) { - - zeroTopNibbleIfEven(op1, op1Offset, precOp1); - zeroTopNibbleIfEven(op2, op2Offset, precOp2); - - // check for long - switch (op) { - case MULTIPLY: - if (precOp1 + precOp2 <= 18 && precResult <= 18) { - long op1long = DecimalData.convertPackedDecimalToLong(op1, - op1Offset, precOp1, checkOverflow); - long op2long = DecimalData.convertPackedDecimalToLong(op2, - op2Offset, precOp2, checkOverflow); - long resultLong = op1long * op2long; - DecimalData.convertLongToPackedDecimal(resultLong, result, - offsetResult, precResult, checkOverflow); - if (resultLong == 0) - forceSign(result, offsetResult, precResult, op1, op1Offset, - precOp1, op2, op2Offset, precOp2); - return; - } - break; - case DIVIDE: - case REMAINDER: - if (precOp1 <= 18 && precOp2 <= 18 && precResult <= 18) { - long op1long = DecimalData.convertPackedDecimalToLong(op1, - op1Offset, precOp1, checkOverflow); - long op2long = DecimalData.convertPackedDecimalToLong(op2, - op2Offset, precOp2, checkOverflow); - long resultLong; - if (op == DIVIDE) - resultLong = op1long / op2long; - else - resultLong = op1long % op2long; - DecimalData.convertLongToPackedDecimal(resultLong, result, - offsetResult, precResult, checkOverflow); - if (resultLong == 0) - forceSign(result, offsetResult, precResult, op1, op1Offset, - precOp1, op2, op2Offset, precOp2); - return; - } - break; - } - - // long is too small - BigInteger op1BigInt; - BigInteger op2BigInt; - try { - op1BigInt = getBigInteger(op1, op1Offset, - precisionToByteLength(precOp1)); - op2BigInt = getBigInteger(op2, op2Offset, - precisionToByteLength(precOp2)); - } catch (NumberFormatException e) { - if (checkOverflow) - throw new IllegalArgumentException("Invalid packed data value", - e); - return; - } - - BigInteger resultBigInt = null; - switch (op) { - case MULTIPLY: - resultBigInt = op1BigInt.multiply(op2BigInt); - break; - case DIVIDE: - resultBigInt = op1BigInt.divide(op2BigInt); - break; - case REMAINDER: - resultBigInt = op1BigInt.remainder(op2BigInt); - break; - } - - putBigInteger(result, offsetResult, precisionToByteLength(precResult), - resultBigInt, checkOverflow); - - // force the sign because BigInteger will never produce negative zero - if (BigInteger.ZERO.equals(resultBigInt)) { - forceSign(result, offsetResult, precResult, op1, op1Offset, - precOp1, op2, op2Offset, precOp2); - } - } - - /** - * Using BigInteger or long will never produce negative zero, so we need to - * make sure to set the correct sign code. - */ - private static void forceSign(byte[] result, int offsetResult, - int precResult, byte[] op1, int op1Offset, int precOp1, byte[] op2, - int op2Offset, int precOp2) { - - int endOp1 = op1Offset + precisionToByteLength(precOp1) - 1; - int endOp2 = op2Offset + precisionToByteLength(precOp2) - 1; - int endResult = offsetResult + precisionToByteLength(precResult) - 1; - result[endResult] |= 0x0F; - result[endResult] &= signMask(op1[endOp1], op2[endOp2]); - } - - private static int precisionToByteLength(int precision) { - return (precision + 2) / 2; - } - - private static byte signMask(byte a, byte b) { - return (byte) (sign(a) * sign(b) > 0 ? 0xFC : 0xFD); - } - - private static int sign(byte b) { - return (CommonData.getSign(b & CommonData.LOWER_NIBBLE_MASK) == CommonData.PACKED_MINUS) ? -1 : 1; - } - - /** - * Checks if the first Packed Decimal operand is lesser than the second one. - * - * @param op1Decimal - * byte array that holds the first Packed Decimal operand - * @param op1Offset - * offset into op1Decimal where the first operand is located - * @param op1Precision - * number of Packed Decimal digits for the first operand - * @param op2Decimal - * byte array that holds the second Packed Decimal operand - * @param op2Offset - * offset into op2Decimal where the second operand is located - * @param op2Precision - * number of Packed Decimal digits for the second operand - * - * @return true if op1Decimal < op2Decimal, false otherwise - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static boolean lessThanPackedDecimal(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "lessThanPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "lessThanPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - return lessThanPackedDecimal_(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - } - - private static boolean lessThanPackedDecimal_(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - - return greaterThanPackedDecimal_(op2Decimal, op2Offset, op2Precision, op1Decimal, - op1Offset, op1Precision); - } - - /** - * Checks if the first Packed Decimal operand is less than or equal to the second one. - * - * @param op1Decimal - * byte array that holds the first Packed Decimal operand - * @param op1Offset - * offset into op1Decimal where the first operand is located - * @param op1Precision - * number of Packed Decimal digits for the first operand - * @param op2Decimal - * byte array that holds the second Packed Decimal operand - * @param op2Offset - * offset into op2Decimal where the second operand is located - * @param op2Precision - * number of Packed Decimal digits for the second operand - * - * @return true if op1Decimal <= op2Decimal, false otherwise - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static boolean lessThanOrEqualsPackedDecimal(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "lessThanOrEqualsPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "lessThanOrEqualsPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - return lessThanOrEqualsPackedDecimal_(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - - } - private static boolean lessThanOrEqualsPackedDecimal_(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - return !greaterThanPackedDecimal_(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - } - - /** - * Checks if the first Packed Decimal operand is greater than the second one. - * - * @param op1Decimal - * byte array that holds the first Packed Decimal operand - * @param op1Offset - * offset into op1Decimal where the first operand is located - * @param op1Precision - * number of Packed Decimal digits for the first operand - * @param op2Decimal - * byte array that holds the second Packed Decimal operand - * @param op2Offset - * offset into op2Decimal where the second operand is located - * @param op2Precision - * number of Packed Decimal digits for the second operand - * - * @return true if op1Decimal > op2Decimal, false otherwise - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static boolean greaterThanPackedDecimal(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "greaterThanPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "greaterThanPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - return greaterThanPackedDecimal_(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - } - - private static boolean greaterThanPackedDecimal_(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - - if (op1Precision < 1 || op2Precision < 1) - throw new IllegalArgumentException("Invalid Precision for an operand"); - - //boolean result = false; - int op1End = op1Offset + precisionToByteLength(op1Precision) - 1; - int op2End = op2Offset + precisionToByteLength(op2Precision) - 1; - - //check signs, if a different signs we're done! - byte op1Sign = CommonData.getSign((byte)(op1Decimal[op1End] & CommonData.LOWER_NIBBLE_MASK)); - byte op2Sign = CommonData.getSign((byte)(op2Decimal[op2End] & CommonData.LOWER_NIBBLE_MASK)); - - boolean isNegative = (op1Sign == CommonData.PACKED_MINUS) ? true : false; - - //skip leading zeros - for (; op1Offset < op1End && op1Decimal[op1Offset] == CommonData.PACKED_ZERO; op1Offset++) - ; - for (; op2Offset < op2End && op2Decimal[op2Offset] == CommonData.PACKED_ZERO; op2Offset++) - ; - - int op1Length = op1End - op1Offset; - int op2Length = op2End - op2Offset; - - if (op1Length + op2Length == 0) - { - int op1LastDigit = (op1Decimal[op1Offset] >> 4) & CommonData.LOWER_NIBBLE_MASK; - int op2LastDigit = (op2Decimal[op2Offset] >> 4) & CommonData.LOWER_NIBBLE_MASK; - if (op1LastDigit + op2LastDigit == 0) //both zeros - return false; - if (op1Sign < op2Sign) - return true; - else if (op1Sign > op2Sign) - return false; - if ((op1LastDigit > op2LastDigit && !isNegative) || (op1LastDigit < op2LastDigit && isNegative)) - return true; - - return false; - } - - if (op1Sign < op2Sign) - return true; - else if (op1Sign > op2Sign) - return false; - - if ((op1Length > op2Length && !isNegative) || (op1Length < op2Length && isNegative)) - return true; - else if ((op1Length < op2Length && !isNegative) || (op1Length > op2Length && isNegative)) - return false; - - while(op1Offset < op1End && op2Offset < op2End) - { - int op1Byte = (op1Decimal[op1Offset] & 0xFF); - int op2Byte = (op2Decimal[op2Offset] & 0xFF); - int opDiff = op1Byte - op2Byte; - - if ((opDiff < 0 && !isNegative) || (opDiff > 0 && isNegative)) - return false; - else if ((opDiff > 0 && !isNegative) || (opDiff < 0 && isNegative)) - return true; - - op1Offset++; - op2Offset++; - } - //last digit - int op1LastDigit = (op1Decimal[op1Offset] >> 4) & CommonData.LOWER_NIBBLE_MASK; - int op2LastDigit = (op2Decimal[op2Offset] >> 4) & CommonData.LOWER_NIBBLE_MASK; - - if ((op1LastDigit > op2LastDigit && !isNegative) || (op1LastDigit < op2LastDigit && isNegative)) - return true; - - return false; //either equal or less than - - } - - /** - * Checks if the first Packed Decimal operand is greater than or equal to the second one. - * - * @param op1Decimal - * byte array that holds the first Packed Decimal operand - * @param op1Offset - * offset into op1Decimal where the first operand is located - * @param op1Precision - * number of Packed Decimal digits for the first operand - * @param op2Decimal - * byte array that holds the second Packed Decimal operand - * @param op2Offset - * offset into op2Decimal where the second operand is located - * @param op2Precision - * number of Packed Decimal digits for the second operand - * - * @return true if op1Decimal >= op2Decimal, false otherwise - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static boolean greaterThanOrEqualsPackedDecimal(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "greaterThanOrEqualsPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "greaterThanOrEqualsPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - return greaterThanOrEqualsPackedDecimal_(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - } - - private static boolean greaterThanOrEqualsPackedDecimal_(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - return !lessThanPackedDecimal_(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - } - - /** - * Checks if the two Packed Decimal operands are equal. - * - * @param op1Decimal - * byte array that holds the first Packed Decimal operand - * @param op1Offset - * offset into op1Decimal where the first operand is located - * @param op1Precision - * number of Packed Decimal digits for the first operand - * @param op2Decimal - * byte array that holds the second Packed Decimal operand - * @param op2Offset - * offset into op2Decimal where the second operand is located - * @param op2Precision - * number of Packed Decimal digits for the second operand - * - * @return true if op1Decimal == op2Decimal, false otherwise - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static boolean equalsPackedDecimal(byte[] op1Decimal, int op1Offset, - int op1Precision, byte[] op2Decimal, int op2Offset, int op2Precision) { - if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "equalsPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "equalsPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - return equalsPackedDecimal_(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - } - - private static boolean equalsPackedDecimal_(byte[] op1Decimal, int op1Offset, int op1Precision, - byte[] op2Decimal, int op2Offset, int op2Precision) { - if (op1Precision < 1 || op2Precision < 1) - throw new IllegalArgumentException("Invalid Precision for an operand"); - - int op1End = op1Offset + precisionToByteLength(op1Precision) - 1; - int op2End = op2Offset + precisionToByteLength(op2Precision) - 1; - - byte op1Sign = CommonData.getSign((byte) (op1Decimal[op1End] & CommonData.LOWER_NIBBLE_MASK)); - byte op2Sign = CommonData.getSign((byte) (op2Decimal[op2End] & CommonData.LOWER_NIBBLE_MASK)); - - boolean op1IsEven = op1Precision % 2 == 0; - boolean op2IsEven = op2Precision % 2 == 0; - - // Must handle the +0 and -0 case - if (op1Sign != op2Sign) - return checkZeroBetweenOpOffsetAndOpEnd (op1Decimal, op1Offset, op1End, op1IsEven, true) && - checkZeroBetweenOpOffsetAndOpEnd (op2Decimal, op2Offset, op2End, op2IsEven, true); - - // Check if least significant digit is different - if ((op1Decimal[op1End] & CommonData.HIGHER_NIBBLE_MASK) != - (op2Decimal[op2End] & CommonData.HIGHER_NIBBLE_MASK)) { - return false; - } - - // Avoid decrementing if op1End == op1Offset || op2End == op2Offset - if (op1End > op1Offset && op2End > op2Offset) { - op1End--; - op2End--; - } - - while (op1End > op1Offset && op2End > op2Offset) { - // Check if intermediate digits are different - if (op1Decimal[op1End] != op2Decimal[op2End]) - return false; - - op1End--; - op2End--; - } - - // At this point it is true that op1End == op1Offset || op2End == op2Offset - if (op1End == op1Offset) { - if (op1IsEven) { - // Check if most significant digit is different - if ((op1Decimal[op1End] & CommonData.LOWER_NIBBLE_MASK) == - (op2Decimal[op2End] & CommonData.LOWER_NIBBLE_MASK)) { - return checkZeroBetweenOpOffsetAndOpEnd (op2Decimal, op2Offset, op2End, op2IsEven, !op2IsEven || op2End != op2Offset); - } - } else { - // Check if two most significant digits are different - if (op1Decimal[op1End] == op2Decimal[op2End]) - return checkZeroBetweenOpOffsetAndOpEnd (op2Decimal, op2Offset, op2End, op2IsEven, false); - } - } else { - if (op2IsEven) { - // Check if most significant digit is different - if ((op1Decimal[op1End] & CommonData.LOWER_NIBBLE_MASK) == - (op2Decimal[op2End] & CommonData.LOWER_NIBBLE_MASK)) { - return checkZeroBetweenOpOffsetAndOpEnd (op1Decimal, op1Offset, op1End, op1IsEven, !op1IsEven || op1End != op1Offset); - } - } else { - // Check if two most significant digits are different - if (op1Decimal[op1End] == op2Decimal[op2End]) - return checkZeroBetweenOpOffsetAndOpEnd (op1Decimal, op1Offset, op1End, op1IsEven, false); - } - } - - return false; - } - - /** - * Checks if the Packed Decimal digits between opDecimal[opOffset] and opDecimal[opEnd] - * (inclusive depending on checkHighNibbleAtOpEnd) are all zeros. - * - * @param opDecimal - * byte array that holds the Packed Decimal operand - * @param opOffset - * offset into opDecimal where the first byte of the Packed Decimal is located - * @param opEnd - * offset into opDecimal where the last byte to be checked is located - * @param opIsEven - * boolean is true if the opDecimal has even precision - * @param checkHighNibbleAtOpEnd - * boolean indicates whether the high nibble of opDecimal[opEnd] should be checked that it - * contains a zero. If false, opEnd will be decremented and this will be the new starting point of the - * algorithm which verifies that the remaining Packed Decimal digits are zeros. - * - * @return true if all digits from opOffset to opEnd are zero, false otherwise - * - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - private static boolean checkZeroBetweenOpOffsetAndOpEnd(byte[] opDecimal, int opOffset, int opEnd, boolean opIsEven, boolean checkHighNibbleAtOpEnd) { - if (checkHighNibbleAtOpEnd && (opDecimal[opEnd] & CommonData.HIGHER_NIBBLE_MASK) != 0x00) - return false; - - if (opEnd-- > opOffset) { - // Handle intermediate bytes - while (opEnd > opOffset) { - if (opDecimal[opEnd--] != 0x00) - return false; - } - - // Handle the most significant nibble/byte - if (opIsEven) { - if ((opDecimal[opEnd] & CommonData.LOWER_NIBBLE_MASK) != 0x00) - return false; - } else { - if (opDecimal[opEnd] != 0x00) - return false; - } - } - - return true; - } - - - /** - * Checks if the two Packed Decimal operands are unequal. - * - * @param op1Decimal - * byte array that holds the first Packed Decimal operand - * @param op1Offset - * offset into op1Decimal where the first operand is located - * @param op1Precision - * number of Packed Decimal digits for the first operand - * @param op2Decimal - * byte array that holds the second Packed Decimal operand - * @param op2Offset - * offset into op2Decimal where the second operand is located - * @param op2Precision - * number of Packed Decimal digits for the second operand - * - * @return true if op1Decimal != op2Decimal, false otherwise - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - */ - public static boolean notEqualsPackedDecimal(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "notEqualsPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); - - if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "notEqualsPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + - " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); - - return notEqualsPackedDecimal_(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - } - - private static boolean notEqualsPackedDecimal_(byte[] op1Decimal, - int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, - int op2Precision) { - return !equalsPackedDecimal(op1Decimal, op1Offset, op1Precision, - op2Decimal, op2Offset, op2Precision); - } - - private static void roundUpPackedDecimal(byte[] packedDecimal, int offset, - int end, int precision, int roundingDigit, boolean checkOverflow) { - - packedDecimal[end] = CommonData.getPackedAddOneSignValues(packedDecimal[end]); - - if ((byte) (packedDecimal[end] & CommonData.HIGHER_NIBBLE_MASK) == (byte) 0x00) - { - byte[] addTenArray = { 0x01, packedDecimal[end] }; - addPackedDecimal(packedDecimal, offset, precision, - packedDecimal, offset, precision, addTenArray, 0, 2, - checkOverflow); - } - } - - /** - * In case of a shift operation, this method is called to ensure if the resulting value of the shift is - * zero that it is converted to a positive zero, meaning {0x....0C}. This is done to match the expected - * result in COBOL. - */ - private static void checkIfZero(byte[] packedDecimal, int offset, int end, int precision, boolean isEvenPrecision) { - - if (CommonData.getSign(packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK) != CommonData.PACKED_MINUS) - return; - if (isEvenPrecision && ((packedDecimal[offset] & CommonData.LOWER_NIBBLE_MASK) != 0x00)) - return; - //else if (packedDecimal[offset] != 0x00) - // return; - int i = offset;// + 1; - for (; i < end && packedDecimal[i] == 0x00; i++) ; - if (i < end) - return; - else if ((packedDecimal[end] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) - packedDecimal[end] = CommonData.PACKED_PLUS; - - return; - } - - /** - * Right shift, and optionally round, a Packed Decimal. If the resultant is zero, - * it can either be a positive zero 0x0C or a negative zero 0x0D. - * - * @param destination - * byte array that holds the result of the right shift (and rounding) - * @param destinationOffset - * offset into destination where the result Packed Decimal is located - * @param destinationPrecision - * number of Packed Decimal digits in the destination - * @param source - * byte array that holds the Packed Decimal operand to be right shifted - * @param sourceOffset - * offset into source where the operand is located - * @param sourcePrecision - * number of Packed Decimal digits in the operand - * @param shiftAmount - * amount by which the source will be right shifted - * @param round - * if set to true, causes rounding to occur - * @param checkOverflow - * if set to true, check for overflow - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if a decimal overflow occurs - * @throws IllegalArgumentException - * if the shiftAmount or sourcePrecision parameter is invalid or - * the source packed decimal contains invalid sign or digit code - */ - public static void shiftRightPackedDecimal(byte[] destination, - int destinationOffset, int destinationPrecision, byte[] source, - int sourceOffset, int sourcePrecision, int shiftAmount, - boolean round, boolean checkOverflow) { - - if ((destinationOffset + ((destinationPrecision / 2) + 1) > destination.length) || (destinationOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "shiftRightPackedDecimal is trying to access destinationDecimal[" + destinationOffset + "] to destinationDecimal[" + (destinationOffset + (destinationPrecision / 2)) + "]" + - " but valid indices are from 0 to " + (destination.length - 1) + "."); - - if ((sourceOffset < 0) || (sourceOffset + ((sourcePrecision / 2) + 1) > source.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "shiftRightPackedDecimal is trying to access sourceDecimal[" + sourceOffset + "] to sourceDecimal[" + (sourceOffset + (sourcePrecision / 2)) + "]" + - " but valid indices are from 0 to " + (source.length - 1) + "."); - - shiftRightPackedDecimal_(destination, destinationOffset, destinationPrecision, - source, sourceOffset, sourcePrecision, shiftAmount, - round, checkOverflow); - } - - private static void shiftRightPackedDecimal_(byte[] destination, - int destinationOffset, int destinationPrecision, byte[] source, - int sourceOffset, int sourcePrecision, int shiftAmount, - boolean round, boolean checkOverflow) { - - // Figure out the sign of the source Packed Decimal - int end = sourceOffset + precisionToByteLength(sourcePrecision) - 1; - byte sign = CommonData.getSign(source[end] & CommonData.LOWER_NIBBLE_MASK); - int newDstOffset = destinationOffset; - int newDstPrec = destinationPrecision; - int dstEnd = destinationOffset - + precisionToByteLength(destinationPrecision) - 1; - int highDigit = sourcePrecision - 1; - int lowDigit = 0; - int precDiff = sourcePrecision - destinationPrecision; - ; - int newSrcOffset; - int newSrcEnd; - boolean evenPrecision = sourcePrecision % 2 == 0; - boolean isLeastSigDigitInHighNibble = false; - boolean isMostSigDigitInLowNibble = false; - int roundingDigit = 0; - boolean overRanPD = false; // when the shifting left no digits to copy - - if (destinationPrecision < 1 || sourcePrecision < 1 || shiftAmount < 0) { - throw new IllegalArgumentException( - "Invalid Precisions or shift amount"); - } - - if(checkPackedDecimal_(source, sourceOffset, sourcePrecision, true, false) != 0) { - throw new IllegalArgumentException( - "Invalid sign or digit code in input packed decimal"); - } - - lowDigit += shiftAmount; - precDiff -= shiftAmount; // every time we shift, we lose precision - if (precDiff > 0) // if we still need to lose some precision, take off - // higher digits - { - highDigit -= precDiff; - if (checkOverflow) { - int bytes; - int iter = 0; - if (evenPrecision) { - precDiff--; - iter++; - if ((byte) (source[sourceOffset] & CommonData.LOWER_NIBBLE_MASK) != 0x00) - throw new ArithmeticException( - "Decimal overflow in shiftRightPackedDecimal."); - } - bytes = (precDiff) / 2; - precDiff -= bytes * 2; - - for (int i = 0; i < bytes; i++) { - if (source[i + sourceOffset + iter] != 0x00) - throw new ArithmeticException( - "Decimal overflow in shiftRightPackedDecimal."); - } - - if (precDiff == 1 - && (byte) (source[bytes + sourceOffset] & CommonData.HIGHER_NIBBLE_MASK) != 0x00) - throw new ArithmeticException( - "Decimal overflow in shiftRightPackedDecimal."); - - } - } - // add zeros if precDiff < 0, do this at end - int newDifference = (highDigit + 1) - lowDigit; // might want to deal - // with diff = 1 - if (checkOverflow && newDifference < 1) - overRanPD = true; - int highDiff = sourcePrecision - (highDigit + 1); - - if (evenPrecision && newDifference % 2 == 0) // still even - { - if (highDiff % 2 == 0) // both low and high moved even - { - isMostSigDigitInLowNibble = true; // the highest digit is on a - // low nibble - isLeastSigDigitInHighNibble = true; // the lowest digit is on a - // high nibble - newSrcOffset = sourceOffset + (highDiff) / 2; - newSrcEnd = end - (lowDigit) / 2; - } else // high moved odd, low moved odd - { - newSrcOffset = sourceOffset + (highDiff + 1) / 2; - newSrcEnd = end - (lowDigit + 1) / 2; - } - } else if (evenPrecision && newDifference % 2 != 0) { - if (highDiff % 2 != 0) // high moved odd, low moved even - { - isLeastSigDigitInHighNibble = true; - newSrcOffset = sourceOffset + (highDiff + 1) / 2; - newSrcEnd = end - (lowDigit) / 2; - } else // high moved even, low moved odd, perfect scenario - { - isMostSigDigitInLowNibble = true; - newSrcOffset = sourceOffset + (highDiff) / 2; - newSrcEnd = end - (lowDigit + 1) / 2; - } - } else if (!evenPrecision && newDifference % 2 == 0) { - if (highDiff % 2 == 0) // high moved even, low moved odd - { - newSrcOffset = sourceOffset + (highDiff) / 2; - newSrcEnd = end - (lowDigit + 1) / 2; - } else // high moved odd, low moved even - { - isMostSigDigitInLowNibble = true; // get this high nibble - // individually - isLeastSigDigitInHighNibble = true; // get this lower nibble - // individually - newSrcOffset = sourceOffset + (highDiff) / 2; - newSrcEnd = end - (lowDigit) / 2; - } - } else { - if (highDiff % 2 == 0) // both moved even, perfect scenario - { - isLeastSigDigitInHighNibble = true; - newSrcOffset = sourceOffset + (highDiff) / 2; - newSrcEnd = end - (lowDigit) / 2; - } else // both moved odd - { - isMostSigDigitInLowNibble = true; - newSrcOffset = sourceOffset + (highDiff) / 2; - newSrcEnd = end - (lowDigit + 1) / 2; - } - } - - // find rounding digit - if (round && shiftAmount > 0 && newDifference > -1) { - if (isLeastSigDigitInHighNibble) - roundingDigit = (source[newSrcEnd]) - & CommonData.LOWER_NIBBLE_MASK; - else - roundingDigit = (source[newSrcEnd + 1] >> 4) - & CommonData.LOWER_NIBBLE_MASK; - ; - } - - while (precDiff < 0) // deal with dst prec being higher, put leading - // zeros - { - destination[newDstOffset] = 0x00; - if (newDstPrec % 2 == 0 || precDiff == -1) { - if (newDstPrec % 2 == 0) - newDstOffset++; - precDiff++; - newDstPrec--; - - } else if ((precDiff / -2) >= 1) { - precDiff += 2; - newDstPrec -= 2; - newDstOffset++; - } - } - - if (isLeastSigDigitInHighNibble && !overRanPD) // can do arrayCopy, - // instead of individual - // nibbles - { - if (!isMostSigDigitInLowNibble) // just a simple arrayCopy - System.arraycopy(source, newSrcOffset, destination, - newDstOffset, newSrcEnd - newSrcOffset + 1); - else { - destination[newDstOffset] = (byte) ((source[newSrcOffset] & CommonData.LOWER_NIBBLE_MASK)); - newDstOffset++; - newSrcOffset++; - System.arraycopy(source, newSrcOffset, destination, - newDstOffset, newSrcEnd - newSrcOffset + 1); - } - } else if (!overRanPD) // must copy each nibble over - { - int newDstEnd = newDstOffset + precisionToByteLength(newDstPrec) - - 1; - byte shiftByte = newSrcEnd < sourceOffset ? 0x00 : source[newSrcEnd]; - destination[newDstEnd] = (byte) ((shiftByte << 4) & CommonData.HIGHER_NIBBLE_MASK); - newDstEnd--; - newDstPrec--; - byte current_nibble = 0; - while ((newSrcEnd > newSrcOffset) && (newDstEnd > newDstOffset)) { - current_nibble = (byte) ((source[newSrcEnd] >> 4) & CommonData.LOWER_NIBBLE_MASK); - newSrcEnd--; - current_nibble |= (byte) ((source[newSrcEnd] << 4) & CommonData.HIGHER_NIBBLE_MASK); - destination[newDstEnd] = current_nibble; - newDstEnd--; - newDstPrec -= 2; - } - if (newDstPrec > 0) { - destination[newDstEnd] = (byte) ((source[newSrcEnd] >> 4) & CommonData.LOWER_NIBBLE_MASK); - newSrcEnd--; - newDstPrec--; - if (newDstPrec > 0 && isMostSigDigitInLowNibble) - destination[newDstEnd] |= (byte) ((source[newSrcEnd] << 4) & CommonData.HIGHER_NIBBLE_MASK); - } - } - // sign assignment - if(overRanPD && roundingDigit < 5 && sign != CommonData.PACKED_PLUS) - destination[dstEnd] = (byte) ((destination[dstEnd] & CommonData.HIGHER_NIBBLE_MASK) | sign); - else - { - destination[dstEnd] = (byte) ((destination[dstEnd] & CommonData.HIGHER_NIBBLE_MASK) | (sign)); - if (round && roundingDigit >= 5) - roundUpPackedDecimal(destination, destinationOffset, dstEnd, - destinationPrecision, roundingDigit, checkOverflow); - if (checkOverflow || round) - checkIfZero(destination, destinationOffset, dstEnd, destinationPrecision, (destinationPrecision % 2 == 0 ? true : false)); - - } - } - - /** - * Left shift a Packed Decimal appending zeros to the right. In the absence of overflow, the sign - * of a zero can either be positive 0x0C or negative 0x0D. - * - * @param destination - * byte array that holds the result of the left shift - * @param destinationOffset - * offset into destination where the result Packed Decimal is located - * @param destinationPrecision - * number of Packed Decimal digits in the destination - * @param source - * byte array that holds the Packed Decimal operand to be left shifted - * @param sourceOffset - * offset into source where the operand is located - * @param sourcePrecision - * number of Packed Decimal digits in the operand - * @param shiftAmount - * amount by which the source will be left shifted - * @param checkOverflow - * if set to true, check for overflow - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws ArithmeticException - * if a decimal overflow occurs - * @throws IllegalArgumentException - * if the shiftAmount or sourcePrecision parameter is invalid or - * the source packed decimal contains invalid sign or digit code - */ - public static void shiftLeftPackedDecimal(byte[] destination, - int destinationOffset, int destinationPrecision, byte[] source, - int sourceOffset, int sourcePrecision, int shiftAmount, - boolean checkOverflow) { - if ((destinationOffset + ((destinationPrecision / 2) + 1) > destination.length) || (destinationOffset < 0)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "shiftLeftPackedDecimal is trying to access destinationDecimal[" + destinationOffset + "] to destinationDecimal[" + (destinationOffset + (destinationPrecision / 2)) + "]" + - " but valid indices are from 0 to " + (destination.length - 1) + "."); - - if ((sourceOffset < 0) || (sourceOffset + ((sourcePrecision / 2) + 1) > source.length)) - throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + - "shiftLeftPackedDecimal is trying to access sourceDecimal[" + sourceOffset + "] to sourceDecimal[" + (sourceOffset + (sourcePrecision / 2)) + "]" + - " but valid indices are from 0 to " + (source.length - 1) + "."); - - shiftLeftPackedDecimal_(destination, destinationOffset, destinationPrecision, - source, sourceOffset, sourcePrecision, shiftAmount, - checkOverflow); - } - - private static void shiftLeftPackedDecimal_(byte[] destination, - int destinationOffset, int destinationPrecision, byte[] source, - int sourceOffset, int sourcePrecision, int shiftAmount, - boolean checkOverflow) { - - if (destinationPrecision < 1 || sourcePrecision < 1 || shiftAmount < 0) { - throw new IllegalArgumentException( - "Invalid Precisions or shift amount"); - } - - if(checkPackedDecimal_(source, sourceOffset, sourcePrecision, true, false) != 0) { - throw new IllegalArgumentException( - "Invalid sign or digit code in input packed decimal"); - } - // Figure out the sign of the source Packed Decimal - int end = sourceOffset + precisionToByteLength(sourcePrecision) - 1; - byte sign = CommonData.getSign(source[end] & CommonData.LOWER_NIBBLE_MASK); - boolean overRanPD = false; - int sourceLength = precisionToByteLength(sourcePrecision); - int destinationLength = precisionToByteLength(destinationPrecision); - int shiftByte = shiftAmount / 2; - int zerosBytesAtFront = 0; - int totalZeros = 0; - - // odd Precision - if (sourcePrecision % 2 != 0) { - - // Figure out how many 0x00s are at the front starting from the - // offset - for (zerosBytesAtFront = 0; zerosBytesAtFront < sourceLength; zerosBytesAtFront++) { - if (source[zerosBytesAtFront + sourceOffset] != 0x00) - break; - } - - // Figure out if 0x0* - if ((byte) (source[zerosBytesAtFront + sourceOffset] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) - totalZeros++; - - }// even precision - else { - // Figure out if bottom nibble of offset is 0 if it is then count - // how many zero bytes there are at the front - if ((byte) (source[sourceOffset] & CommonData.LOWER_NIBBLE_MASK) == 0x00) { - totalZeros++; - for (int i = 1; i < sourceLength; i++) { - if (source[i + sourceOffset] != 0x00) - break; - else - zerosBytesAtFront++; - } - if ((byte) (source[zerosBytesAtFront + sourceOffset + 1] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) - totalZeros++; - } - } - // Add up all the zeros - totalZeros += zerosBytesAtFront * 2; - - // Check for overflow - if (checkOverflow - && ((destinationPrecision + totalZeros < sourcePrecision - + shiftAmount))) - throw new ArithmeticException( - "Overflow - Destination precision not enough to hold the result of the shift operation"); - - // Zero out destination array in range - Arrays.fill(destination, destinationOffset, destinationOffset - + destinationLength, (byte) 0x00); - - int startIndexSource = zerosBytesAtFront + sourceOffset; - int diff = destinationLength - sourceLength; - int startIndexDestination = destinationOffset + zerosBytesAtFront - - shiftByte + diff; - int numberLength = sourceLength - zerosBytesAtFront; // non-zeros digits - // length in bytes - int movedSignIndex = startIndexDestination + numberLength - 1; // where - // the - // moved - // sign - // is - // displaced - // to - - // if all digits are completely shifted out do nothing - if (destinationPrecision <= shiftAmount) - { - if (checkOverflow && sign != CommonData.PACKED_PLUS) - overRanPD = true; - } - else - { - // Even shift, can move byte by byte - if (shiftAmount % 2 == 0) - { - if (startIndexDestination < destinationOffset) - { - int difference = sourcePrecision - (destinationPrecision - shiftAmount); - int sourceIndex; - if (sourcePrecision % 2 == 0) - sourceIndex = sourceOffset + ((difference + 1) / 2); - else - sourceIndex = sourceOffset + (difference / 2); - - System.arraycopy(source, sourceIndex, destination, destinationOffset, destinationLength - - (shiftAmount / 2)); - } - else - System.arraycopy(source, startIndexSource, destination, - startIndexDestination, sourceLength - zerosBytesAtFront); - - // Strip off moved sign - if (movedSignIndex >= 0) - destination[movedSignIndex] = (byte) (destination[movedSignIndex] & CommonData.HIGHER_NIBBLE_MASK); - } - else - { - byte top; - byte bottom; - - // Move each nibble by appropriate index - for (int i = 0; i < numberLength; i++) { - top = (byte) (source[startIndexSource + i] & CommonData.HIGHER_NIBBLE_MASK); - bottom = (byte) (source[startIndexSource + i] & CommonData.LOWER_NIBBLE_MASK); - - if (startIndexDestination - 1 + i >= destinationOffset) { - destination[startIndexDestination - 1 + i] = (byte) ((top >> 4 & CommonData.LOWER_NIBBLE_MASK) | (byte) (destination[startIndexDestination - - 1 + i] & CommonData.HIGHER_NIBBLE_MASK)); - } - if (startIndexDestination + i >= destinationOffset) { - destination[startIndexDestination + i] = (byte) (bottom << 4); - } - - } - // Strip off moved sign - if (movedSignIndex >= 0) - destination[movedSignIndex] = CommonData.PACKED_ZERO; - } - } - int destinationEnd = destinationOffset + destinationLength - 1; - boolean isDestionationEvenPrecision = destinationPrecision % 2 == 0 ? true : false; - // Mask top Nibble - if (isDestionationEvenPrecision) - destination[destinationOffset] = (byte) (destination[destinationOffset] & CommonData.LOWER_NIBBLE_MASK); - // Put sign in proper position - - if (overRanPD) - destination[destinationEnd] = (byte) (CommonData.PACKED_PLUS | destination[destinationEnd]); - else - { - destination[destinationEnd] = (byte) (sign | destination[destinationEnd]); - //checkOverflow will generate pdshlOverflow, which will cause it to reset sign. pdshl will not - if (checkOverflow) - checkIfZero(destination, destinationOffset, destinationEnd, destinationPrecision, isDestionationEvenPrecision); - } - } - - /** - * Creates a copy of a Packed Decimal. - * - * @param destination - * byte array representing the destination - * @param destinationOffset - * offset into destination destination where the Packed Decimal is located - * @param destinationPrecision - * number of Packed Decimal digits for the destination - * @param source - * byte array which holds the source Packed Decimal - * @param sourceOffset - * offset into source where the Packed Decimal is located - * @param sourcePrecision - * number of Packed Decimal digits for the source. Maximum valid precision is 253 - * @param checkOverflow - * if set to true, moved Packed Decimals are validated, and an IllegalArgumentException or - * ArithmeticException is thrown if non-zero nibbles are truncated during the move - * operation. If set to false, no validating is conducted. - * - * @throws NullPointerException - * if any of the byte arrays are null - * @throws ArrayIndexOutOfBoundsException - * if an invalid array access occurs - * @throws IllegalArgumentException - * if the source Packed Decimal is invalid - * @throws ArithmeticException - * if a decimal overflow occurs - */ - public static void movePackedDecimal(byte[] destination, - int destinationOffset, int destinationPrecision, byte[] source, - int sourceOffset, int sourcePrecision, boolean checkOverflow) { - shiftLeftPackedDecimal(destination, destinationOffset, - destinationPrecision, source, sourceOffset, - sourcePrecision, 0, checkOverflow); - - } - - private static class PackedDecimalOperand { - - PackedDecimalOperand() { - super(); - } - - private static final byte PACKED_ZERO = 0x00; - - byte[] byteArray; - int offset; - int precision; - int bytes; - int signOffset; - int currentOffset; - int signByteValue; - int sign; - int signDigit; - int byteValue; - int indexValue; - - /** - * Sets up the attributes of a Packed Decimal operand. Truncates leading zeros. Captures the sign value. - * - * @param byteArray - * byte array which holds the Packed Decimal - * @param offset - * offset in byteArray where the Packed Decimal begins - * @param precision - * number of Packed Decimal digits. Maximum valid precision is 253 - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBounds - * if an invalid array access occurs - */ - public void setOperand(byte[] byteArray, int offset, int precision) { - - this.byteArray = byteArray; - this.offset = offset; - this.precision = precision; - - // truncate leading zeros - bytes = CommonData.getPackedByteCount(precision); - signOffset = this.offset + bytes - 1; - currentOffset = signOffset - 1; - for (; byteArray[this.offset] == PACKED_ZERO - && this.offset < signOffset; this.offset++) - ; - bytes = signOffset - this.offset + 1; - - // capture sign values - signByteValue = this.byteArray[signOffset] - & CommonData.INTEGER_MASK; - signDigit = signByteValue & CommonData.HIGHER_NIBBLE_MASK; - sign = CommonData.getSign(signByteValue & CommonData.LOWER_NIBBLE_MASK); - - } - - /** - * Sets up attributes of a Packed Decimal which is about to be the result operand holding the sum of two Packed - * Decimal operands. Does not truncate leading zeroes. Does not capture the sign. - * - * @param byteArray - * byte array which holds the Packed Decimal - * @param offset - * offset in byteArray where the Packed Decimal begins - * @param precision - * number of Packed Decimal digits. Maximum valid precision is 253 - * - * @throws NullPointerException - * if byteArray is null - * @throws ArrayIndexOutOfBounds - * if an invalid array access occurs - */ - public void setSumOperand(byte[] byteArray, int offset, int precision) { - - this.byteArray = byteArray; - this.offset = offset; - this.precision = precision; - - bytes = CommonData.getPackedByteCount(precision); - signOffset = this.offset + bytes - 1; - currentOffset = signOffset - 1; - - } - - } + /** + * Private constructor, class contains only static methods. + */ + private PackedDecimal() { + super(); + } + + private static final ThreadLocal op1_threadLocal = new ThreadLocal() { + protected PackedDecimalOperand initialValue() + { + return new PackedDecimalOperand(); + } + }; + + private static final ThreadLocal op2_threadLocal = new ThreadLocal() { + protected PackedDecimalOperand initialValue() + { + return new PackedDecimalOperand(); + } + }; + + private static final ThreadLocal sum_threadLocal = new ThreadLocal() { + protected PackedDecimalOperand initialValue() + { + return new PackedDecimalOperand(); + } + }; + + /** + * Checks the validity of a Packed Decimal, return code indicating the status of the Packed Decimal. + * + * @param byteArray + * the source container array + * @param offset + * starting offset of the Packed Decimal + * @param precision + * precision of the Packed Decimal. Maximum valid precision is 253 + * @param ignoreHighNibbleForEvenPrecision + * if true, ignore to check if the top nibble (first 4 bits) of the input is an invalid sign value in the + * case of even precision + * @param canOverwriteHighNibbleForEvenPrecision + * if true, change the high nibble to a zero in case of even precision + * @return the condition code: 0 All digit codes and the sign valid 1 Sign invalid 2 At least one digit code invalid + * 3 Sign invalid and at least one digit code invalid + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static int checkPackedDecimal(byte[] byteArray, int offset, + int precision, boolean ignoreHighNibbleForEvenPrecision, + boolean canOverwriteHighNibbleForEvenPrecision) { + if ((offset + ((precision / 2) + 1) > byteArray.length) || (offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "checkPackedDecimal is trying to access byteArray[" + offset + "] to byteArray[" + (offset + (precision / 2)) + "]" + + " but valid indices are from 0 to " + (byteArray.length - 1) + "."); + + return checkPackedDecimal_(byteArray, offset, precision, + ignoreHighNibbleForEvenPrecision, canOverwriteHighNibbleForEvenPrecision); + } + + private static int checkPackedDecimal_(byte[] byteArray, int offset, + int precision, boolean ignoreHighNibbleForEvenPrecision, + boolean canOverwriteHighNibbleForEvenPrecision) { + + if (precision < 1) + throw new IllegalArgumentException("Illegal Precision."); + + boolean evenPrecision = precision % 2 == 0 ? true : false; + int signOffset = offset + CommonData.getPackedByteCount(precision) - 1; + + int returnCode = 0; + + if (canOverwriteHighNibbleForEvenPrecision && evenPrecision) { + byteArray[offset] = (byte) (byteArray[offset] & CommonData.LOWER_NIBBLE_MASK); + } + + if (evenPrecision && ignoreHighNibbleForEvenPrecision) + { + if ((byteArray[offset] & CommonData.LOWER_NIBBLE_MASK) > 0x09) + returnCode = 2; + offset++; + } + + // ordinary checking places here: + int i; + for (i = offset; i < signOffset && byteArray[i] == CommonData.PACKED_ZERO; i++) + ; + + for (; i < signOffset; i++) + { + if ((byteArray[i] & CommonData.LOWER_NIBBLE_MASK) > 0x09 || + (byteArray[i] & CommonData.HIGHER_NIBBLE_MASK & 0xFF) > 0x90) + { + returnCode = 2; + break; + } + } + + if (i == signOffset && (byteArray[signOffset] & CommonData.HIGHER_NIBBLE_MASK & 0xFF) > 0x90) + returnCode = 2; + + // Check sign nibble + if ((byteArray[signOffset] & CommonData.LOWER_NIBBLE_MASK) < 0x0A) + { + returnCode++; + } + return returnCode; + } + + // Assuming canOverwriteMostSignificantEvenNibble == false + /** + * Checks the validity of a Packed Decimal, return code indicating the status of the Packed Decimal. The most + * significant nibble cannot be overwritten. + * + * @param byteArray + * the source container array + * @param offset + * starting offset of the Packed Decimal + * @param precision + * precision of the Packed Decimal + * @param ignoreHighNibbleForEvenPrecision + * if true, ignore the high nibble in the case of even precision + * @return the condition code: 0 All digit codes and the sign valid 1 Sign invalid 2 At least one digit code invalid + * 3 Sign invalid and at least one digit code invalid + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static int checkPackedDecimal(byte[] byteArray, int offset, + int precision, boolean ignoreHighNibbleForEvenPrecision) { + return checkPackedDecimal(byteArray, offset, precision, + ignoreHighNibbleForEvenPrecision, false); + } + + // Assuming canOverwriteMostSignificantEvenNibble == false + /** + * Checks the validity of a Packed Decimal, return code indicating the status of the Packed Decimal. Don't ignore + * the most significant nibble. The most significant nibble cannot be overwritten. + * + * @param byteArray + * the source container array + * @param offset + * starting offset of the Packed Decimal + * @param precision + * precision of the Packed Decimal + * @return the condition code: 0 All digit codes and the sign valid 1 Sign invalid 2 At least one digit code invalid + * 3 Sign invalid and at least one digit code invalid + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static int checkPackedDecimal(byte[] byteArray, int offset, + int precision) { + return checkPackedDecimal(byteArray, offset, precision, false, false); + } + + private static void copyRemainingDigits(PackedDecimalOperand op1, + PackedDecimalOperand op2, boolean checkOverflow) + throws ArithmeticException { + PackedDecimalOperand sum = sum_threadLocal.get(); + + int bytes; + // copy any high order digits left in larger value to result + if (op1.currentOffset >= op1.offset) { + + bytes = op1.currentOffset - op1.offset + 1; + int sumBytes = sum.currentOffset - sum.offset + 1; + if (bytes >= sumBytes) { + if (checkOverflow && bytes > sumBytes) + throw new ArithmeticException( + "Decimal overflow during addition/subtraction."); + else + bytes = sum.currentOffset - sum.offset + 1; + sum.currentOffset = sum.currentOffset - bytes + 1; + op1.currentOffset += -bytes + 1; + System.arraycopy(op1.byteArray, op1.currentOffset, + sum.byteArray, sum.currentOffset, bytes); + if (sum.precision % 2 == 0) { + byte highNibble = (byte) (sum.byteArray[sum.currentOffset] & CommonData.HIGHER_NIBBLE_MASK); + if (checkOverflow && bytes == sumBytes + && highNibble != 0x00) + throw new ArithmeticException( + "Decimal overflow during addition/subtraction."); + else + sum.byteArray[sum.currentOffset] &= CommonData.LOWER_NIBBLE_MASK; + } + } else { + sum.currentOffset = sum.currentOffset - bytes + 1; + System.arraycopy(op1.byteArray, op1.offset, sum.byteArray, + sum.currentOffset, bytes); + } + sum.currentOffset--; + + } + // pad high order result bytes with zeros + if (sum.currentOffset >= sum.offset) { + bytes = sum.currentOffset - sum.offset + 1; + Arrays.fill(sum.byteArray, sum.offset, sum.offset + bytes, CommonData.PACKED_ZERO); + } + } + + /** + * Add two Packed Decimals in byte arrays. The sign of an input Packed Decimal is assumed to be positive unless + * the sign nibble contains one of the negative sign codes, in which case the sign of the respective input Packed + * Decimal is interpreted as negative. + * + * @param result + * byte array that will hold the sum of the two operand Packed Decimals + * @param resultOffset + * offset into result where the sum Packed Decimal begins + * @param resultPrecision + * number of Packed Decimal digits for the sum. Maximum valid precision is 253 + * @param op1Decimal + * byte array that holds the first operand Packed Decimal. + * @param op1Offset + * offset into op1Decimal where the Packed Decimal. is located + * @param op1Precision + * number of Packed Decimal digits for the first operand. Maximum valid precision is 253 + * @param op2Decimal + * byte array that holds the second operand Packed Decimal + * @param op2Offset + * offset into op2Decimal where the Packed Decimal is located + * @param op2Precision + * number of Packed Decimal digits for the second operand. Maximum valid precision is 253 + * @param checkOverflow + * check for overflow + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if an overflow occurs during the computation of the sum + */ + public static void addPackedDecimal(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision, boolean checkOverflow) throws ArithmeticException { + if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "addPackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + + " but valid indices are from 0 to " + (result.length - 1) + "."); + + if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "addPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "addPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + addPackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, + op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); + } + + private static void addPackedDecimal_(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision, boolean checkOverflow) throws ArithmeticException { + // capture result type information + sum_threadLocal.get().setSumOperand(result, resultOffset, + resultPrecision); + // ignore leading zeros in operand values + op1_threadLocal.get().setOperand(op1Decimal, op1Offset, op1Precision); + op2_threadLocal.get().setOperand(op2Decimal, op2Offset, op2Precision); + // add values + computeValue(checkOverflow); + } + + /** + * Subtracts two Packed Decimals in byte arrays. The sign of an input Packed Decimal is assumed to be positive + * unless the sign nibble contains one of the negative sign codes, in which case the sign of the respective input + * Packed Decimal is interpreted as negative. + * + * @param result + * byte array that will hold the difference of the two operand Packed Decimals + * @param resultOffset + * offset into result where the result Packed Decimal is located + * @param resultPrecision + * number of Packed Decimal digits for the result. Maximum valid precision is 253 + * @param op1Decimal + * byte array that holds the first Packed Decimal operand + * @param op1Offset + * offset into op1Decimal where the first operand is located + * @param op1Precision + * number of Packed Decimal digits for the first operand. Maximum valid precision is 253 + * @param op2Decimal + * byte array that holds the second Packed Decimal operand + * @param op2Offset + * offset into op2Decimal where the second operand is located + * @param op2Precision + * number of Packed Decimal digits for the second operand. Maximum valid precision is 253 + * @param checkOverflow + * check for overflow + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if an overflow occurs during the computation of the difference + */ + public static void subtractPackedDecimal(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision, boolean checkOverflow) throws ArithmeticException { + if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "subtractPackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + + " but valid indices are from 0 to " + (result.length - 1) + "."); + + if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "subtractPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "subtractPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + subtractPackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, + op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); + } + + private static void subtractPackedDecimal_(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision, boolean checkOverflow) throws ArithmeticException { + + PackedDecimalOperand sum = sum_threadLocal.get(); + PackedDecimalOperand op1 = op1_threadLocal.get(); + PackedDecimalOperand op2 = op2_threadLocal.get(); + + // capture result type information + sum.setSumOperand(result, resultOffset, resultPrecision); + // ignore leading zeros in operand values + op1.setOperand(op1Decimal, op1Offset, op1Precision); + op2.setOperand(op2Decimal, op2Offset, op2Precision); + // change op2 sign for subtraction + if ((op2.sign & CommonData.LOWER_NIBBLE_MASK) == CommonData.PACKED_PLUS) + op2.sign = (op2.sign & CommonData.HIGHER_NIBBLE_MASK) + | CommonData.PACKED_MINUS; + else + op2.sign = (op2.sign & CommonData.HIGHER_NIBBLE_MASK) + | CommonData.PACKED_PLUS; + // add values + computeValue(checkOverflow); + } + + /** + * Create a positive Packed Decimal representation of zero. + * + * @param byteArray + * byte array which will hold the packed zero + * @param offset + * offset into toBytes where the packed zero begins + * @param len + * length of the packed zero. Maximum valid length is 253 + * + * @throws NullPointerException + * if toBytes is null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static void setPackedZero(byte[] byteArray, int offset, int len) { + int byteLen = CommonData.getPackedByteCount(len); + Arrays.fill(byteArray, offset, offset + byteLen - 1, CommonData.PACKED_ZERO); + byteArray[offset + byteLen - 1] = CommonData.PACKED_PLUS; + } + + private static void computeSum(PackedDecimalOperand op1, + PackedDecimalOperand op2, boolean checkOverflow) + throws ArithmeticException { + + PackedDecimalOperand sum = sum_threadLocal.get(); + + boolean carry;// add op2 sign digit to op1 sign digit + sum.indexValue = ((op1.signDigit + op2.signDigit) << 1) & 0x3FF; + sum.byteValue = CommonData.getPackedSumValues(sum.indexValue); + carry = sum.byteValue < op1.signDigit; + sum.byteArray[sum.signOffset] = (byte) (sum.byteValue | (op1.sign & CommonData.LOWER_NIBBLE_MASK)); + + // add op2 digits to op1 digits + for (; op2.currentOffset >= op2.offset + && sum.currentOffset >= sum.offset; op2.currentOffset -= 1, op1.currentOffset -= 1, sum.currentOffset -= 1) { + if (checkOverflow && sum.currentOffset < sum.offset) { + throw new ArithmeticException( + "Decimal overflow in addPackedDecimal."); + } + ; + op1.byteValue = op1.byteArray[op1.currentOffset] + & CommonData.INTEGER_MASK; + op2.byteValue = op2.byteArray[op2.currentOffset] + & CommonData.INTEGER_MASK; + op1.indexValue = op1.byteValue + + (op1.byteValue & CommonData.HIGHER_NIBBLE_MASK); + op2.indexValue = op2.byteValue + + (op2.byteValue & CommonData.HIGHER_NIBBLE_MASK); + sum.indexValue = op1.indexValue + op2.indexValue; + if (carry) + sum.byteValue = CommonData + .getPackedSumPlusOneValues(sum.indexValue); + else + sum.byteValue = CommonData.getPackedSumValues(sum.indexValue); + carry = (sum.byteValue & CommonData.INTEGER_MASK) < ((op1.byteValue & CommonData.INTEGER_MASK) + (op2.byteValue & CommonData.INTEGER_MASK)); + sum.byteArray[sum.currentOffset] = (byte) (sum.byteValue); + } + // if carry, add one to remaining high order digits from op1 + for (; carry && op1.currentOffset >= op1.offset + && sum.currentOffset >= sum.offset; op1.currentOffset -= 1, sum.currentOffset -= 1) { + if (checkOverflow && sum.currentOffset < sum.offset) { + throw new ArithmeticException( + "Decimal overflow in addPackedDecimal"); + } + sum.byteValue = CommonData + .getPackedAddOneValues(op1.byteArray[op1.currentOffset]) + & CommonData.INTEGER_MASK; + carry = (sum.byteValue == 0x00); + sum.byteArray[sum.currentOffset] = (byte) (sum.byteValue); + } + if (sum.currentOffset < sum.offset) // reached the end + { + if ((carry && checkOverflow) + || (checkOverflow && op1.currentOffset >= op1.offset)) + throw new ArithmeticException( + "Decimal overflow in addPackedDecimal"); + else if (sum.precision % 2 == 0) { + if ((byte) (sum.byteArray[sum.offset] & CommonData.HIGHER_NIBBLE_MASK) > (byte) 0x00 + && checkOverflow) + throw new ArithmeticException( + "Decimal overflow in addPackedDecimal"); + sum.byteArray[sum.offset] &= CommonData.LOWER_NIBBLE_MASK; + } + return; + } + // if still carry, add high order one to sum + if (carry) { // carry + sum.byteArray[sum.currentOffset] = 1; + sum.currentOffset -= 1; + } + // copy any remaining digits + copyRemainingDigits(op1, op2, checkOverflow); + } + + private static void computeDifference(PackedDecimalOperand op1, + PackedDecimalOperand op2, boolean checkOverflow) + throws ArithmeticException { + + PackedDecimalOperand sum = sum_threadLocal.get(); + + boolean borrow; + // compute difference from sign byte + borrow = op1.signDigit < op2.signDigit; + + sum.byteValue = Math.abs((op1.signDigit >> 4) - (op2.signDigit >> 4) + + 10) % 10; + sum.byteArray[sum.signOffset] = (byte) ((sum.byteValue << 4) | (op1.sign & CommonData.LOWER_NIBBLE_MASK)); + + // compute op1 digit values - op2 digit values ; + for (op2.currentOffset = op2.signOffset - 1, op1.currentOffset = op1.signOffset - 1; op2.currentOffset >= op2.offset + && sum.currentOffset >= sum.offset; op2.currentOffset -= 1, op1.currentOffset -= 1, sum.currentOffset -= 1) { + if (checkOverflow && sum.currentOffset < sum.offset) { + throw new ArithmeticException( + "Decimal overflow in subtractPackedDecimal"); + } + + op1.byteValue = op1.byteArray[op1.currentOffset] + & CommonData.INTEGER_MASK; + op2.byteValue = op2.byteArray[op2.currentOffset] + & CommonData.INTEGER_MASK; + op1.indexValue = op1.byteValue + + (op1.byteValue & CommonData.HIGHER_NIBBLE_MASK); + op2.indexValue = op2.byteValue + + (op2.byteValue & CommonData.HIGHER_NIBBLE_MASK); + sum.indexValue = (op1.indexValue - op2.indexValue) & 0x3FF; + if (borrow) + sum.byteValue = CommonData + .getPackedDifferenceMinusOneValues(sum.indexValue); + else + sum.byteValue = CommonData + .getPackedDifferenceValues(sum.indexValue); + borrow = (sum.byteValue & CommonData.INTEGER_MASK) > ((op1.byteValue & CommonData.INTEGER_MASK) - (op2.byteValue & CommonData.INTEGER_MASK)); + if (sum.currentOffset >= sum.offset) + sum.byteArray[sum.currentOffset] = (byte) (sum.byteValue); + } + // if borrow, subtract one from remaining high order digits + for (; borrow && op1.currentOffset >= op1.offset + && sum.currentOffset >= sum.offset; op1.currentOffset -= 1, sum.currentOffset -= 1) { + if (checkOverflow && sum.currentOffset < sum.offset) { + throw new ArithmeticException( + "Decimal overflow in subtractPackedDecimal"); + } + sum.byteValue = CommonData + .getPackedBorrowOneValues(op1.byteArray[op1.currentOffset]) + & CommonData.INTEGER_MASK; + borrow = (sum.byteValue == 0x99); + if (sum.currentOffset >= sum.offset) + sum.byteArray[sum.currentOffset] = (byte) (sum.byteValue); + } + + copyRemainingDigits(op1, op2, checkOverflow); + } + + private static void computeValue(boolean checkOverflow) + throws ArithmeticException { + + PackedDecimalOperand sum = sum_threadLocal.get(); + PackedDecimalOperand op1 = op1_threadLocal.get(); + PackedDecimalOperand op2 = op2_threadLocal.get(); + + if ((op1.sign & CommonData.LOWER_NIBBLE_MASK) == (op2.sign & CommonData.LOWER_NIBBLE_MASK)) { + // signs are same, compute sum of values + // add less bytes to more bytes + if (op1.bytes < op2.bytes) + computeSum(op2, op1, checkOverflow); + else + computeSum(op1, op2, checkOverflow); + } else { // signs are different, compute difference of values + // subtract smaller value from larger value so we will always + // have one to borrow + if (op1.bytes < op2.bytes) + computeDifference(op2, op1, checkOverflow); // op2 has more + // non-zero bytes + else if (op1.bytes > op2.bytes) + computeDifference(op1, op2, checkOverflow); // op2 has more + // non-zero bytes + else { + // compare values to find which is larger. + // adjust offsets at same time - difference between equal bytes + // is 0 + findDifference: { + for (; op1.offset < op1.signOffset; op1.offset += 1, op2.offset += 1) { + op1.byteValue = op1.byteArray[op1.offset]; + op2.byteValue = op2.byteArray[op2.offset]; + if (op1.byteValue != op2.byteValue) + break findDifference; + } + op1.byteValue = op1.byteArray[op1.offset] + & CommonData.HIGHER_NIBBLE_MASK; + op2.byteValue = op2.byteArray[op2.offset] + & CommonData.HIGHER_NIBBLE_MASK; + if (op1.byteValue == op2.byteValue) { + // values are equal, difference is zero + setPackedZero(sum.byteArray, sum.offset, sum.precision); + return; + } + } + if ((op1.byteValue & CommonData.INTEGER_MASK) > (op2.byteValue & CommonData.INTEGER_MASK)) + computeDifference(op1, op2, checkOverflow); + else + computeDifference(op2, op1, checkOverflow); + } + } + } + + // The implementations of multiply, divide and remainder are based on + // BigDecimal + // for simplicity and also because it has been shown that they have + // acceptable performance. + + private static final int MULTIPLY = 1, DIVIDE = 2, REMAINDER = 3; + + /** + * Multiplies two Packed Decimals in byte arrays. The sign of an input Packed Decimal is assumed to be positive + * unless the sign nibble contains one of the negative sign codes, in which case the sign of the respective input + * Packed Decimal is interpreted as negative. + * + * @param result + * byte array that will hold the product Packed Decimal + * @param resultOffset + * offset into result where the product Packed Decimal is located + * @param resultPrecision + * the length (number of digits) of the product Packed Decimal. Maximum valid precision is 253 + * @param op1Decimal + * byte array that will hold the multiplicand Packed Decimal + * @param op1Offset + * offset into op1Decimal where the multiplicand is located + * @param op1Precision + * the length (number of digits) of the multiplicand Packed Decimal. Maximum valid precision is 253 + * @param op2Decimal + * byte array that will hold the multiplier + * @param op2Offset + * offset into op2Decimal where the multiplier is located + * @param op2Precision + * the length (number of digits) of the multiplier Packed Decimal. Maximum valid precision is 253 + * @param checkOverflow + * if set to true, Packed Decimals are validated before multiplication and an + * IllegalArgumentException or ArithmeticException may be thrown. If not, the + * result can be invalid + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws IllegalArgumentException + * if an overflow occurs during multiplication + * @throws ArithmeticException + * if any of the Packed Decimal operands are invalid + */ + public static void multiplyPackedDecimal(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, // multiplicand + byte[] op2Decimal, int op2Offset, int op2Precision, // multiplier + boolean checkOverflow) { + if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "multiplyPackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + + " but valid indices are from 0 to " + (result.length - 1) + "."); + + if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "multiplyPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "multiplyPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + multiplyPackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, + op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); + } + + private static void multiplyPackedDecimal_(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, // multiplicand + byte[] op2Decimal, int op2Offset, int op2Precision, // multiplier + boolean checkOverflow) { + packedDecimalBinaryOp(MULTIPLY, result, resultOffset, resultPrecision, + op1Decimal, op1Offset, op1Precision, op2Decimal, op2Offset, + op2Precision, checkOverflow); + } + + /** + * Divides two Packed Decimals is byte arrays. The sign of an input Packed Decimal is assumed to be positive + * unless the sign nibble contains one of the negative sign codes, in which case the sign of the respective input + * Packed Decimal is interpreted as negative. + * + * @param result + * byte array that will hold the quotient Packed Decimal + * @param resultOffset + * offset into result where the quotient Packed Decimal is located + * @param resultPrecision + * the length (number of digits) of the quotient Packed Decimal. Maximum valid precision is 253 + * @param op1Decimal + * byte array that will hold the dividend Packed Decimal + * @param op1Offset + * offset into op1Decimal where the dividend is located + * @param op1Precision + * the length (number of digits) of the dividend Packed Decimal. Maximum valid precision is 253 + * @param op2Decimal + * byte array that will hold the divisor + * @param op2Offset + * offset into op2Decimal where the divisor is located + * @param op2Precision + * the length (number of digits) of the divisor Packed Decimal. Maximum valid precision is 253 + * @param checkOverflow + * if set to true, Packed Decimals are validated before division and an + * IllegalArgumentException or ArithmeticException may be thrown. If not, the + * result can be invalid + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws IllegalArgumentException + * if an overflow occurs during division + * @throws ArithmeticException + * if any of the Packed Decimal operands are invalid + */ + public static void dividePackedDecimal(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision, boolean checkOverflow) { + if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "dividePackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + + " but valid indices are from 0 to " + (result.length - 1) + "."); + + if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "dividePackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "dividePackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + dividePackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, + op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); + } + + private static void dividePackedDecimal_(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision, boolean checkOverflow) { + packedDecimalBinaryOp(DIVIDE, result, resultOffset, resultPrecision, + op1Decimal, op1Offset, op1Precision, op2Decimal, op2Offset, + op2Precision, checkOverflow); + + } + + /** + * Calculates the remainder resulting from the division of two Packed Decimals in byte arrays. The sign of an input + * Packed Decimal is assumed to be positive unless the sign nibble contains one of the negative sign codes, in + * which case the sign of the respective input Packed Decimal is interpreted as negative. + * + * @param result + * byte array that will hold the remainder Packed Decimal + * @param resultOffset + * offset into result where the remainder Packed Decimal is located + * @param resultPrecision + * number of Packed Decimal digits for the remainder. Maximum valid precision is 253 + * @param op1Decimal + * byte array that will hold the dividend Packed Decimal + * @param op1Offset + * offset into op1Decimal where the dividend is located + * @param op1Precision + * number of Packed Decimal digits for the dividend. Maximum valid precision is 253 + * @param op2Decimal + * byte array that will hold the divisor + * @param op2Offset + * offset into op2Decimal where the divisor is located + * @param op2Precision + * number of Packed Decimal digits for the divisor. Maximum valid precision is 253 + * @param checkOverflow + * if set to true, Packed Decimals are validated before division and an + * IllegalArgumentException or ArithmeticException may be thrown. If not, the + * result can be invalid + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws IllegalArgumentException + * if an overflow occurs during division + * @throws ArithmeticException + * if any of the Packed Decimal operands are invalid + */ + public static void remainderPackedDecimal(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision, boolean checkOverflow) { + if ((resultOffset + ((resultPrecision / 2) + 1) > result.length) || (resultOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "remainderPackedDecimal is trying to access result[" + resultOffset + "] to result[" + (resultOffset + (resultPrecision / 2)) + "]" + + " but valid indices are from 0 to " + (result.length - 1) + "."); + + if ((op1Offset < 0) || (op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "remainderPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "remainderPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + remainderPackedDecimal_(result, resultOffset, resultPrecision, op1Decimal, op1Offset, + op1Precision, op2Decimal, op2Offset, op2Precision, checkOverflow); + } + private static void remainderPackedDecimal_(byte[] result, int resultOffset, + int resultPrecision, byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision, boolean checkOverflow) { + packedDecimalBinaryOp(REMAINDER, result, resultOffset, resultPrecision, + op1Decimal, op1Offset, op1Precision, op2Decimal, op2Offset, + op2Precision, checkOverflow); + } + + private static BigInteger getBigInteger(byte[] pd, int offset, int length) { + int end = offset + length - 1; + StringBuilder sb = new StringBuilder(); + + if ((pd[end] & CommonData.LOWER_NIBBLE_MASK) == 0x0B + || (pd[end] & CommonData.LOWER_NIBBLE_MASK) == 0x0D) + sb.append('-'); + + for (int i = offset; i < end; i++) { + sb.append((char) ('0' + (pd[i] >> 4 & CommonData.LOWER_NIBBLE_MASK))); + sb.append((char) ('0' + (pd[i] & CommonData.LOWER_NIBBLE_MASK))); + } + sb.append((char) ('0' + (pd[end] >> 4 & CommonData.LOWER_NIBBLE_MASK))); + return new BigInteger(sb.toString()); + } + + private static void putBigInteger(byte[] pd, int offset, int length, + BigInteger bigInt, boolean checkOverflow) + throws ArithmeticException { + int end = offset + length - 1; + + // could use abs(), but want to avoid creating another BigInteger object + char[] chars = bigInt.toString().toCharArray(); + boolean neg = chars[0] == '-'; + + int charStart = neg ? 1 : 0; + int charEnd = chars.length - 1; + + pd[end--] = (byte) ((neg ? 0x0D : 0x0C) | ((chars[charEnd--] - '0') << 4)); + + while (end >= offset) { + byte b = 0; + if (charEnd >= charStart) { + b = (byte) (chars[charEnd--] - '0'); + if (charEnd >= charStart) { + b |= (byte) ((chars[charEnd--] - '0') << 4); + } + } + pd[end--] = b; + } + + if (checkOverflow && charEnd < charStart) { + while (charEnd >= charStart) { + if (chars[charEnd--] != '0') { + throw new ArithmeticException( + "Packed Decimal overflow during multiplication/division, non-zero digits lost"); + } + } + } + } + + private static void zeroTopNibbleIfEven(byte[] bytes, int offset, int prec) { + if (prec % 2 == 0) + bytes[offset] &= CommonData.LOWER_NIBBLE_MASK; + } + + private static void packedDecimalBinaryOp(int op, byte[] result, + int offsetResult, int precResult, byte[] op1, int op1Offset, + int precOp1, byte[] op2, int op2Offset, int precOp2, + boolean checkOverflow) { + + zeroTopNibbleIfEven(op1, op1Offset, precOp1); + zeroTopNibbleIfEven(op2, op2Offset, precOp2); + + // check for long + switch (op) { + case MULTIPLY: + if (precOp1 + precOp2 <= 18 && precResult <= 18) { + long op1long = DecimalData.convertPackedDecimalToLong(op1, + op1Offset, precOp1, checkOverflow); + long op2long = DecimalData.convertPackedDecimalToLong(op2, + op2Offset, precOp2, checkOverflow); + long resultLong = op1long * op2long; + DecimalData.convertLongToPackedDecimal(resultLong, result, + offsetResult, precResult, checkOverflow); + if (resultLong == 0) + forceSign(result, offsetResult, precResult, op1, op1Offset, + precOp1, op2, op2Offset, precOp2); + return; + } + break; + case DIVIDE: + case REMAINDER: + if (precOp1 <= 18 && precOp2 <= 18 && precResult <= 18) { + long op1long = DecimalData.convertPackedDecimalToLong(op1, + op1Offset, precOp1, checkOverflow); + long op2long = DecimalData.convertPackedDecimalToLong(op2, + op2Offset, precOp2, checkOverflow); + long resultLong; + if (op == DIVIDE) + resultLong = op1long / op2long; + else + resultLong = op1long % op2long; + DecimalData.convertLongToPackedDecimal(resultLong, result, + offsetResult, precResult, checkOverflow); + if (resultLong == 0) + forceSign(result, offsetResult, precResult, op1, op1Offset, + precOp1, op2, op2Offset, precOp2); + return; + } + break; + } + + // long is too small + BigInteger op1BigInt; + BigInteger op2BigInt; + try { + op1BigInt = getBigInteger(op1, op1Offset, + precisionToByteLength(precOp1)); + op2BigInt = getBigInteger(op2, op2Offset, + precisionToByteLength(precOp2)); + } catch (NumberFormatException e) { + if (checkOverflow) + throw new IllegalArgumentException("Invalid packed data value", + e); + return; + } + + BigInteger resultBigInt = null; + switch (op) { + case MULTIPLY: + resultBigInt = op1BigInt.multiply(op2BigInt); + break; + case DIVIDE: + resultBigInt = op1BigInt.divide(op2BigInt); + break; + case REMAINDER: + resultBigInt = op1BigInt.remainder(op2BigInt); + break; + } + + putBigInteger(result, offsetResult, precisionToByteLength(precResult), + resultBigInt, checkOverflow); + + // force the sign because BigInteger will never produce negative zero + if (BigInteger.ZERO.equals(resultBigInt)) { + forceSign(result, offsetResult, precResult, op1, op1Offset, + precOp1, op2, op2Offset, precOp2); + } + } + + /** + * Using BigInteger or long will never produce negative zero, so we need to + * make sure to set the correct sign code. + */ + private static void forceSign(byte[] result, int offsetResult, + int precResult, byte[] op1, int op1Offset, int precOp1, byte[] op2, + int op2Offset, int precOp2) { + + int endOp1 = op1Offset + precisionToByteLength(precOp1) - 1; + int endOp2 = op2Offset + precisionToByteLength(precOp2) - 1; + int endResult = offsetResult + precisionToByteLength(precResult) - 1; + result[endResult] |= 0x0F; + result[endResult] &= signMask(op1[endOp1], op2[endOp2]); + } + + private static int precisionToByteLength(int precision) { + return (precision + 2) / 2; + } + + private static byte signMask(byte a, byte b) { + return (byte) (sign(a) * sign(b) > 0 ? 0xFC : 0xFD); + } + + private static int sign(byte b) { + return (CommonData.getSign(b & CommonData.LOWER_NIBBLE_MASK) == CommonData.PACKED_MINUS) ? -1 : 1; + } + + /** + * Checks if the first Packed Decimal operand is lesser than the second one. + * + * @param op1Decimal + * byte array that holds the first Packed Decimal operand + * @param op1Offset + * offset into op1Decimal where the first operand is located + * @param op1Precision + * number of Packed Decimal digits for the first operand + * @param op2Decimal + * byte array that holds the second Packed Decimal operand + * @param op2Offset + * offset into op2Decimal where the second operand is located + * @param op2Precision + * number of Packed Decimal digits for the second operand + * + * @return true if op1Decimal < op2Decimal, false otherwise + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static boolean lessThanPackedDecimal(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "lessThanPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "lessThanPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + return lessThanPackedDecimal_(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + } + + private static boolean lessThanPackedDecimal_(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + + return greaterThanPackedDecimal_(op2Decimal, op2Offset, op2Precision, op1Decimal, + op1Offset, op1Precision); + } + + /** + * Checks if the first Packed Decimal operand is less than or equal to the second one. + * + * @param op1Decimal + * byte array that holds the first Packed Decimal operand + * @param op1Offset + * offset into op1Decimal where the first operand is located + * @param op1Precision + * number of Packed Decimal digits for the first operand + * @param op2Decimal + * byte array that holds the second Packed Decimal operand + * @param op2Offset + * offset into op2Decimal where the second operand is located + * @param op2Precision + * number of Packed Decimal digits for the second operand + * + * @return true if op1Decimal <= op2Decimal, false otherwise + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static boolean lessThanOrEqualsPackedDecimal(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "lessThanOrEqualsPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "lessThanOrEqualsPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + return lessThanOrEqualsPackedDecimal_(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + + } + + private static boolean lessThanOrEqualsPackedDecimal_(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + return !greaterThanPackedDecimal_(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + } + + /** + * Checks if the first Packed Decimal operand is greater than the second one. + * + * @param op1Decimal + * byte array that holds the first Packed Decimal operand + * @param op1Offset + * offset into op1Decimal where the first operand is located + * @param op1Precision + * number of Packed Decimal digits for the first operand + * @param op2Decimal + * byte array that holds the second Packed Decimal operand + * @param op2Offset + * offset into op2Decimal where the second operand is located + * @param op2Precision + * number of Packed Decimal digits for the second operand + * + * @return true if op1Decimal > op2Decimal, false otherwise + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static boolean greaterThanPackedDecimal(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "greaterThanPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "greaterThanPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + return greaterThanPackedDecimal_(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + } + + private static boolean greaterThanPackedDecimal_(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + + if (op1Precision < 1 || op2Precision < 1) + throw new IllegalArgumentException("Invalid Precision for an operand"); + + //boolean result = false; + int op1End = op1Offset + precisionToByteLength(op1Precision) - 1; + int op2End = op2Offset + precisionToByteLength(op2Precision) - 1; + + //check signs, if a different signs we're done! + byte op1Sign = CommonData.getSign((byte)(op1Decimal[op1End] & CommonData.LOWER_NIBBLE_MASK)); + byte op2Sign = CommonData.getSign((byte)(op2Decimal[op2End] & CommonData.LOWER_NIBBLE_MASK)); + + boolean isNegative = (op1Sign == CommonData.PACKED_MINUS) ? true : false; + + //skip leading zeros + for (; op1Offset < op1End && op1Decimal[op1Offset] == CommonData.PACKED_ZERO; op1Offset++) + ; + for (; op2Offset < op2End && op2Decimal[op2Offset] == CommonData.PACKED_ZERO; op2Offset++) + ; + + int op1Length = op1End - op1Offset; + int op2Length = op2End - op2Offset; + + if (op1Length + op2Length == 0) + { + int op1LastDigit = (op1Decimal[op1Offset] >> 4) & CommonData.LOWER_NIBBLE_MASK; + int op2LastDigit = (op2Decimal[op2Offset] >> 4) & CommonData.LOWER_NIBBLE_MASK; + if (op1LastDigit + op2LastDigit == 0) //both zeros + return false; + if (op1Sign < op2Sign) + return true; + else if (op1Sign > op2Sign) + return false; + if ((op1LastDigit > op2LastDigit && !isNegative) || (op1LastDigit < op2LastDigit && isNegative)) + return true; + + return false; + } + + if (op1Sign < op2Sign) + return true; + else if (op1Sign > op2Sign) + return false; + + if ((op1Length > op2Length && !isNegative) || (op1Length < op2Length && isNegative)) + return true; + else if ((op1Length < op2Length && !isNegative) || (op1Length > op2Length && isNegative)) + return false; + + while(op1Offset < op1End && op2Offset < op2End) + { + int op1Byte = (op1Decimal[op1Offset] & 0xFF); + int op2Byte = (op2Decimal[op2Offset] & 0xFF); + int opDiff = op1Byte - op2Byte; + + if ((opDiff < 0 && !isNegative) || (opDiff > 0 && isNegative)) + return false; + else if ((opDiff > 0 && !isNegative) || (opDiff < 0 && isNegative)) + return true; + + op1Offset++; + op2Offset++; + } + //last digit + int op1LastDigit = (op1Decimal[op1Offset] >> 4) & CommonData.LOWER_NIBBLE_MASK; + int op2LastDigit = (op2Decimal[op2Offset] >> 4) & CommonData.LOWER_NIBBLE_MASK; + + if ((op1LastDigit > op2LastDigit && !isNegative) || (op1LastDigit < op2LastDigit && isNegative)) + return true; + + return false; //either equal or less than + + } + + /** + * Checks if the first Packed Decimal operand is greater than or equal to the second one. + * + * @param op1Decimal + * byte array that holds the first Packed Decimal operand + * @param op1Offset + * offset into op1Decimal where the first operand is located + * @param op1Precision + * number of Packed Decimal digits for the first operand + * @param op2Decimal + * byte array that holds the second Packed Decimal operand + * @param op2Offset + * offset into op2Decimal where the second operand is located + * @param op2Precision + * number of Packed Decimal digits for the second operand + * + * @return true if op1Decimal >= op2Decimal, false otherwise + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static boolean greaterThanOrEqualsPackedDecimal(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "greaterThanOrEqualsPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "greaterThanOrEqualsPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + return greaterThanOrEqualsPackedDecimal_(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + } + + private static boolean greaterThanOrEqualsPackedDecimal_(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + return !lessThanPackedDecimal_(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + } + + /** + * Checks if the two Packed Decimal operands are equal. + * + * @param op1Decimal + * byte array that holds the first Packed Decimal operand + * @param op1Offset + * offset into op1Decimal where the first operand is located + * @param op1Precision + * number of Packed Decimal digits for the first operand + * @param op2Decimal + * byte array that holds the second Packed Decimal operand + * @param op2Offset + * offset into op2Decimal where the second operand is located + * @param op2Precision + * number of Packed Decimal digits for the second operand + * + * @return true if op1Decimal == op2Decimal, false otherwise + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static boolean equalsPackedDecimal(byte[] op1Decimal, int op1Offset, + int op1Precision, byte[] op2Decimal, int op2Offset, int op2Precision) { + if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "equalsPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "equalsPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + return equalsPackedDecimal_(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + } + + private static boolean equalsPackedDecimal_(byte[] op1Decimal, int op1Offset, int op1Precision, + byte[] op2Decimal, int op2Offset, int op2Precision) { + if (op1Precision < 1 || op2Precision < 1) + throw new IllegalArgumentException("Invalid Precision for an operand"); + + int op1End = op1Offset + precisionToByteLength(op1Precision) - 1; + int op2End = op2Offset + precisionToByteLength(op2Precision) - 1; + + byte op1Sign = CommonData.getSign((byte) (op1Decimal[op1End] & CommonData.LOWER_NIBBLE_MASK)); + byte op2Sign = CommonData.getSign((byte) (op2Decimal[op2End] & CommonData.LOWER_NIBBLE_MASK)); + + boolean op1IsEven = op1Precision % 2 == 0; + boolean op2IsEven = op2Precision % 2 == 0; + + // Must handle the +0 and -0 case + if (op1Sign != op2Sign) + return checkZeroBetweenOpOffsetAndOpEnd (op1Decimal, op1Offset, op1End, op1IsEven, true) && + checkZeroBetweenOpOffsetAndOpEnd (op2Decimal, op2Offset, op2End, op2IsEven, true); + + // Check if least significant digit is different + if ((op1Decimal[op1End] & CommonData.HIGHER_NIBBLE_MASK) != + (op2Decimal[op2End] & CommonData.HIGHER_NIBBLE_MASK)) { + return false; + } + + // Avoid decrementing if op1End == op1Offset || op2End == op2Offset + if (op1End > op1Offset && op2End > op2Offset) { + op1End--; + op2End--; + } + + while (op1End > op1Offset && op2End > op2Offset) { + // Check if intermediate digits are different + if (op1Decimal[op1End] != op2Decimal[op2End]) + return false; + + op1End--; + op2End--; + } + + // At this point it is true that op1End == op1Offset || op2End == op2Offset + if (op1End == op1Offset) { + if (op1IsEven) { + // Check if most significant digit is different + if ((op1Decimal[op1End] & CommonData.LOWER_NIBBLE_MASK) == + (op2Decimal[op2End] & CommonData.LOWER_NIBBLE_MASK)) { + return checkZeroBetweenOpOffsetAndOpEnd (op2Decimal, op2Offset, op2End, op2IsEven, !op2IsEven || op2End != op2Offset); + } + } else { + // Check if two most significant digits are different + if (op1Decimal[op1End] == op2Decimal[op2End]) + return checkZeroBetweenOpOffsetAndOpEnd (op2Decimal, op2Offset, op2End, op2IsEven, false); + } + } else { + if (op2IsEven) { + // Check if most significant digit is different + if ((op1Decimal[op1End] & CommonData.LOWER_NIBBLE_MASK) == + (op2Decimal[op2End] & CommonData.LOWER_NIBBLE_MASK)) { + return checkZeroBetweenOpOffsetAndOpEnd (op1Decimal, op1Offset, op1End, op1IsEven, !op1IsEven || op1End != op1Offset); + } + } else { + // Check if two most significant digits are different + if (op1Decimal[op1End] == op2Decimal[op2End]) + return checkZeroBetweenOpOffsetAndOpEnd (op1Decimal, op1Offset, op1End, op1IsEven, false); + } + } + + return false; + } + + /** + * Checks if the Packed Decimal digits between opDecimal[opOffset] and opDecimal[opEnd] + * (inclusive depending on checkHighNibbleAtOpEnd) are all zeros. + * + * @param opDecimal + * byte array that holds the Packed Decimal operand + * @param opOffset + * offset into opDecimal where the first byte of the Packed Decimal is located + * @param opEnd + * offset into opDecimal where the last byte to be checked is located + * @param opIsEven + * boolean is true if the opDecimal has even precision + * @param checkHighNibbleAtOpEnd + * boolean indicates whether the high nibble of opDecimal[opEnd] should be checked that it + * contains a zero. If false, opEnd will be decremented and this will be the new starting point of the + * algorithm which verifies that the remaining Packed Decimal digits are zeros. + * + * @return true if all digits from opOffset to opEnd are zero, false otherwise + * + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + private static boolean checkZeroBetweenOpOffsetAndOpEnd(byte[] opDecimal, int opOffset, int opEnd, boolean opIsEven, boolean checkHighNibbleAtOpEnd) { + if (checkHighNibbleAtOpEnd && (opDecimal[opEnd] & CommonData.HIGHER_NIBBLE_MASK) != 0x00) + return false; + + if (opEnd-- > opOffset) { + // Handle intermediate bytes + while (opEnd > opOffset) { + if (opDecimal[opEnd--] != 0x00) + return false; + } + + // Handle the most significant nibble/byte + if (opIsEven) { + if ((opDecimal[opEnd] & CommonData.LOWER_NIBBLE_MASK) != 0x00) + return false; + } else { + if (opDecimal[opEnd] != 0x00) + return false; + } + } + + return true; + } + + /** + * Checks if the two Packed Decimal operands are unequal. + * + * @param op1Decimal + * byte array that holds the first Packed Decimal operand + * @param op1Offset + * offset into op1Decimal where the first operand is located + * @param op1Precision + * number of Packed Decimal digits for the first operand + * @param op2Decimal + * byte array that holds the second Packed Decimal operand + * @param op2Offset + * offset into op2Decimal where the second operand is located + * @param op2Precision + * number of Packed Decimal digits for the second operand + * + * @return true if op1Decimal != op2Decimal, false otherwise + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + */ + public static boolean notEqualsPackedDecimal(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + if ((op1Offset + ((op1Precision / 2) + 1) > op1Decimal.length) || (op1Offset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "notEqualsPackedDecimal is trying to access op1Decimal[" + op1Offset + "] to op1Decimal[" + (op1Offset + (op1Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op1Decimal.length - 1) + "."); + + if ((op2Offset < 0) || (op2Offset + ((op2Precision / 2) + 1) > op2Decimal.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "notEqualsPackedDecimal is trying to access op2Decimal[" + op2Offset + "] to op2Decimal[" + (op2Offset + (op2Precision / 2)) + "]" + + " but valid indices are from 0 to " + (op2Decimal.length - 1) + "."); + + return notEqualsPackedDecimal_(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + } + + private static boolean notEqualsPackedDecimal_(byte[] op1Decimal, + int op1Offset, int op1Precision, byte[] op2Decimal, int op2Offset, + int op2Precision) { + return !equalsPackedDecimal(op1Decimal, op1Offset, op1Precision, + op2Decimal, op2Offset, op2Precision); + } + + private static void roundUpPackedDecimal(byte[] packedDecimal, int offset, + int end, int precision, int roundingDigit, boolean checkOverflow) { + + packedDecimal[end] = CommonData.getPackedAddOneSignValues(packedDecimal[end]); + + if ((byte) (packedDecimal[end] & CommonData.HIGHER_NIBBLE_MASK) == (byte) 0x00) + { + byte[] addTenArray = { 0x01, packedDecimal[end] }; + addPackedDecimal(packedDecimal, offset, precision, + packedDecimal, offset, precision, addTenArray, 0, 2, + checkOverflow); + } + } + + /** + * In case of a shift operation, this method is called to ensure if the resulting value of the shift is + * zero that it is converted to a positive zero, meaning {0x....0C}. This is done to match the expected + * result in COBOL. + */ + private static void checkIfZero(byte[] packedDecimal, int offset, int end, int precision, boolean isEvenPrecision) { + + if (CommonData.getSign(packedDecimal[end] & CommonData.LOWER_NIBBLE_MASK) != CommonData.PACKED_MINUS) + return; + if (isEvenPrecision && ((packedDecimal[offset] & CommonData.LOWER_NIBBLE_MASK) != 0x00)) + return; + //else if (packedDecimal[offset] != 0x00) + // return; + int i = offset;// + 1; + for (; i < end && packedDecimal[i] == 0x00; i++) ; + if (i < end) + return; + else if ((packedDecimal[end] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) + packedDecimal[end] = CommonData.PACKED_PLUS; + + return; + } + + /** + * Right shift, and optionally round, a Packed Decimal. If the resultant is zero, + * it can either be a positive zero 0x0C or a negative zero 0x0D. + * + * @param destination + * byte array that holds the result of the right shift (and rounding) + * @param destinationOffset + * offset into destination where the result Packed Decimal is located + * @param destinationPrecision + * number of Packed Decimal digits in the destination + * @param source + * byte array that holds the Packed Decimal operand to be right shifted + * @param sourceOffset + * offset into source where the operand is located + * @param sourcePrecision + * number of Packed Decimal digits in the operand + * @param shiftAmount + * amount by which the source will be right shifted + * @param round + * if set to true, causes rounding to occur + * @param checkOverflow + * if set to true, check for overflow + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if a decimal overflow occurs + * @throws IllegalArgumentException + * if the shiftAmount or sourcePrecision parameter is invalid or + * the source packed decimal contains invalid sign or digit code + */ + public static void shiftRightPackedDecimal(byte[] destination, + int destinationOffset, int destinationPrecision, byte[] source, + int sourceOffset, int sourcePrecision, int shiftAmount, + boolean round, boolean checkOverflow) { + + if ((destinationOffset + ((destinationPrecision / 2) + 1) > destination.length) || (destinationOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "shiftRightPackedDecimal is trying to access destinationDecimal[" + destinationOffset + "] to destinationDecimal[" + (destinationOffset + (destinationPrecision / 2)) + "]" + + " but valid indices are from 0 to " + (destination.length - 1) + "."); + + if ((sourceOffset < 0) || (sourceOffset + ((sourcePrecision / 2) + 1) > source.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "shiftRightPackedDecimal is trying to access sourceDecimal[" + sourceOffset + "] to sourceDecimal[" + (sourceOffset + (sourcePrecision / 2)) + "]" + + " but valid indices are from 0 to " + (source.length - 1) + "."); + + shiftRightPackedDecimal_(destination, destinationOffset, destinationPrecision, + source, sourceOffset, sourcePrecision, shiftAmount, + round, checkOverflow); + } + + private static void shiftRightPackedDecimal_(byte[] destination, + int destinationOffset, int destinationPrecision, byte[] source, + int sourceOffset, int sourcePrecision, int shiftAmount, + boolean round, boolean checkOverflow) { + + // Figure out the sign of the source Packed Decimal + int end = sourceOffset + precisionToByteLength(sourcePrecision) - 1; + byte sign = CommonData.getSign(source[end] & CommonData.LOWER_NIBBLE_MASK); + int newDstOffset = destinationOffset; + int newDstPrec = destinationPrecision; + int dstEnd = destinationOffset + + precisionToByteLength(destinationPrecision) - 1; + int highDigit = sourcePrecision - 1; + int lowDigit = 0; + int precDiff = sourcePrecision - destinationPrecision; + ; + int newSrcOffset; + int newSrcEnd; + boolean evenPrecision = sourcePrecision % 2 == 0; + boolean isLeastSigDigitInHighNibble = false; + boolean isMostSigDigitInLowNibble = false; + int roundingDigit = 0; + boolean overRanPD = false; // when the shifting left no digits to copy + + if (destinationPrecision < 1 || sourcePrecision < 1 || shiftAmount < 0) { + throw new IllegalArgumentException( + "Invalid Precisions or shift amount"); + } + + if(checkPackedDecimal_(source, sourceOffset, sourcePrecision, true, false) != 0) { + throw new IllegalArgumentException( + "Invalid sign or digit code in input packed decimal"); + } + + lowDigit += shiftAmount; + precDiff -= shiftAmount; // every time we shift, we lose precision + if (precDiff > 0) // if we still need to lose some precision, take off + // higher digits + { + highDigit -= precDiff; + if (checkOverflow) { + int bytes; + int iter = 0; + if (evenPrecision) { + precDiff--; + iter++; + if ((byte) (source[sourceOffset] & CommonData.LOWER_NIBBLE_MASK) != 0x00) + throw new ArithmeticException( + "Decimal overflow in shiftRightPackedDecimal."); + } + bytes = (precDiff) / 2; + precDiff -= bytes * 2; + + for (int i = 0; i < bytes; i++) { + if (source[i + sourceOffset + iter] != 0x00) + throw new ArithmeticException( + "Decimal overflow in shiftRightPackedDecimal."); + } + + if (precDiff == 1 + && (byte) (source[bytes + sourceOffset] & CommonData.HIGHER_NIBBLE_MASK) != 0x00) + throw new ArithmeticException( + "Decimal overflow in shiftRightPackedDecimal."); + } + } + // add zeros if precDiff < 0, do this at end + int newDifference = (highDigit + 1) - lowDigit; // might want to deal + // with diff = 1 + if (checkOverflow && newDifference < 1) + overRanPD = true; + int highDiff = sourcePrecision - (highDigit + 1); + + if (evenPrecision && newDifference % 2 == 0) // still even + { + if (highDiff % 2 == 0) // both low and high moved even + { + isMostSigDigitInLowNibble = true; // the highest digit is on a + // low nibble + isLeastSigDigitInHighNibble = true; // the lowest digit is on a + // high nibble + newSrcOffset = sourceOffset + (highDiff) / 2; + newSrcEnd = end - (lowDigit) / 2; + } else // high moved odd, low moved odd + { + newSrcOffset = sourceOffset + (highDiff + 1) / 2; + newSrcEnd = end - (lowDigit + 1) / 2; + } + } else if (evenPrecision && newDifference % 2 != 0) { + if (highDiff % 2 != 0) // high moved odd, low moved even + { + isLeastSigDigitInHighNibble = true; + newSrcOffset = sourceOffset + (highDiff + 1) / 2; + newSrcEnd = end - (lowDigit) / 2; + } else // high moved even, low moved odd, perfect scenario + { + isMostSigDigitInLowNibble = true; + newSrcOffset = sourceOffset + (highDiff) / 2; + newSrcEnd = end - (lowDigit + 1) / 2; + } + } else if (!evenPrecision && newDifference % 2 == 0) { + if (highDiff % 2 == 0) // high moved even, low moved odd + { + newSrcOffset = sourceOffset + (highDiff) / 2; + newSrcEnd = end - (lowDigit + 1) / 2; + } else // high moved odd, low moved even + { + isMostSigDigitInLowNibble = true; // get this high nibble + // individually + isLeastSigDigitInHighNibble = true; // get this lower nibble + // individually + newSrcOffset = sourceOffset + (highDiff) / 2; + newSrcEnd = end - (lowDigit) / 2; + } + } else { + if (highDiff % 2 == 0) // both moved even, perfect scenario + { + isLeastSigDigitInHighNibble = true; + newSrcOffset = sourceOffset + (highDiff) / 2; + newSrcEnd = end - (lowDigit) / 2; + } else // both moved odd + { + isMostSigDigitInLowNibble = true; + newSrcOffset = sourceOffset + (highDiff) / 2; + newSrcEnd = end - (lowDigit + 1) / 2; + } + } + + // find rounding digit + if (round && shiftAmount > 0 && newDifference > -1) { + if (isLeastSigDigitInHighNibble) + roundingDigit = (source[newSrcEnd]) + & CommonData.LOWER_NIBBLE_MASK; + else + roundingDigit = (source[newSrcEnd + 1] >> 4) + & CommonData.LOWER_NIBBLE_MASK; + ; + } + + while (precDiff < 0) // deal with dst prec being higher, put leading + // zeros + { + destination[newDstOffset] = 0x00; + if (newDstPrec % 2 == 0 || precDiff == -1) { + if (newDstPrec % 2 == 0) + newDstOffset++; + precDiff++; + newDstPrec--; + + } else if ((precDiff / -2) >= 1) { + precDiff += 2; + newDstPrec -= 2; + newDstOffset++; + } + } + + if (isLeastSigDigitInHighNibble && !overRanPD) // can do arrayCopy, + // instead of individual + // nibbles + { + if (!isMostSigDigitInLowNibble) // just a simple arrayCopy + System.arraycopy(source, newSrcOffset, destination, + newDstOffset, newSrcEnd - newSrcOffset + 1); + else { + destination[newDstOffset] = (byte) ((source[newSrcOffset] & CommonData.LOWER_NIBBLE_MASK)); + newDstOffset++; + newSrcOffset++; + System.arraycopy(source, newSrcOffset, destination, + newDstOffset, newSrcEnd - newSrcOffset + 1); + } + } else if (!overRanPD) // must copy each nibble over + { + int newDstEnd = newDstOffset + precisionToByteLength(newDstPrec) + - 1; + byte shiftByte = newSrcEnd < sourceOffset ? 0x00 : source[newSrcEnd]; + destination[newDstEnd] = (byte) ((shiftByte << 4) & CommonData.HIGHER_NIBBLE_MASK); + newDstEnd--; + newDstPrec--; + byte current_nibble = 0; + while ((newSrcEnd > newSrcOffset) && (newDstEnd > newDstOffset)) { + current_nibble = (byte) ((source[newSrcEnd] >> 4) & CommonData.LOWER_NIBBLE_MASK); + newSrcEnd--; + current_nibble |= (byte) ((source[newSrcEnd] << 4) & CommonData.HIGHER_NIBBLE_MASK); + destination[newDstEnd] = current_nibble; + newDstEnd--; + newDstPrec -= 2; + } + if (newDstPrec > 0) { + destination[newDstEnd] = (byte) ((source[newSrcEnd] >> 4) & CommonData.LOWER_NIBBLE_MASK); + newSrcEnd--; + newDstPrec--; + if (newDstPrec > 0 && isMostSigDigitInLowNibble) + destination[newDstEnd] |= (byte) ((source[newSrcEnd] << 4) & CommonData.HIGHER_NIBBLE_MASK); + } + } + // sign assignment + if(overRanPD && roundingDigit < 5 && sign != CommonData.PACKED_PLUS) + destination[dstEnd] = (byte) ((destination[dstEnd] & CommonData.HIGHER_NIBBLE_MASK) | sign); + else + { + destination[dstEnd] = (byte) ((destination[dstEnd] & CommonData.HIGHER_NIBBLE_MASK) | (sign)); + if (round && roundingDigit >= 5) + roundUpPackedDecimal(destination, destinationOffset, dstEnd, + destinationPrecision, roundingDigit, checkOverflow); + if (checkOverflow || round) + checkIfZero(destination, destinationOffset, dstEnd, destinationPrecision, (destinationPrecision % 2 == 0 ? true : false)); + + } + } + + /** + * Left shift a Packed Decimal appending zeros to the right. In the absence of overflow, the sign + * of a zero can either be positive 0x0C or negative 0x0D. + * + * @param destination + * byte array that holds the result of the left shift + * @param destinationOffset + * offset into destination where the result Packed Decimal is located + * @param destinationPrecision + * number of Packed Decimal digits in the destination + * @param source + * byte array that holds the Packed Decimal operand to be left shifted + * @param sourceOffset + * offset into source where the operand is located + * @param sourcePrecision + * number of Packed Decimal digits in the operand + * @param shiftAmount + * amount by which the source will be left shifted + * @param checkOverflow + * if set to true, check for overflow + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws ArithmeticException + * if a decimal overflow occurs + * @throws IllegalArgumentException + * if the shiftAmount or sourcePrecision parameter is invalid or + * the source packed decimal contains invalid sign or digit code + */ + public static void shiftLeftPackedDecimal(byte[] destination, + int destinationOffset, int destinationPrecision, byte[] source, + int sourceOffset, int sourcePrecision, int shiftAmount, + boolean checkOverflow) { + if ((destinationOffset + ((destinationPrecision / 2) + 1) > destination.length) || (destinationOffset < 0)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "shiftLeftPackedDecimal is trying to access destinationDecimal[" + destinationOffset + "] to destinationDecimal[" + (destinationOffset + (destinationPrecision / 2)) + "]" + + " but valid indices are from 0 to " + (destination.length - 1) + "."); + + if ((sourceOffset < 0) || (sourceOffset + ((sourcePrecision / 2) + 1) > source.length)) + throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " + + "shiftLeftPackedDecimal is trying to access sourceDecimal[" + sourceOffset + "] to sourceDecimal[" + (sourceOffset + (sourcePrecision / 2)) + "]" + + " but valid indices are from 0 to " + (source.length - 1) + "."); + + shiftLeftPackedDecimal_(destination, destinationOffset, destinationPrecision, + source, sourceOffset, sourcePrecision, shiftAmount, + checkOverflow); + } + + private static void shiftLeftPackedDecimal_(byte[] destination, + int destinationOffset, int destinationPrecision, byte[] source, + int sourceOffset, int sourcePrecision, int shiftAmount, + boolean checkOverflow) { + + if (destinationPrecision < 1 || sourcePrecision < 1 || shiftAmount < 0) { + throw new IllegalArgumentException( + "Invalid Precisions or shift amount"); + } + + if(checkPackedDecimal_(source, sourceOffset, sourcePrecision, true, false) != 0) { + throw new IllegalArgumentException( + "Invalid sign or digit code in input packed decimal"); + } + // Figure out the sign of the source Packed Decimal + int end = sourceOffset + precisionToByteLength(sourcePrecision) - 1; + byte sign = CommonData.getSign(source[end] & CommonData.LOWER_NIBBLE_MASK); + boolean overRanPD = false; + int sourceLength = precisionToByteLength(sourcePrecision); + int destinationLength = precisionToByteLength(destinationPrecision); + int shiftByte = shiftAmount / 2; + int zerosBytesAtFront = 0; + int totalZeros = 0; + + // odd Precision + if (sourcePrecision % 2 != 0) { + + // Figure out how many 0x00s are at the front starting from the + // offset + for (zerosBytesAtFront = 0; zerosBytesAtFront < sourceLength; zerosBytesAtFront++) { + if (source[zerosBytesAtFront + sourceOffset] != 0x00) + break; + } + + // Figure out if 0x0* + if ((byte) (source[zerosBytesAtFront + sourceOffset] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) + totalZeros++; + + }// even precision + else { + // Figure out if bottom nibble of offset is 0 if it is then count + // how many zero bytes there are at the front + if ((byte) (source[sourceOffset] & CommonData.LOWER_NIBBLE_MASK) == 0x00) { + totalZeros++; + for (int i = 1; i < sourceLength; i++) { + if (source[i + sourceOffset] != 0x00) + break; + else + zerosBytesAtFront++; + } + if ((byte) (source[zerosBytesAtFront + sourceOffset + 1] & CommonData.HIGHER_NIBBLE_MASK) == 0x00) + totalZeros++; + } + } + // Add up all the zeros + totalZeros += zerosBytesAtFront * 2; + + // Check for overflow + if (checkOverflow + && ((destinationPrecision + totalZeros < sourcePrecision + + shiftAmount))) + throw new ArithmeticException( + "Overflow - Destination precision not enough to hold the result of the shift operation"); + + // Zero out destination array in range + Arrays.fill(destination, destinationOffset, destinationOffset + + destinationLength, (byte) 0x00); + + int startIndexSource = zerosBytesAtFront + sourceOffset; + int diff = destinationLength - sourceLength; + int startIndexDestination = destinationOffset + zerosBytesAtFront + - shiftByte + diff; + int numberLength = sourceLength - zerosBytesAtFront; // non-zeros digits + // length in bytes + int movedSignIndex = startIndexDestination + numberLength - 1; // where + // the + // moved + // sign + // is + // displaced + // to + + // if all digits are completely shifted out do nothing + if (destinationPrecision <= shiftAmount) + { + if (checkOverflow && sign != CommonData.PACKED_PLUS) + overRanPD = true; + } + else + { + // Even shift, can move byte by byte + if (shiftAmount % 2 == 0) + { + if (startIndexDestination < destinationOffset) + { + int difference = sourcePrecision - (destinationPrecision - shiftAmount); + int sourceIndex; + if (sourcePrecision % 2 == 0) + sourceIndex = sourceOffset + ((difference + 1) / 2); + else + sourceIndex = sourceOffset + (difference / 2); + + System.arraycopy(source, sourceIndex, destination, destinationOffset, destinationLength + - (shiftAmount / 2)); + } + else + System.arraycopy(source, startIndexSource, destination, + startIndexDestination, sourceLength - zerosBytesAtFront); + + // Strip off moved sign + if (movedSignIndex >= 0) + destination[movedSignIndex] = (byte) (destination[movedSignIndex] & CommonData.HIGHER_NIBBLE_MASK); + } + else + { + byte top; + byte bottom; + + // Move each nibble by appropriate index + for (int i = 0; i < numberLength; i++) { + top = (byte) (source[startIndexSource + i] & CommonData.HIGHER_NIBBLE_MASK); + bottom = (byte) (source[startIndexSource + i] & CommonData.LOWER_NIBBLE_MASK); + + if (startIndexDestination - 1 + i >= destinationOffset) { + destination[startIndexDestination - 1 + i] = (byte) ((top >> 4 & CommonData.LOWER_NIBBLE_MASK) | (byte) (destination[startIndexDestination + - 1 + i] & CommonData.HIGHER_NIBBLE_MASK)); + } + if (startIndexDestination + i >= destinationOffset) { + destination[startIndexDestination + i] = (byte) (bottom << 4); + } + + } + // Strip off moved sign + if (movedSignIndex >= 0) + destination[movedSignIndex] = CommonData.PACKED_ZERO; + } + } + int destinationEnd = destinationOffset + destinationLength - 1; + boolean isDestionationEvenPrecision = destinationPrecision % 2 == 0 ? true : false; + // Mask top Nibble + if (isDestionationEvenPrecision) + destination[destinationOffset] = (byte) (destination[destinationOffset] & CommonData.LOWER_NIBBLE_MASK); + // Put sign in proper position + + if (overRanPD) + destination[destinationEnd] = (byte) (CommonData.PACKED_PLUS | destination[destinationEnd]); + else + { + destination[destinationEnd] = (byte) (sign | destination[destinationEnd]); + //checkOverflow will generate pdshlOverflow, which will cause it to reset sign. pdshl will not + if (checkOverflow) + checkIfZero(destination, destinationOffset, destinationEnd, destinationPrecision, isDestionationEvenPrecision); + } + } + + /** + * Creates a copy of a Packed Decimal. + * + * @param destination + * byte array representing the destination + * @param destinationOffset + * offset into destination destination where the Packed Decimal is located + * @param destinationPrecision + * number of Packed Decimal digits for the destination + * @param source + * byte array which holds the source Packed Decimal + * @param sourceOffset + * offset into source where the Packed Decimal is located + * @param sourcePrecision + * number of Packed Decimal digits for the source. Maximum valid precision is 253 + * @param checkOverflow + * if set to true, moved Packed Decimals are validated, and an IllegalArgumentException or + * ArithmeticException is thrown if non-zero nibbles are truncated during the move + * operation. If set to false, no validating is conducted. + * + * @throws NullPointerException + * if any of the byte arrays are null + * @throws ArrayIndexOutOfBoundsException + * if an invalid array access occurs + * @throws IllegalArgumentException + * if the source Packed Decimal is invalid + * @throws ArithmeticException + * if a decimal overflow occurs + */ + public static void movePackedDecimal(byte[] destination, + int destinationOffset, int destinationPrecision, byte[] source, + int sourceOffset, int sourcePrecision, boolean checkOverflow) { + shiftLeftPackedDecimal(destination, destinationOffset, + destinationPrecision, source, sourceOffset, + sourcePrecision, 0, checkOverflow); + } + + private static class PackedDecimalOperand { + + PackedDecimalOperand() { + super(); + } + + private static final byte PACKED_ZERO = 0x00; + + byte[] byteArray; + int offset; + int precision; + int bytes; + int signOffset; + int currentOffset; + int signByteValue; + int sign; + int signDigit; + int byteValue; + int indexValue; + + /** + * Sets up the attributes of a Packed Decimal operand. Truncates leading zeros. Captures the sign value. + * + * @param byteArray + * byte array which holds the Packed Decimal + * @param offset + * offset in byteArray where the Packed Decimal begins + * @param precision + * number of Packed Decimal digits. Maximum valid precision is 253 + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBounds + * if an invalid array access occurs + */ + public void setOperand(byte[] byteArray, int offset, int precision) { + + this.byteArray = byteArray; + this.offset = offset; + this.precision = precision; + + // truncate leading zeros + bytes = CommonData.getPackedByteCount(precision); + signOffset = this.offset + bytes - 1; + currentOffset = signOffset - 1; + for (; byteArray[this.offset] == PACKED_ZERO + && this.offset < signOffset; this.offset++) + ; + bytes = signOffset - this.offset + 1; + + // capture sign values + signByteValue = this.byteArray[signOffset] + & CommonData.INTEGER_MASK; + signDigit = signByteValue & CommonData.HIGHER_NIBBLE_MASK; + sign = CommonData.getSign(signByteValue & CommonData.LOWER_NIBBLE_MASK); + } + + /** + * Sets up attributes of a Packed Decimal which is about to be the result operand holding the sum of two Packed + * Decimal operands. Does not truncate leading zeroes. Does not capture the sign. + * + * @param byteArray + * byte array which holds the Packed Decimal + * @param offset + * offset in byteArray where the Packed Decimal begins + * @param precision + * number of Packed Decimal digits. Maximum valid precision is 253 + * + * @throws NullPointerException + * if byteArray is null + * @throws ArrayIndexOutOfBounds + * if an invalid array access occurs + */ + public void setSumOperand(byte[] byteArray, int offset, int precision) { + this.byteArray = byteArray; + this.offset = offset; + this.precision = precision; + + bytes = CommonData.getPackedByteCount(precision); + signOffset = this.offset + bytes - 1; + currentOffset = signOffset - 1; + } + + } } From c40ceb86643c5bfe70f80b4945823c8a94c0201e Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 15:12:27 -0400 Subject: [PATCH 10/16] Tidy up whitespace in openj9.dtfj * remove trailing whitespace * indent with tabs consistently * remove extra trailing blank lines Signed-off-by: Keith W. Campbell --- .../dtfj/corereaders/NativeThreadContext.java | 52 +- .../com/ibm/dtfj/corereaders/NewAixDump.java | 54 +- .../com/ibm/dtfj/corereaders/NewWinDump.java | 6 +- .../com/ibm/dtfj/corereaders/NewZosDump.java | 4 +- .../com/ibm/dtfj/corereaders/Symbol.java | 24 +- .../zos/dumpreader/AddressRange.java | 64 +- .../zos/dumpreader/AddressSpace.java | 1196 +++++------ .../AddressSpaceImageInputStream.java | 124 +- .../dtfj/corereaders/zos/dumpreader/Dump.java | 1092 +++++----- .../zos/dumpreader/SearchListener.java | 28 +- .../com/ibm/dtfj/corereaders/zos/le/Caa.java | 1524 ++++++------- .../corereaders/zos/le/Caa32Template.java | 214 +- .../corereaders/zos/le/Caa32_11Template.java | 261 ++- .../corereaders/zos/le/Caa64Template.java | 212 +- .../corereaders/zos/le/Caa64_11Template.java | 257 ++- .../dtfj/corereaders/zos/le/CaaTemplate.java | 56 +- .../corereaders/zos/le/CeedsaTemplate.java | 168 +- .../zos/le/Ceedsahp32Template.java | 96 +- .../zos/le/Ceedsahp64Template.java | 99 +- .../corereaders/zos/le/CeedsahpTemplate.java | 26 +- .../zos/le/Ceedsahp_transitionTemplate.java | 99 +- .../corereaders/zos/le/CeelcaTemplate.java | 56 +- .../corereaders/zos/le/CeexcibTemplate.java | 53 +- .../corereaders/zos/le/CeexcibhTemplate.java | 82 +- .../zos/le/Ceexdlcb32Template.java | 128 +- .../zos/le/Ceexdlcb64Template.java | 128 +- .../corereaders/zos/le/CeexdlcbTemplate.java | 32 +- .../corereaders/zos/le/Ceexedb32Template.java | 99 +- .../corereaders/zos/le/Ceexedb64Template.java | 97 +- .../corereaders/zos/le/CeexedbTemplate.java | 26 +- .../zos/le/Ceexhcom32Template.java | 53 +- .../zos/le/Ceexhcom64Template.java | 53 +- .../corereaders/zos/le/CeexhcomTemplate.java | 14 +- .../corereaders/zos/le/CeexhepvTemplate.java | 53 +- .../corereaders/zos/le/Ceexhp1bTemplate.java | 53 +- .../corereaders/zos/le/CeexlaaTemplate.java | 28 +- .../corereaders/zos/le/CeexoepvTemplate.java | 99 +- .../corereaders/zos/le/Ceexpp1bTemplate.java | 53 +- .../corereaders/zos/le/Ceexrcb32Template.java | 53 +- .../corereaders/zos/le/Ceexrcb64Template.java | 53 +- .../corereaders/zos/le/CeexrcbTemplate.java | 14 +- .../corereaders/zos/le/CeexsfxmTemplate.java | 99 +- .../corereaders/zos/le/CeexstkhTemplate.java | 28 +- .../corereaders/zos/le/CeextvbTemplate.java | 34 +- .../corereaders/zos/le/CeextvbeTemplate.java | 53 +- .../zos/le/Ciet2ExpFuncEntryTemplate.java | 138 +- .../zos/le/Ciet2ExpVarEntryTemplate.java | 82 +- .../corereaders/zos/le/Ciet2Template.java | 122 +- .../zos/le/CietExpEntryTemplate.java | 115 +- .../dtfj/corereaders/zos/le/CietTemplate.java | 99 +- .../com/ibm/dtfj/corereaders/zos/le/Dll.java | 636 +++--- .../dtfj/corereaders/zos/le/DllFunction.java | 42 +- .../dtfj/corereaders/zos/le/DllVariable.java | 34 +- .../corereaders/zos/le/DllcsectTemplate.java | 53 +- .../zos/le/DllexpfuncsTemplate.java | 99 +- .../zos/le/DllexpvarsTemplate.java | 99 +- .../corereaders/zos/le/DsaStackFrame.java | 1902 ++++++++--------- .../com/ibm/dtfj/corereaders/zos/le/Edb.java | 252 +-- .../ibm/dtfj/corereaders/zos/le/Function.java | 50 +- .../dtfj/corereaders/zos/le/SmcbTemplate.java | 28 +- .../corereaders/zos/mvs/BpxzotcbTemplate.java | 61 +- .../corereaders/zos/mvs/BpxzustaTemplate.java | 53 +- .../corereaders/zos/mvs/CeexcvtTemplate.java | 28 +- .../corereaders/zos/mvs/IhaascbTemplate.java | 28 +- .../corereaders/zos/mvs/IhaasxbTemplate.java | 53 +- .../corereaders/zos/mvs/IhapsaTemplate.java | 53 +- .../corereaders/zos/mvs/IharbTemplate.java | 76 +- .../corereaders/zos/mvs/Ihartm2aTemplate.java | 53 +- .../corereaders/zos/mvs/IhastcbTemplate.java | 122 +- .../corereaders/zos/mvs/IkjrbTemplate.java | 36 +- .../corereaders/zos/mvs/IkjtcbTemplate.java | 145 +- .../com/ibm/dtfj/corereaders/zos/mvs/Lse.java | 208 +- .../corereaders/zos/mvs/LsedTemplate.java | 34 +- .../zos/mvs/Lses1lsed1Template.java | 36 +- .../corereaders/zos/mvs/LseslsedTemplate.java | 36 +- .../zos/mvs/Lsestate1Template.java | 105 +- .../corereaders/zos/mvs/LsestateTemplate.java | 99 +- .../zos/mvs/OtcbcopyonforkTemplate.java | 28 +- .../dtfj/corereaders/zos/mvs/RegisterSet.java | 132 +- .../com/ibm/dtfj/corereaders/zos/mvs/Tcb.java | 692 +++--- .../corereaders/zos/util/AbstractHashMap.java | 494 ++--- .../zos/util/AbstractLruCache.java | 190 +- .../dtfj/corereaders/zos/util/BitStream.java | 962 ++++----- .../corereaders/zos/util/CharConversion.java | 302 +-- .../ibm/dtfj/corereaders/zos/util/Clib.java | 228 +- .../zos/util/CompressedRecordArray.java | 822 +++---- .../corereaders/zos/util/IntEnumeration.java | 9 +- .../dtfj/corereaders/zos/util/IntegerMap.java | 194 +- .../corereaders/zos/util/ObjectLruCache.java | 98 +- .../dtfj/corereaders/zos/util/ObjectMap.java | 118 +- .../ibm/dtfj/image/CorruptDataException.java | 16 +- .../com/ibm/dtfj/image/DTFJException.java | 16 +- .../com/ibm/dtfj/image/DataUnavailable.java | 6 +- .../classes/com/ibm/dtfj/image/Image.java | 54 +- .../com/ibm/dtfj/image/ImageAddressSpace.java | 86 +- .../com/ibm/dtfj/image/ImageModule.java | 92 +- .../com/ibm/dtfj/image/ImagePointer.java | 242 +-- .../com/ibm/dtfj/image/ImageProcess.java | 246 +-- .../com/ibm/dtfj/image/ImageRegister.java | 32 +- .../com/ibm/dtfj/image/ImageSection.java | 112 +- .../com/ibm/dtfj/image/ImageStackFrame.java | 84 +- .../com/ibm/dtfj/image/ImageThread.java | 110 +- .../ibm/dtfj/image/MemoryAccessException.java | 48 +- .../com/ibm/dtfj/java/JavaClassLoader.java | 90 +- .../classes/com/ibm/dtfj/java/JavaHeap.java | 46 +- .../classes/com/ibm/dtfj/java/JavaMember.java | 48 +- .../classes/com/ibm/dtfj/java/JavaMethod.java | 52 +- .../com/ibm/dtfj/java/JavaMonitor.java | 84 +- .../com/ibm/dtfj/java/JavaReference.java | 208 +- .../com/ibm/dtfj/java/JavaRuntime.java | 278 +-- .../com/ibm/dtfj/java/JavaStackFrame.java | 36 +- .../classes/com/ibm/dtfj/java/JavaThread.java | 184 +- .../ibm/dtfj/java/j9/JavaAbstractClass.java | 24 +- .../com/ibm/dtfj/java/j9/JavaReference.java | 72 +- .../com/ibm/dtfj/java/j9/JavaRuntime.java | 2 +- .../builder/javacore/ImageBuilder.java | 2 +- .../j9/section/memory/MemoryTagParser.java | 1 - .../com/ibm/dtfj/phd/PHDJavaObject.java | 2 +- .../com/ibm/dtfj/phd/PHDJavaReference.java | 26 +- .../classes/com/ibm/dtfj/phd/parser/Base.java | 1 - .../ibm/dtfj/phd/parser/HeapdumpWriter.java | 8 +- .../com/ibm/dtfj/phd/util/BitStream.java | 2 +- .../ibm/dtfj/phd/util/LongEnumeration.java | 1 - .../com/ibm/dtfj/utils/file/FileManager.java | 1 - .../com/ibm/dtfj/utils/file/FileSniffer.java | 66 +- .../file/MultipleCandidateException.java | 1 - .../diagnostics/utils/commands/ICommand.java | 6 +- .../jvm/j9/dump/indexsupport/NodeFrame.java | 2 +- .../j9/dump/indexsupport/XMLIndexReader.java | 24 +- 129 files changed, 9618 insertions(+), 9136 deletions(-) diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NativeThreadContext.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NativeThreadContext.java index b04b7c18f8d..cf3409685dc 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NativeThreadContext.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NativeThreadContext.java @@ -29,35 +29,35 @@ public class NativeThreadContext { long ee; - long pc; - long lr; - long sp; - long bp; + long pc; + long lr; + long sp; + long bp; - public NativeThreadContext () {} + public NativeThreadContext () {} - public NativeThreadContext (int size, long ee, long pc, long lr, long sp, long bp ) { - long anderFlag = 0x00000000ffffffffL; - if (size == 64) { - anderFlag = 0xffffffffffffffffL; - } - this.ee = ee & anderFlag; - this.pc = pc & anderFlag; - this.lr = lr & anderFlag; - this.sp = sp & anderFlag; - this.bp = bp & anderFlag; - } + public NativeThreadContext (int size, long ee, long pc, long lr, long sp, long bp ) { + long anderFlag = 0x00000000ffffffffL; + if (size == 64) { + anderFlag = 0xffffffffffffffffL; + } + this.ee = ee & anderFlag; + this.pc = pc & anderFlag; + this.lr = lr & anderFlag; + this.sp = sp & anderFlag; + this.bp = bp & anderFlag; + } - public void setEE(long ee) { this.ee = ee; } - public void setPc(long pc) { this.pc = pc; } - public void setLr(long lr) { this.lr = lr; } - public void setSp(long sp) { this.sp = sp; } - public void setBp(long bp) { this.bp = bp; } + public void setEE(long ee) { this.ee = ee; } + public void setPc(long pc) { this.pc = pc; } + public void setLr(long lr) { this.lr = lr; } + public void setSp(long sp) { this.sp = sp; } + public void setBp(long bp) { this.bp = bp; } - public long getEE() { return ee; } - public long getPc() { return pc; } - public long getSp() { return sp; } - public long getBp() { return bp; } - public long getLr() { return lr; } + public long getEE() { return ee; } + public long getPc() { return pc; } + public long getSp() { return sp; } + public long getBp() { return bp; } + public long getLr() { return lr; } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewAixDump.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewAixDump.java index 78b8627a18e..a2efaa52599 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewAixDump.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewAixDump.java @@ -461,33 +461,33 @@ private Properties getEnvironmentVariables(long environmentAddress) throws IOExc address = coreReadAddress(); } - // Get the environment variables - Properties environment = new Properties(); - for (Iterator iter = addresses.iterator(); iter.hasNext();) { - Long varAddress = (Long)iter.next(); - String pair = null; - try { - coreSeekVirtual(varAddress.longValue()); - pair = readString(); - } catch (MemoryAccessException e) { - // catch errors here, we can carry on getting other environment variables - unlikely to be missing only some of these - continue; - } - if (null != pair) - { - // Pair is the x=y string, now break it into key and value - int equalSignIndex = pair.indexOf('='); - if (equalSignIndex >= 0) - { - String key = pair.substring(0, equalSignIndex); - String value = pair.substring(equalSignIndex + 1); - environment.put(key, value); - } - } - } - - return environment; - } + // Get the environment variables + Properties environment = new Properties(); + for (Iterator iter = addresses.iterator(); iter.hasNext();) { + Long varAddress = (Long)iter.next(); + String pair = null; + try { + coreSeekVirtual(varAddress.longValue()); + pair = readString(); + } catch (MemoryAccessException e) { + // catch errors here, we can carry on getting other environment variables - unlikely to be missing only some of these + continue; + } + if (null != pair) + { + // Pair is the x=y string, now break it into key and value + int equalSignIndex = pair.indexOf('='); + if (equalSignIndex >= 0) + { + String key = pair.substring(0, equalSignIndex); + String value = pair.substring(equalSignIndex + 1); + environment.put(key, value); + } + } + } + + return environment; + } private List readThreads(Builder builder, Object addressSpace) throws IOException { List threads = new ArrayList(); diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewWinDump.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewWinDump.java index 54c8cba0950..397f6c4382d 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewWinDump.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewWinDump.java @@ -651,9 +651,9 @@ public void readFrom(MiniDump dump, Builder builder, Object addressSpace, IAbstr long stackEnd = stackStart + stackSize; Object section = builder.buildStackSection(addressSpace, stackStart, stackEnd); List frames = readStackFrames(dump, builder, addressSpace, stackStart, stackEnd, stackRva, registers, memory, is64Bit); - //TODO: find the signal number! - int signalNumber = 0; - Object thread = builder.buildThread(String.valueOf(threadId), registers.iterator(), + //TODO: find the signal number! + int signalNumber = 0; + Object thread = builder.buildThread(String.valueOf(threadId), registers.iterator(), Collections.singletonList(section).iterator(), frames.iterator(), properties, signalNumber); threads.add(thread); diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewZosDump.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewZosDump.java index 07dcaefd579..b88cec2693d 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewZosDump.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewZosDump.java @@ -77,8 +77,8 @@ public class NewZosDump implements ICoreFileReader { /** Maintains the list of Java address spaces */ private HashMap _javaAddressSpaces = new LinkedHashMap(); - /** Logger */ - private static Logger log = Logger.getLogger(NewZosDump.class.getName()); + /** Logger */ + private static Logger log = Logger.getLogger(NewZosDump.class.getName()); // Zebedee variables private com.ibm.dtfj.corereaders.zos.dumpreader.Dump _dump; diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/Symbol.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/Symbol.java index 6055259ce25..d3f15715432 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/Symbol.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/Symbol.java @@ -49,18 +49,18 @@ public class Symbol { final static int STB_GLOBAL = 1; final static int STB_WEAK = 2; - // values for st_info field - static final int STT_NOTYPE = 0; - static final int STT_OBJECT = 1; - static final int STT_FUNC = 2; - static final int STT_SECTION = 3; - static final int STT_FILE = 4; - static final int STT_COMMON = 5; - static final int STT_TLS = 6; - static final int STT_LOOS = 10; - static final int STT_HIOS = 12; - static final int STT_LOPROC = 13; - static final int STT_HIPROC = 15; + // values for st_info field + static final int STT_NOTYPE = 0; + static final int STT_OBJECT = 1; + static final int STT_FUNC = 2; + static final int STT_SECTION = 3; + static final int STT_FILE = 4; + static final int STT_COMMON = 5; + static final int STT_TLS = 6; + static final int STT_LOOS = 10; + static final int STT_HIOS = 12; + static final int STT_LOPROC = 13; + static final int STT_HIPROC = 15; public Symbol(String name, long address, int extent, int type, int bind) { diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressRange.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressRange.java index 6253168bba8..5e547160c49 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressRange.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressRange.java @@ -27,40 +27,40 @@ * a length. */ public class AddressRange { - long startAddress; - long length; + long startAddress; + long length; - /** - * Create a new address range. - * @param startAddress the lower bound of the address range - * @param length the length of the address range - */ - public AddressRange(long startAddress, long length) { - this.startAddress = startAddress; - this.length = length; - } + /** + * Create a new address range. + * @param startAddress the lower bound of the address range + * @param length the length of the address range + */ + public AddressRange(long startAddress, long length) { + this.startAddress = startAddress; + this.length = length; + } - /** - * Get the lower bound of this address range. - * @return the start address - */ - public long getStartAddress() { - return startAddress; - } + /** + * Get the lower bound of this address range. + * @return the start address + */ + public long getStartAddress() { + return startAddress; + } - /** - * Get the upper bound of this address range (inclusive). - * @return the end address - */ - public long getEndAddress() { - return startAddress + length - 1; - } + /** + * Get the upper bound of this address range (inclusive). + * @return the end address + */ + public long getEndAddress() { + return startAddress + length - 1; + } - /** - * Get the length of this address range. - * @return the length - */ - public long getLength() { - return length; - } + /** + * Get the length of this address range. + * @return the length + */ + public long getLength() { + return length; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressSpace.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressSpace.java index 63520efef24..db6ba56948a 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressSpace.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressSpace.java @@ -52,606 +52,606 @@ * @depend - - - com.ibm.dtfj.corereaders.zos.util.Template */ public class AddressSpace implements Serializable { - /** The dump we belong to */ - protected Dump dump; - /** Our address space id */ - protected int asid; - /** Mapping of address to file offsets */ - protected IntegerMap addressMap = new IntegerMap(); - /** The number of times we found a block in the quick cache */ - private int quickCacheHits; - /** The number of times we found a block in the cache */ - private int cacheHits; - /** And the number of times we didn't */ - private int cacheMisses; - /** The block cache - 500 blocks is normally plenty */ - private ObjectLruCache blockCache; - /** The last block address requested (quick block cache) */ - protected long lastBlockAddress; - /** The last block read (quick block cache) */ - private byte[] lastBlock; - /** The last but one block address requested (quick block cache) */ - protected long lastButOneBlockAddress; - /** The last but one block read (quick block cache) */ - private byte[] lastButOneBlock; - /** Array of AddressRanges */ - protected AddressRange[] ranges; - /** Our image stream */ - private AddressSpaceImageInputStream imageStream; - /** Whether we are a 64-bit address space */ - private boolean is64bit; - /** A general purpose map that AddressSpace users can use for their own purposes */ - private HashMap userMap = new HashMap(); - /** Constant used to indicate an uninitialized pointer (for performance reasons - * we use primitive longs for pointers rather than objects) */ - public static final long WILD_POINTER = 0xbaadf00ddeadbeefL; - /** Logger */ - private static Logger log = Logger.getLogger(AddressSpace.class.getName()); - /* XXX Temp debugging */ - private static final boolean printStats = Boolean.getBoolean("zebedee.printStats"); - - /** - * Creates a new AddressSpace belonging to the given Dump and having the given id. - * @param dump the {@link com.ibm.dtfj.corereaders.zos.dumpreader.Dump} this space belongs to - * @param asid the address space id - */ - public AddressSpace(Dump dump, int asid) { - this.dump = dump; - this.asid = asid; - initialize(); - } - - /** - * @return the Dump we belong to - */ - public Dump getDump() { - return dump; - } - - /** - * @return the root address space - */ - public AddressSpace getRootAddressSpace() { - return dump.rootSpace; - } - - /** - * Do any transient initialization required. This method is called both from the - * AddressSpace constructor and from the readObject method when the AddressSpace - * is read from the cache. - */ - private void initialize() { - blockCache = new ObjectLruCache(500); - userMap = new HashMap(); - lastBlockAddress = -1; - lastButOneBlockAddress = -1; - if (printStats && getClass() == AddressSpace.class) { - Runtime.getRuntime().addShutdownHook(new Thread() { - /* - * Print some cache stats. - */ - public void run() { - System.out.println("stats for asid " + hex(asid) + ":"); - System.out.println(" cacheMisses = " + cacheMisses); - System.out.println(" cacheHits = " + cacheHits); - System.out.println(" quickCacheHits = " + quickCacheHits); - } - }); - } - } - - /** - * Returns a general purpose Map object that AddressSpace users can use as they see fit. - * This map is provided as a convenience since users of AddressSpace often want to store - * related info somewhere. Care should be taken that nobody else has used the same key - - * one way to achieve this would be to use a class object as a key. - */ - public Map getUserMap() { - return userMap; - } - - /** - * Returns the MVS ASID (Address Space Identifier) for this address space. - */ - public int getAsid() { - return asid; - } - - /** - * Returns an array of all the {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressRange}s in this - * address space. An address range is simply a pair of [low, high] addresses for which - * memory is available in the dump. - */ - public AddressRange[] getAddressRanges() { - if (ranges != null) - return ranges; - /* Get the list of the start addresses of each block */ - long[] addresses = addressMap.getKeysArray(); - /* Sort it */ - Arrays.sort(addresses); - /* Now go through the list and create a new range every time we find a gap */ - long startAddress = 0; - long lastAddress = 0; - Vector v = new Vector(); - for (int i = 0; i < addresses.length; i++) { - if (i == 0) { - startAddress = addresses[0]; - } else if (addresses[i] != lastAddress + Dump.DATABLOCKSIZE) { - /* Found a discontinuity so create new AddressRange */ - v.add(new AddressRange(startAddress, lastAddress + 0x1000 - startAddress)); - startAddress = addresses[i]; - } - lastAddress = addresses[i]; - } - v.add(new AddressRange(startAddress, lastAddress + 0x1000 - startAddress)); - ranges = (AddressRange[])v.toArray(new AddressRange[0]); - return ranges; - } - - /** - * Returns an array of all the unused address ranges in the address space. This is - * the inverse of {@link #getAddressRanges}. - */ - public AddressRange[] getUnusedAddressRanges() { - getAddressRanges(); - AddressRange[] unused = new AddressRange[ranges.length - 1]; - for (int i = 0; i < unused.length; i++) { - long start = ranges[i].getEndAddress() + 1; - long end = ranges[i + 1].getStartAddress() - 1; - unused[i] = new AddressRange(start, end - start); - } - return unused; - } - - /** - * Returns an {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressSpaceImageInputStream} for this - * address space. The ImageInputStream interface provides a wealth of read methods. - */ - public AddressSpaceImageInputStream getImageInputStream() { - if (imageStream == null) - imageStream = new AddressSpaceImageInputStream(this); - assert imageStream != null; - return imageStream; - } - - /** - * This method is for debugging purposes only and should eventually disappear. We use the - * value of WILD_POINTER to indicate that a pointer has not been initialized (the chances - * of getting this value by accident are one in a very large number indeed). - */ - private void checkIfWild(long address) { - assert address != WILD_POINTER; - assert (int)address != (int)WILD_POINTER; - /* Also check if the access is anywhere near the uninitialized value for the - * time being. We may have done some pointer arithmetic with it. */ - assert (address < WILD_POINTER - 0x1000) || (address > WILD_POINTER + 0x1000) : hex(address); - assert ((int)address < (int)WILD_POINTER - 0x1000) || ((int)address > (int)WILD_POINTER + 0x1000) : hex((int)address); - } - - /** - * Rounds the address to the base page address and also strips the top bit if in 32-bit mode. - */ - protected long roundToPage(long address) { - checkIfWild(address); - if (is64bit()) { - return address & 0xfffffffffffff000L; - } else { - return address & 0x7ffff000; - } - } - - /** Strip the top bit if this is a 32-bit platform */ - public long stripTopBit(long address) { - checkIfWild(address); - if (is64bit()) { - assert address >= 0 : hex(address); - return address; - } else { - return address & 0x7fffffff; - } - } - - /** - * Read from the given address into the given buffer. - * @param address the address to read from - * @param buf the buffer to read into - */ - private void read(long address, byte[] buf) throws IOException { - if (log.isLoggable(Level.FINER)) - log.finer("request to read " + buf.length + " from address 0x" + hex(address)); - /* Round down to the nearest block */ - long blockAddress = roundToPage(address); - /* Get the offset in the dump file */ - long offset = addressMap.get(blockAddress); - if (offset == -1) { - /* - * Now this is weird code and almost certainly the wrong way to do it, - * but it seems to work: for certain low memory addresses, if they can't be - * found in our address space, they can sometimes be found in what I call - * the "root" address space with asid 1. Maybe this is kernel memory mapped into - * all other spaces? Who knows, anyway let's go and try there before giving up. - */ - if (asid != 1) { - offset = dump.rootSpace.addressMap.get(blockAddress); - if (offset != -1) - log.fine("found address " + hex(address) + " in root address space"); - } - if (offset == -1) - throw new IOException("block address " + hex(address) + " not in dump"); - } - /* Now we seek to that offset to get to the actual data */ - /* XXX not thread safe! */ - dump.seek(offset); - /* Finally read the requested bytes */ - if (buf.length <= Dump.DATABLOCKSIZE) { - dump.readFully(buf); - } else { - /* XXX do we actually need this? */ - throw new Error("to be completed"); - } - } - - /** - * See if the block is in the quick cache. - */ - final byte[] getBlockFromQuickCache(long address) { - assert (address & 0xfff) == 0; - if (address == lastBlockAddress) { - quickCacheHits++; - if (log.isLoggable(Level.FINEST)) - log.finest("request to get block for address 0x" + hex(address) + " met by quick cache"); - return lastBlock; - } - if (address == lastButOneBlockAddress) { - quickCacheHits++; - if (log.isLoggable(Level.FINEST)) - log.finest("request to get block for address 0x" + hex(address) + " met by quick cache"); - return lastButOneBlock; - } - return null; - } - - /** - * Place block in the quick cache. - */ - final void putBlockInQuickCache(long address, byte[] block) { - assert (address & 0xfff) == 0; - lastButOneBlockAddress = lastBlockAddress; - lastButOneBlock = lastBlock; - lastBlockAddress = address; - lastBlock = block; - } - - /** - * Get the block of bytes for the given address. Usually we find this in the cache. - */ - final byte[] getBlock(long address) throws IOException { - address = roundToPage(address); - /* Quickly check the cached last block(s). This gets the vast majority */ - byte[] b = getBlockFromQuickCache(address); - return b != null ? b : getBlockFromCacheOrDisk(address); - } - - /** - * Get the block either from the cache or from disk. This protected method is - * provided so that MutableAddressSpace has the chance to look in its own cache first. - */ - protected byte[] getBlockFromCacheOrDisk(long address) throws IOException { - assert (address & 0xfff) == 0; - /* Now look to see if the block is in the lru cache */ - byte[] block = (byte[])blockCache.get(address); - if (block == null) { - cacheMisses++; - /* Not found in cache so read from the file itself */ - block = new byte[Dump.DATABLOCKSIZE]; - read(address, block); - /* Put it in the cache */ - blockCache.put(address, block); - if (log.isLoggable(Level.FINEST)) - log.finest("request to get block for address 0x" + hex(address) + " met by file read"); - } else { - cacheHits++; - if (log.isLoggable(Level.FINEST)) - log.finest("request to get block for address 0x" + hex(address) + " met by cache"); - } - /* Store the last block read as a quick cache */ - putBlockInQuickCache(address, block); - return block; - } - - /** - * Read an unsigned byte at the specified address. - * @throws IOException if the given address is not present in this address space - */ - public int read(long address) throws IOException { - return (int)getBlock(address)[(int)address & 0xfff] & 0xff; - } - - /** - * Read an int at the specified address. - * @throws IOException if the given address is not present in this address space - */ - public int readInt(long address) throws IOException { - int offset = (int)address & 0xfff; - if (offset <= 0xffc) - return Dump.readInt(getBlock(address), offset); - int ch1 = read(address++); - int ch2 = read(address++); - int ch3 = read(address++); - int ch4 = read(address++); - return (ch1 << 24) | (ch2 << 16) | (ch3 << 8) | ch4; - } - - /** - * Read an unsigned byte at the specified address. - * @throws IOException if the given address is not present in this address space - */ - public int readUnsignedByte(long address) throws IOException { - return read(address); - } - - /** - * Read a (signed) byte at the specified address. - * @throws IOException if the given address is not present in this address space - */ - public byte readByte(long address) throws IOException { - return (byte)readUnsignedByte(address); - } - - /** - * Read an unsigned short at the specified address. - * @throws IOException if the given address is not present in this address space - */ - public int readUnsignedShort(long address) throws IOException { + /** The dump we belong to */ + protected Dump dump; + /** Our address space id */ + protected int asid; + /** Mapping of address to file offsets */ + protected IntegerMap addressMap = new IntegerMap(); + /** The number of times we found a block in the quick cache */ + private int quickCacheHits; + /** The number of times we found a block in the cache */ + private int cacheHits; + /** And the number of times we didn't */ + private int cacheMisses; + /** The block cache - 500 blocks is normally plenty */ + private ObjectLruCache blockCache; + /** The last block address requested (quick block cache) */ + protected long lastBlockAddress; + /** The last block read (quick block cache) */ + private byte[] lastBlock; + /** The last but one block address requested (quick block cache) */ + protected long lastButOneBlockAddress; + /** The last but one block read (quick block cache) */ + private byte[] lastButOneBlock; + /** Array of AddressRanges */ + protected AddressRange[] ranges; + /** Our image stream */ + private AddressSpaceImageInputStream imageStream; + /** Whether we are a 64-bit address space */ + private boolean is64bit; + /** A general purpose map that AddressSpace users can use for their own purposes */ + private HashMap userMap = new HashMap(); + /** Constant used to indicate an uninitialized pointer (for performance reasons + * we use primitive longs for pointers rather than objects) */ + public static final long WILD_POINTER = 0xbaadf00ddeadbeefL; + /** Logger */ + private static Logger log = Logger.getLogger(AddressSpace.class.getName()); + /* XXX Temp debugging */ + private static final boolean printStats = Boolean.getBoolean("zebedee.printStats"); + + /** + * Creates a new AddressSpace belonging to the given Dump and having the given id. + * @param dump the {@link com.ibm.dtfj.corereaders.zos.dumpreader.Dump} this space belongs to + * @param asid the address space id + */ + public AddressSpace(Dump dump, int asid) { + this.dump = dump; + this.asid = asid; + initialize(); + } + + /** + * @return the Dump we belong to + */ + public Dump getDump() { + return dump; + } + + /** + * @return the root address space + */ + public AddressSpace getRootAddressSpace() { + return dump.rootSpace; + } + + /** + * Do any transient initialization required. This method is called both from the + * AddressSpace constructor and from the readObject method when the AddressSpace + * is read from the cache. + */ + private void initialize() { + blockCache = new ObjectLruCache(500); + userMap = new HashMap(); + lastBlockAddress = -1; + lastButOneBlockAddress = -1; + if (printStats && getClass() == AddressSpace.class) { + Runtime.getRuntime().addShutdownHook(new Thread() { + /* + * Print some cache stats. + */ + public void run() { + System.out.println("stats for asid " + hex(asid) + ":"); + System.out.println(" cacheMisses = " + cacheMisses); + System.out.println(" cacheHits = " + cacheHits); + System.out.println(" quickCacheHits = " + quickCacheHits); + } + }); + } + } + + /** + * Returns a general purpose Map object that AddressSpace users can use as they see fit. + * This map is provided as a convenience since users of AddressSpace often want to store + * related info somewhere. Care should be taken that nobody else has used the same key - + * one way to achieve this would be to use a class object as a key. + */ + public Map getUserMap() { + return userMap; + } + + /** + * Returns the MVS ASID (Address Space Identifier) for this address space. + */ + public int getAsid() { + return asid; + } + + /** + * Returns an array of all the {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressRange}s in this + * address space. An address range is simply a pair of [low, high] addresses for which + * memory is available in the dump. + */ + public AddressRange[] getAddressRanges() { + if (ranges != null) + return ranges; + /* Get the list of the start addresses of each block */ + long[] addresses = addressMap.getKeysArray(); + /* Sort it */ + Arrays.sort(addresses); + /* Now go through the list and create a new range every time we find a gap */ + long startAddress = 0; + long lastAddress = 0; + Vector v = new Vector(); + for (int i = 0; i < addresses.length; i++) { + if (i == 0) { + startAddress = addresses[0]; + } else if (addresses[i] != lastAddress + Dump.DATABLOCKSIZE) { + /* Found a discontinuity so create new AddressRange */ + v.add(new AddressRange(startAddress, lastAddress + 0x1000 - startAddress)); + startAddress = addresses[i]; + } + lastAddress = addresses[i]; + } + v.add(new AddressRange(startAddress, lastAddress + 0x1000 - startAddress)); + ranges = (AddressRange[])v.toArray(new AddressRange[0]); + return ranges; + } + + /** + * Returns an array of all the unused address ranges in the address space. This is + * the inverse of {@link #getAddressRanges}. + */ + public AddressRange[] getUnusedAddressRanges() { + getAddressRanges(); + AddressRange[] unused = new AddressRange[ranges.length - 1]; + for (int i = 0; i < unused.length; i++) { + long start = ranges[i].getEndAddress() + 1; + long end = ranges[i + 1].getStartAddress() - 1; + unused[i] = new AddressRange(start, end - start); + } + return unused; + } + + /** + * Returns an {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressSpaceImageInputStream} for this + * address space. The ImageInputStream interface provides a wealth of read methods. + */ + public AddressSpaceImageInputStream getImageInputStream() { + if (imageStream == null) + imageStream = new AddressSpaceImageInputStream(this); + assert imageStream != null; + return imageStream; + } + + /** + * This method is for debugging purposes only and should eventually disappear. We use the + * value of WILD_POINTER to indicate that a pointer has not been initialized (the chances + * of getting this value by accident are one in a very large number indeed). + */ + private void checkIfWild(long address) { + assert address != WILD_POINTER; + assert (int)address != (int)WILD_POINTER; + /* Also check if the access is anywhere near the uninitialized value for the + * time being. We may have done some pointer arithmetic with it. */ + assert (address < WILD_POINTER - 0x1000) || (address > WILD_POINTER + 0x1000) : hex(address); + assert ((int)address < (int)WILD_POINTER - 0x1000) || ((int)address > (int)WILD_POINTER + 0x1000) : hex((int)address); + } + + /** + * Rounds the address to the base page address and also strips the top bit if in 32-bit mode. + */ + protected long roundToPage(long address) { + checkIfWild(address); + if (is64bit()) { + return address & 0xfffffffffffff000L; + } else { + return address & 0x7ffff000; + } + } + + /** Strip the top bit if this is a 32-bit platform */ + public long stripTopBit(long address) { + checkIfWild(address); + if (is64bit()) { + assert address >= 0 : hex(address); + return address; + } else { + return address & 0x7fffffff; + } + } + + /** + * Read from the given address into the given buffer. + * @param address the address to read from + * @param buf the buffer to read into + */ + private void read(long address, byte[] buf) throws IOException { + if (log.isLoggable(Level.FINER)) + log.finer("request to read " + buf.length + " from address 0x" + hex(address)); + /* Round down to the nearest block */ + long blockAddress = roundToPage(address); + /* Get the offset in the dump file */ + long offset = addressMap.get(blockAddress); + if (offset == -1) { + /* + * Now this is weird code and almost certainly the wrong way to do it, + * but it seems to work: for certain low memory addresses, if they can't be + * found in our address space, they can sometimes be found in what I call + * the "root" address space with asid 1. Maybe this is kernel memory mapped into + * all other spaces? Who knows, anyway let's go and try there before giving up. + */ + if (asid != 1) { + offset = dump.rootSpace.addressMap.get(blockAddress); + if (offset != -1) + log.fine("found address " + hex(address) + " in root address space"); + } + if (offset == -1) + throw new IOException("block address " + hex(address) + " not in dump"); + } + /* Now we seek to that offset to get to the actual data */ + /* XXX not thread safe! */ + dump.seek(offset); + /* Finally read the requested bytes */ + if (buf.length <= Dump.DATABLOCKSIZE) { + dump.readFully(buf); + } else { + /* XXX do we actually need this? */ + throw new Error("to be completed"); + } + } + + /** + * See if the block is in the quick cache. + */ + final byte[] getBlockFromQuickCache(long address) { + assert (address & 0xfff) == 0; + if (address == lastBlockAddress) { + quickCacheHits++; + if (log.isLoggable(Level.FINEST)) + log.finest("request to get block for address 0x" + hex(address) + " met by quick cache"); + return lastBlock; + } + if (address == lastButOneBlockAddress) { + quickCacheHits++; + if (log.isLoggable(Level.FINEST)) + log.finest("request to get block for address 0x" + hex(address) + " met by quick cache"); + return lastButOneBlock; + } + return null; + } + + /** + * Place block in the quick cache. + */ + final void putBlockInQuickCache(long address, byte[] block) { + assert (address & 0xfff) == 0; + lastButOneBlockAddress = lastBlockAddress; + lastButOneBlock = lastBlock; + lastBlockAddress = address; + lastBlock = block; + } + + /** + * Get the block of bytes for the given address. Usually we find this in the cache. + */ + final byte[] getBlock(long address) throws IOException { + address = roundToPage(address); + /* Quickly check the cached last block(s). This gets the vast majority */ + byte[] b = getBlockFromQuickCache(address); + return b != null ? b : getBlockFromCacheOrDisk(address); + } + + /** + * Get the block either from the cache or from disk. This protected method is + * provided so that MutableAddressSpace has the chance to look in its own cache first. + */ + protected byte[] getBlockFromCacheOrDisk(long address) throws IOException { + assert (address & 0xfff) == 0; + /* Now look to see if the block is in the lru cache */ + byte[] block = (byte[])blockCache.get(address); + if (block == null) { + cacheMisses++; + /* Not found in cache so read from the file itself */ + block = new byte[Dump.DATABLOCKSIZE]; + read(address, block); + /* Put it in the cache */ + blockCache.put(address, block); + if (log.isLoggable(Level.FINEST)) + log.finest("request to get block for address 0x" + hex(address) + " met by file read"); + } else { + cacheHits++; + if (log.isLoggable(Level.FINEST)) + log.finest("request to get block for address 0x" + hex(address) + " met by cache"); + } + /* Store the last block read as a quick cache */ + putBlockInQuickCache(address, block); + return block; + } + + /** + * Read an unsigned byte at the specified address. + * @throws IOException if the given address is not present in this address space + */ + public int read(long address) throws IOException { + return (int)getBlock(address)[(int)address & 0xfff] & 0xff; + } + + /** + * Read an int at the specified address. + * @throws IOException if the given address is not present in this address space + */ + public int readInt(long address) throws IOException { + int offset = (int)address & 0xfff; + if (offset <= 0xffc) + return Dump.readInt(getBlock(address), offset); + int ch1 = read(address++); + int ch2 = read(address++); + int ch3 = read(address++); + int ch4 = read(address++); + return (ch1 << 24) | (ch2 << 16) | (ch3 << 8) | ch4; + } + + /** + * Read an unsigned byte at the specified address. + * @throws IOException if the given address is not present in this address space + */ + public int readUnsignedByte(long address) throws IOException { + return read(address); + } + + /** + * Read a (signed) byte at the specified address. + * @throws IOException if the given address is not present in this address space + */ + public byte readByte(long address) throws IOException { + return (byte)readUnsignedByte(address); + } + + /** + * Read an unsigned short at the specified address. + * @throws IOException if the given address is not present in this address space + */ + public int readUnsignedShort(long address) throws IOException { int ch1 = read(address); int ch2 = read(address + 1); return (ch1 << 8) | ch2; - } - - /** - * Read a (signed) short at the specified address. - * @throws IOException if the given address is not present in this address space - */ - public short readShort(long address) throws IOException { - return (short)readUnsignedShort(address); - } - - /** - * Read an unsigned int at the specified address. - * @throws IOException if the given address is not present in this address space - */ - public long readUnsignedInt(long address) throws IOException { - long i = readInt(address); - return i & 0xffffffffL; - } - - /** - * Read a long at the specified address. - * @throws IOException if the given address is not present in this address space - */ - public long readLong(long address) throws IOException { - long upper = readInt(address); - long lower = readInt(address + 4); - return (upper << 32) | (lower & 0xffffffffL); - } - - /** - * Read a word at the specified address. A word is either 32 or 64 bits depending on - * the machine context. - */ - public long readWord(long address) throws IOException { - return is64bit ? readLong(address) : (long)readInt(address) & 0xffffffffL; - } - - /** - * Returns the word length in bytes (either 4 or 8 bytes depending on the machine context). - */ - public int getWordLength() { - return is64bit ? 8 : 4; - } - - /** - * Reads len bytes of data from the given address into an array of bytes. - * @param address the address to read from - * @param b - the buffer into which the data is read - * @param off - the start offset in array b at which the data is written - * @param len - the number of bytes to read - */ - public void read(long address, byte[] b, int off, int len) throws IOException { - address = stripTopBit(address); - for (;;) { - byte[] block = getBlock(address); - int blockOffset = (int)(address % block.length); - int blockRemainder = block.length - blockOffset; - if (len <= blockRemainder) { - System.arraycopy(block, blockOffset, b, off, len); - return; - } - System.arraycopy(block, blockOffset, b, off, blockRemainder); - address += blockRemainder; - off += blockRemainder; - len -= blockRemainder; - } - } - - /** - * Read an EBCDIC String. This method expects to find a sequence of EBCDIC bytes at the - * given address. - * @param address the start address of the EBCDIC bytes - * @param length the number of bytes to be read - * @throws IOException if the given address is not present in this address space - */ - public String readEbcdicString(long address, int length) throws IOException { - byte[] b = new byte[length]; - read(address, b, 0, length); - return CharConversion.getEbcdicString(b); - } - - /** - * Read an EBCDIC String. Assumes that address points to the halfword length immediately - * followed by the EBCDIC bytes. - * @param address the start address of the EBCDIC bytes - * @throws IOException if the given address is not present in this address space - */ - public String readEbcdicString(long address) throws IOException { - int length = readUnsignedShort(address); - return readEbcdicString(address + 2, length); - } - - /** - * Read an EBCDIC String. Assumes that address points to a null-terminated EBCDIC string. - * @param address the start address of the EBCDIC bytes - * @throws IOException if the given address is not present in this address space - */ - public String readEbcdicCString(long address) throws IOException { - int length = 0; - for (long addr = address; read(addr) != 0; addr++, length++); - return readEbcdicString(address, length); - } - - /** - * Read an ASCII String. This method expects to find a sequence of ASCII bytes at the - * given address. - * @param address the start address of the ASCII bytes - * @param length the number of bytes to be read - * @throws IOException if the given address is not present in this address space - */ - public String readAsciiString(long address, int length) throws IOException { - StringBuffer buf = new StringBuffer(); - - for (int i = 0; i < length; i++) { - buf.append((char)read(address++)); - } - return buf.toString(); - } - - /** - * Read the ASCII string at the given address. Assumes that address points to a - * null-terminated ASCII C string. - * @param address the start address of the ASCII bytes - * @throws IOException if the given address is not present in this address space - */ - public String readAsciiCString(long address) throws IOException { - StringBuffer buf = new StringBuffer(); - int c; - - while ((c = read(address++)) != 0) { - buf.append((char)c); - } - return buf.toString(); - } - - /** - * Read an ASCII String. Assumes that address points to the halfword length immediately - * followed by the ASCII bytes. - * @param address the start address of the ASCII bytes - * @throws IOException if the given address is not present in this address space - */ - public String readAsciiString(long address) throws IOException { - int length = readUnsignedShort(address); - return readAsciiString(address + 2, length); - } - - /** - * Read a UTF8 String. Assumes that address points to the halfword length immediately - * followed by the utf8 bytes. - * XXX Despite the name no UTF8 conversion is done yet! (i.e. assumes ASCII) - * @param address the start address of the structure - * @throws IOException if the given address is not present in this address space - */ - public String readUtf8String(long address) throws IOException { - int length = readUnsignedShort(address); - return readAsciiString(address + 2, length); - } - - /** - * Returns true if the given address is present in this address space. - */ - public boolean isValid(long address) { - AddressRange[] ranges = getAddressRanges(); - for (int i = 0; i < ranges.length; i++) { - if (address >= ranges[i].getStartAddress() && address <= ranges[i].getEndAddress()) - return true; - } - return false; - } - - //zebedee function not required - // public long readLong(long address, Template template, String field) - - /** - * Returns true if this is a 64-bit machine - */ - public boolean is64bit() { - return is64bit; - } - - /** - * Sets whether this is a 64-bit machine. Unfortunately there is no way of knowing at - * the beginning if we are running in 64-bit mode, this is only discovered in le/Caa. - * So perhaps this knowledge should only be in the le layer? - */ - public void setIs64bit(boolean is64bit) { - log.fine("Set address space " + asid + " as " + (is64bit ? "64-bit" : "32-bit")); - this.is64bit = is64bit; - } - - /** - * Map an address to an offset in the dump file. This is the offset of the block header. - */ - void mapAddressToFileOffset(long address, long offset) { - /* - * You can get the same address mapped to different offsets in the dump and the contents - * vary slightly. I'm not sure why this is or what to do about it, but for now we just - * ignore any duplicates. - */ - if (addressMap.get(address) != -1) { - if (log.isLoggable(Level.FINER)) - log.finer("duplicate address 0x" + hex(address) + " for asid " + asid); - return; - } - if (log.isLoggable(Level.FINER)) - log.finer("mapping address 0x" + hex(address) + " to offset " + hex(offset) + " for asid " + asid); - addressMap.put(address, offset); - } - - private static String hex(int i) { - return Integer.toHexString(i); - } - - private static String hex(long i) { - return Long.toHexString(i); - } - - /** - * Returns the address space id as a hex string. - */ - public String toString() { - return hex(asid); - } - - /** - * Sets the dump (only used when an AddressSpace has been deserialized). - */ - void setDump(Dump dump) { - this.dump = dump; - } - - /** - * Serialize this object. - */ - private void writeObject(ObjectOutputStream out) throws IOException { - out.writeInt(asid); - out.writeObject(addressMap); - } - - /** - * Unserialize this object. - */ - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - asid = in.readInt(); - addressMap = (IntegerMap)in.readObject(); - initialize(); - } + } + + /** + * Read a (signed) short at the specified address. + * @throws IOException if the given address is not present in this address space + */ + public short readShort(long address) throws IOException { + return (short)readUnsignedShort(address); + } + + /** + * Read an unsigned int at the specified address. + * @throws IOException if the given address is not present in this address space + */ + public long readUnsignedInt(long address) throws IOException { + long i = readInt(address); + return i & 0xffffffffL; + } + + /** + * Read a long at the specified address. + * @throws IOException if the given address is not present in this address space + */ + public long readLong(long address) throws IOException { + long upper = readInt(address); + long lower = readInt(address + 4); + return (upper << 32) | (lower & 0xffffffffL); + } + + /** + * Read a word at the specified address. A word is either 32 or 64 bits depending on + * the machine context. + */ + public long readWord(long address) throws IOException { + return is64bit ? readLong(address) : (long)readInt(address) & 0xffffffffL; + } + + /** + * Returns the word length in bytes (either 4 or 8 bytes depending on the machine context). + */ + public int getWordLength() { + return is64bit ? 8 : 4; + } + + /** + * Reads len bytes of data from the given address into an array of bytes. + * @param address the address to read from + * @param b - the buffer into which the data is read + * @param off - the start offset in array b at which the data is written + * @param len - the number of bytes to read + */ + public void read(long address, byte[] b, int off, int len) throws IOException { + address = stripTopBit(address); + for (;;) { + byte[] block = getBlock(address); + int blockOffset = (int)(address % block.length); + int blockRemainder = block.length - blockOffset; + if (len <= blockRemainder) { + System.arraycopy(block, blockOffset, b, off, len); + return; + } + System.arraycopy(block, blockOffset, b, off, blockRemainder); + address += blockRemainder; + off += blockRemainder; + len -= blockRemainder; + } + } + + /** + * Read an EBCDIC String. This method expects to find a sequence of EBCDIC bytes at the + * given address. + * @param address the start address of the EBCDIC bytes + * @param length the number of bytes to be read + * @throws IOException if the given address is not present in this address space + */ + public String readEbcdicString(long address, int length) throws IOException { + byte[] b = new byte[length]; + read(address, b, 0, length); + return CharConversion.getEbcdicString(b); + } + + /** + * Read an EBCDIC String. Assumes that address points to the halfword length immediately + * followed by the EBCDIC bytes. + * @param address the start address of the EBCDIC bytes + * @throws IOException if the given address is not present in this address space + */ + public String readEbcdicString(long address) throws IOException { + int length = readUnsignedShort(address); + return readEbcdicString(address + 2, length); + } + + /** + * Read an EBCDIC String. Assumes that address points to a null-terminated EBCDIC string. + * @param address the start address of the EBCDIC bytes + * @throws IOException if the given address is not present in this address space + */ + public String readEbcdicCString(long address) throws IOException { + int length = 0; + for (long addr = address; read(addr) != 0; addr++, length++); + return readEbcdicString(address, length); + } + + /** + * Read an ASCII String. This method expects to find a sequence of ASCII bytes at the + * given address. + * @param address the start address of the ASCII bytes + * @param length the number of bytes to be read + * @throws IOException if the given address is not present in this address space + */ + public String readAsciiString(long address, int length) throws IOException { + StringBuffer buf = new StringBuffer(); + + for (int i = 0; i < length; i++) { + buf.append((char)read(address++)); + } + return buf.toString(); + } + + /** + * Read the ASCII string at the given address. Assumes that address points to a + * null-terminated ASCII C string. + * @param address the start address of the ASCII bytes + * @throws IOException if the given address is not present in this address space + */ + public String readAsciiCString(long address) throws IOException { + StringBuffer buf = new StringBuffer(); + int c; + + while ((c = read(address++)) != 0) { + buf.append((char)c); + } + return buf.toString(); + } + + /** + * Read an ASCII String. Assumes that address points to the halfword length immediately + * followed by the ASCII bytes. + * @param address the start address of the ASCII bytes + * @throws IOException if the given address is not present in this address space + */ + public String readAsciiString(long address) throws IOException { + int length = readUnsignedShort(address); + return readAsciiString(address + 2, length); + } + + /** + * Read a UTF8 String. Assumes that address points to the halfword length immediately + * followed by the utf8 bytes. + * XXX Despite the name no UTF8 conversion is done yet! (i.e. assumes ASCII) + * @param address the start address of the structure + * @throws IOException if the given address is not present in this address space + */ + public String readUtf8String(long address) throws IOException { + int length = readUnsignedShort(address); + return readAsciiString(address + 2, length); + } + + /** + * Returns true if the given address is present in this address space. + */ + public boolean isValid(long address) { + AddressRange[] ranges = getAddressRanges(); + for (int i = 0; i < ranges.length; i++) { + if (address >= ranges[i].getStartAddress() && address <= ranges[i].getEndAddress()) + return true; + } + return false; + } + + //zebedee function not required + // public long readLong(long address, Template template, String field) + + /** + * Returns true if this is a 64-bit machine + */ + public boolean is64bit() { + return is64bit; + } + + /** + * Sets whether this is a 64-bit machine. Unfortunately there is no way of knowing at + * the beginning if we are running in 64-bit mode, this is only discovered in le/Caa. + * So perhaps this knowledge should only be in the le layer? + */ + public void setIs64bit(boolean is64bit) { + log.fine("Set address space " + asid + " as " + (is64bit ? "64-bit" : "32-bit")); + this.is64bit = is64bit; + } + + /** + * Map an address to an offset in the dump file. This is the offset of the block header. + */ + void mapAddressToFileOffset(long address, long offset) { + /* + * You can get the same address mapped to different offsets in the dump and the contents + * vary slightly. I'm not sure why this is or what to do about it, but for now we just + * ignore any duplicates. + */ + if (addressMap.get(address) != -1) { + if (log.isLoggable(Level.FINER)) + log.finer("duplicate address 0x" + hex(address) + " for asid " + asid); + return; + } + if (log.isLoggable(Level.FINER)) + log.finer("mapping address 0x" + hex(address) + " to offset " + hex(offset) + " for asid " + asid); + addressMap.put(address, offset); + } + + private static String hex(int i) { + return Integer.toHexString(i); + } + + private static String hex(long i) { + return Long.toHexString(i); + } + + /** + * Returns the address space id as a hex string. + */ + public String toString() { + return hex(asid); + } + + /** + * Sets the dump (only used when an AddressSpace has been deserialized). + */ + void setDump(Dump dump) { + this.dump = dump; + } + + /** + * Serialize this object. + */ + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeInt(asid); + out.writeObject(addressMap); + } + + /** + * Unserialize this object. + */ + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + asid = in.readInt(); + addressMap = (IntegerMap)in.readObject(); + initialize(); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressSpaceImageInputStream.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressSpaceImageInputStream.java index 71e858b9590..8a8c814dbdd 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressSpaceImageInputStream.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/AddressSpaceImageInputStream.java @@ -41,74 +41,74 @@ public final class AddressSpaceImageInputStream extends ImageInputStreamImpl { - private AddressSpace space; - /** Logger */ - private static Logger log = Logger.getLogger(AddressSpaceImageInputStream.class.getName()); + private AddressSpace space; + /** Logger */ + private static Logger log = Logger.getLogger(AddressSpaceImageInputStream.class.getName()); - /** - * Create a new AddressSpaceImageInputStream for the given AddressSpace. - * @param space the AddressSpace which this stream reads - */ - public AddressSpaceImageInputStream(AddressSpace space) { - this.space = space; - } + /** + * Create a new AddressSpaceImageInputStream for the given AddressSpace. + * @param space the AddressSpace which this stream reads + */ + public AddressSpaceImageInputStream(AddressSpace space) { + this.space = space; + } - /** - * Read a byte from the current position. Also increments streamPos. - */ - public int read() throws IOException { - return space.read(streamPos++); - } + /** + * Read a byte from the current position. Also increments streamPos. + */ + public int read() throws IOException { + return space.read(streamPos++); + } - /** - * Read some bytes from the current position and add len to streamPos. - */ - public int read(byte[] b, int off, int len) throws IOException { - space.read(streamPos, b, off, len); - streamPos += len; - return len; - } + /** + * Read some bytes from the current position and add len to streamPos. + */ + public int read(byte[] b, int off, int len) throws IOException { + space.read(streamPos, b, off, len); + streamPos += len; + return len; + } - public void seek(long pos) throws IOException { - pos = space.stripTopBit(pos); - if (pos <= 0) - throw new IOException("attempt to seek to invalid pos: 0x" + hex(pos)); - super.seek(pos); - if (log.isLoggable(Level.FINER)) - log.finer("seek to 0x" + hex(pos) + " streamPos now 0x" + hex(streamPos)); - } + public void seek(long pos) throws IOException { + pos = space.stripTopBit(pos); + if (pos <= 0) + throw new IOException("attempt to seek to invalid pos: 0x" + hex(pos)); + super.seek(pos); + if (log.isLoggable(Level.FINER)) + log.finer("seek to 0x" + hex(pos) + " streamPos now 0x" + hex(streamPos)); + } - /** - * Read an int from the current position. Also increments streamPos. - * For efficiency to avoid multiple reads via ImageInputStream - */ - public int readInt() throws IOException { - int ret = space.readInt(streamPos); - streamPos += 4; - return ret; - } + /** + * Read an int from the current position. Also increments streamPos. + * For efficiency to avoid multiple reads via ImageInputStream + */ + public int readInt() throws IOException { + int ret = space.readInt(streamPos); + streamPos += 4; + return ret; + } - /** - * Read an unsigned int from the current position. Also increments streamPos. - * For efficiency to avoid multiple reads via ImageInputStream - */ - public long readUnsignedInt() throws IOException { - long ret = space.readUnsignedInt(streamPos); - streamPos += 4; - return ret; - } + /** + * Read an unsigned int from the current position. Also increments streamPos. + * For efficiency to avoid multiple reads via ImageInputStream + */ + public long readUnsignedInt() throws IOException { + long ret = space.readUnsignedInt(streamPos); + streamPos += 4; + return ret; + } - /** - * Read a long from the current position. Also increments streamPos. - * For efficiency to avoid multiple reads via ImageInputStream - */ - public long readLong() throws IOException { - long ret = space.readLong(streamPos); - streamPos += 8; - return ret; - } + /** + * Read a long from the current position. Also increments streamPos. + * For efficiency to avoid multiple reads via ImageInputStream + */ + public long readLong() throws IOException { + long ret = space.readLong(streamPos); + streamPos += 8; + return ret; + } - private static String hex(long i) { - return Long.toHexString(i); - } + private static String hex(long i) { + return Long.toHexString(i); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/Dump.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/Dump.java index 14deb3f1413..852236821ef 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/Dump.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/Dump.java @@ -66,328 +66,328 @@ public final class Dump extends ImageInputStreamImpl { - //com.ibm.jvm.ras.svcdump.Dump dump; - /** The dump filename */ - private String filename; - /** The file pointer if this is an MVS dataset */ - private long fp; - /** True if this is an MVS dataset */ - private boolean isMvsDataset; - /** The file object to use if not an MVS dataset */ - private ImageInputStream raf; - /** The array of AddressSpaces */ - private AddressSpace[] spaces; - /** The title of the dump */ - private String title; - /** The z/OS product name */ - private String productName; - /** The z/OS product version */ - private String productVersion; - /** The z/OS product release */ - private String productRelease; - /** The z/OS product modification */ - private String productModification; - /** The date when the dump was created */ - private Date creationDate; - /** This is the special "root" address space with asid 1. I don't know why, but for some - low addresses you have to look in here. */ - AddressSpace rootSpace; - /** Contains the fpos positions for every block in an MVS dataset */ - private CompressedRecordArray fposArray; - private int[] fpos = new int[8]; - /** Size of a block header */ - static final int HEADERSIZE = 0x40; - /** Size of a block excluding header */ - static final int DATABLOCKSIZE = 0x1000; - /** Size of a block including header */ - static final int BLOCKSIZE = DATABLOCKSIZE + HEADERSIZE; - private static final int DR1 = 0xc4d9f140; - private static final int DR2 = 0xc4d9f240; - /** Logger */ - private static Logger log = Logger.getLogger(Dump.class.getName()); - - /** - * Returns true if the given filename is a valid svcdump. - */ - public static boolean isValid(String filename) { - try { - // RNC: never create .zcache files in DTFJ - new Dump(filename, null, false, null, true); - return true; - } catch (FileNotFoundException e) { - return false; - } - } - - /** - * Creates a new instance of Dump from the given filename. The filename must represent - * either an absolute or relative pathname of the dump file, or if running on z/os it can - * be an MVS dataset name (eg DGRIFF.MYDUMP). - * @param filename the name of the dump to open - * @throws FileNotFoundException - */ - public Dump(String filename) throws FileNotFoundException { - // RNC: never create .zcache files in DTFJ - this(filename, null, true, null, false); - } - - /** - * Creates a new instance of Dump from the given filename. The filename must represent - * either an absolute or relative pathname of the dump file, or if running on z/os it can - * be an MVS dataset name (eg DGRIFF.MYDUMP). - * Alternatively an ImageInputStream can be provided if the file is already open. - * @param filename the name of the dump to open, also used to open the cache file - * @param stream an ImageInputStream for the dump or null - used in preference to opening the file - * @param createCacheFile Create a cache file based on the filename - * @throws FileNotFoundException - */ - public Dump(String filename, ImageInputStream stream, boolean createCacheFile) throws FileNotFoundException { - // RNC: never create .zcache files in DTFJ - this(filename, null, true, stream, createCacheFile); - } - - /** - * Creates a new instance of Dump from the given filename. The filename must represent - * either an absolute or relative pathname of the dump file, or if running on z/os it can - * be an MVS dataset name. - *

        - * This constructor also supplies an array of {@link SearchListener}s - * to inform the caller of matches found whilst scanning the dump. Note that this will - * force a scan of the dump which is otherwise normally only done the first time this dump - * is opened. (XXX can probably avoid this by cacheing earlier search results). - * @param filename the name of the dump to open - * @param listeners the array of {@link SearchListener}s to be notified of interesting matches - * @throws FileNotFoundException - */ - public Dump(String filename, SearchListener[] listeners) throws FileNotFoundException { - // RNC: never create .zcache files in DTFJ - this(filename, listeners, true, null, true); - } - - /** - * This is the private constructor where the real work is done. - * @param filename the name of the dump to open - * @param listeners the array of {@link SearchListener}s to be notified of interesting matches - * @param buildAddressSpaces true if the list of address spaces is also to be built - * @param createCacheFile Whether to create a cache file - * @throws FileNotFoundException - */ - private Dump(String filename, SearchListener[] listeners, boolean buildAddressSpaces, ImageInputStream instream, boolean createCacheFile) throws FileNotFoundException { - log.fine("opening dump " + filename+" stream "+instream); - this.filename = filename; - if (listeners != null) - throw new Error("tbc"); - try { - //dump = new com.ibm.jvm.ras.svcdump.Dump(filename); - //log.fine("finished opening old svcdump"); - if (instream != null) { - raf = instream; - } else { - raf = new FileImageInputStream(new RandomAccessFile(filename, "r")); - } - if (buildAddressSpaces) { - buildAddressSpaces(createCacheFile); - log.fine("finished building address spaces"); - } - return; - } catch (Exception e) { - if (!System.getProperty("os.arch").equals("390")) { - FileNotFoundException e2 = new FileNotFoundException("Could not find: " + filename+ " stream " + instream); - e2.initCause(e); - throw e2; - } - } - openMvsDataset(); - if (buildAddressSpaces) { - buildAddressSpaces(createCacheFile); - log.fine("finished building address spaces"); - } - } - - private void openMvsDataset() throws FileNotFoundException { - try { - /* - * Ok, we couldn't find the file and we're running on z/OS so maybe this is - * an MVS dataset. Load the native library and try to open it with fopen. - */ - - /* - * Following code allows us to bundle the lib inside the jar file. Wish there was - * an easier way! - */ - log.fine("trying to open dump as an MVS dataset"); - String version = System.getProperty("java.version"); - InputStream is = getClass().getResourceAsStream("libzebedee" + version.charAt(2) + ".so"); - BufferedInputStream bis = new BufferedInputStream(is); - File tmp = File.createTempFile("lib", ".so"); - java.lang.Process proc = Runtime.getRuntime().exec("chmod +x " + tmp.getPath()); - proc.waitFor(); - int exitcode = proc.exitValue(); - FileOutputStream fos = new FileOutputStream(tmp); - BufferedOutputStream bos = new BufferedOutputStream(fos); - byte[] b = new byte[10000]; - for (int n = 0; (n = bis.read(b)) != -1;) { - bos.write(b, 0, n); - } - bos.close(); - tmp.deleteOnExit(); - System.load(tmp.getPath()); - log.fine("lib loaded ok"); - /* - * Phew, we've loaded the library at last, now call fopen. - */ - fp = Clib.fopen("//'" + filename + "'", "rb"); - if (fp == 0) { - throw new FileNotFoundException("Could not find either " + filename + " or //" + filename); - } - isMvsDataset = true; - log.fine("MVS dataset opened ok"); - } catch (Exception e) { - throw new FileNotFoundException("Could not find: " + filename); - } - } - - /** - * Build the array of AddressSpaces. If this is the first time this dump has been opened - * (no cache file exists) then every block of the dump is scanned to build a mapping for - * each AddressSpace of address to block number (each block has a header containing the - * AddressSpace id and the address it maps to). At the same time if this is an MVS dataset, - * the table of fpos info is built. - *

        - * If a cache file exists then the AddressSpace and fpos info is read from that instead. - * @param createCacheFile Whether to create a new cache file - */ - private void buildAddressSpaces(boolean createCacheFile) { - try { - try { - /* - * First try and get everything from the cache file. - */ - if (filename == null) throw new FileNotFoundException("No filename supplied so no cache available"); - File fn = new File(filename + ".zcache"); - readCacheFile(fn); - } catch (Exception e) { - log.log(Level.FINE, "cache read failed: ", e); - /* - * Well reading from the cache file didn't work so create a new cache file - * and scan the dump. - */ - log.fine("no cache file, scanning file"); - byte[] blockHeader = null; - /* fpos stuff is for MVS datasets only */ - fposArray = new CompressedRecordArray(5, fpos.length); - /* Address space map */ - ObjectMap asidMap = new ObjectMap(); - for (long offset = 0; ; offset += BLOCKSIZE) { - /* Seek to this block header */ - if (isMvsDataset) { - if (offset > 0) { - /* - * For MVS datasets we have to be careful how we do the seek. - * fseek is basically broken, it gives horrendous results when - * you seek to an absolute position owing to the fact it must scan - * from the start of the file each time to cater for "holes" in - * the file. So we seek from the current position (just after the - * last read). - */ - int rc = Clib.fseek(fp, BLOCKSIZE - HEADERSIZE, Clib.SEEK_CUR); - assert rc == 0 : rc; - } - } else { - raf.seek(offset); - } - /* - * Read the block header. - */ - if (offset == 0) - /* We read a little bit more of the first block */ - blockHeader = new byte[0x200]; - else if (offset == BLOCKSIZE) - blockHeader = new byte[HEADERSIZE]; - try { - readFully(blockHeader); - } catch (EOFException eof) { - /* Reached the end of the file so break from the loop */ - break; - } - - if (isMvsDataset) { - /* - * For MVS datasets we now squirrel away the fpos info. Once we're done - * scanning the file, from then on we will use fsetpos rather than fseek - * due to the aforementioned performance problems with fseek. The fpos - * structure contains sufficient info for fsetpos to go straight there. - */ - int rc = Clib.fgetpos(fp, fpos); - assert rc == 0 : rc; - fposArray.add(fpos); - } - /* Get the eyecatcher which should be either "DR1 " (old format) or "DR2 " */ - int eye = readInt(blockHeader, 0); - boolean oldFormat = false; - if (eye == DR1) { - oldFormat = true; - } else if (eye != DR2) { - throw new Error("bad eyecatcher " + hex(eye) + " at offset " + offset); - } - /* Get the address space id */ - int asid = readInt(blockHeader, 12); - /* Ignore the ones with weird asids */ - if (asid < 0) - continue; - /* Get the logical address */ - long address = oldFormat ? readInt(blockHeader, 20) : readLong(blockHeader, 20); - if (log.isLoggable(Level.FINER)) - log.finer("read block, asid = " + hex(asid) + " address = " + hex(address)); - /* - * Do we already have an AddressSpace object for this asid? If not, create one - */ - AddressSpace space = (AddressSpace)asidMap.get(asid); - if (space == null) { - space = new AddressSpace(this, asid); - asidMap.put(asid, space); - } - /* Map the address to the current file position */ - space.mapAddressToFileOffset(address, offset + HEADERSIZE); - /* Save the "root" address space */ - if (asid == 1) - rootSpace = space; - if (offset == 0) { - /* This is the first block so save away the date and title */ - byte[] titlebuf = new byte[100]; - System.arraycopy(blockHeader, 0x58, titlebuf, 0, 100); - title = CharConversion.getEbcdicString(titlebuf); - productName = CharConversion.getEbcdicString(blockHeader, 0xf4, 16); - productVersion = CharConversion.getEbcdicString(blockHeader, 0x104, 2); - productRelease = CharConversion.getEbcdicString(blockHeader, 0x106, 2); - long c1 = readInt(blockHeader, 0x12 * 4); - long c2 = readInt(blockHeader, 0x13 * 4); - creationDate = mvsClockToDate((c1 << 32) | (c2 & 0xffffffffL)); - } - } - fposArray.close(); - if (isMvsDataset) log.fine("fposArray used " + fposArray.memoryUsage()); - spaces = (AddressSpace[])asidMap.toArray(new AddressSpace[0]); - Arrays.sort(spaces, new Comparator() { - public int compare(Object o1, Object o2) { - AddressSpace space1 = (AddressSpace)o1; - AddressSpace space2 = (AddressSpace)o2; - return space1.getAsid() - space2.getAsid(); - } - }); - // Reset the file pointer for the Dump ImageInputStream - seek(0); - log.fine("scan complete"); - // Create the cache if required - if (createCacheFile && filename != null) { - File cacheFile = new File(filename + ".zcache"); - createCacheFile(cacheFile); - } - } - } catch (IOException e) { - throw new Error("Unexpected exception reading address spaces", e); - } - } + //com.ibm.jvm.ras.svcdump.Dump dump; + /** The dump filename */ + private String filename; + /** The file pointer if this is an MVS dataset */ + private long fp; + /** True if this is an MVS dataset */ + private boolean isMvsDataset; + /** The file object to use if not an MVS dataset */ + private ImageInputStream raf; + /** The array of AddressSpaces */ + private AddressSpace[] spaces; + /** The title of the dump */ + private String title; + /** The z/OS product name */ + private String productName; + /** The z/OS product version */ + private String productVersion; + /** The z/OS product release */ + private String productRelease; + /** The z/OS product modification */ + private String productModification; + /** The date when the dump was created */ + private Date creationDate; + /** This is the special "root" address space with asid 1. I don't know why, but for some + low addresses you have to look in here. */ + AddressSpace rootSpace; + /** Contains the fpos positions for every block in an MVS dataset */ + private CompressedRecordArray fposArray; + private int[] fpos = new int[8]; + /** Size of a block header */ + static final int HEADERSIZE = 0x40; + /** Size of a block excluding header */ + static final int DATABLOCKSIZE = 0x1000; + /** Size of a block including header */ + static final int BLOCKSIZE = DATABLOCKSIZE + HEADERSIZE; + private static final int DR1 = 0xc4d9f140; + private static final int DR2 = 0xc4d9f240; + /** Logger */ + private static Logger log = Logger.getLogger(Dump.class.getName()); + + /** + * Returns true if the given filename is a valid svcdump. + */ + public static boolean isValid(String filename) { + try { + // RNC: never create .zcache files in DTFJ + new Dump(filename, null, false, null, true); + return true; + } catch (FileNotFoundException e) { + return false; + } + } + + /** + * Creates a new instance of Dump from the given filename. The filename must represent + * either an absolute or relative pathname of the dump file, or if running on z/os it can + * be an MVS dataset name (eg DGRIFF.MYDUMP). + * @param filename the name of the dump to open + * @throws FileNotFoundException + */ + public Dump(String filename) throws FileNotFoundException { + // RNC: never create .zcache files in DTFJ + this(filename, null, true, null, false); + } + + /** + * Creates a new instance of Dump from the given filename. The filename must represent + * either an absolute or relative pathname of the dump file, or if running on z/os it can + * be an MVS dataset name (eg DGRIFF.MYDUMP). + * Alternatively an ImageInputStream can be provided if the file is already open. + * @param filename the name of the dump to open, also used to open the cache file + * @param stream an ImageInputStream for the dump or null - used in preference to opening the file + * @param createCacheFile Create a cache file based on the filename + * @throws FileNotFoundException + */ + public Dump(String filename, ImageInputStream stream, boolean createCacheFile) throws FileNotFoundException { + // RNC: never create .zcache files in DTFJ + this(filename, null, true, stream, createCacheFile); + } + + /** + * Creates a new instance of Dump from the given filename. The filename must represent + * either an absolute or relative pathname of the dump file, or if running on z/os it can + * be an MVS dataset name. + *

        + * This constructor also supplies an array of {@link SearchListener}s + * to inform the caller of matches found whilst scanning the dump. Note that this will + * force a scan of the dump which is otherwise normally only done the first time this dump + * is opened. (XXX can probably avoid this by cacheing earlier search results). + * @param filename the name of the dump to open + * @param listeners the array of {@link SearchListener}s to be notified of interesting matches + * @throws FileNotFoundException + */ + public Dump(String filename, SearchListener[] listeners) throws FileNotFoundException { + // RNC: never create .zcache files in DTFJ + this(filename, listeners, true, null, true); + } + + /** + * This is the private constructor where the real work is done. + * @param filename the name of the dump to open + * @param listeners the array of {@link SearchListener}s to be notified of interesting matches + * @param buildAddressSpaces true if the list of address spaces is also to be built + * @param createCacheFile Whether to create a cache file + * @throws FileNotFoundException + */ + private Dump(String filename, SearchListener[] listeners, boolean buildAddressSpaces, ImageInputStream instream, boolean createCacheFile) throws FileNotFoundException { + log.fine("opening dump " + filename+" stream "+instream); + this.filename = filename; + if (listeners != null) + throw new Error("tbc"); + try { + //dump = new com.ibm.jvm.ras.svcdump.Dump(filename); + //log.fine("finished opening old svcdump"); + if (instream != null) { + raf = instream; + } else { + raf = new FileImageInputStream(new RandomAccessFile(filename, "r")); + } + if (buildAddressSpaces) { + buildAddressSpaces(createCacheFile); + log.fine("finished building address spaces"); + } + return; + } catch (Exception e) { + if (!System.getProperty("os.arch").equals("390")) { + FileNotFoundException e2 = new FileNotFoundException("Could not find: " + filename+ " stream " + instream); + e2.initCause(e); + throw e2; + } + } + openMvsDataset(); + if (buildAddressSpaces) { + buildAddressSpaces(createCacheFile); + log.fine("finished building address spaces"); + } + } + + private void openMvsDataset() throws FileNotFoundException { + try { + /* + * Ok, we couldn't find the file and we're running on z/OS so maybe this is + * an MVS dataset. Load the native library and try to open it with fopen. + */ + + /* + * Following code allows us to bundle the lib inside the jar file. Wish there was + * an easier way! + */ + log.fine("trying to open dump as an MVS dataset"); + String version = System.getProperty("java.version"); + InputStream is = getClass().getResourceAsStream("libzebedee" + version.charAt(2) + ".so"); + BufferedInputStream bis = new BufferedInputStream(is); + File tmp = File.createTempFile("lib", ".so"); + java.lang.Process proc = Runtime.getRuntime().exec("chmod +x " + tmp.getPath()); + proc.waitFor(); + int exitcode = proc.exitValue(); + FileOutputStream fos = new FileOutputStream(tmp); + BufferedOutputStream bos = new BufferedOutputStream(fos); + byte[] b = new byte[10000]; + for (int n = 0; (n = bis.read(b)) != -1;) { + bos.write(b, 0, n); + } + bos.close(); + tmp.deleteOnExit(); + System.load(tmp.getPath()); + log.fine("lib loaded ok"); + /* + * Phew, we've loaded the library at last, now call fopen. + */ + fp = Clib.fopen("//'" + filename + "'", "rb"); + if (fp == 0) { + throw new FileNotFoundException("Could not find either " + filename + " or //" + filename); + } + isMvsDataset = true; + log.fine("MVS dataset opened ok"); + } catch (Exception e) { + throw new FileNotFoundException("Could not find: " + filename); + } + } + + /** + * Build the array of AddressSpaces. If this is the first time this dump has been opened + * (no cache file exists) then every block of the dump is scanned to build a mapping for + * each AddressSpace of address to block number (each block has a header containing the + * AddressSpace id and the address it maps to). At the same time if this is an MVS dataset, + * the table of fpos info is built. + *

        + * If a cache file exists then the AddressSpace and fpos info is read from that instead. + * @param createCacheFile Whether to create a new cache file + */ + private void buildAddressSpaces(boolean createCacheFile) { + try { + try { + /* + * First try and get everything from the cache file. + */ + if (filename == null) throw new FileNotFoundException("No filename supplied so no cache available"); + File fn = new File(filename + ".zcache"); + readCacheFile(fn); + } catch (Exception e) { + log.log(Level.FINE, "cache read failed: ", e); + /* + * Well reading from the cache file didn't work so create a new cache file + * and scan the dump. + */ + log.fine("no cache file, scanning file"); + byte[] blockHeader = null; + /* fpos stuff is for MVS datasets only */ + fposArray = new CompressedRecordArray(5, fpos.length); + /* Address space map */ + ObjectMap asidMap = new ObjectMap(); + for (long offset = 0; ; offset += BLOCKSIZE) { + /* Seek to this block header */ + if (isMvsDataset) { + if (offset > 0) { + /* + * For MVS datasets we have to be careful how we do the seek. + * fseek is basically broken, it gives horrendous results when + * you seek to an absolute position owing to the fact it must scan + * from the start of the file each time to cater for "holes" in + * the file. So we seek from the current position (just after the + * last read). + */ + int rc = Clib.fseek(fp, BLOCKSIZE - HEADERSIZE, Clib.SEEK_CUR); + assert rc == 0 : rc; + } + } else { + raf.seek(offset); + } + /* + * Read the block header. + */ + if (offset == 0) + /* We read a little bit more of the first block */ + blockHeader = new byte[0x200]; + else if (offset == BLOCKSIZE) + blockHeader = new byte[HEADERSIZE]; + try { + readFully(blockHeader); + } catch (EOFException eof) { + /* Reached the end of the file so break from the loop */ + break; + } + + if (isMvsDataset) { + /* + * For MVS datasets we now squirrel away the fpos info. Once we're done + * scanning the file, from then on we will use fsetpos rather than fseek + * due to the aforementioned performance problems with fseek. The fpos + * structure contains sufficient info for fsetpos to go straight there. + */ + int rc = Clib.fgetpos(fp, fpos); + assert rc == 0 : rc; + fposArray.add(fpos); + } + /* Get the eyecatcher which should be either "DR1 " (old format) or "DR2 " */ + int eye = readInt(blockHeader, 0); + boolean oldFormat = false; + if (eye == DR1) { + oldFormat = true; + } else if (eye != DR2) { + throw new Error("bad eyecatcher " + hex(eye) + " at offset " + offset); + } + /* Get the address space id */ + int asid = readInt(blockHeader, 12); + /* Ignore the ones with weird asids */ + if (asid < 0) + continue; + /* Get the logical address */ + long address = oldFormat ? readInt(blockHeader, 20) : readLong(blockHeader, 20); + if (log.isLoggable(Level.FINER)) + log.finer("read block, asid = " + hex(asid) + " address = " + hex(address)); + /* + * Do we already have an AddressSpace object for this asid? If not, create one + */ + AddressSpace space = (AddressSpace)asidMap.get(asid); + if (space == null) { + space = new AddressSpace(this, asid); + asidMap.put(asid, space); + } + /* Map the address to the current file position */ + space.mapAddressToFileOffset(address, offset + HEADERSIZE); + /* Save the "root" address space */ + if (asid == 1) + rootSpace = space; + if (offset == 0) { + /* This is the first block so save away the date and title */ + byte[] titlebuf = new byte[100]; + System.arraycopy(blockHeader, 0x58, titlebuf, 0, 100); + title = CharConversion.getEbcdicString(titlebuf); + productName = CharConversion.getEbcdicString(blockHeader, 0xf4, 16); + productVersion = CharConversion.getEbcdicString(blockHeader, 0x104, 2); + productRelease = CharConversion.getEbcdicString(blockHeader, 0x106, 2); + long c1 = readInt(blockHeader, 0x12 * 4); + long c2 = readInt(blockHeader, 0x13 * 4); + creationDate = mvsClockToDate((c1 << 32) | (c2 & 0xffffffffL)); + } + } + fposArray.close(); + if (isMvsDataset) log.fine("fposArray used " + fposArray.memoryUsage()); + spaces = (AddressSpace[])asidMap.toArray(new AddressSpace[0]); + Arrays.sort(spaces, new Comparator() { + public int compare(Object o1, Object o2) { + AddressSpace space1 = (AddressSpace)o1; + AddressSpace space2 = (AddressSpace)o2; + return space1.getAsid() - space2.getAsid(); + } + }); + // Reset the file pointer for the Dump ImageInputStream + seek(0); + log.fine("scan complete"); + // Create the cache if required + if (createCacheFile && filename != null) { + File cacheFile = new File(filename + ".zcache"); + createCacheFile(cacheFile); + } + } + } catch (IOException e) { + throw new Error("Unexpected exception reading address spaces", e); + } + } /** * Read the cache file in @@ -404,18 +404,18 @@ private void readCacheFile(File cacheFile) throws FileNotFoundException, spaces = (AddressSpace[])ois.readObject(); /* Got the spaces, now set the dump to us */ for (int i = 0; i < spaces.length; i++) { - spaces[i].setDump(this); - /* Save the "root" address space */ - if (spaces[i].getAsid() == 1) - rootSpace = spaces[i]; + spaces[i].setDump(this); + /* Save the "root" address space */ + if (spaces[i].getAsid() == 1) + rootSpace = spaces[i]; } fposArray = (CompressedRecordArray)ois.readObject(); title = (String)ois.readObject(); creationDate = (Date)ois.readObject(); - productName = (String)ois.readObject(); - productVersion = (String)ois.readObject(); - productRelease = (String)ois.readObject(); - productModification = (String)ois.readObject(); + productName = (String)ois.readObject(); + productVersion = (String)ois.readObject(); + productRelease = (String)ois.readObject(); + productModification = (String)ois.readObject(); ois.close(); } @@ -434,9 +434,9 @@ private void createCacheFile(File cacheFile) { oos.writeObject(title); oos.writeObject(creationDate); oos.writeObject(productName); - oos.writeObject(productVersion); - oos.writeObject(productRelease); - oos.writeObject(productModification); + oos.writeObject(productVersion); + oos.writeObject(productRelease); + oos.writeObject(productModification); log.fine("created cache file "+cacheFile); } finally { oos.close(); @@ -454,217 +454,217 @@ private void createCacheFile(File cacheFile) { } } - /** - * Read an int from a byte array at a given offset. - * @param buf the byte array to read from - * @param offset the offset in the byte array - */ - static int readInt(byte[] buf, int offset) { - int n = (((int)buf[offset] & 0xff) << 24) | (((int)buf[offset+1] & 0xff) << 16) | (((int)buf[offset+2] & 0xff) << 8) | ((int)buf[offset+3] & 0xff); - if (log.isLoggable(Level.FINEST)) - log.finest("read int 0x" + hex(n) + " at offset 0x" + hex(offset)); - return n; - } - - /** - * Read a long from a byte array at a given offset. - * @param buf the byte array to read from - * @param offset the offset in the byte array - */ - static long readLong(byte[] buf, int offset) { - long upper = readInt(buf, offset); - long lower = readInt(buf, offset + 4); - return (upper << 32) | (lower & 0xffffffffL); - } - - /** - * Seek to the given offset in the dump file. This also handles MVS datasets in an - * efficient way (simply using fseek is too slow because the seek appears to read the - * file from the beginning every time!). - * @param offset the offset to seek to - */ - // XXX why is this public? not thread safe - absorb into single read method - public void seek(long offset) throws IOException { - super.seek(offset); - if (isMvsDataset) { - /* Get the fpos that we squirreled away earlier */ - long blockNumber = offset / BLOCKSIZE; - fposArray.get((int)blockNumber, fpos); - /* Go straight to that position (much faster than fseek) */ - int rc = Clib.fsetpos(fp, fpos); - if (rc != 0) - throw new IOException("fsetpos failed"); - /* - * We are now positioned at the correct block just after the header. If this is - * not the desired position, adjust. - */ - long remainder = offset - ((blockNumber * BLOCKSIZE) + HEADERSIZE); - if (remainder != 0) { -throw new Error("TEMP!"); // XXX - //rc = Clib.fseek(fp, remainder, Clib.SEEK_CUR); - //if (rc != 0) - //throw new IOException("fseek failed"); - } - } else { - if (log.isLoggable(Level.FINER)) - log.finer("raf seek to offset 0x" + hex(offset)); - raf.seek(offset); - } - } - - /** - * Reads an unsigned byte from the file - * @return - * @throws IOException - */ - public int read() throws IOException { - byte buf[] = new byte[1]; - int r = read(buf); - if (r <= 0) return -1; - return buf[0] & 0xff; - } - - /** - * Read from the dump file into the given buffer. - * @param buf the buffer to read into - * @param off the offset into the buffer to start at - * @param len the maximum number of bytes to read - */ - public int read(byte[] buf, int off, int len) throws IOException { - if (log.isLoggable(Level.FINER)) - log.finer("Read into "+buf+" "+hex(off)+" "+hex(len)); - int n; - if (isMvsDataset) { - if (off == 0) { - n = Clib.fread(buf, 1, len, fp); - } else { - byte buf2[] = new byte[len]; - n = Clib.fread(buf2, 1, len, fp); - if (n > 0) { - System.arraycopy(buf2, 0, buf, off, n); - } - } - } else { - n = raf.read(buf, off, len); - } - - if (n > 0) streamPos += n; - - if (log.isLoggable(Level.FINER)) - log.finer("read 0x" + hex(n) + " bytes"); - - return n; - } - - /** - * Read from the dump file into the given buffer. - * @param buf the buffer to read into - */ - public int read(byte[] buf) throws IOException { - if (log.isLoggable(Level.FINER)) - log.finer("Read into "+buf+" "+hex(buf.length)); - int n; - if (isMvsDataset) { - n = Clib.fread(buf, 1, buf.length, fp); - } else { - n = raf.read(buf); - } - if (n > 0) streamPos += n; - if (log.isLoggable(Level.FINER)) - log.finer("read 0x" + hex(n) + " bytes"); - return n; - } - - /** - * Get the length of the dump file - */ - public long length() { - if (isMvsDataset) { - return -1; - } else { - try { - return raf.length(); - } catch (IOException e) { - return -1; - } - } - } - - /** - * Returns an array of all the address spaces in the dump. - */ - public AddressSpace[] getAddressSpaces() { - return spaces; - } - - /** - * Returns true if this is a 64-bit dump. Always returns false at the moment 'cos I - * haven't yet got my paws on a 64-bit dump. - */ - public boolean is64bit() { - return false; - } - - /** - * Returns the title of the dump. - */ - public String getTitle() { - return title; - } - - /** - * Returns the z/OS product name. - */ - public String getProductName() { - return productName; - } - - /** - * Returns the z/OS product version. - */ - public String getProductVersion() { - return productVersion; - } - - /** - * Returns the z/OS product release. - */ - public String getProductRelease() { - return productRelease; - } - - /** - * Returns the z/OS product modification. - */ - public String getProductModification() { - return productModification; - } - - /** - * Convert an MVS style clock value to a Date object. - */ - public static Date mvsClockToDate(long clock) { - clock >>>= 12; - clock /= 1000; - long epoch = ((70 * 365) + 17) * 24; - epoch *= 3600; - epoch *= 1000; - clock -= epoch; - return new Date(clock); - } - - /** - * Returns the time when the dump was created. - */ - public Date getCreationDate() { - return creationDate; - } - - static String hex(int n) { - return Integer.toHexString(n); - } - - static String hex(long n) { - return Long.toHexString(n); - } + /** + * Read an int from a byte array at a given offset. + * @param buf the byte array to read from + * @param offset the offset in the byte array + */ + static int readInt(byte[] buf, int offset) { + int n = (((int)buf[offset] & 0xff) << 24) | (((int)buf[offset+1] & 0xff) << 16) | (((int)buf[offset+2] & 0xff) << 8) | ((int)buf[offset+3] & 0xff); + if (log.isLoggable(Level.FINEST)) + log.finest("read int 0x" + hex(n) + " at offset 0x" + hex(offset)); + return n; + } + + /** + * Read a long from a byte array at a given offset. + * @param buf the byte array to read from + * @param offset the offset in the byte array + */ + static long readLong(byte[] buf, int offset) { + long upper = readInt(buf, offset); + long lower = readInt(buf, offset + 4); + return (upper << 32) | (lower & 0xffffffffL); + } + + /** + * Seek to the given offset in the dump file. This also handles MVS datasets in an + * efficient way (simply using fseek is too slow because the seek appears to read the + * file from the beginning every time!). + * @param offset the offset to seek to + */ + // XXX why is this public? not thread safe - absorb into single read method + public void seek(long offset) throws IOException { + super.seek(offset); + if (isMvsDataset) { + /* Get the fpos that we squirreled away earlier */ + long blockNumber = offset / BLOCKSIZE; + fposArray.get((int)blockNumber, fpos); + /* Go straight to that position (much faster than fseek) */ + int rc = Clib.fsetpos(fp, fpos); + if (rc != 0) + throw new IOException("fsetpos failed"); + /* + * We are now positioned at the correct block just after the header. If this is + * not the desired position, adjust. + */ + long remainder = offset - ((blockNumber * BLOCKSIZE) + HEADERSIZE); + if (remainder != 0) { + throw new Error("TEMP!"); // XXX + //rc = Clib.fseek(fp, remainder, Clib.SEEK_CUR); + //if (rc != 0) + //throw new IOException("fseek failed"); + } + } else { + if (log.isLoggable(Level.FINER)) + log.finer("raf seek to offset 0x" + hex(offset)); + raf.seek(offset); + } + } + + /** + * Reads an unsigned byte from the file + * @return + * @throws IOException + */ + public int read() throws IOException { + byte buf[] = new byte[1]; + int r = read(buf); + if (r <= 0) return -1; + return buf[0] & 0xff; + } + + /** + * Read from the dump file into the given buffer. + * @param buf the buffer to read into + * @param off the offset into the buffer to start at + * @param len the maximum number of bytes to read + */ + public int read(byte[] buf, int off, int len) throws IOException { + if (log.isLoggable(Level.FINER)) + log.finer("Read into "+buf+" "+hex(off)+" "+hex(len)); + int n; + if (isMvsDataset) { + if (off == 0) { + n = Clib.fread(buf, 1, len, fp); + } else { + byte buf2[] = new byte[len]; + n = Clib.fread(buf2, 1, len, fp); + if (n > 0) { + System.arraycopy(buf2, 0, buf, off, n); + } + } + } else { + n = raf.read(buf, off, len); + } + + if (n > 0) streamPos += n; + + if (log.isLoggable(Level.FINER)) + log.finer("read 0x" + hex(n) + " bytes"); + + return n; + } + + /** + * Read from the dump file into the given buffer. + * @param buf the buffer to read into + */ + public int read(byte[] buf) throws IOException { + if (log.isLoggable(Level.FINER)) + log.finer("Read into "+buf+" "+hex(buf.length)); + int n; + if (isMvsDataset) { + n = Clib.fread(buf, 1, buf.length, fp); + } else { + n = raf.read(buf); + } + if (n > 0) streamPos += n; + if (log.isLoggable(Level.FINER)) + log.finer("read 0x" + hex(n) + " bytes"); + return n; + } + + /** + * Get the length of the dump file + */ + public long length() { + if (isMvsDataset) { + return -1; + } else { + try { + return raf.length(); + } catch (IOException e) { + return -1; + } + } + } + + /** + * Returns an array of all the address spaces in the dump. + */ + public AddressSpace[] getAddressSpaces() { + return spaces; + } + + /** + * Returns true if this is a 64-bit dump. Always returns false at the moment 'cos I + * haven't yet got my paws on a 64-bit dump. + */ + public boolean is64bit() { + return false; + } + + /** + * Returns the title of the dump. + */ + public String getTitle() { + return title; + } + + /** + * Returns the z/OS product name. + */ + public String getProductName() { + return productName; + } + + /** + * Returns the z/OS product version. + */ + public String getProductVersion() { + return productVersion; + } + + /** + * Returns the z/OS product release. + */ + public String getProductRelease() { + return productRelease; + } + + /** + * Returns the z/OS product modification. + */ + public String getProductModification() { + return productModification; + } + + /** + * Convert an MVS style clock value to a Date object. + */ + public static Date mvsClockToDate(long clock) { + clock >>>= 12; + clock /= 1000; + long epoch = ((70 * 365) + 17) * 24; + epoch *= 3600; + epoch *= 1000; + clock -= epoch; + return new Date(clock); + } + + /** + * Returns the time when the dump was created. + */ + public Date getCreationDate() { + return creationDate; + } + + static String hex(int n) { + return Integer.toHexString(n); + } + + static String hex(long n) { + return Long.toHexString(n); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/SearchListener.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/SearchListener.java index 8e686eae32f..305d5d52b9e 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/SearchListener.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/dumpreader/SearchListener.java @@ -28,19 +28,19 @@ */ public interface SearchListener { - /** - * This method determines the pattern to be searched for. This is called before the - * search begins. - * @return the pattern of bytes to search for - */ - public byte[] getPattern(); + /** + * This method determines the pattern to be searched for. This is called before the + * search begins. + * @return the pattern of bytes to search for + */ + public byte[] getPattern(); - /** - * Called to report a match has been found. The listener must return true to continue - * the search. - * @param space the {@link AddressSpace} in which the match was found - * @param address the address where the match was found - * @return true if the search is to continue - */ - public boolean foundMatch(AddressSpace space, long address); + /** + * Called to report a match has been found. The listener must return true to continue + * the search. + * @param space the {@link AddressSpace} in which the match was found + * @param address the address where the match was found + * @return true if the search is to continue + */ + public boolean foundMatch(AddressSpace space, long address); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa.java index 845de20c85c..7d5ee80c736 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa.java @@ -51,768 +51,768 @@ public class Caa { - /** The address of the CAA structure */ - private long address; - /** The TCB we are associated with */ - private Tcb tcb; - /** The AddressSpace we belong to */ - private AddressSpace space; - /** The AddressSpace ImageInputStream */ - private AddressSpaceImageInputStream inputStream; - /** The Edb we belong to */ - private Edb edb; - /** The current DSA */ - private DsaStackFrame currentFrame; - /** The stack direction - down is XPLINK. Use this field rather than call ceecaa_stackdirection - * because the latter call is only valid for later levels of LE */ - private int stackdirection; - /** The template we use, either 32 bit or 64 bit */ - private /*static*/ CaaTemplate caaTemplate; - private static int hcomLength = new Ceexhcom32Template().length(); - private String whereFound; - static final int CEECAASTACK_UP = 0; - static final int CEECAASTACK_DOWN = 1; - private static final int WARNING = 4; - private static final int ERROR = 8; - private static final long F1SA = 0xe6f1e2c1; - //private static final long F4SA = 0xe6f4e2c1; - //private static final long F5SA = 0xe6f5e2c1; - /** Logger */ - private static Logger log = Logger.getLogger(Caa.class.getName()); - - //CMVC 156864 : : updated code to fix traversal of native stacks - /** Address of LE Library Anchor Area (64-bit only) */ - private long laa; - /** Is this a 64bit Caa? */ - private boolean is64bit; - - /** - * Returns an array containing all of the Caas in the given - * {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressSpace} - */ - public static Caa[] getCaas(AddressSpace space) { - Tcb[] tcbs = Tcb.getTcbs(space); - if (tcbs == null) { - log.fine("no tcbs found in address space " + space); - return new Caa[0]; - } - log.fine("found " + tcbs.length + " tcbs for address space " + space); - Vector v = new Vector(); - for (int i = 0; i < tcbs.length; i++) { - try { - v.add(new Caa(tcbs[i])); - } catch (CaaNotFound e) { - } - } - return (Caa[])v.toArray(new Caa[0]); - } - - /** - * Create a new Caa from the given {@link com.ibm.dtfj.corereaders.zos.mvs.Tcb}. Note that not all - * Tcbs have a Caa associated with them. - * @throws CaaNotFound if there is no Caa associated with this Tcb. - */ - // CMVC 160438 : changes made to the address space configuration to enable to correct determination of the CAA - public Caa(Tcb tcb) throws CaaNotFound { - log.finer("creating Caa for Tcb at address " + hex(tcb.address())); - this.tcb = tcb; - space = tcb.space(); - inputStream = space.getImageInputStream(); - space.setIs64bit(false); - if (is32bitCaa()) { - /* Now we know this is 32 bit, create the template */ - caaTemplate = new Caa32Template(); - String s = space.getDump().getProductRelease(); - if (s != null) { - int release = Integer.parseInt(s); - if (release >= 11) { - caaTemplate = new Caa32_11Template(); - log.fine("switched to new caa format"); - } - } - log.fine("created 32-bit Caa " + hex(address) + " for Tcb at address " + hex(tcb.address())); - return; - } - space.setIs64bit(true); //have to assume now that we are dealing with 64 bit address space - if (is64bitCaa()) { - /* Now we know this is 64 bit, create the template and set flag in address space */ - is64bit = true; - caaTemplate = new Caa64Template(); - String s = space.getDump().getProductRelease(); - if (s != null) { - int release = Integer.parseInt(s); - if (release >= 11) { - caaTemplate = new Caa64_11Template(); - log.fine("switched to new caa format"); - } - } - log.fine("created 64-bit Caa " + hex(address) + " for Tcb at address " + hex(tcb.address())); - return; - } - space.setIs64bit(false); //now treat the address space as 32 bit again for final attempt to create the CAA - if (is32bitCaaLastDitch()) { - caaTemplate = new Caa32Template(); - String s = space.getDump().getProductRelease(); - if (s != null) { - int release = Integer.parseInt(s); - if (release >= 11) { - caaTemplate = new Caa32_11Template(); - log.fine("switched to new caa format"); - } - } - log.fine("created 32-bit Caa " + hex(address) + " for Tcb at address " + hex(tcb.address()) + " (last ditch)"); - return; - } - throw new CaaNotFound(); - } - - /** - * Try to locate the 32-bit caa pointer - */ - private boolean is32bitCaa() { - try { - long celap = tcb.tcbcelap(); - log.finer("celap = 0x" + hex(celap)); - // http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/CEEV1180/1.15.1?SHELF=CEE2BK80&DT=20070428015544&CASE= - int celap0 = space.readInt(celap); - log.finer("celap0 = 0x" + hex(celap0)); - if (celap0 == 0) - return false; - address = space.readInt(celap0 + 0x20); - int xxx = space.readInt(celap0 + 8); - log.finer("caa address = " + hex(address)); - return validate(); - } catch (IOException e) { - log.finer("caught exception: " + e); - return false; - } - } - - /** - * Try to locate the 64-bit caa pointer - */ - private boolean is64bitCaa() { - try { - long stcb = tcb.tcbstcb(); - log.finer("stcb = 0x" + hex(stcb)); - laa = IhastcbTemplate.getStcblaa(inputStream, stcb); - log.finer("laa = 0x" + hex(laa)); - long lca = CeexlaaTemplate.getCeelaa_lca64(inputStream, laa); - log.finer("lca = 0x" + hex(lca)); - address = CeelcaTemplate.getCeelca_caa(inputStream, lca); - log.finer("caa address = " + hex(address)); - return validate(); - } catch (IOException e) { - log.finer("caught exception: " + e); - return false; - } - } - - /** - * Try to locate the 32-bit caa pointer (last ditch if all else fails!) - */ - private boolean is32bitCaaLastDitch() { - try { - address = space.readInt(tcb.address() + 0x60); - log.finer("tcb caa address = " + hex(address)); - if (address == 0) - throw new IOException("oh"); - return validate(); - } catch (IOException e) { - log.finer("caught exception: " + e); - return false; - } - } - - /** - * Returns a string indicating where the registers were found. This is mainly for - * debugging purposes. - */ - public String whereFound() { - return whereFound; - } - - /** - * Validates the caa address. - */ - private boolean validate() { - try { - int eye1 = space.readInt(address - 0x18); - int eye2 = space.readInt(address - 0x14) & 0xffff0000; - - if (eye1 == 0xc3c5c5c3 && eye2 == 0xc1c10000) { // CEECAA - log.fine("found valid caa at " + hex(address)); - return true; - } - } catch (IOException e) { - log.finer("caught exception: " + e); - } - return false; - } - - /** - * This class emulates the cel4rreg macro. Most of the comments are from there. - */ - class Cel4rreg { - - long seghigh; - long seglow; - int p_dsafmt = -1; - long p_dsaptr; - RegisterSet regs; - - /** - * Creates the instance and attempts to locate the registers. - */ - Cel4rreg() { - /* - * Try and get the registers from the following locations: - * - * 1) RTM2 work area - * 2) BPXGMSTA service - * 3) linkage stack entries - * 4) TCB - * - * if any succeeds we return otherwise move to the next location. - */ - try { - if ((regs = getRegistersFromRTM2()) != null) { - whereFound = "RTM2"; - return; - } - } catch (IOException e) { - throw new Error("oops: " + e); - } - /* If we still have not found a dsa, invoke kernel svs */ - try { - if ((regs = getRegistersFromBPXGMSTA()) != null) { - whereFound = regs.whereFound(); - if (whereFound == null) - whereFound = "BPXGMSTA"; - return; - } - } catch (IOException e) { - throw new Error("oops: " + e); - } - try { - if ((regs = getRegistersFromLinkageStack()) != null) { - whereFound = "Linkage"; - return; - } - } catch (IOException e) { - e.printStackTrace(); - throw new Error("oops: " + e); - } - try { - if ((regs = getRegistersFromTCB()) != null) { - whereFound = "TCB"; - return; - } - } catch (IOException e) { - throw new Error("oops: " + e); - } - //CMVC 156864 : : updated code to fix traversal of native stacks - try { - if (is64bit) { - /* This is from celqrreg.plx370: "Get the save R4 from a NOSTACK call" */ - long lca = CeexlaaTemplate.getCeelaa_lca64(inputStream, laa); - p_dsaptr = CeelcaTemplate.getCeelca_savstack(inputStream, lca); - log.fine("p_dsaptr from lca = " + hex(p_dsaptr)); - p_dsafmt = stackdirection = CEECAASTACK_DOWN; - if (validateDSA() == 0 ) { - whereFound = "LCA"; - return; - } - } - } catch (IOException e) { - throw new Error("oops: " + e); - } - whereFound = "not found"; - } - - /** - * Try and get the registers from the RTM2 work area. Returns null if none found. As a - * side-effect it also sets the stackdirection. - */ - private RegisterSet getRegistersFromRTM2() throws IOException { - int level = ceecaalevel(); - log.finer("caa level is " + level); - /* If the CAA level is 13 or greater, get stack direction from - * CAA. For older releases or the dummy CAA, default stack - * direction to UP. - */ - if (level >= 13) { /* If LE 2.10 or higher */ - /* Obtain dsa format from the CAA */ - stackdirection = ceecaa_stackdirection(); - log.finer("stack direction is " + (stackdirection == CEECAASTACK_UP ? "up" : "down")); - } else { - stackdirection = CEECAASTACK_UP; - log.finer("stack direction is up"); - } - if (stackdirection == CEECAASTACK_DOWN) { - try { - long tempptr = ceecaasmcb(); - seghigh = SmcbTemplate.getSmcb_dsbos(inputStream, tempptr); - seglow = CeexstkhTemplate.getStkh_stackfloor(inputStream, seghigh); - } catch (Exception e) { - //throw new Error("oops: " + e); - return null; - } - } - /* At this point, a valid CAA has been obtained. Access the RTM2 to obtain the DSA. */ - long rtm2ptr = tcb.tcbrtwa(); - if (rtm2ptr != 0) { - try { - log.fine("found some rtm2 registers"); - RegisterSet regs = new RegisterSet(); - long rtm2grs = rtm2ptr + Ihartm2aTemplate.getRtm2ereg$offset(); - for (int i = 0; i < 16; i++) { - regs.setRegister(i, space.readUnsignedInt(rtm2grs + i*4)); - } - long rtm2psw = rtm2ptr + Ihartm2aTemplate.getRtm2apsw$offset(); - regs.setPSW(space.readLong(rtm2psw)); - if (registersValid(regs)) { - log.fine("found good dsa in rtm2"); - return regs; - } else { - log.fine("bad dsa in rtm2"); - return null; - } - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new Error("oops: " + e); - } - } else { - log.finer("failed to get registers from rtm2"); - return null; - } - } - - /** - * Validates the given register set with retry for down stack - */ - private boolean registersValid(RegisterSet regs) throws IOException { - p_dsafmt = stackdirection; - if (p_dsafmt == CEECAASTACK_DOWN) { - p_dsaptr = regs.getRegisterAsAddress(4); - log.fine("p_dsaptr from reg 4 = " + hex(p_dsaptr)); - } else { - p_dsaptr = regs.getRegisterAsAddress(13); - log.fine("p_dsaptr from reg 13 = " + hex(p_dsaptr)); - } - int lastrc = validateDSA(); - if (lastrc == 0) { - log.fine("found valid dsa"); - return true; - } else { - if (stackdirection == CEECAASTACK_DOWN) { - p_dsaptr = regs.getRegisterAsAddress(13); - log.fine("p_dsaptr from reg 13 (again) = " + hex(p_dsaptr)); - p_dsafmt = CEECAASTACK_UP; - lastrc = validateDSA(); - if (lastrc == WARNING) { - lastrc = validateDSA(); - if (lastrc == 0) { - log.fine("found valid dsa"); - return true; - } - } - } - /* reset values */ - log.fine("p_dsaptr invalid so reset: " + hex(p_dsaptr)); - p_dsaptr = 0; - } - return false; - } - - /** - * Try and get the registers from the BPXGMSTA service. - */ - private RegisterSet getRegistersFromBPXGMSTA() throws IOException { - RegisterSet regs = tcb.getRegistersFromBPXGMSTA(); - if (space.is64bit()) { - // celqrreg appears to always assume down stack - stackdirection = CEECAASTACK_DOWN; + /** The address of the CAA structure */ + private long address; + /** The TCB we are associated with */ + private Tcb tcb; + /** The AddressSpace we belong to */ + private AddressSpace space; + /** The AddressSpace ImageInputStream */ + private AddressSpaceImageInputStream inputStream; + /** The Edb we belong to */ + private Edb edb; + /** The current DSA */ + private DsaStackFrame currentFrame; + /** The stack direction - down is XPLINK. Use this field rather than call ceecaa_stackdirection + * because the latter call is only valid for later levels of LE */ + private int stackdirection; + /** The template we use, either 32 bit or 64 bit */ + private /*static*/ CaaTemplate caaTemplate; + private static int hcomLength = new Ceexhcom32Template().length(); + private String whereFound; + static final int CEECAASTACK_UP = 0; + static final int CEECAASTACK_DOWN = 1; + private static final int WARNING = 4; + private static final int ERROR = 8; + private static final long F1SA = 0xe6f1e2c1; + //private static final long F4SA = 0xe6f4e2c1; + //private static final long F5SA = 0xe6f5e2c1; + /** Logger */ + private static Logger log = Logger.getLogger(Caa.class.getName()); + + //CMVC 156864 : : updated code to fix traversal of native stacks + /** Address of LE Library Anchor Area (64-bit only) */ + private long laa; + /** Is this a 64bit Caa? */ + private boolean is64bit; + + /** + * Returns an array containing all of the Caas in the given + * {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressSpace} + */ + public static Caa[] getCaas(AddressSpace space) { + Tcb[] tcbs = Tcb.getTcbs(space); + if (tcbs == null) { + log.fine("no tcbs found in address space " + space); + return new Caa[0]; + } + log.fine("found " + tcbs.length + " tcbs for address space " + space); + Vector v = new Vector(); + for (int i = 0; i < tcbs.length; i++) { + try { + v.add(new Caa(tcbs[i])); + } catch (CaaNotFound e) { + } + } + return (Caa[])v.toArray(new Caa[0]); + } + + /** + * Create a new Caa from the given {@link com.ibm.dtfj.corereaders.zos.mvs.Tcb}. Note that not all + * Tcbs have a Caa associated with them. + * @throws CaaNotFound if there is no Caa associated with this Tcb. + */ + // CMVC 160438 : changes made to the address space configuration to enable to correct determination of the CAA + public Caa(Tcb tcb) throws CaaNotFound { + log.finer("creating Caa for Tcb at address " + hex(tcb.address())); + this.tcb = tcb; + space = tcb.space(); + inputStream = space.getImageInputStream(); + space.setIs64bit(false); + if (is32bitCaa()) { + /* Now we know this is 32 bit, create the template */ + caaTemplate = new Caa32Template(); + String s = space.getDump().getProductRelease(); + if (s != null) { + int release = Integer.parseInt(s); + if (release >= 11) { + caaTemplate = new Caa32_11Template(); + log.fine("switched to new caa format"); + } + } + log.fine("created 32-bit Caa " + hex(address) + " for Tcb at address " + hex(tcb.address())); + return; + } + space.setIs64bit(true); //have to assume now that we are dealing with 64 bit address space + if (is64bitCaa()) { + /* Now we know this is 64 bit, create the template and set flag in address space */ + is64bit = true; + caaTemplate = new Caa64Template(); + String s = space.getDump().getProductRelease(); + if (s != null) { + int release = Integer.parseInt(s); + if (release >= 11) { + caaTemplate = new Caa64_11Template(); + log.fine("switched to new caa format"); + } + } + log.fine("created 64-bit Caa " + hex(address) + " for Tcb at address " + hex(tcb.address())); + return; + } + space.setIs64bit(false); //now treat the address space as 32 bit again for final attempt to create the CAA + if (is32bitCaaLastDitch()) { + caaTemplate = new Caa32Template(); + String s = space.getDump().getProductRelease(); + if (s != null) { + int release = Integer.parseInt(s); + if (release >= 11) { + caaTemplate = new Caa32_11Template(); + log.fine("switched to new caa format"); + } + } + log.fine("created 32-bit Caa " + hex(address) + " for Tcb at address " + hex(tcb.address()) + " (last ditch)"); + return; + } + throw new CaaNotFound(); + } + + /** + * Try to locate the 32-bit caa pointer + */ + private boolean is32bitCaa() { + try { + long celap = tcb.tcbcelap(); + log.finer("celap = 0x" + hex(celap)); + // http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/CEEV1180/1.15.1?SHELF=CEE2BK80&DT=20070428015544&CASE= + int celap0 = space.readInt(celap); + log.finer("celap0 = 0x" + hex(celap0)); + if (celap0 == 0) + return false; + address = space.readInt(celap0 + 0x20); + int xxx = space.readInt(celap0 + 8); + log.finer("caa address = " + hex(address)); + return validate(); + } catch (IOException e) { + log.finer("caught exception: " + e); + return false; + } + } + + /** + * Try to locate the 64-bit caa pointer + */ + private boolean is64bitCaa() { + try { + long stcb = tcb.tcbstcb(); + log.finer("stcb = 0x" + hex(stcb)); + laa = IhastcbTemplate.getStcblaa(inputStream, stcb); + log.finer("laa = 0x" + hex(laa)); + long lca = CeexlaaTemplate.getCeelaa_lca64(inputStream, laa); + log.finer("lca = 0x" + hex(lca)); + address = CeelcaTemplate.getCeelca_caa(inputStream, lca); + log.finer("caa address = " + hex(address)); + return validate(); + } catch (IOException e) { + log.finer("caught exception: " + e); + return false; + } + } + + /** + * Try to locate the 32-bit caa pointer (last ditch if all else fails!) + */ + private boolean is32bitCaaLastDitch() { + try { + address = space.readInt(tcb.address() + 0x60); + log.finer("tcb caa address = " + hex(address)); + if (address == 0) + throw new IOException("oh"); + return validate(); + } catch (IOException e) { + log.finer("caught exception: " + e); + return false; + } + } + + /** + * Returns a string indicating where the registers were found. This is mainly for + * debugging purposes. + */ + public String whereFound() { + return whereFound; + } + + /** + * Validates the caa address. + */ + private boolean validate() { + try { + int eye1 = space.readInt(address - 0x18); + int eye2 = space.readInt(address - 0x14) & 0xffff0000; + + if (eye1 == 0xc3c5c5c3 && eye2 == 0xc1c10000) { // CEECAA + log.fine("found valid caa at " + hex(address)); + return true; + } + } catch (IOException e) { + log.finer("caught exception: " + e); + } + return false; + } + + /** + * This class emulates the cel4rreg macro. Most of the comments are from there. + */ + class Cel4rreg { + + long seghigh; + long seglow; + int p_dsafmt = -1; + long p_dsaptr; + RegisterSet regs; + + /** + * Creates the instance and attempts to locate the registers. + */ + Cel4rreg() { + /* + * Try and get the registers from the following locations: + * + * 1) RTM2 work area + * 2) BPXGMSTA service + * 3) linkage stack entries + * 4) TCB + * + * if any succeeds we return otherwise move to the next location. + */ + try { + if ((regs = getRegistersFromRTM2()) != null) { + whereFound = "RTM2"; + return; + } + } catch (IOException e) { + throw new Error("oops: " + e); + } + /* If we still have not found a dsa, invoke kernel svs */ + try { + if ((regs = getRegistersFromBPXGMSTA()) != null) { + whereFound = regs.whereFound(); + if (whereFound == null) + whereFound = "BPXGMSTA"; + return; + } + } catch (IOException e) { + throw new Error("oops: " + e); + } + try { + if ((regs = getRegistersFromLinkageStack()) != null) { + whereFound = "Linkage"; + return; + } + } catch (IOException e) { + e.printStackTrace(); + throw new Error("oops: " + e); + } + try { + if ((regs = getRegistersFromTCB()) != null) { + whereFound = "TCB"; + return; + } + } catch (IOException e) { + throw new Error("oops: " + e); + } + //CMVC 156864 : : updated code to fix traversal of native stacks + try { + if (is64bit) { + /* This is from celqrreg.plx370: "Get the save R4 from a NOSTACK call" */ + long lca = CeexlaaTemplate.getCeelaa_lca64(inputStream, laa); + p_dsaptr = CeelcaTemplate.getCeelca_savstack(inputStream, lca); + log.fine("p_dsaptr from lca = " + hex(p_dsaptr)); + p_dsafmt = stackdirection = CEECAASTACK_DOWN; + if (validateDSA() == 0) { + whereFound = "LCA"; + return; + } + } + } catch (IOException e) { + throw new Error("oops: " + e); + } + whereFound = "not found"; + } + + /** + * Try and get the registers from the RTM2 work area. Returns null if none found. As a + * side-effect it also sets the stackdirection. + */ + private RegisterSet getRegistersFromRTM2() throws IOException { + int level = ceecaalevel(); + log.finer("caa level is " + level); + /* If the CAA level is 13 or greater, get stack direction from + * CAA. For older releases or the dummy CAA, default stack + * direction to UP. + */ + if (level >= 13) { /* If LE 2.10 or higher */ + /* Obtain dsa format from the CAA */ + stackdirection = ceecaa_stackdirection(); + log.finer("stack direction is " + (stackdirection == CEECAASTACK_UP ? "up" : "down")); + } else { + stackdirection = CEECAASTACK_UP; + log.finer("stack direction is up"); + } + if (stackdirection == CEECAASTACK_DOWN) { + try { + long tempptr = ceecaasmcb(); + seghigh = SmcbTemplate.getSmcb_dsbos(inputStream, tempptr); + seglow = CeexstkhTemplate.getStkh_stackfloor(inputStream, seghigh); + } catch (Exception e) { + //throw new Error("oops: " + e); + return null; + } + } + /* At this point, a valid CAA has been obtained. Access the RTM2 to obtain the DSA. */ + long rtm2ptr = tcb.tcbrtwa(); + if (rtm2ptr != 0) { + try { + log.fine("found some rtm2 registers"); + RegisterSet regs = new RegisterSet(); + long rtm2grs = rtm2ptr + Ihartm2aTemplate.getRtm2ereg$offset(); + for (int i = 0; i < 16; i++) { + regs.setRegister(i, space.readUnsignedInt(rtm2grs + i*4)); + } + long rtm2psw = rtm2ptr + Ihartm2aTemplate.getRtm2apsw$offset(); + regs.setPSW(space.readLong(rtm2psw)); + if (registersValid(regs)) { + log.fine("found good dsa in rtm2"); + return regs; + } else { + log.fine("bad dsa in rtm2"); + return null; + } + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new Error("oops: " + e); + } + } else { + log.finer("failed to get registers from rtm2"); + return null; + } + } + + /** + * Validates the given register set with retry for down stack + */ + private boolean registersValid(RegisterSet regs) throws IOException { + p_dsafmt = stackdirection; + if (p_dsafmt == CEECAASTACK_DOWN) { + p_dsaptr = regs.getRegisterAsAddress(4); + log.fine("p_dsaptr from reg 4 = " + hex(p_dsaptr)); + } else { + p_dsaptr = regs.getRegisterAsAddress(13); + log.fine("p_dsaptr from reg 13 = " + hex(p_dsaptr)); + } + int lastrc = validateDSA(); + if (lastrc == 0) { + log.fine("found valid dsa"); + return true; + } else { + if (stackdirection == CEECAASTACK_DOWN) { + p_dsaptr = regs.getRegisterAsAddress(13); + log.fine("p_dsaptr from reg 13 (again) = " + hex(p_dsaptr)); + p_dsafmt = CEECAASTACK_UP; + lastrc = validateDSA(); + if (lastrc == WARNING) { + lastrc = validateDSA(); + if (lastrc == 0) { + log.fine("found valid dsa"); + return true; + } + } + } + /* reset values */ + log.fine("p_dsaptr invalid so reset: " + hex(p_dsaptr)); + p_dsaptr = 0; + } + return false; + } + + /** + * Try and get the registers from the BPXGMSTA service. + */ + private RegisterSet getRegistersFromBPXGMSTA() throws IOException { + RegisterSet regs = tcb.getRegistersFromBPXGMSTA(); + if (space.is64bit()) { + // celqrreg appears to always assume down stack + stackdirection = CEECAASTACK_DOWN; log.fine("forced stack direction down as 64-bit"); - } - if (registersValid(regs)) { - log.fine("found good dsa in BPXGMSTA"); - return regs; - } else { - return null; - } - } - - /** - * Try and get the registers from the linkage stack. - */ - private RegisterSet getRegistersFromLinkageStack() throws IOException { - log.fine("enter getRegistersFromLinkageStack"); - try { - Lse[] linkageStack = tcb.getLinkageStack(); - /* If Linkage stack is empty, leave */ - if (linkageStack.length == 0) { - log.fine("empty linkage stack"); - return null; - } - for (int i = 0; i < linkageStack.length; i++) { - Lse lse = linkageStack[i]; - if (lse.lses1pasn() == space.getAsid()) { - RegisterSet regs = new RegisterSet(); - if (lse.isZArchitecture() && (lse.lses1typ7() == Lse.LSED1PC || lse.lses1typ7() == Lse.LSED1BAKR)) { - log.fine("found some z arch registers"); - regs.setPSW(lse.lses1pswh()); - for (int j = 0; j < 16; j++) { - regs.setRegister(j, lse.lses1grs(j)); - } - } else { - log.fine("found some non z arch registers"); - regs.setPSW(lse.lsespsw()); - for (int j = 0; j < 16; j++) { - regs.setRegister(j, lse.lsesgrs(j)); - } - } - if (registersValid(regs)) { - log.fine("found good dsa in linkage stack"); - return regs; - } - } else { - log.fine("different asid: " + hex(lse.lses1pasn())); - } - } - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new Error("oops: " + e); - } - log.fine("could not find registers in linkage stack"); - return null; - } - - /** - * Try and get the registers from the TCB. - */ - private RegisterSet getRegistersFromTCB() throws IOException { - log.fine("getRegistersFromTCB"); - RegisterSet regs = tcb.getRegisters(); - if (registersValid(regs)) { - log.fine("found good dsa in TCB"); - return regs; - } else { - return null; - } - } - - /** - * Validate the given DSA. Returns 0 if valid. Note because this is Java, we can't - * modify the input parameters, so we use the instance variables instead and - * val_dsa == p_dsaptr, val_dsafmt == p_dsafmt. - */ - private int validateDSA() { - log.fine("attempt to validate " + hex(p_dsaptr) + " on " + (p_dsafmt == CEECAASTACK_DOWN ? "down" : "up") + " stack"); - try { - if (p_dsafmt == CEECAASTACK_DOWN) { - /* the check for being in the current segment is commented out */ - } else { - if (space.is64bit()) - return ERROR; - long tptr = ceecaaerrcm(); - /* Chicken egg situation */ - //assert !space.is64bit(); - /* If the input DSA address is within the HCOM and double word aligned, - * assume that it is good. */ - if (p_dsaptr < (tptr + hcomLength) && p_dsaptr >= tptr && (p_dsaptr & 7) == 0) { - log.fine("upstack dsa " + hex(p_dsaptr) + " is inside hcom"); - return 0; - } - } - long ddsa = ceecaaddsa(); - long dsaptr = p_dsaptr; - int dsafmt8 = p_dsafmt; - long slowdsaptr = p_dsaptr; - int slowdsafmt8 = p_dsafmt; - for (boolean slow = false;; slow = !slow) { - DsaStackFrame.Ceexdsaf dsaf = new DsaStackFrame.Ceexdsaf(space, dsaptr, dsafmt8); - /* If the stack direction is down but we are validating an upstack DSA - * and the current DSA is inside the current segment of the down stack, - * assume this must be a OS_NOSTACK call, return WARNING and replace - * input DSA and DSAFmt with R4 value from this DSA */ - if (stackdirection == CEECAASTACK_DOWN && p_dsafmt == CEECAASTACK_UP && - dsaptr < seghigh && dsaptr >= seglow) { - p_dsaptr = CeedsaTemplate.getCeedsar4(inputStream, dsaptr); - p_dsafmt = CEECAASTACK_DOWN; - log.fine("warning, try switching to down stack"); - return WARNING; - } - long callers_dsaptr = dsaf.DSA_Prev; - dsafmt8 = dsaf.DSA_Format; - /* If we are not able to backchain any farther or we have encountered - * a linkage stack, assume that the input DSA address is bad. */ - if (callers_dsaptr == 0 || callers_dsaptr == F1SA) { - log.fine("cannot backchain futher because " + (callers_dsaptr == 0 ? "zero" : "linkage stack") + " found"); - return ERROR; - } - /* If we were able to backchain to the dummy DSA, the input DSA address - * must be good. */ - if (callers_dsaptr == ddsa) { - log.fine("dummy dsa reached"); - return 0; - } - /* If we backchained across a stack transition, assume that the input - * DSA address is good. */ - if (dsafmt8 != p_dsafmt) { - log.fine("backchained across a stack transition"); - return 0; - } - /* If we have located an upstack DSA with a valid NAB value, assume that - * the input DSA address is good. */ - if (dsafmt8 == CEECAASTACK_UP) { - long tptr = CeedsaTemplate.getCeedsanab(inputStream, callers_dsaptr); - if (tptr == dsaptr) { - log.fine("upstack DSA is good"); - return 0; - } - } - dsaptr = callers_dsaptr; - /* We use the Tortoise and the Hare algorithm to detect loops. If the slow - * iterator is lapped it means there is a loop. */ - if (slow) { - dsaf = new DsaStackFrame.Ceexdsaf(space, slowdsaptr, slowdsafmt8); - slowdsaptr = dsaf.DSA_Prev; - slowdsafmt8 = dsaf.DSA_Format; - } - if (dsaptr == slowdsaptr) { - log.fine("loop detected in DSA chain"); - return ERROR; - } - } - } catch (IOException e) { - /* Any bad read means the DSA was invalid */ - log.fine("bad read: " + e); - return ERROR; - } catch (Exception e) { - e.printStackTrace(); - throw new Error("oops: " + e); - } - } - } - - /** - * Get the current (ie top) stack frame for this thread. - * @return the current stack frame or null if there is no stack - */ - public DsaStackFrame getCurrentFrame() { - if (currentFrame == null) { - log.fine("about to get top dsa for caa " + hex(address)); - Cel4rreg cel = new Cel4rreg(); - assert cel.p_dsafmt != -1; - RegisterSet regs = cel.regs; - boolean isDownStack = cel.p_dsafmt == CEECAASTACK_DOWN; - long dsa = cel.p_dsaptr; - if (dsa == 0) { - log.fine("dsa is zero for caa " + hex(address)); - return null; - } - try { - currentFrame = new DsaStackFrame(dsa, isDownStack, regs, space, this); - } catch (IOException e) { - /* Return null if we can't find one */ - log.fine("exception getting top dsa: " + e); - } - } - return currentFrame; - } - - /** - * Get the pthread id for this thread. This is the top half of the CEECAATHDID field in the CAA - */ - public int getPThreadID() throws IOException { - return caaTemplate.getCeecaathdid(inputStream, address); - } - - /** - * Returns true if this thread failed (ie crashed, abended, has gone to meet its maker). - */ - public boolean hasFailed() { - throw new Error("tbc"); - } - - /** - * Returns the {@link com.ibm.dtfj.corereaders.zos.mvs.RegisterSet} for a failed thread. This will return null if the - * thread did not fail. In general, registers are only available (or at least only - * useful) for a failed thread. - */ - public RegisterSet getRegisterSet() { - throw new Error("tbc"); - } - - /** - * Returns the EDB (Enclave Data Block) for this Caa. - */ - public Edb getEdb() { - // XXX there should be just one copy of the EDB - if (edb == null) { - try { - edb = new Edb(ceecaaedb(), space); - } catch (Exception e) { - throw new Error("oops: " + e); - } - } - return edb; - } - - /** - * Returns the address of this Caa. - */ - public long address() { - return address; - } - - /** - * Returns the AddressSpace we belong to - */ - public AddressSpace space() { - return space; - } - - /** - * Returns the Tcb we are associated with. - */ - public Tcb getTcb() { - return tcb; - } - - /** - * Returns the CEL level identifier. - * @throws IOException if an error occurred reading from the address space - */ - public int ceecaalevel() throws IOException { - return (int)caaTemplate.getCeecaalevel(inputStream, address); - } - - /** - * Returns the stack direction, either 0 (up) or 1 (down). Should only be called if the LE - * level is 13 or greater. - * @throws IOException if an error occurred reading from the address space - */ - public int ceecaa_stackdirection() throws IOException { - if (ceecaalevel() < 13) - // sanity check - throw new Error("ceecaa_stackdirection is not available in this level of LE! "+ceecaalevel()); - return (int)caaTemplate.getCeecaa_stackdirection(inputStream, address); - } - - /** - * Returns the address of the storage manager control block. - * @throws IOException if an error occurred reading from the address space - */ - public long ceecaasmcb() throws IOException { - // XXX only appears to be in 32-bit version? - return ((Caa32Template)caaTemplate).getCeecaasmcb(inputStream, address); - } - - /** - * Returns the address of the region control block. - * @throws IOException if an error occurred reading from the address space - */ - public long ceecaarcb() throws IOException { - return caaTemplate.getCeecaarcb(inputStream, address); - } - - /** - * Returns the address of the thread value block anchor - * @throws IOException if an error occurred reading from the address space - */ - public long ceecaavba() throws IOException { - return caaTemplate.getCeecaavba(inputStream, address); - } - - /** - * Searches thread value blocks for key matching the input key - * and returns the thread specific data associated with the specified - * key for the current thread. - * If no thread specific data has been set for key, Zero is returned. - */ - public long pthread_getspecific_d8_np(long key) throws IOException { - long ceecaavba = ceecaavba(); - if (ceecaavba == 0) { - log.fine("ceecaavba is zero!"); - return 0; - } + } + if (registersValid(regs)) { + log.fine("found good dsa in BPXGMSTA"); + return regs; + } else { + return null; + } + } + + /** + * Try and get the registers from the linkage stack. + */ + private RegisterSet getRegistersFromLinkageStack() throws IOException { + log.fine("enter getRegistersFromLinkageStack"); + try { + Lse[] linkageStack = tcb.getLinkageStack(); + /* If Linkage stack is empty, leave */ + if (linkageStack.length == 0) { + log.fine("empty linkage stack"); + return null; + } + for (int i = 0; i < linkageStack.length; i++) { + Lse lse = linkageStack[i]; + if (lse.lses1pasn() == space.getAsid()) { + RegisterSet regs = new RegisterSet(); + if (lse.isZArchitecture() && (lse.lses1typ7() == Lse.LSED1PC || lse.lses1typ7() == Lse.LSED1BAKR)) { + log.fine("found some z arch registers"); + regs.setPSW(lse.lses1pswh()); + for (int j = 0; j < 16; j++) { + regs.setRegister(j, lse.lses1grs(j)); + } + } else { + log.fine("found some non z arch registers"); + regs.setPSW(lse.lsespsw()); + for (int j = 0; j < 16; j++) { + regs.setRegister(j, lse.lsesgrs(j)); + } + } + if (registersValid(regs)) { + log.fine("found good dsa in linkage stack"); + return regs; + } + } else { + log.fine("different asid: " + hex(lse.lses1pasn())); + } + } + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new Error("oops: " + e); + } + log.fine("could not find registers in linkage stack"); + return null; + } + + /** + * Try and get the registers from the TCB. + */ + private RegisterSet getRegistersFromTCB() throws IOException { + log.fine("getRegistersFromTCB"); + RegisterSet regs = tcb.getRegisters(); + if (registersValid(regs)) { + log.fine("found good dsa in TCB"); + return regs; + } else { + return null; + } + } + + /** + * Validate the given DSA. Returns 0 if valid. Note because this is Java, we can't + * modify the input parameters, so we use the instance variables instead and + * val_dsa == p_dsaptr, val_dsafmt == p_dsafmt. + */ + private int validateDSA() { + log.fine("attempt to validate " + hex(p_dsaptr) + " on " + (p_dsafmt == CEECAASTACK_DOWN ? "down" : "up") + " stack"); + try { + if (p_dsafmt == CEECAASTACK_DOWN) { + /* the check for being in the current segment is commented out */ + } else { + if (space.is64bit()) + return ERROR; + long tptr = ceecaaerrcm(); + /* Chicken egg situation */ + //assert !space.is64bit(); + /* If the input DSA address is within the HCOM and double word aligned, + * assume that it is good. */ + if (p_dsaptr < (tptr + hcomLength) && p_dsaptr >= tptr && (p_dsaptr & 7) == 0) { + log.fine("upstack dsa " + hex(p_dsaptr) + " is inside hcom"); + return 0; + } + } + long ddsa = ceecaaddsa(); + long dsaptr = p_dsaptr; + int dsafmt8 = p_dsafmt; + long slowdsaptr = p_dsaptr; + int slowdsafmt8 = p_dsafmt; + for (boolean slow = false;; slow = !slow) { + DsaStackFrame.Ceexdsaf dsaf = new DsaStackFrame.Ceexdsaf(space, dsaptr, dsafmt8); + /* If the stack direction is down but we are validating an upstack DSA + * and the current DSA is inside the current segment of the down stack, + * assume this must be a OS_NOSTACK call, return WARNING and replace + * input DSA and DSAFmt with R4 value from this DSA */ + if (stackdirection == CEECAASTACK_DOWN && p_dsafmt == CEECAASTACK_UP && + dsaptr < seghigh && dsaptr >= seglow) { + p_dsaptr = CeedsaTemplate.getCeedsar4(inputStream, dsaptr); + p_dsafmt = CEECAASTACK_DOWN; + log.fine("warning, try switching to down stack"); + return WARNING; + } + long callers_dsaptr = dsaf.DSA_Prev; + dsafmt8 = dsaf.DSA_Format; + /* If we are not able to backchain any farther or we have encountered + * a linkage stack, assume that the input DSA address is bad. */ + if (callers_dsaptr == 0 || callers_dsaptr == F1SA) { + log.fine("cannot backchain futher because " + (callers_dsaptr == 0 ? "zero" : "linkage stack") + " found"); + return ERROR; + } + /* If we were able to backchain to the dummy DSA, the input DSA address + * must be good. */ + if (callers_dsaptr == ddsa) { + log.fine("dummy dsa reached"); + return 0; + } + /* If we backchained across a stack transition, assume that the input + * DSA address is good. */ + if (dsafmt8 != p_dsafmt) { + log.fine("backchained across a stack transition"); + return 0; + } + /* If we have located an upstack DSA with a valid NAB value, assume that + * the input DSA address is good. */ + if (dsafmt8 == CEECAASTACK_UP) { + long tptr = CeedsaTemplate.getCeedsanab(inputStream, callers_dsaptr); + if (tptr == dsaptr) { + log.fine("upstack DSA is good"); + return 0; + } + } + dsaptr = callers_dsaptr; + /* We use the Tortoise and the Hare algorithm to detect loops. If the slow + * iterator is lapped it means there is a loop. */ + if (slow) { + dsaf = new DsaStackFrame.Ceexdsaf(space, slowdsaptr, slowdsafmt8); + slowdsaptr = dsaf.DSA_Prev; + slowdsafmt8 = dsaf.DSA_Format; + } + if (dsaptr == slowdsaptr) { + log.fine("loop detected in DSA chain"); + return ERROR; + } + } + } catch (IOException e) { + /* Any bad read means the DSA was invalid */ + log.fine("bad read: " + e); + return ERROR; + } catch (Exception e) { + e.printStackTrace(); + throw new Error("oops: " + e); + } + } + } + + /** + * Get the current (ie top) stack frame for this thread. + * @return the current stack frame or null if there is no stack + */ + public DsaStackFrame getCurrentFrame() { + if (currentFrame == null) { + log.fine("about to get top dsa for caa " + hex(address)); + Cel4rreg cel = new Cel4rreg(); + assert cel.p_dsafmt != -1; + RegisterSet regs = cel.regs; + boolean isDownStack = cel.p_dsafmt == CEECAASTACK_DOWN; + long dsa = cel.p_dsaptr; + if (dsa == 0) { + log.fine("dsa is zero for caa " + hex(address)); + return null; + } + try { + currentFrame = new DsaStackFrame(dsa, isDownStack, regs, space, this); + } catch (IOException e) { + /* Return null if we can't find one */ + log.fine("exception getting top dsa: " + e); + } + } + return currentFrame; + } + + /** + * Get the pthread id for this thread. This is the top half of the CEECAATHDID field in the CAA + */ + public int getPThreadID() throws IOException { + return caaTemplate.getCeecaathdid(inputStream, address); + } + + /** + * Returns true if this thread failed (ie crashed, abended, has gone to meet its maker). + */ + public boolean hasFailed() { + throw new Error("tbc"); + } + + /** + * Returns the {@link com.ibm.dtfj.corereaders.zos.mvs.RegisterSet} for a failed thread. This will return null if the + * thread did not fail. In general, registers are only available (or at least only + * useful) for a failed thread. + */ + public RegisterSet getRegisterSet() { + throw new Error("tbc"); + } + + /** + * Returns the EDB (Enclave Data Block) for this Caa. + */ + public Edb getEdb() { + // XXX there should be just one copy of the EDB + if (edb == null) { + try { + edb = new Edb(ceecaaedb(), space); + } catch (Exception e) { + throw new Error("oops: " + e); + } + } + return edb; + } + + /** + * Returns the address of this Caa. + */ + public long address() { + return address; + } + + /** + * Returns the AddressSpace we belong to + */ + public AddressSpace space() { + return space; + } + + /** + * Returns the Tcb we are associated with. + */ + public Tcb getTcb() { + return tcb; + } + + /** + * Returns the CEL level identifier. + * @throws IOException if an error occurred reading from the address space + */ + public int ceecaalevel() throws IOException { + return (int)caaTemplate.getCeecaalevel(inputStream, address); + } + + /** + * Returns the stack direction, either 0 (up) or 1 (down). Should only be called if the LE + * level is 13 or greater. + * @throws IOException if an error occurred reading from the address space + */ + public int ceecaa_stackdirection() throws IOException { + if (ceecaalevel() < 13) + // sanity check + throw new Error("ceecaa_stackdirection is not available in this level of LE! "+ceecaalevel()); + return (int)caaTemplate.getCeecaa_stackdirection(inputStream, address); + } + + /** + * Returns the address of the storage manager control block. + * @throws IOException if an error occurred reading from the address space + */ + public long ceecaasmcb() throws IOException { + // XXX only appears to be in 32-bit version? + return ((Caa32Template)caaTemplate).getCeecaasmcb(inputStream, address); + } + + /** + * Returns the address of the region control block. + * @throws IOException if an error occurred reading from the address space + */ + public long ceecaarcb() throws IOException { + return caaTemplate.getCeecaarcb(inputStream, address); + } + + /** + * Returns the address of the thread value block anchor + * @throws IOException if an error occurred reading from the address space + */ + public long ceecaavba() throws IOException { + return caaTemplate.getCeecaavba(inputStream, address); + } + + /** + * Searches thread value blocks for key matching the input key + * and returns the thread specific data associated with the specified + * key for the current thread. + * If no thread specific data has been set for key, Zero is returned. + */ + public long pthread_getspecific_d8_np(long key) throws IOException { + long ceecaavba = ceecaavba(); + if (ceecaavba == 0) { + log.fine("ceecaavba is zero!"); + return 0; + } //if (space.is64bit()) return 0;// Safest! - long eyecatcher = space.readInt(ceecaavba); - if (eyecatcher == 0xe3e5c240) { - /* This is a TVB */ - // XXX Use templates and fixup for 64-bit - long ceeedbdba = getEdb().ceeedbdba(); - log.fine("ceeedbdba = " + hex(ceeedbdba)); - assert space.readInt(ceeedbdba) == 0xd2c4c240; // KDB - long ceekdb_bptr = space.readInt(ceeedbdba + 8); - long keyIndex = (key - ceekdb_bptr) / 16; - int bucketNumber = (int)keyIndex / 32; - int bucketIndex = (int)keyIndex % 32; - assert bucketNumber < 32; - long bucket = space.readInt(ceecaavba + 4 + (bucketNumber * 4)); - if (bucket == 0) { - return 0; - } - log.fine("bucket = " + hex(bucket)); - long value = space.readInt(bucket + 4 + (bucketIndex * 4)); - log.fine("value = " + hex(value)); - return value; - } - long ceetvbcount = CeextvbTemplate.getCeetvbcount(inputStream, ceecaavba); - log.fine("eye = " + hex(space.readInt(ceecaavba))); - long ceetvbe = ceecaavba + CeextvbTemplate.length(); - for (int i = 0; i < ceetvbcount; i++) { - long ceetvbekey = CeextvbeTemplate.getCeetvbekey(inputStream, ceetvbe); - if (key == ceetvbekey) { - return CeextvbeTemplate.getCeetvbevalue(inputStream, ceetvbe); - } - ceetvbe += CeextvbeTemplate.length(); - } - /* XXX Note: this is incomplete. Should also check other blocks */ - return 0; - } - - /** - * Returns the address of the dummy dsa. This is used to indicate the bottom of - * the stack. - */ - public long ceecaaddsa() { - try { - return caaTemplate.getCeecaaddsa(inputStream, address); - } catch (IOException e) { - throw new Error("oops"); - } - } - - /** - * Returns the address of the enclave data block. - * @throws IOException if an error occurred reading from the address space - */ - public long ceecaaedb() throws IOException { - return caaTemplate.getCeecaaedb(inputStream, address); - } - - /** - * Returns the address of the hcom. - * @throws IOException if an error occurred reading from the address space - */ - public long ceecaaerrcm() throws IOException { - return caaTemplate.getCeecaaerrcm(inputStream, address); - } - - private static String hex(int i) { - return Integer.toHexString(i); - } - - private static String hex(long i) { - return Long.toHexString(i); - } - - public String toString() { - return hex(address); - } + long eyecatcher = space.readInt(ceecaavba); + if (eyecatcher == 0xe3e5c240) { + /* This is a TVB */ + // XXX Use templates and fixup for 64-bit + long ceeedbdba = getEdb().ceeedbdba(); + log.fine("ceeedbdba = " + hex(ceeedbdba)); + assert space.readInt(ceeedbdba) == 0xd2c4c240; // KDB + long ceekdb_bptr = space.readInt(ceeedbdba + 8); + long keyIndex = (key - ceekdb_bptr) / 16; + int bucketNumber = (int)keyIndex / 32; + int bucketIndex = (int)keyIndex % 32; + assert bucketNumber < 32; + long bucket = space.readInt(ceecaavba + 4 + (bucketNumber * 4)); + if (bucket == 0) { + return 0; + } + log.fine("bucket = " + hex(bucket)); + long value = space.readInt(bucket + 4 + (bucketIndex * 4)); + log.fine("value = " + hex(value)); + return value; + } + long ceetvbcount = CeextvbTemplate.getCeetvbcount(inputStream, ceecaavba); + log.fine("eye = " + hex(space.readInt(ceecaavba))); + long ceetvbe = ceecaavba + CeextvbTemplate.length(); + for (int i = 0; i < ceetvbcount; i++) { + long ceetvbekey = CeextvbeTemplate.getCeetvbekey(inputStream, ceetvbe); + if (key == ceetvbekey) { + return CeextvbeTemplate.getCeetvbevalue(inputStream, ceetvbe); + } + ceetvbe += CeextvbeTemplate.length(); + } + /* XXX Note: this is incomplete. Should also check other blocks */ + return 0; + } + + /** + * Returns the address of the dummy dsa. This is used to indicate the bottom of + * the stack. + */ + public long ceecaaddsa() { + try { + return caaTemplate.getCeecaaddsa(inputStream, address); + } catch (IOException e) { + throw new Error("oops"); + } + } + + /** + * Returns the address of the enclave data block. + * @throws IOException if an error occurred reading from the address space + */ + public long ceecaaedb() throws IOException { + return caaTemplate.getCeecaaedb(inputStream, address); + } + + /** + * Returns the address of the hcom. + * @throws IOException if an error occurred reading from the address space + */ + public long ceecaaerrcm() throws IOException { + return caaTemplate.getCeecaaerrcm(inputStream, address); + } + + private static String hex(int i) { + return Integer.toHexString(i); + } + + private static String hex(long i) { + return Long.toHexString(i); + } + + public String toString() { + return hex(address); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa32Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa32Template.java index ad466362708..4975eaeb3c8 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa32Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa32Template.java @@ -29,98 +29,124 @@ public final class Caa32Template implements CaaTemplate { - public int length() { - return 1892; - } - - public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 688); - return inputStream.readByte(); - } - public int getCeecaalevel$offset() { - return 688; - } - public int getCeecaalevel$length() { - return 8; - } - public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 736); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaaddsa$offset() { - return 736; - } - public int getCeecaaddsa$length() { - return 32; - } - public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 752); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaaedb$offset() { - return 752; - } - public int getCeecaaedb$length() { - return 32; - } - public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 828); - return inputStream.readInt(); - } - public int getCeecaathdid$offset() { - return 828; - } - public int getCeecaathdid$length() { - return 32; - } - public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 848); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaarcb$offset() { - return 848; - } - public int getCeecaarcb$length() { - return 32; - } - public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 925); - return inputStream.readByte(); - } - public int getCeecaa_stackdirection$offset() { - return 925; - } - public int getCeecaa_stackdirection$length() { - return 8; - } - public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1020); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaasmcb$offset() { - return 1020; - } - public int getCeecaasmcb$length() { - return 32; - } - public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1024); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaaerrcm$offset() { - return 1024; - } - public int getCeecaaerrcm$length() { - return 32; - } - public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1100); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaavba$offset() { - return 1100; - } - public int getCeecaavba$length() { - return 32; - } + public int length() { + return 1892; + } + + public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 688); + return inputStream.readByte(); + } + + public int getCeecaalevel$offset() { + return 688; + } + + public int getCeecaalevel$length() { + return 8; + } + + public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 736); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaaddsa$offset() { + return 736; + } + + public int getCeecaaddsa$length() { + return 32; + } + + public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 752); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaaedb$offset() { + return 752; + } + + public int getCeecaaedb$length() { + return 32; + } + + public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 828); + return inputStream.readInt(); + } + + public int getCeecaathdid$offset() { + return 828; + } + + public int getCeecaathdid$length() { + return 32; + } + + public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 848); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaarcb$offset() { + return 848; + } + + public int getCeecaarcb$length() { + return 32; + } + + public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 925); + return inputStream.readByte(); + } + + public int getCeecaa_stackdirection$offset() { + return 925; + } + + public int getCeecaa_stackdirection$length() { + return 8; + } + + public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1020); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaasmcb$offset() { + return 1020; + } + + public int getCeecaasmcb$length() { + return 32; + } + + public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1024); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaaerrcm$offset() { + return 1024; + } + + public int getCeecaaerrcm$length() { + return 32; + } + + public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1100); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaavba$offset() { + return 1100; + } + + public int getCeecaavba$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa32_11Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa32_11Template.java index b6f0b5f0d68..82e07881a32 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa32_11Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa32_11Template.java @@ -29,119 +29,150 @@ public final class Caa32_11Template implements CaaTemplate { - public int length() { - return 2156; - } - - public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 688); - return inputStream.readByte(); - } - public int getCeecaalevel$offset() { - return 688; - } - public int getCeecaalevel$length() { - return 8; - } - public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 736); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaaddsa$offset() { - return 736; - } - public int getCeecaaddsa$length() { - return 32; - } - public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 752); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaaedb$offset() { - return 752; - } - public int getCeecaaedb$length() { - return 32; - } - public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 828); - return inputStream.readInt(); - } - public int getCeecaathdid$offset() { - return 828; - } - public int getCeecaathdid$length() { - return 64; - } - public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 848); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaarcb$offset() { - return 848; - } - public int getCeecaarcb$length() { - return 32; - } - public long getCeecaa_stackfloor(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 868); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaa_stackfloor$offset() { - return 868; - } - public int getCeecaa_stackfloor$length() { - return 32; - } - public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 925); - return inputStream.readByte(); - } - public int getCeecaa_stackdirection$offset() { - return 925; - } - public int getCeecaa_stackdirection$length() { - return 8; - } - public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1284); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaasmcb$offset() { - return 1284; - } - public int getCeecaasmcb$length() { - return 32; - } - public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1288); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaaerrcm$offset() { - return 1288; - } - public int getCeecaaerrcm$length() { - return 32; - } - public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1364); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaavba$offset() { - return 1364; - } - public int getCeecaavba$length() { - return 32; - } - public long getCeecaatcs(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1368); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeecaatcs$offset() { - return 1368; - } - public int getCeecaatcs$length() { - return 32; - } -} + public int length() { + return 2156; + } + + public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 688); + return inputStream.readByte(); + } + + public int getCeecaalevel$offset() { + return 688; + } + + public int getCeecaalevel$length() { + return 8; + } + + public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 736); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaaddsa$offset() { + return 736; + } + + public int getCeecaaddsa$length() { + return 32; + } + + public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 752); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaaedb$offset() { + return 752; + } + + public int getCeecaaedb$length() { + return 32; + } + + public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 828); + return inputStream.readInt(); + } + + public int getCeecaathdid$offset() { + return 828; + } + + public int getCeecaathdid$length() { + return 64; + } + + public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 848); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaarcb$offset() { + return 848; + } + + public int getCeecaarcb$length() { + return 32; + } + + public long getCeecaa_stackfloor(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 868); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + public int getCeecaa_stackfloor$offset() { + return 868; + } + + public int getCeecaa_stackfloor$length() { + return 32; + } + + public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 925); + return inputStream.readByte(); + } + + public int getCeecaa_stackdirection$offset() { + return 925; + } + + public int getCeecaa_stackdirection$length() { + return 8; + } + + public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1284); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaasmcb$offset() { + return 1284; + } + + public int getCeecaasmcb$length() { + return 32; + } + + public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1288); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaaerrcm$offset() { + return 1288; + } + + public int getCeecaaerrcm$length() { + return 32; + } + + public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1364); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaavba$offset() { + return 1364; + } + + public int getCeecaavba$length() { + return 32; + } + + public long getCeecaatcs(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1368); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeecaatcs$offset() { + return 1368; + } + + public int getCeecaatcs$length() { + return 32; + } +} diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa64Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa64Template.java index 86ab2ae7216..ac21d873f89 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa64Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa64Template.java @@ -29,97 +29,123 @@ public final class Caa64Template implements CaaTemplate { - public int length() { - return 2304; - } - - public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 868); - return inputStream.readByte(); - } - public int getCeecaalevel$offset() { - return 868; - } - public int getCeecaalevel$length() { - return 8; - } - public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 896); - return inputStream.readLong(); - } - public int getCeecaaddsa$offset() { - return 896; - } - public int getCeecaaddsa$length() { - return 64; - } - public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 904); - return inputStream.readLong(); - } - public int getCeecaaedb$offset() { - return 904; - } - public int getCeecaaedb$length() { - return 64; - } - public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 976); - return inputStream.readInt(); - } - public int getCeecaathdid$offset() { - return 976; - } - public int getCeecaathdid$length() { - return 32; - } - public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 984); - return inputStream.readLong(); - } - public int getCeecaarcb$offset() { - return 984; - } - public int getCeecaarcb$length() { - return 64; - } - public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1053); - return inputStream.readByte(); - } - public int getCeecaa_stackdirection$offset() { - return 1053; - } - public int getCeecaa_stackdirection$length() { - return 8; - } - public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1224); - return inputStream.readLong(); - } - public int getCeecaaerrcm$offset() { - return 1224; - } - public int getCeecaaerrcm$length() { - return 64; - } - public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1296); - return inputStream.readLong(); - } - public int getCeecaavba$offset() { - return 1296; - } - public int getCeecaavba$length() { - return 64; - } - public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException { - throw new Error("field ceecaasmcb does not exist in template Caa64Template"); - } - public int getCeecaasmcb$offset() { - throw new Error("field ceecaasmcb does not exist in template Caa64Template"); - } - public int getCeecaasmcb$length() { - throw new Error("field ceecaasmcb does not exist in template Caa64Template"); - } + public int length() { + return 2304; + } + + public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 868); + return inputStream.readByte(); + } + + public int getCeecaalevel$offset() { + return 868; + } + + public int getCeecaalevel$length() { + return 8; + } + + public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 896); + return inputStream.readLong(); + } + + public int getCeecaaddsa$offset() { + return 896; + } + + public int getCeecaaddsa$length() { + return 64; + } + + public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 904); + return inputStream.readLong(); + } + + public int getCeecaaedb$offset() { + return 904; + } + + public int getCeecaaedb$length() { + return 64; + } + + public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 976); + return inputStream.readInt(); + } + + public int getCeecaathdid$offset() { + return 976; + } + + public int getCeecaathdid$length() { + return 32; + } + + public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 984); + return inputStream.readLong(); + } + + public int getCeecaarcb$offset() { + return 984; + } + + public int getCeecaarcb$length() { + return 64; + } + + public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1053); + return inputStream.readByte(); + } + + public int getCeecaa_stackdirection$offset() { + return 1053; + } + + public int getCeecaa_stackdirection$length() { + return 8; + } + + public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1224); + return inputStream.readLong(); + } + + public int getCeecaaerrcm$offset() { + return 1224; + } + + public int getCeecaaerrcm$length() { + return 64; + } + + public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1296); + return inputStream.readLong(); + } + + public int getCeecaavba$offset() { + return 1296; + } + + public int getCeecaavba$length() { + return 64; + } + + public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException { + throw new Error("field ceecaasmcb does not exist in template Caa64Template"); + } + + public int getCeecaasmcb$offset() { + throw new Error("field ceecaasmcb does not exist in template Caa64Template"); + } + + public int getCeecaasmcb$length() { + throw new Error("field ceecaasmcb does not exist in template Caa64Template"); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa64_11Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa64_11Template.java index 8bf5f36d29a..1645a7e9240 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa64_11Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Caa64_11Template.java @@ -29,117 +29,148 @@ public final class Caa64_11Template implements CaaTemplate { - public int length() { - return 2304; - } - - public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 868); - return inputStream.readByte(); - } - public int getCeecaalevel$offset() { - return 868; - } - public int getCeecaalevel$length() { - return 8; - } - public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 896); - return inputStream.readLong(); - } - public int getCeecaaddsa$offset() { - return 896; - } - public int getCeecaaddsa$length() { - return 64; - } - public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 904); - return inputStream.readLong(); - } - public int getCeecaaedb$offset() { - return 904; - } - public int getCeecaaedb$length() { - return 64; - } - public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 976); - return inputStream.readInt(); - } - public int getCeecaathdid$offset() { - return 976; - } - public int getCeecaathdid$length() { - return 64; - } - public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 984); - return inputStream.readLong(); - } - public int getCeecaarcb$offset() { - return 984; - } - public int getCeecaarcb$length() { - return 64; - } - public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1053); - return inputStream.readByte(); - } - public int getCeecaa_stackdirection$offset() { - return 1053; - } - public int getCeecaa_stackdirection$length() { - return 8; - } - public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1224); - return inputStream.readLong(); - } - public int getCeecaaerrcm$offset() { - return 1224; - } - public int getCeecaaerrcm$length() { - return 64; - } - public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1296); - return inputStream.readLong(); - } - public int getCeecaavba$offset() { - return 1296; - } - public int getCeecaavba$length() { - return 64; - } - public long getCeecaatcs(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1304); - return inputStream.readLong(); - } - public int getCeecaatcs$offset() { - return 1304; - } - public int getCeecaatcs$length() { - return 64; - } - public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException { - throw new Error("field ceecaasmcb does not exist in template Caa64_11Template"); - } - public int getCeecaasmcb$offset() { - throw new Error("field ceecaasmcb does not exist in template Caa64_11Template"); - } - public int getCeecaasmcb$length() { - throw new Error("field ceecaasmcb does not exist in template Caa64_11Template"); - } - public long getCeecaa_stackfloor(ImageInputStream inputStream, long address) throws IOException { - throw new Error("field ceecaa_stackfloor does not exist in template Caa64_11Template"); - } - public int getCeecaa_stackfloor$offset() { - throw new Error("field ceecaa_stackfloor does not exist in template Caa64_11Template"); - } - public int getCeecaa_stackfloor$length() { - throw new Error("field ceecaa_stackfloor does not exist in template Caa64_11Template"); - } -} + public int length() { + return 2304; + } + + public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 868); + return inputStream.readByte(); + } + + public int getCeecaalevel$offset() { + return 868; + } + + public int getCeecaalevel$length() { + return 8; + } + + public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 896); + return inputStream.readLong(); + } + + public int getCeecaaddsa$offset() { + return 896; + } + + public int getCeecaaddsa$length() { + return 64; + } + + public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 904); + return inputStream.readLong(); + } + + public int getCeecaaedb$offset() { + return 904; + } + + public int getCeecaaedb$length() { + return 64; + } + + public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 976); + return inputStream.readInt(); + } + + public int getCeecaathdid$offset() { + return 976; + } + + public int getCeecaathdid$length() { + return 64; + } + + public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 984); + return inputStream.readLong(); + } + + public int getCeecaarcb$offset() { + return 984; + } + + public int getCeecaarcb$length() { + return 64; + } + + public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1053); + return inputStream.readByte(); + } + public int getCeecaa_stackdirection$offset() { + return 1053; + } + + public int getCeecaa_stackdirection$length() { + return 8; + } + + public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1224); + return inputStream.readLong(); + } + + public int getCeecaaerrcm$offset() { + return 1224; + } + + public int getCeecaaerrcm$length() { + return 64; + } + + public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1296); + return inputStream.readLong(); + } + + public int getCeecaavba$offset() { + return 1296; + } + + public int getCeecaavba$length() { + return 64; + } + + public long getCeecaatcs(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1304); + return inputStream.readLong(); + } + + public int getCeecaatcs$offset() { + return 1304; + } + + public int getCeecaatcs$length() { + return 64; + } + + public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException { + throw new Error("field ceecaasmcb does not exist in template Caa64_11Template"); + } + + public int getCeecaasmcb$offset() { + throw new Error("field ceecaasmcb does not exist in template Caa64_11Template"); + } + + public int getCeecaasmcb$length() { + throw new Error("field ceecaasmcb does not exist in template Caa64_11Template"); + } + + public long getCeecaa_stackfloor(ImageInputStream inputStream, long address) throws IOException { + throw new Error("field ceecaa_stackfloor does not exist in template Caa64_11Template"); + } + + public int getCeecaa_stackfloor$offset() { + throw new Error("field ceecaa_stackfloor does not exist in template Caa64_11Template"); + } + + public int getCeecaa_stackfloor$length() { + throw new Error("field ceecaa_stackfloor does not exist in template Caa64_11Template"); + } +} diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CaaTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CaaTemplate.java index 2d7e146a318..48b7e166306 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CaaTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CaaTemplate.java @@ -29,32 +29,32 @@ public interface CaaTemplate { - public int length(); - public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaalevel$offset(); - public int getCeecaalevel$length(); - public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaaddsa$offset(); - public int getCeecaaddsa$length(); - public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaaedb$offset(); - public int getCeecaaedb$length(); - public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaathdid$offset(); - public int getCeecaathdid$length(); - public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaarcb$offset(); - public int getCeecaarcb$length(); - public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaa_stackdirection$offset(); - public int getCeecaa_stackdirection$length(); - public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaaerrcm$offset(); - public int getCeecaaerrcm$length(); - public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaavba$offset(); - public int getCeecaavba$length(); - public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException; - public int getCeecaasmcb$offset(); - public int getCeecaasmcb$length(); + public int length(); + public long getCeecaalevel(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaalevel$offset(); + public int getCeecaalevel$length(); + public long getCeecaaddsa(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaaddsa$offset(); + public int getCeecaaddsa$length(); + public long getCeecaaedb(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaaedb$offset(); + public int getCeecaaedb$length(); + public int getCeecaathdid(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaathdid$offset(); + public int getCeecaathdid$length(); + public long getCeecaarcb(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaarcb$offset(); + public int getCeecaarcb$length(); + public long getCeecaa_stackdirection(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaa_stackdirection$offset(); + public int getCeecaa_stackdirection$length(); + public long getCeecaaerrcm(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaaerrcm$offset(); + public int getCeecaaerrcm$length(); + public long getCeecaavba(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaavba$offset(); + public int getCeecaavba$length(); + public long getCeecaasmcb(ImageInputStream inputStream, long address) throws IOException; + public int getCeecaasmcb$offset(); + public int getCeecaasmcb$length(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeedsaTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeedsaTemplate.java index 39fc963ac5e..5e4207b9837 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeedsaTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeedsaTemplate.java @@ -29,78 +29,98 @@ public final class CeedsaTemplate { - public static int length() { - return 128; - } - - public static long getCeedsabkc(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsabkc$offset() { - return 4; - } - public static int getCeedsabkc$length() { - return 32; - } - public static long getCeedsar14(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 12); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsar14$offset() { - return 12; - } - public static int getCeedsar14$length() { - return 32; - } - public static long getCeedsar15(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsar15$offset() { - return 16; - } - public static int getCeedsar15$length() { - return 32; - } - public static long getCeedsar4(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 36); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsar4$offset() { - return 36; - } - public static int getCeedsar4$length() { - return 32; - } - public static long getCeedsanab(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 76); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsanab$offset() { - return 76; - } - public static int getCeedsanab$length() { - return 32; - } - public static long getCeedsatran(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 100); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsatran$offset() { - return 100; - } - public static int getCeedsatran$length() { - return 32; - } - public static long getCeedsamode(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 108); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsamode$offset() { - return 108; - } - public static int getCeedsamode$length() { - return 32; - } + public static int length() { + return 128; + } + + public static long getCeedsabkc(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsabkc$offset() { + return 4; + } + + public static int getCeedsabkc$length() { + return 32; + } + + public static long getCeedsar14(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 12); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsar14$offset() { + return 12; + } + + public static int getCeedsar14$length() { + return 32; + } + + public static long getCeedsar15(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsar15$offset() { + return 16; + } + + public static int getCeedsar15$length() { + return 32; + } + + public static long getCeedsar4(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 36); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsar4$offset() { + return 36; + } + + public static int getCeedsar4$length() { + return 32; + } + + public static long getCeedsanab(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 76); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsanab$offset() { + return 76; + } + + public static int getCeedsanab$length() { + return 32; + } + + public static long getCeedsatran(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 100); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsatran$offset() { + return 100; + } + + public static int getCeedsatran$length() { + return 32; + } + + public static long getCeedsamode(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 108); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsamode$offset() { + return 108; + } + + public static int getCeedsamode$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp32Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp32Template.java index 119e29dfd76..e97bf42111e 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp32Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp32Template.java @@ -29,48 +29,58 @@ public final class Ceedsahp32Template implements CeedsahpTemplate { - public int length() { - return 2113; - } + public int length() { + return 2113; + } - public long getCeedsahpr4(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 2048); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeedsahpr4$offset() { - return 2048; - } - public int getCeedsahpr4$length() { - return 32; - } - public long getCeedsahpr6(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 2056); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeedsahpr6$offset() { - return 2056; - } - public int getCeedsahpr6$length() { - return 32; - } - public long getCeedsahpr7(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 2060); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeedsahpr7$offset() { - return 2060; - } - public int getCeedsahpr7$length() { - return 32; - } - public long getCeedsahptran(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 2104); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeedsahptran$offset() { - return 2104; - } - public int getCeedsahptran$length() { - return 32; - } + public long getCeedsahpr4(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 2048); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeedsahpr4$offset() { + return 2048; + } + public int getCeedsahpr4$length() { + return 32; + } + + public long getCeedsahpr6(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 2056); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeedsahpr6$offset() { + return 2056; + } + + public int getCeedsahpr6$length() { + return 32; + } + + public long getCeedsahpr7(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 2060); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeedsahpr7$offset() { + return 2060; + } + + public int getCeedsahpr7$length() { + return 32; + } + + public long getCeedsahptran(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 2104); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeedsahptran$offset() { + return 2104; + } + + public int getCeedsahptran$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp64Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp64Template.java index ddec0a3c5ec..dc2e72b8abd 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp64Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp64Template.java @@ -29,48 +29,59 @@ public final class Ceedsahp64Template implements CeedsahpTemplate { - public int length() { - return 2177; - } - - public long getCeedsahpr4(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 2048); - return inputStream.readLong(); - } - public int getCeedsahpr4$offset() { - return 2048; - } - public int getCeedsahpr4$length() { - return 64; - } - public long getCeedsahpr6(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 2064); - return inputStream.readLong(); - } - public int getCeedsahpr6$offset() { - return 2064; - } - public int getCeedsahpr6$length() { - return 64; - } - public long getCeedsahpr7(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 2072); - return inputStream.readLong(); - } - public int getCeedsahpr7$offset() { - return 2072; - } - public int getCeedsahpr7$length() { - return 64; - } - public long getCeedsahptran(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 2160); - return inputStream.readLong(); - } - public int getCeedsahptran$offset() { - return 2160; - } - public int getCeedsahptran$length() { - return 64; - } + public int length() { + return 2177; + } + + public long getCeedsahpr4(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 2048); + return inputStream.readLong(); + } + + public int getCeedsahpr4$offset() { + return 2048; + } + + public int getCeedsahpr4$length() { + return 64; + } + + public long getCeedsahpr6(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 2064); + return inputStream.readLong(); + } + + public int getCeedsahpr6$offset() { + return 2064; + } + + public int getCeedsahpr6$length() { + return 64; + } + + public long getCeedsahpr7(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 2072); + return inputStream.readLong(); + } + + public int getCeedsahpr7$offset() { + return 2072; + } + + public int getCeedsahpr7$length() { + return 64; + } + + public long getCeedsahptran(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 2160); + return inputStream.readLong(); + } + + public int getCeedsahptran$offset() { + return 2160; + } + + public int getCeedsahptran$length() { + return 64; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeedsahpTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeedsahpTemplate.java index 6381af94b3f..4b5147910bf 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeedsahpTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeedsahpTemplate.java @@ -29,17 +29,17 @@ public interface CeedsahpTemplate { - public int length(); - public long getCeedsahpr4(ImageInputStream inputStream, long address) throws IOException; - public int getCeedsahpr4$offset(); - public int getCeedsahpr4$length(); - public long getCeedsahpr6(ImageInputStream inputStream, long address) throws IOException; - public int getCeedsahpr6$offset(); - public int getCeedsahpr6$length(); - public long getCeedsahpr7(ImageInputStream inputStream, long address) throws IOException; - public int getCeedsahpr7$offset(); - public int getCeedsahpr7$length(); - public long getCeedsahptran(ImageInputStream inputStream, long address) throws IOException; - public int getCeedsahptran$offset(); - public int getCeedsahptran$length(); + public int length(); + public long getCeedsahpr4(ImageInputStream inputStream, long address) throws IOException; + public int getCeedsahpr4$offset(); + public int getCeedsahpr4$length(); + public long getCeedsahpr6(ImageInputStream inputStream, long address) throws IOException; + public int getCeedsahpr6$offset(); + public int getCeedsahpr6$length(); + public long getCeedsahpr7(ImageInputStream inputStream, long address) throws IOException; + public int getCeedsahpr7$offset(); + public int getCeedsahpr7$length(); + public long getCeedsahptran(ImageInputStream inputStream, long address) throws IOException; + public int getCeedsahptran$offset(); + public int getCeedsahptran$length(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp_transitionTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp_transitionTemplate.java index 9fa23ac96b4..bb6b2312ceb 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp_transitionTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceedsahp_transitionTemplate.java @@ -29,48 +29,59 @@ public final class Ceedsahp_transitionTemplate { - public static int length() { - return 108; - } - - public static long getCeedsahp_trtype(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readInt(); - } - public static int getCeedsahp_trtype$offset() { - return 8; - } - public static int getCeedsahp_trtype$length() { - return 32; - } - public static long getCeedsahp_tran_ep(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 28); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsahp_tran_ep$offset() { - return 28; - } - public static int getCeedsahp_tran_ep$length() { - return 32; - } - public static long getCeedsahp_bkc(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 48); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsahp_bkc$offset() { - return 48; - } - public static int getCeedsahp_bkc$length() { - return 32; - } - public static long getCeedsahp_retaddr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 60); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeedsahp_retaddr$offset() { - return 60; - } - public static int getCeedsahp_retaddr$length() { - return 32; - } + public static int length() { + return 108; + } + + public static long getCeedsahp_trtype(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readInt(); + } + + public static int getCeedsahp_trtype$offset() { + return 8; + } + + public static int getCeedsahp_trtype$length() { + return 32; + } + + public static long getCeedsahp_tran_ep(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 28); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsahp_tran_ep$offset() { + return 28; + } + + public static int getCeedsahp_tran_ep$length() { + return 32; + } + + public static long getCeedsahp_bkc(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 48); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsahp_bkc$offset() { + return 48; + } + + public static int getCeedsahp_bkc$length() { + return 32; + } + + public static long getCeedsahp_retaddr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 60); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeedsahp_retaddr$offset() { + return 60; + } + + public static int getCeedsahp_retaddr$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeelcaTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeelcaTemplate.java index 68862b7a3dc..feeb6205819 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeelcaTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeelcaTemplate.java @@ -29,30 +29,34 @@ public final class CeelcaTemplate { - public static int length() { - return 864; - } - - public static long getCeelca_caa(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readLong(); - } - public static int getCeelca_caa$offset() { - return 8; - } - public static int getCeelca_caa$length() { - return 64; - } - - //CMVC 156864 : : updated code to fix traversal of native stacks - public static long getCeelca_savstack(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 32); - return inputStream.readLong(); - } - public static int getCeelca_savstack$offset() { - return 32; - } - public static int getCeelca_savstack$length() { - return 64; - } + public static int length() { + return 864; + } + + public static long getCeelca_caa(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readLong(); + } + + public static int getCeelca_caa$offset() { + return 8; + } + + public static int getCeelca_caa$length() { + return 64; + } + + //CMVC 156864 : : updated code to fix traversal of native stacks + public static long getCeelca_savstack(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 32); + return inputStream.readLong(); + } + + public static int getCeelca_savstack$offset() { + return 32; + } + + public static int getCeelca_savstack$length() { + return 64; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexcibTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexcibTemplate.java index 5e9babbb90d..121f97f6dfc 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexcibTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexcibTemplate.java @@ -29,28 +29,33 @@ public final class CeexcibTemplate { - public static int length() { - return 268; - } - - public static long getCib_sv1(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 204); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCib_sv1$offset() { - return 204; - } - public static int getCib_sv1$length() { - return 32; - } - public static long getCib_int(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 208); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCib_int$offset() { - return 208; - } - public static int getCib_int$length() { - return 32; - } + public static int length() { + return 268; + } + + public static long getCib_sv1(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 204); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCib_sv1$offset() { + return 204; + } + + public static int getCib_sv1$length() { + return 32; + } + + public static long getCib_int(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 208); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCib_int$offset() { + return 208; + } + + public static int getCib_int$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexcibhTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexcibhTemplate.java index 57bcb58f395..06ad752e6b6 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexcibhTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexcibhTemplate.java @@ -29,42 +29,50 @@ public final class CeexcibhTemplate { - public static int length() { - return 2816; - } + public static int length() { + return 2816; + } - public static long getCibh_back(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCibh_back$offset() { - return 4; - } - public static int getCibh_back$length() { - return 32; - } - public static long getCibh_ptr_cib(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCibh_ptr_cib$offset() { - return 16; - } - public static int getCibh_ptr_cib$length() { - return 32; - } - public static long getCibh_in_use(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 20); - inputStream.setBitOffset(1); - long result = inputStream.readBits(1); - result <<= 63; - result >>= 63; - return result; - } - public static int getCibh_in_use$offset() { - return 20; - } - public static int getCibh_in_use$length() { - return 1; - } + public static long getCibh_back(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCibh_back$offset() { + return 4; + } + + public static int getCibh_back$length() { + return 32; + } + + public static long getCibh_ptr_cib(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCibh_ptr_cib$offset() { + return 16; + } + + public static int getCibh_ptr_cib$length() { + return 32; + } + + public static long getCibh_in_use(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 20); + inputStream.setBitOffset(1); + long result = inputStream.readBits(1); + result <<= 63; + result >>= 63; + return result; + } + + public static int getCibh_in_use$offset() { + return 20; + } + + public static int getCibh_in_use$length() { + return 1; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexdlcb32Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexdlcb32Template.java index cb578a78da2..216e3ed31c5 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexdlcb32Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexdlcb32Template.java @@ -29,61 +29,75 @@ public final class Ceexdlcb32Template implements CeexdlcbTemplate { - public int length() { - return 96; - } - - public long getDlcbnextptr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getDlcbnextptr$offset() { - return 0; - } - public int getDlcbnextptr$length() { - return 32; - } - public long getDlcbwsaptr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 20); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getDlcbwsaptr$offset() { - return 20; - } - public int getDlcbwsaptr$length() { - return 32; - } - public long getDlcbnamelen(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 60); - long result = inputStream.readBits(16); - result <<= 48; - result >>= 48; - return result; - } - public int getDlcbnamelen$offset() { - return 60; - } - public int getDlcbnamelen$length() { - return 16; - } - public long getDlcbnameptr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 64); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getDlcbnameptr$offset() { - return 64; - } - public int getDlcbnameptr$length() { - return 32; - } - public long getDlcbiewbcie(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 68); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getDlcbiewbcie$offset() { - return 68; - } - public int getDlcbiewbcie$length() { - return 32; - } + public int length() { + return 96; + } + + public long getDlcbnextptr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getDlcbnextptr$offset() { + return 0; + } + + public int getDlcbnextptr$length() { + return 32; + } + + public long getDlcbwsaptr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 20); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getDlcbwsaptr$offset() { + return 20; + } + + public int getDlcbwsaptr$length() { + return 32; + } + + public long getDlcbnamelen(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 60); + long result = inputStream.readBits(16); + result <<= 48; + result >>= 48; + return result; + } + + public int getDlcbnamelen$offset() { + return 60; + } + + public int getDlcbnamelen$length() { + return 16; + } + + public long getDlcbnameptr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 64); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getDlcbnameptr$offset() { + return 64; + } + + public int getDlcbnameptr$length() { + return 32; + } + + public long getDlcbiewbcie(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 68); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getDlcbiewbcie$offset() { + return 68; + } + + public int getDlcbiewbcie$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexdlcb64Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexdlcb64Template.java index b430e20f835..0373342f247 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexdlcb64Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexdlcb64Template.java @@ -29,61 +29,75 @@ public final class Ceexdlcb64Template implements CeexdlcbTemplate { - public int length() { - return 152; - } - - public long getDlcbnextptr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readLong(); - } - public int getDlcbnextptr$offset() { - return 0; - } - public int getDlcbnextptr$length() { - return 64; - } - public long getDlcbwsaptr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 40); - return inputStream.readLong(); - } - public int getDlcbwsaptr$offset() { - return 40; - } - public int getDlcbwsaptr$length() { - return 64; - } - public long getDlcbnamelen(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 88); - long result = inputStream.readBits(16); - result <<= 48; - result >>= 48; - return result; - } - public int getDlcbnamelen$offset() { - return 88; - } - public int getDlcbnamelen$length() { - return 16; - } - public long getDlcbnameptr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 96); - return inputStream.readLong(); - } - public int getDlcbnameptr$offset() { - return 96; - } - public int getDlcbnameptr$length() { - return 64; - } - public long getDlcbiewbcie(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 104); - return inputStream.readLong(); - } - public int getDlcbiewbcie$offset() { - return 104; - } - public int getDlcbiewbcie$length() { - return 64; - } + public int length() { + return 152; + } + + public long getDlcbnextptr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readLong(); + } + + public int getDlcbnextptr$offset() { + return 0; + } + + public int getDlcbnextptr$length() { + return 64; + } + + public long getDlcbwsaptr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 40); + return inputStream.readLong(); + } + + public int getDlcbwsaptr$offset() { + return 40; + } + + public int getDlcbwsaptr$length() { + return 64; + } + + public long getDlcbnamelen(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 88); + long result = inputStream.readBits(16); + result <<= 48; + result >>= 48; + return result; + } + + public int getDlcbnamelen$offset() { + return 88; + } + + public int getDlcbnamelen$length() { + return 16; + } + + public long getDlcbnameptr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 96); + return inputStream.readLong(); + } + + public int getDlcbnameptr$offset() { + return 96; + } + + public int getDlcbnameptr$length() { + return 64; + } + + public long getDlcbiewbcie(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 104); + return inputStream.readLong(); + } + + public int getDlcbiewbcie$offset() { + return 104; + } + + public int getDlcbiewbcie$length() { + return 64; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexdlcbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexdlcbTemplate.java index 7aa94abce5f..b386d549037 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexdlcbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexdlcbTemplate.java @@ -29,20 +29,20 @@ public interface CeexdlcbTemplate { - public int length(); - public long getDlcbnextptr(ImageInputStream inputStream, long address) throws IOException; - public int getDlcbnextptr$offset(); - public int getDlcbnextptr$length(); - public long getDlcbwsaptr(ImageInputStream inputStream, long address) throws IOException; - public int getDlcbwsaptr$offset(); - public int getDlcbwsaptr$length(); - public long getDlcbnamelen(ImageInputStream inputStream, long address) throws IOException; - public int getDlcbnamelen$offset(); - public int getDlcbnamelen$length(); - public long getDlcbnameptr(ImageInputStream inputStream, long address) throws IOException; - public int getDlcbnameptr$offset(); - public int getDlcbnameptr$length(); - public long getDlcbiewbcie(ImageInputStream inputStream, long address) throws IOException; - public int getDlcbiewbcie$offset(); - public int getDlcbiewbcie$length(); + public int length(); + public long getDlcbnextptr(ImageInputStream inputStream, long address) throws IOException; + public int getDlcbnextptr$offset(); + public int getDlcbnextptr$length(); + public long getDlcbwsaptr(ImageInputStream inputStream, long address) throws IOException; + public int getDlcbwsaptr$offset(); + public int getDlcbwsaptr$length(); + public long getDlcbnamelen(ImageInputStream inputStream, long address) throws IOException; + public int getDlcbnamelen$offset(); + public int getDlcbnamelen$length(); + public long getDlcbnameptr(ImageInputStream inputStream, long address) throws IOException; + public int getDlcbnameptr$offset(); + public int getDlcbnameptr$length(); + public long getDlcbiewbcie(ImageInputStream inputStream, long address) throws IOException; + public int getDlcbiewbcie$offset(); + public int getDlcbiewbcie$length(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexedb32Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexedb32Template.java index 776eb09d9f7..0049c067253 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexedb32Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexedb32Template.java @@ -29,48 +29,59 @@ public final class Ceexedb32Template implements CeexedbTemplate { - public int length() { - return 1216; - } - - public long getCeeedbenvar(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 88); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeeedbenvar$offset() { - return 88; - } - public int getCeeedbenvar$length() { - return 32; - } - public long getCeeedb_ceeosigr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 96); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeeedb_ceeosigr$offset() { - return 96; - } - public int getCeeedb_ceeosigr$length() { - return 32; - } - public long getCeeedbdba(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 924); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeeedbdba$offset() { - return 924; - } - public int getCeeedbdba$length() { - return 32; - } - public long getCeeedb_dlcb_first(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1096); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeeedb_dlcb_first$offset() { - return 1096; - } - public int getCeeedb_dlcb_first$length() { - return 32; - } + public int length() { + return 1216; + } + + public long getCeeedbenvar(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 88); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeeedbenvar$offset() { + return 88; + } + + public int getCeeedbenvar$length() { + return 32; + } + + public long getCeeedb_ceeosigr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 96); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeeedb_ceeosigr$offset() { + return 96; + } + + public int getCeeedb_ceeosigr$length() { + return 32; + } + + public long getCeeedbdba(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 924); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeeedbdba$offset() { + return 924; + } + + public int getCeeedbdba$length() { + return 32; + } + + public long getCeeedb_dlcb_first(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1096); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeeedb_dlcb_first$offset() { + return 1096; + } + + public int getCeeedb_dlcb_first$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexedb64Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexedb64Template.java index defc3abd6a6..e1585a5a17e 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexedb64Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexedb64Template.java @@ -29,47 +29,58 @@ public final class Ceexedb64Template implements CeexedbTemplate { - public int length() { - return 172; - } - - public long getCeeedbenvar(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 312); - return inputStream.readLong(); - } - public int getCeeedbenvar$offset() { - return 312; - } - public int getCeeedbenvar$length() { - return 64; - } - public long getCeeedbdba(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1272); - return inputStream.readLong(); - } - public int getCeeedbdba$offset() { - return 1272; - } - public int getCeeedbdba$length() { - return 64; - } - public long getCeeedb_dlcb_first(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1544); - return inputStream.readLong(); - } - public int getCeeedb_dlcb_first$offset() { - return 1544; - } - public int getCeeedb_dlcb_first$length() { - return 64; - } - public long getCeeedb_ceeosigr(ImageInputStream inputStream, long address) throws IOException { - throw new Error("field ceeedb_ceeosigr does not exist in template Ceexedb64Template"); - } - public int getCeeedb_ceeosigr$offset() { - throw new Error("field ceeedb_ceeosigr does not exist in template Ceexedb64Template"); - } - public int getCeeedb_ceeosigr$length() { - throw new Error("field ceeedb_ceeosigr does not exist in template Ceexedb64Template"); - } + public int length() { + return 172; + } + + public long getCeeedbenvar(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 312); + return inputStream.readLong(); + } + + public int getCeeedbenvar$offset() { + return 312; + } + + public int getCeeedbenvar$length() { + return 64; + } + + public long getCeeedbdba(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1272); + return inputStream.readLong(); + } + + public int getCeeedbdba$offset() { + return 1272; + } + + public int getCeeedbdba$length() { + return 64; + } + + public long getCeeedb_dlcb_first(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1544); + return inputStream.readLong(); + } + + public int getCeeedb_dlcb_first$offset() { + return 1544; + } + + public int getCeeedb_dlcb_first$length() { + return 64; + } + + public long getCeeedb_ceeosigr(ImageInputStream inputStream, long address) throws IOException { + throw new Error("field ceeedb_ceeosigr does not exist in template Ceexedb64Template"); + } + + public int getCeeedb_ceeosigr$offset() { + throw new Error("field ceeedb_ceeosigr does not exist in template Ceexedb64Template"); + } + + public int getCeeedb_ceeosigr$length() { + throw new Error("field ceeedb_ceeosigr does not exist in template Ceexedb64Template"); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexedbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexedbTemplate.java index f3262a67464..1f7e321285a 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexedbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexedbTemplate.java @@ -29,17 +29,17 @@ public interface CeexedbTemplate { - public int length(); - public long getCeeedbenvar(ImageInputStream inputStream, long address) throws IOException; - public int getCeeedbenvar$offset(); - public int getCeeedbenvar$length(); - public long getCeeedbdba(ImageInputStream inputStream, long address) throws IOException; - public int getCeeedbdba$offset(); - public int getCeeedbdba$length(); - public long getCeeedb_dlcb_first(ImageInputStream inputStream, long address) throws IOException; - public int getCeeedb_dlcb_first$offset(); - public int getCeeedb_dlcb_first$length(); - public long getCeeedb_ceeosigr(ImageInputStream inputStream, long address) throws IOException; - public int getCeeedb_ceeosigr$offset(); - public int getCeeedb_ceeosigr$length(); + public int length(); + public long getCeeedbenvar(ImageInputStream inputStream, long address) throws IOException; + public int getCeeedbenvar$offset(); + public int getCeeedbenvar$length(); + public long getCeeedbdba(ImageInputStream inputStream, long address) throws IOException; + public int getCeeedbdba$offset(); + public int getCeeedbdba$length(); + public long getCeeedb_dlcb_first(ImageInputStream inputStream, long address) throws IOException; + public int getCeeedb_dlcb_first$offset(); + public int getCeeedb_dlcb_first$length(); + public long getCeeedb_ceeosigr(ImageInputStream inputStream, long address) throws IOException; + public int getCeeedb_ceeosigr$offset(); + public int getCeeedb_ceeosigr$length(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhcom32Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhcom32Template.java index 801136addfd..26803bfc424 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhcom32Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhcom32Template.java @@ -29,28 +29,33 @@ public final class Ceexhcom32Template implements CeexhcomTemplate { - public int length() { - return 5352; - } - - public long getHcom_exit_stk(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 28); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getHcom_exit_stk$offset() { - return 28; - } - public int getHcom_exit_stk$length() { - return 32; - } - public long getHcom_cibh(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 48); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getHcom_cibh$offset() { - return 48; - } - public int getHcom_cibh$length() { - return 32; - } + public int length() { + return 5352; + } + + public long getHcom_exit_stk(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 28); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getHcom_exit_stk$offset() { + return 28; + } + + public int getHcom_exit_stk$length() { + return 32; + } + + public long getHcom_cibh(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 48); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getHcom_cibh$offset() { + return 48; + } + + public int getHcom_cibh$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhcom64Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhcom64Template.java index ffb08f58949..78ac38b0ab0 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhcom64Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhcom64Template.java @@ -29,28 +29,33 @@ public final class Ceexhcom64Template implements CeexhcomTemplate { - public int length() { - return 10464; - } - - public long getHcom_exit_stk(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 32); - return inputStream.readLong(); - } - public int getHcom_exit_stk$offset() { - return 32; - } - public int getHcom_exit_stk$length() { - return 64; - } - public long getHcom_cibh(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 72); - return inputStream.readLong(); - } - public int getHcom_cibh$offset() { - return 72; - } - public int getHcom_cibh$length() { - return 64; - } + public int length() { + return 10464; + } + + public long getHcom_exit_stk(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 32); + return inputStream.readLong(); + } + + public int getHcom_exit_stk$offset() { + return 32; + } + + public int getHcom_exit_stk$length() { + return 64; + } + + public long getHcom_cibh(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 72); + return inputStream.readLong(); + } + + public int getHcom_cibh$offset() { + return 72; + } + + public int getHcom_cibh$length() { + return 64; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexhcomTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexhcomTemplate.java index 82e8d126ad2..5cc0c62471a 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexhcomTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexhcomTemplate.java @@ -29,11 +29,11 @@ public interface CeexhcomTemplate { - public int length(); - public long getHcom_exit_stk(ImageInputStream inputStream, long address) throws IOException; - public int getHcom_exit_stk$offset(); - public int getHcom_exit_stk$length(); - public long getHcom_cibh(ImageInputStream inputStream, long address) throws IOException; - public int getHcom_cibh$offset(); - public int getHcom_cibh$length(); + public int length(); + public long getHcom_exit_stk(ImageInputStream inputStream, long address) throws IOException; + public int getHcom_exit_stk$offset(); + public int getHcom_exit_stk$length(); + public long getHcom_cibh(ImageInputStream inputStream, long address) throws IOException; + public int getHcom_cibh$offset(); + public int getHcom_cibh$length(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexhepvTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexhepvTemplate.java index d75d52dcb59..37c885542a0 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexhepvTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexhepvTemplate.java @@ -29,28 +29,33 @@ public final class CeexhepvTemplate { - public static int length() { - return 16; - } - - public static long getHepv_ppa1_offset_p(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getHepv_ppa1_offset_p$offset() { - return 8; - } - public static int getHepv_ppa1_offset_p$length() { - return 32; - } - public static long getHepv_entry_point(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - throw new Error("request for long value for field hepv_entry_point which has length of 0"); - } - public static int getHepv_entry_point$offset() { - return 16; - } - public static int getHepv_entry_point$length() { - throw new Error("request for Hepv_entry_point$length which is zero"); - } + public static int length() { + return 16; + } + + public static long getHepv_ppa1_offset_p(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getHepv_ppa1_offset_p$offset() { + return 8; + } + + public static int getHepv_ppa1_offset_p$length() { + return 32; + } + + public static long getHepv_entry_point(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + throw new Error("request for long value for field hepv_entry_point which has length of 0"); + } + + public static int getHepv_entry_point$offset() { + return 16; + } + + public static int getHepv_entry_point$length() { + throw new Error("request for Hepv_entry_point$length which is zero"); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhp1bTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhp1bTemplate.java index d60fdc00630..f5a7a32fe0a 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhp1bTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexhp1bTemplate.java @@ -29,28 +29,33 @@ public final class Ceexhp1bTemplate { - public static int length() { - return 20; - } - - public static long getPpa1h_ppa2_off(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readInt(); - } - public static int getPpa1h_ppa2_off$offset() { - return 4; - } - public static int getPpa1h_ppa2_off$length() { - return 32; - } - public static long getPpa1h_flag3(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 10); - return inputStream.readByte(); - } - public static int getPpa1h_flag3$offset() { - return 10; - } - public static int getPpa1h_flag3$length() { - return 8; - } + public static int length() { + return 20; + } + + public static long getPpa1h_ppa2_off(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readInt(); + } + + public static int getPpa1h_ppa2_off$offset() { + return 4; + } + + public static int getPpa1h_ppa2_off$length() { + return 32; + } + + public static long getPpa1h_flag3(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 10); + return inputStream.readByte(); + } + + public static int getPpa1h_flag3$offset() { + return 10; + } + + public static int getPpa1h_flag3$length() { + return 8; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexlaaTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexlaaTemplate.java index 238c0842a94..b6b72f07ce2 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexlaaTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexlaaTemplate.java @@ -29,18 +29,20 @@ public final class CeexlaaTemplate { - public static int length() { - return 384; - } + public static int length() { + return 384; + } - public static long getCeelaa_lca64(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 88); - return inputStream.readLong(); - } - public static int getCeelaa_lca64$offset() { - return 88; - } - public static int getCeelaa_lca64$length() { - return 64; - } + public static long getCeelaa_lca64(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 88); + return inputStream.readLong(); + } + + public static int getCeelaa_lca64$offset() { + return 88; + } + + public static int getCeelaa_lca64$length() { + return 64; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexoepvTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexoepvTemplate.java index ec37a3c9877..81b5d599a08 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexoepvTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexoepvTemplate.java @@ -29,48 +29,59 @@ public final class CeexoepvTemplate { - public static int length() { - return 20; - } - - public static long getOepv_oldep(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readInt(); - } - public static int getOepv_oldep$offset() { - return 0; - } - public static int getOepv_oldep$length() { - return 32; - } - public static long getOepv_eyecatch(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readInt(); - } - public static int getOepv_eyecatch$offset() { - return 4; - } - public static int getOepv_eyecatch$length() { - return 32; - } - public static long getOepv_cnameoffs(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readByte(); - } - public static int getOepv_cnameoffs$offset() { - return 4; - } - public static int getOepv_cnameoffs$length() { - return 8; - } - public static long getOepv_ppa1offset(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 12); - return inputStream.readInt(); - } - public static int getOepv_ppa1offset$offset() { - return 12; - } - public static int getOepv_ppa1offset$length() { - return 32; - } + public static int length() { + return 20; + } + + public static long getOepv_oldep(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readInt(); + } + + public static int getOepv_oldep$offset() { + return 0; + } + + public static int getOepv_oldep$length() { + return 32; + } + + public static long getOepv_eyecatch(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readInt(); + } + + public static int getOepv_eyecatch$offset() { + return 4; + } + + public static int getOepv_eyecatch$length() { + return 32; + } + + public static long getOepv_cnameoffs(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readByte(); + } + + public static int getOepv_cnameoffs$offset() { + return 4; + } + + public static int getOepv_cnameoffs$length() { + return 8; + } + + public static long getOepv_ppa1offset(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 12); + return inputStream.readInt(); + } + + public static int getOepv_ppa1offset$offset() { + return 12; + } + + public static int getOepv_ppa1offset$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexpp1bTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexpp1bTemplate.java index db233643224..cbf7b432bf9 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexpp1bTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexpp1bTemplate.java @@ -29,28 +29,33 @@ public final class Ceexpp1bTemplate { - public static int length() { - return 32; - } - - public static long getPpa1_nmo(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readByte(); - } - public static int getPpa1_nmo$offset() { - return 0; - } - public static int getPpa1_nmo$length() { - return 8; - } - public static long getPpa1_sig(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1); - return inputStream.readByte(); - } - public static int getPpa1_sig$offset() { - return 1; - } - public static int getPpa1_sig$length() { - return 8; - } + public static int length() { + return 32; + } + + public static long getPpa1_nmo(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readByte(); + } + + public static int getPpa1_nmo$offset() { + return 0; + } + + public static int getPpa1_nmo$length() { + return 8; + } + + public static long getPpa1_sig(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1); + return inputStream.readByte(); + } + + public static int getPpa1_sig$offset() { + return 1; + } + + public static int getPpa1_sig$length() { + return 8; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexrcb32Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexrcb32Template.java index 09c4c9f65a9..32b890643d6 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexrcb32Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexrcb32Template.java @@ -29,28 +29,33 @@ public final class Ceexrcb32Template implements CeexrcbTemplate { - public int length() { - return 168; - } - - public long getCeercb_ceeosigx(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 152); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeercb_ceeosigx$offset() { - return 152; - } - public int getCeercb_ceeosigx$length() { - return 32; - } - public long getCeercb_ppa1tabl(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 156); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public int getCeercb_ppa1tabl$offset() { - return 156; - } - public int getCeercb_ppa1tabl$length() { - return 32; - } + public int length() { + return 168; + } + + public long getCeercb_ceeosigx(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 152); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeercb_ceeosigx$offset() { + return 152; + } + + public int getCeercb_ceeosigx$length() { + return 32; + } + + public long getCeercb_ppa1tabl(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 156); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public int getCeercb_ppa1tabl$offset() { + return 156; + } + + public int getCeercb_ppa1tabl$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexrcb64Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexrcb64Template.java index dfd5f2ee001..6ad79198fc0 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexrcb64Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ceexrcb64Template.java @@ -29,28 +29,33 @@ public final class Ceexrcb64Template implements CeexrcbTemplate { - public int length() { - return 256; - } - - public long getCeercb_ceeosigx(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 168); - return inputStream.readLong(); - } - public int getCeercb_ceeosigx$offset() { - return 168; - } - public int getCeercb_ceeosigx$length() { - return 64; - } - public long getCeercb_ppa1tabl(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 176); - return inputStream.readLong(); - } - public int getCeercb_ppa1tabl$offset() { - return 176; - } - public int getCeercb_ppa1tabl$length() { - return 64; - } + public int length() { + return 256; + } + + public long getCeercb_ceeosigx(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 168); + return inputStream.readLong(); + } + + public int getCeercb_ceeosigx$offset() { + return 168; + } + + public int getCeercb_ceeosigx$length() { + return 64; + } + + public long getCeercb_ppa1tabl(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 176); + return inputStream.readLong(); + } + + public int getCeercb_ppa1tabl$offset() { + return 176; + } + + public int getCeercb_ppa1tabl$length() { + return 64; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexrcbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexrcbTemplate.java index 460727fb364..adf84200967 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexrcbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexrcbTemplate.java @@ -29,11 +29,11 @@ public interface CeexrcbTemplate { - public int length(); - public long getCeercb_ceeosigx(ImageInputStream inputStream, long address) throws IOException; - public int getCeercb_ceeosigx$offset(); - public int getCeercb_ceeosigx$length(); - public long getCeercb_ppa1tabl(ImageInputStream inputStream, long address) throws IOException; - public int getCeercb_ppa1tabl$offset(); - public int getCeercb_ppa1tabl$length(); + public int length(); + public long getCeercb_ceeosigx(ImageInputStream inputStream, long address) throws IOException; + public int getCeercb_ceeosigx$offset(); + public int getCeercb_ceeosigx$length(); + public long getCeercb_ppa1tabl(ImageInputStream inputStream, long address) throws IOException; + public int getCeercb_ppa1tabl$offset(); + public int getCeercb_ppa1tabl$length(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexsfxmTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexsfxmTemplate.java index db477e228ae..6b075f5b8ad 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexsfxmTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexsfxmTemplate.java @@ -29,48 +29,59 @@ public final class CeexsfxmTemplate { - public static int length() { - return 332; - } - - public static long getSfxm_code_eyecatch(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readLong(); - } - public static int getSfxm_code_eyecatch$offset() { - return 0; - } - public static int getSfxm_code_eyecatch$length() { - return 64; - } - public static long getSfxm_code_return_pt(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 10); - return inputStream.readInt(); - } - public static int getSfxm_code_return_pt$offset() { - return 10; - } - public static int getSfxm_code_return_pt$length() { - return 32; - } - public static long getSfxm_next(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 68); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getSfxm_next$offset() { - return 68; - } - public static int getSfxm_next$length() { - return 32; - } - public static long getSfxm_parm_sf(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 300); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getSfxm_parm_sf$offset() { - return 300; - } - public static int getSfxm_parm_sf$length() { - return 32; - } + public static int length() { + return 332; + } + + public static long getSfxm_code_eyecatch(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readLong(); + } + + public static int getSfxm_code_eyecatch$offset() { + return 0; + } + + public static int getSfxm_code_eyecatch$length() { + return 64; + } + + public static long getSfxm_code_return_pt(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 10); + return inputStream.readInt(); + } + + public static int getSfxm_code_return_pt$offset() { + return 10; + } + + public static int getSfxm_code_return_pt$length() { + return 32; + } + + public static long getSfxm_next(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 68); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getSfxm_next$offset() { + return 68; + } + + public static int getSfxm_next$length() { + return 32; + } + + public static long getSfxm_parm_sf(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 300); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getSfxm_parm_sf$offset() { + return 300; + } + + public static int getSfxm_parm_sf$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexstkhTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexstkhTemplate.java index 08563421ca2..d402dddf2e7 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexstkhTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeexstkhTemplate.java @@ -29,18 +29,20 @@ public final class CeexstkhTemplate { - public static int length() { - return 24; - } + public static int length() { + return 24; + } - public static long getStkh_stackfloor(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 20); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getStkh_stackfloor$offset() { - return 20; - } - public static int getStkh_stackfloor$length() { - return 32; - } + public static long getStkh_stackfloor(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 20); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getStkh_stackfloor$offset() { + return 20; + } + + public static int getStkh_stackfloor$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeextvbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeextvbTemplate.java index b531f350d9d..0052587fcf2 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeextvbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeextvbTemplate.java @@ -29,21 +29,23 @@ public final class CeextvbTemplate { - public static int length() { - return 12; - } + public static int length() { + return 12; + } - public static long getCeetvbcount(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - long result = inputStream.readBits(16); - result <<= 48; - result >>= 48; - return result; - } - public static int getCeetvbcount$offset() { - return 4; - } - public static int getCeetvbcount$length() { - return 16; - } + public static long getCeetvbcount(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + long result = inputStream.readBits(16); + result <<= 48; + result >>= 48; + return result; + } + + public static int getCeetvbcount$offset() { + return 4; + } + + public static int getCeetvbcount$length() { + return 16; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeextvbeTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeextvbeTemplate.java index 75564ef507e..8da9bc581e6 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeextvbeTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CeextvbeTemplate.java @@ -29,28 +29,33 @@ public final class CeextvbeTemplate { - public static int length() { - return 8; - } - - public static long getCeetvbekey(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeetvbekey$offset() { - return 0; - } - public static int getCeetvbekey$length() { - return 32; - } - public static long getCeetvbevalue(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCeetvbevalue$offset() { - return 4; - } - public static int getCeetvbevalue$length() { - return 32; - } + public static int length() { + return 8; + } + + public static long getCeetvbekey(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeetvbekey$offset() { + return 0; + } + + public static int getCeetvbekey$length() { + return 32; + } + + public static long getCeetvbevalue(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCeetvbevalue$offset() { + return 4; + } + + public static int getCeetvbevalue$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2ExpFuncEntryTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2ExpFuncEntryTemplate.java index b611fdfcfa4..ab6bfc82187 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2ExpFuncEntryTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2ExpFuncEntryTemplate.java @@ -29,66 +29,80 @@ public final class Ciet2ExpFuncEntryTemplate { - public static int length() { - return 36; - } - - public static long getCiet2_exp_func_offset(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet2_exp_func_offset$offset() { - return 4; - } - public static int getCiet2_exp_func_offset$length() { - return 32; - } - public static long getCiet2_exp_func_name_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet2_exp_func_name_addr$offset() { - return 8; - } - public static int getCiet2_exp_func_name_addr$length() { - return 32; - } - public static long getCiet2_exp_func_is_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 12); - inputStream.setBitOffset(1); - long result = inputStream.readBits(1); - result <<= 63; - result >>= 63; - return result; - } - public static int getCiet2_exp_func_is_addr$offset() { - return 12; - } - public static int getCiet2_exp_func_is_addr$length() { - return 1; - } - public static long getCiet2_exp_ada_is_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 12); - inputStream.setBitOffset(2); - long result = inputStream.readBits(1); - result <<= 63; - result >>= 63; - return result; - } - public static int getCiet2_exp_ada_is_addr$offset() { - return 12; - } - public static int getCiet2_exp_ada_is_addr$length() { - return 1; - } - public static long getCiet2_exp_func_ada_offset(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 20); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet2_exp_func_ada_offset$offset() { - return 20; - } - public static int getCiet2_exp_func_ada_offset$length() { - return 32; - } + public static int length() { + return 36; + } + + public static long getCiet2_exp_func_offset(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet2_exp_func_offset$offset() { + return 4; + } + + public static int getCiet2_exp_func_offset$length() { + return 32; + } + + public static long getCiet2_exp_func_name_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet2_exp_func_name_addr$offset() { + return 8; + } + + public static int getCiet2_exp_func_name_addr$length() { + return 32; + } + + public static long getCiet2_exp_func_is_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 12); + inputStream.setBitOffset(1); + long result = inputStream.readBits(1); + result <<= 63; + result >>= 63; + return result; + } + + public static int getCiet2_exp_func_is_addr$offset() { + return 12; + } + + public static int getCiet2_exp_func_is_addr$length() { + return 1; + } + + public static long getCiet2_exp_ada_is_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 12); + inputStream.setBitOffset(2); + long result = inputStream.readBits(1); + result <<= 63; + result >>= 63; + return result; + } + + public static int getCiet2_exp_ada_is_addr$offset() { + return 12; + } + + public static int getCiet2_exp_ada_is_addr$length() { + return 1; + } + + public static long getCiet2_exp_func_ada_offset(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 20); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet2_exp_func_ada_offset$offset() { + return 20; + } + + public static int getCiet2_exp_func_ada_offset$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2ExpVarEntryTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2ExpVarEntryTemplate.java index 6551bcc6d53..56ea402527f 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2ExpVarEntryTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2ExpVarEntryTemplate.java @@ -29,42 +29,50 @@ public final class Ciet2ExpVarEntryTemplate { - public static int length() { - return 16; - } + public static int length() { + return 16; + } - public static long getCiet2_exp_var_offset(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet2_exp_var_offset$offset() { - return 4; - } - public static int getCiet2_exp_var_offset$length() { - return 32; - } - public static long getCiet2_exp_var_name_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet2_exp_var_name_addr$offset() { - return 8; - } - public static int getCiet2_exp_var_name_addr$length() { - return 32; - } - public static long getCiet2_exp_var_is_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 12); - inputStream.setBitOffset(1); - long result = inputStream.readBits(1); - result <<= 63; - result >>= 63; - return result; - } - public static int getCiet2_exp_var_is_addr$offset() { - return 12; - } - public static int getCiet2_exp_var_is_addr$length() { - return 1; - } + public static long getCiet2_exp_var_offset(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet2_exp_var_offset$offset() { + return 4; + } + + public static int getCiet2_exp_var_offset$length() { + return 32; + } + + public static long getCiet2_exp_var_name_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet2_exp_var_name_addr$offset() { + return 8; + } + + public static int getCiet2_exp_var_name_addr$length() { + return 32; + } + + public static long getCiet2_exp_var_is_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 12); + inputStream.setBitOffset(1); + long result = inputStream.readBits(1); + result <<= 63; + result >>= 63; + return result; + } + + public static int getCiet2_exp_var_is_addr$offset() { + return 12; + } + + public static int getCiet2_exp_var_is_addr$length() { + return 1; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2Template.java index bd90b90f7a8..97514b50374 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Ciet2Template.java @@ -29,58 +29,72 @@ public final class Ciet2Template { - public static int length() { - return 36; - } - - public static long getCiet2_version(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readByte(); - } - public static int getCiet2_version$offset() { - return 8; - } - public static int getCiet2_version$length() { - return 8; - } - public static long getCiet2_func_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 12); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet2_func_addr$offset() { - return 12; - } - public static int getCiet2_func_addr$length() { - return 32; - } - public static long getCiet2_func_count(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - return inputStream.readInt(); - } - public static int getCiet2_func_count$offset() { - return 16; - } - public static int getCiet2_func_count$length() { - return 32; - } - public static long getCiet2_var_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 20); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet2_var_addr$offset() { - return 20; - } - public static int getCiet2_var_addr$length() { - return 32; - } - public static long getCiet2_var_count(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 24); - return inputStream.readInt(); - } - public static int getCiet2_var_count$offset() { - return 24; - } - public static int getCiet2_var_count$length() { - return 32; - } + public static int length() { + return 36; + } + + public static long getCiet2_version(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readByte(); + } + + public static int getCiet2_version$offset() { + return 8; + } + + public static int getCiet2_version$length() { + return 8; + } + + public static long getCiet2_func_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 12); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet2_func_addr$offset() { + return 12; + } + + public static int getCiet2_func_addr$length() { + return 32; + } + + public static long getCiet2_func_count(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + return inputStream.readInt(); + } + + public static int getCiet2_func_count$offset() { + return 16; + } + + public static int getCiet2_func_count$length() { + return 32; + } + + public static long getCiet2_var_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 20); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet2_var_addr$offset() { + return 20; + } + + public static int getCiet2_var_addr$length() { + return 32; + } + + public static long getCiet2_var_count(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 24); + return inputStream.readInt(); + } + + public static int getCiet2_var_count$offset() { + return 24; + } + + public static int getCiet2_var_count$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CietExpEntryTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CietExpEntryTemplate.java index 0b422eb9284..ef3f0ac9f87 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CietExpEntryTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CietExpEntryTemplate.java @@ -29,56 +29,67 @@ public final class CietExpEntryTemplate { - public static int length() { - return 28; - } - - public static long getCiet_exp_offset(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - return inputStream.readInt(); - } - public static int getCiet_exp_offset$offset() { - return 16; - } - public static int getCiet_exp_offset$length() { - return 32; - } - public static long getCiet_exp_name_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 20); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet_exp_name_addr$offset() { - return 20; - } - public static int getCiet_exp_name_addr$length() { - return 32; - } - public static long getCiet_is_function(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 24); - inputStream.setBitOffset(0); - long result = inputStream.readBits(1); - result <<= 63; - result >>= 63; - return result; - } - public static int getCiet_is_function$offset() { - return 24; - } - public static int getCiet_is_function$length() { - return 1; - } - public static long getCiet_is_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 24); - inputStream.setBitOffset(1); - long result = inputStream.readBits(1); - result <<= 63; - result >>= 63; - return result; - } - public static int getCiet_is_addr$offset() { - return 24; - } - public static int getCiet_is_addr$length() { - return 1; - } + public static int length() { + return 28; + } + + public static long getCiet_exp_offset(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + return inputStream.readInt(); + } + + public static int getCiet_exp_offset$offset() { + return 16; + } + + public static int getCiet_exp_offset$length() { + return 32; + } + + public static long getCiet_exp_name_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 20); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet_exp_name_addr$offset() { + return 20; + } + + public static int getCiet_exp_name_addr$length() { + return 32; + } + + public static long getCiet_is_function(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 24); + inputStream.setBitOffset(0); + long result = inputStream.readBits(1); + result <<= 63; + result >>= 63; + return result; + } + + public static int getCiet_is_function$offset() { + return 24; + } + + public static int getCiet_is_function$length() { + return 1; + } + + public static long getCiet_is_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 24); + inputStream.setBitOffset(1); + long result = inputStream.readBits(1); + result <<= 63; + result >>= 63; + return result; + } + + public static int getCiet_is_addr$offset() { + return 24; + } + + public static int getCiet_is_addr$length() { + return 1; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CietTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CietTemplate.java index e8aeaab7a8a..0b008d41182 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CietTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/CietTemplate.java @@ -29,48 +29,59 @@ public final class CietTemplate { - public static int length() { - return 36; - } - - public static long getCiet_func_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 12); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet_func_addr$offset() { - return 12; - } - public static int getCiet_func_addr$length() { - return 32; - } - public static long getCiet_func_count(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - return inputStream.readInt(); - } - public static int getCiet_func_count$offset() { - return 16; - } - public static int getCiet_func_count$length() { - return 32; - } - public static long getCiet_var_addr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 20); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getCiet_var_addr$offset() { - return 20; - } - public static int getCiet_var_addr$length() { - return 32; - } - public static long getCiet_var_count(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 24); - return inputStream.readInt(); - } - public static int getCiet_var_count$offset() { - return 24; - } - public static int getCiet_var_count$length() { - return 32; - } + public static int length() { + return 36; + } + + public static long getCiet_func_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 12); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet_func_addr$offset() { + return 12; + } + + public static int getCiet_func_addr$length() { + return 32; + } + + public static long getCiet_func_count(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + return inputStream.readInt(); + } + + public static int getCiet_func_count$offset() { + return 16; + } + + public static int getCiet_func_count$length() { + return 32; + } + + public static long getCiet_var_addr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 20); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getCiet_var_addr$offset() { + return 20; + } + + public static int getCiet_var_addr$length() { + return 32; + } + + public static long getCiet_var_count(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 24); + return inputStream.readInt(); + } + + public static int getCiet_var_count$offset() { + return 24; + } + + public static int getCiet_var_count$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Dll.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Dll.java index 40ab144a0c3..9c83d08e50f 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Dll.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Dll.java @@ -34,337 +34,337 @@ public class Dll { - /** The address of the DLCB structure */ - private long address; - /** The AddressSpace we belong to */ - private AddressSpace space; - /** The AddressSpaceImageInputStream */ - private AddressSpaceImageInputStream inputStream; - /** The name of this DLL */ - private String name; - /** The WSA (Writable Static Area) address */ - private long wsa; - /** The next DLL in the chain (or null) */ - private Dll next; - /** The array of DllVariables */ - private DllVariable[] variables; - /** The array of DllFunctions */ - private DllFunction[] functions; - /** Dlcb template - size depends on 32/64 bit mode */ - /*static*/ CeexdlcbTemplate ceexdlcbTemplate; - /** Logger */ - private static Logger log = Logger.getLogger(Dll.class.getName()); + /** The address of the DLCB structure */ + private long address; + /** The AddressSpace we belong to */ + private AddressSpace space; + /** The AddressSpaceImageInputStream */ + private AddressSpaceImageInputStream inputStream; + /** The name of this DLL */ + private String name; + /** The WSA (Writable Static Area) address */ + private long wsa; + /** The next DLL in the chain (or null) */ + private Dll next; + /** The array of DllVariables */ + private DllVariable[] variables; + /** The array of DllFunctions */ + private DllFunction[] functions; + /** Dlcb template - size depends on 32/64 bit mode */ + /*static*/ CeexdlcbTemplate ceexdlcbTemplate; + /** Logger */ + private static Logger log = Logger.getLogger(Dll.class.getName()); - /** - * Constructs a new Dll given the address of the DLCB (DLL Control Block) structure. - * The normal way for a user to get hold of an instance though would be via - * {@link com.ibm.dtfj.corereaders.zos.le.Edb#getFirstDll}. - */ - public Dll(long address, AddressSpace space) { - this.address = address; - this.space = space; - inputStream = space.getImageInputStream(); - /* Create any templates we need if not already created */ - createTemplates(space); - } + /** + * Constructs a new Dll given the address of the DLCB (DLL Control Block) structure. + * The normal way for a user to get hold of an instance though would be via + * {@link com.ibm.dtfj.corereaders.zos.le.Edb#getFirstDll}. + */ + public Dll(long address, AddressSpace space) { + this.address = address; + this.space = space; + inputStream = space.getImageInputStream(); + /* Create any templates we need if not already created */ + createTemplates(space); + } - /** - * Create any templates we need if not already created. - */ - /*static*/ void createTemplates(AddressSpace space) { - if (ceexdlcbTemplate == null) { - if (space.is64bit()) { - ceexdlcbTemplate = new Ceexdlcb64Template(); - } else { - ceexdlcbTemplate = new Ceexdlcb32Template(); - } - } - } + /** + * Create any templates we need if not already created. + */ + /*static*/ void createTemplates(AddressSpace space) { + if (ceexdlcbTemplate == null) { + if (space.is64bit()) { + ceexdlcbTemplate = new Ceexdlcb64Template(); + } else { + ceexdlcbTemplate = new Ceexdlcb32Template(); + } + } + } - /** - * Returns the name of this DLL. - * @throws IOException - */ - public String getName() throws IOException { - if (name == null) { - long dlcbnamelen = ceexdlcbTemplate.getDlcbnamelen(inputStream, address); - long dlcbnameptr = ceexdlcbTemplate.getDlcbnameptr(inputStream, address); - name = space.readEbcdicString(dlcbnameptr, (int)dlcbnamelen); - } - return name; - } + /** + * Returns the name of this DLL. + * @throws IOException + */ + public String getName() throws IOException { + if (name == null) { + long dlcbnamelen = ceexdlcbTemplate.getDlcbnamelen(inputStream, address); + long dlcbnameptr = ceexdlcbTemplate.getDlcbnameptr(inputStream, address); + name = space.readEbcdicString(dlcbnameptr, (int)dlcbnamelen); + } + return name; + } - /** - * Returns the load address for this DLL. - */ - public long getLoadAddress() { - throw new Error("tbc"); - } + /** + * Returns the load address for this DLL. + */ + public long getLoadAddress() { + throw new Error("tbc"); + } - /** - * Returns the address of the WSA (Writable Static Area) for this DLL. - * @throws IOException - */ - public long getWsa() throws IOException { - if (wsa == 0) { - wsa = ceexdlcbTemplate.getDlcbwsaptr(inputStream, address); - } - return wsa; - } + /** + * Returns the address of the WSA (Writable Static Area) for this DLL. + * @throws IOException + */ + public long getWsa() throws IOException { + if (wsa == 0) { + wsa = ceexdlcbTemplate.getDlcbwsaptr(inputStream, address); + } + return wsa; + } - /** - * Returns the next Dll in the chain (or null if none). - * @throws IOException - */ - public Dll getNext() throws IOException { - if (next == null) { - long dlcbnextptr = ceexdlcbTemplate.getDlcbnextptr(inputStream, address); - if (dlcbnextptr != 0) - next = new Dll(dlcbnextptr, space); - } - return next; - } + /** + * Returns the next Dll in the chain (or null if none). + * @throws IOException + */ + public Dll getNext() throws IOException { + if (next == null) { + long dlcbnextptr = ceexdlcbTemplate.getDlcbnextptr(inputStream, address); + if (dlcbnextptr != 0) + next = new Dll(dlcbnextptr, space); + } + return next; + } - /** - * Returns the named {@link com.ibm.dtfj.corereaders.zos.le.DllVariable} (or null if it can't be found). - */ - public DllVariable getVariable(String name) throws IOException { - if (getVariables() == null) - return null; - for (int i = 0; i < variables.length; i++) { - if (variables[i].name.equals(name)) { - return variables[i]; - } - } - return null; - } + /** + * Returns the named {@link com.ibm.dtfj.corereaders.zos.le.DllVariable} (or null if it can't be found). + */ + public DllVariable getVariable(String name) throws IOException { + if (getVariables() == null) + return null; + for (int i = 0; i < variables.length; i++) { + if (variables[i].name.equals(name)) { + return variables[i]; + } + } + return null; + } - /** - * Returns an array of the {@link com.ibm.dtfj.corereaders.zos.le.DllVariable}s belonging to this DLL - */ - public DllVariable[] getVariables() throws IOException { - if (variables != null) - return variables; - long dlcbiewbcie = ceexdlcbTemplate.getDlcbiewbcie(inputStream, address); - int eyecatcher = space.readInt(dlcbiewbcie); - if (eyecatcher == 0xC9C5E6C2) { // IEWB - long ciet2_version = Ciet2Template.getCiet2_version(inputStream, dlcbiewbcie); - if (ciet2_version == 2) { - long ciet2_var_count = Ciet2Template.getCiet2_var_count(inputStream, dlcbiewbcie); - assert ciet2_var_count >=0 && ciet2_var_count < 1000000 : ciet2_var_count; - long ciet2_var_addr = Ciet2Template.getCiet2_var_addr(inputStream, dlcbiewbcie); - variables = new DllVariable[(int)ciet2_var_count]; - for (int i = 0; i < ciet2_var_count; i++) { - try { - long base = ciet2_var_addr + (i * Ciet2ExpVarEntryTemplate.length()); - long ciet2_exp_var_is_addr = Ciet2ExpVarEntryTemplate.getCiet2_exp_var_is_addr(inputStream, base); - long ciet2_exp_var_offset = Ciet2ExpVarEntryTemplate.getCiet2_exp_var_offset(inputStream, base); - long ciet2_exp_var_name_addr = Ciet2ExpVarEntryTemplate.getCiet2_exp_var_name_addr(inputStream, base); - String varName = space.readEbcdicString(ciet2_exp_var_name_addr); - long varAddr = ciet2_exp_var_is_addr == 0 ? ciet2_exp_var_offset + getWsa() : ciet2_exp_var_offset; - long varValue = space.readInt(varAddr); - variables[i] = new DllVariable(varName, varAddr, varValue); - } catch (IOException e) { - variables[i] = new DllVariable(e.toString(), 0, 0); - } - } - } else if (ciet2_version == 1) { - long ciet_var_count = CietTemplate.getCiet_var_count(inputStream, dlcbiewbcie); - long ciet_var_addr = CietTemplate.getCiet_var_addr(inputStream, dlcbiewbcie); - ciet_var_addr = space.readInt(ciet_var_addr); - log.finer("ciet_var_addr = " + hex(ciet_var_addr)); - variables = new DllVariable[(int)ciet_var_count]; - log.finer("count = " + ciet_var_count); - for (int i = 0; i < ciet_var_count; i++) { - long base = ciet_var_addr + (i * CietExpEntryTemplate.length()); - log.finer("base = " + hex(base)); - long ciet_is_addr = CietExpEntryTemplate.getCiet_is_addr(inputStream, base); - log.finer("ciet_is_addr = " + ciet_is_addr); - long ciet_is_function = CietExpEntryTemplate.getCiet_is_function(inputStream, base); - log.finer("ciet_is_function = " + hex(ciet_is_function)); - long ciet_exp_offset = CietExpEntryTemplate.getCiet_exp_offset(inputStream, base); - log.finer("ciet_exp_offset = " + hex(ciet_exp_offset)); - long ciet_exp_name_addr = CietExpEntryTemplate.getCiet_exp_name_addr(inputStream, base); - log.finer("ciet_exp_name_addr = " + hex(ciet_exp_name_addr) + " length = " + space.readUnsignedShort(ciet_exp_name_addr)); - String varName = space.readEbcdicString(ciet_exp_name_addr); - log.finer("varName = " + varName); - long varAddr = ciet_is_addr == 0 ? ciet_exp_offset + getWsa() : ciet_exp_offset; - log.finer("varAddr = " + hex(varAddr)); - log.finer("ciet_is_addr = " + hex(ciet_is_addr)); - long varValue = 0; - try { - varValue = space.readInt(varAddr); - } catch (IOException e) {} // ignore bad addresses - variables[i] = new DllVariable(varName, varAddr, varValue); - } - } else - throw new Error("expected ciet2_version 1 or 2 but instead found " + ciet2_version); - } else if (space.readEbcdicString(dlcbiewbcie, 8).equals("@@DL370$")) { - long dlloffexpvar = DllcsectTemplate.getDlloffexpvar(inputStream, dlcbiewbcie); - long dllexpvars = dlcbiewbcie + dlloffexpvar; - long dllexpvarscount = DllexpvarsTemplate.getDllexpvarscount(inputStream, dllexpvars); - if (dllexpvarscount < 0 || dllexpvarscount > 1000000) { - log.config("impossible dllexpvarscount: " + dllexpvarscount); - variables = new DllVariable[0]; - return variables; - } - variables = new DllVariable[(int)dllexpvarscount]; - for (int i = 0; i < dllexpvarscount; i++) { - long dllexpvarsname = DllexpvarsTemplate.getDllexpvarsname(inputStream, dllexpvars); - long dllexpvarsqcon = DllexpvarsTemplate.getDllexpvarsqcon(inputStream, dllexpvars); - String varName = space.readEbcdicString(dlcbiewbcie + dllexpvarsname); - long varAddr = getWsa() + dllexpvarsqcon; - long varValue = space.readInt(varAddr); - variables[i] = new DllVariable(varName, varAddr, varValue); - // XXX this is naughty - we should handle arrays properly - dllexpvars += DllexpvarsTemplate.getDllexpvarsarray$length() / 8; - } - } else { - throw new Error("tbc"); - } - return variables; - } + /** + * Returns an array of the {@link com.ibm.dtfj.corereaders.zos.le.DllVariable}s belonging to this DLL + */ + public DllVariable[] getVariables() throws IOException { + if (variables != null) + return variables; + long dlcbiewbcie = ceexdlcbTemplate.getDlcbiewbcie(inputStream, address); + int eyecatcher = space.readInt(dlcbiewbcie); + if (eyecatcher == 0xC9C5E6C2) { // IEWB + long ciet2_version = Ciet2Template.getCiet2_version(inputStream, dlcbiewbcie); + if (ciet2_version == 2) { + long ciet2_var_count = Ciet2Template.getCiet2_var_count(inputStream, dlcbiewbcie); + assert ciet2_var_count >=0 && ciet2_var_count < 1000000 : ciet2_var_count; + long ciet2_var_addr = Ciet2Template.getCiet2_var_addr(inputStream, dlcbiewbcie); + variables = new DllVariable[(int)ciet2_var_count]; + for (int i = 0; i < ciet2_var_count; i++) { + try { + long base = ciet2_var_addr + (i * Ciet2ExpVarEntryTemplate.length()); + long ciet2_exp_var_is_addr = Ciet2ExpVarEntryTemplate.getCiet2_exp_var_is_addr(inputStream, base); + long ciet2_exp_var_offset = Ciet2ExpVarEntryTemplate.getCiet2_exp_var_offset(inputStream, base); + long ciet2_exp_var_name_addr = Ciet2ExpVarEntryTemplate.getCiet2_exp_var_name_addr(inputStream, base); + String varName = space.readEbcdicString(ciet2_exp_var_name_addr); + long varAddr = ciet2_exp_var_is_addr == 0 ? ciet2_exp_var_offset + getWsa() : ciet2_exp_var_offset; + long varValue = space.readInt(varAddr); + variables[i] = new DllVariable(varName, varAddr, varValue); + } catch (IOException e) { + variables[i] = new DllVariable(e.toString(), 0, 0); + } + } + } else if (ciet2_version == 1) { + long ciet_var_count = CietTemplate.getCiet_var_count(inputStream, dlcbiewbcie); + long ciet_var_addr = CietTemplate.getCiet_var_addr(inputStream, dlcbiewbcie); + ciet_var_addr = space.readInt(ciet_var_addr); + log.finer("ciet_var_addr = " + hex(ciet_var_addr)); + variables = new DllVariable[(int)ciet_var_count]; + log.finer("count = " + ciet_var_count); + for (int i = 0; i < ciet_var_count; i++) { + long base = ciet_var_addr + (i * CietExpEntryTemplate.length()); + log.finer("base = " + hex(base)); + long ciet_is_addr = CietExpEntryTemplate.getCiet_is_addr(inputStream, base); + log.finer("ciet_is_addr = " + ciet_is_addr); + long ciet_is_function = CietExpEntryTemplate.getCiet_is_function(inputStream, base); + log.finer("ciet_is_function = " + hex(ciet_is_function)); + long ciet_exp_offset = CietExpEntryTemplate.getCiet_exp_offset(inputStream, base); + log.finer("ciet_exp_offset = " + hex(ciet_exp_offset)); + long ciet_exp_name_addr = CietExpEntryTemplate.getCiet_exp_name_addr(inputStream, base); + log.finer("ciet_exp_name_addr = " + hex(ciet_exp_name_addr) + " length = " + space.readUnsignedShort(ciet_exp_name_addr)); + String varName = space.readEbcdicString(ciet_exp_name_addr); + log.finer("varName = " + varName); + long varAddr = ciet_is_addr == 0 ? ciet_exp_offset + getWsa() : ciet_exp_offset; + log.finer("varAddr = " + hex(varAddr)); + log.finer("ciet_is_addr = " + hex(ciet_is_addr)); + long varValue = 0; + try { + varValue = space.readInt(varAddr); + } catch (IOException e) {} // ignore bad addresses + variables[i] = new DllVariable(varName, varAddr, varValue); + } + } else + throw new Error("expected ciet2_version 1 or 2 but instead found " + ciet2_version); + } else if (space.readEbcdicString(dlcbiewbcie, 8).equals("@@DL370$")) { + long dlloffexpvar = DllcsectTemplate.getDlloffexpvar(inputStream, dlcbiewbcie); + long dllexpvars = dlcbiewbcie + dlloffexpvar; + long dllexpvarscount = DllexpvarsTemplate.getDllexpvarscount(inputStream, dllexpvars); + if (dllexpvarscount < 0 || dllexpvarscount > 1000000) { + log.config("impossible dllexpvarscount: " + dllexpvarscount); + variables = new DllVariable[0]; + return variables; + } + variables = new DllVariable[(int)dllexpvarscount]; + for (int i = 0; i < dllexpvarscount; i++) { + long dllexpvarsname = DllexpvarsTemplate.getDllexpvarsname(inputStream, dllexpvars); + long dllexpvarsqcon = DllexpvarsTemplate.getDllexpvarsqcon(inputStream, dllexpvars); + String varName = space.readEbcdicString(dlcbiewbcie + dllexpvarsname); + long varAddr = getWsa() + dllexpvarsqcon; + long varValue = space.readInt(varAddr); + variables[i] = new DllVariable(varName, varAddr, varValue); + // XXX this is naughty - we should handle arrays properly + dllexpvars += DllexpvarsTemplate.getDllexpvarsarray$length() / 8; + } + } else { + throw new Error("tbc"); + } + return variables; + } - /** - * Returns the named {@link com.ibm.dtfj.corereaders.zos.le.DllFunction} (or null if it can't be found). - */ - public DllFunction getFunction(String name) throws IOException { - if (getFunctions() == null) - return null; - for (int i = 0; i < functions.length; i++) { - if (functions[i].name.equals(name)) { - return functions[i]; - } - } - return null; - } + /** + * Returns the named {@link com.ibm.dtfj.corereaders.zos.le.DllFunction} (or null if it can't be found). + */ + public DllFunction getFunction(String name) throws IOException { + if (getFunctions() == null) + return null; + for (int i = 0; i < functions.length; i++) { + if (functions[i].name.equals(name)) { + return functions[i]; + } + } + return null; + } - /** - * Returns an array of the {@link com.ibm.dtfj.corereaders.zos.le.DllFunction}s belonging to this DLL - */ - public DllFunction[] getFunctions() throws IOException { - if (functions != null) - return functions; - long dlcbiewbcie = ceexdlcbTemplate.getDlcbiewbcie(inputStream, address); - int eyecatcher = space.readInt(dlcbiewbcie); - if (eyecatcher == 0xC9C5E6C2) { // IEWB - long ciet2_version = Ciet2Template.getCiet2_version(inputStream, dlcbiewbcie); - if (ciet2_version == 2) { - long ciet2_func_count = Ciet2Template.getCiet2_func_count(inputStream, dlcbiewbcie); - assert ciet2_func_count >=0 && ciet2_func_count < 1000000 : ciet2_func_count; - long ciet2_func_addr = Ciet2Template.getCiet2_func_addr(inputStream, dlcbiewbcie); - functions = new DllFunction[(int)ciet2_func_count]; - for (int i = 0; i < ciet2_func_count; i++) { - try { - long base = ciet2_func_addr + (i * Ciet2ExpFuncEntryTemplate.length()); - long ciet2_exp_func_is_addr = Ciet2ExpFuncEntryTemplate.getCiet2_exp_func_is_addr(inputStream, base); - long ciet2_exp_func_offset = Ciet2ExpFuncEntryTemplate.getCiet2_exp_func_offset(inputStream, base); - long ciet2_exp_func_name_addr = Ciet2ExpFuncEntryTemplate.getCiet2_exp_func_name_addr(inputStream, base); - String funcName = space.readEbcdicString(ciet2_exp_func_name_addr); - long funcAddr = ciet2_exp_func_is_addr == 0 ? ciet2_exp_func_offset + getWsa() : ciet2_exp_func_offset; - long ciet2_exp_ada_is_addr = Ciet2ExpFuncEntryTemplate.getCiet2_exp_ada_is_addr(inputStream, base); - long ciet2_exp_func_ada_offset = Ciet2ExpFuncEntryTemplate.getCiet2_exp_func_ada_offset(inputStream, base); - long funcAda = ciet2_exp_ada_is_addr == 0 ? ciet2_exp_func_ada_offset + getWsa() : ciet2_exp_func_ada_offset; - functions[i] = new DllFunction(funcName, funcAddr, null, funcAda); - } catch (IOException e) { - functions[i] = new DllFunction(e.toString(), 0, null, space.WILD_POINTER); - } - } - } else if (ciet2_version == 1) { - long ciet_func_count = CietTemplate.getCiet_func_count(inputStream, dlcbiewbcie); - long ciet_func_addr = CietTemplate.getCiet_func_addr(inputStream, dlcbiewbcie); - ciet_func_addr = space.readInt(ciet_func_addr); - functions = new DllFunction[(int)ciet_func_count]; - log.finer("count = " + ciet_func_count); - for (int i = 0; i < ciet_func_count; i++) { - long base = ciet_func_addr + (i * CietExpEntryTemplate.length()); - log.finer("base = " + hex(base)); - long ciet_is_addr = CietExpEntryTemplate.getCiet_is_addr(inputStream, base); - long ciet_is_function = CietExpEntryTemplate.getCiet_is_function(inputStream, base); - log.finer("ciet_is_function = " + hex(ciet_is_function)); - long ciet_exp_offset = CietExpEntryTemplate.getCiet_exp_offset(inputStream, base); - log.finer("ciet_exp_offset = " + hex(ciet_exp_offset)); - long ciet_exp_name_addr = CietExpEntryTemplate.getCiet_exp_name_addr(inputStream, base); - log.finer("ciet_exp_name_addr = " + hex(ciet_exp_name_addr) + " length = " + space.readUnsignedShort(ciet_exp_name_addr)); - String funcName = space.readEbcdicString(ciet_exp_name_addr); - log.finer("funcName = " + funcName); - long funcAddr = ciet_is_addr == 0 ? ciet_exp_offset + getWsa() : ciet_exp_offset; - log.finer("funcAddr = " + hex(funcAddr)); - log.finer("ciet_is_addr = " + hex(ciet_is_addr)); - functions[i] = new DllFunction(funcName, funcAddr, null, space.WILD_POINTER); - } - } else - throw new Error("expected ciet2_version 1 or 2 but instead found " + ciet2_version); - } else if (space.readEbcdicString(dlcbiewbcie, 8).equals("@@DL370$")) { - long dlloffexpfunc = DllcsectTemplate.getDlloffexpfunc(inputStream, dlcbiewbcie); - long dllexpfuncs = dlcbiewbcie + dlloffexpfunc; - long dllexpfuncscount = DllexpfuncsTemplate.getDllexpfuncscount(inputStream, dllexpfuncs); - if (dllexpfuncscount < 0 || dllexpfuncscount > 1000000) { - log.config("impossible dllexpfuncscount: " + dllexpfuncscount); - functions = new DllFunction[0]; - return functions; - } - functions = new DllFunction[(int)dllexpfuncscount]; - for (int i = 0; i < dllexpfuncscount; i++) { - long dllexpfuncsname = DllexpfuncsTemplate.getDllexpfuncsname(inputStream, dllexpfuncs); - long dllexpfuncsaddr = DllexpfuncsTemplate.getDllexpfuncsaddr(inputStream, dllexpfuncs); - String funcName = space.readEbcdicString(dlcbiewbcie + dllexpfuncsname); - functions[i] = new DllFunction(funcName, dllexpfuncsaddr, null, getWsa()); - // XXX this is naughty - we should handle arrays properly - dllexpfuncs += DllexpfuncsTemplate.getDllexpfuncsarray$length() / 8; - } - } else { - throw new Error("tbc"); - } - return functions; - } + /** + * Returns an array of the {@link com.ibm.dtfj.corereaders.zos.le.DllFunction}s belonging to this DLL + */ + public DllFunction[] getFunctions() throws IOException { + if (functions != null) + return functions; + long dlcbiewbcie = ceexdlcbTemplate.getDlcbiewbcie(inputStream, address); + int eyecatcher = space.readInt(dlcbiewbcie); + if (eyecatcher == 0xC9C5E6C2) { // IEWB + long ciet2_version = Ciet2Template.getCiet2_version(inputStream, dlcbiewbcie); + if (ciet2_version == 2) { + long ciet2_func_count = Ciet2Template.getCiet2_func_count(inputStream, dlcbiewbcie); + assert ciet2_func_count >=0 && ciet2_func_count < 1000000 : ciet2_func_count; + long ciet2_func_addr = Ciet2Template.getCiet2_func_addr(inputStream, dlcbiewbcie); + functions = new DllFunction[(int)ciet2_func_count]; + for (int i = 0; i < ciet2_func_count; i++) { + try { + long base = ciet2_func_addr + (i * Ciet2ExpFuncEntryTemplate.length()); + long ciet2_exp_func_is_addr = Ciet2ExpFuncEntryTemplate.getCiet2_exp_func_is_addr(inputStream, base); + long ciet2_exp_func_offset = Ciet2ExpFuncEntryTemplate.getCiet2_exp_func_offset(inputStream, base); + long ciet2_exp_func_name_addr = Ciet2ExpFuncEntryTemplate.getCiet2_exp_func_name_addr(inputStream, base); + String funcName = space.readEbcdicString(ciet2_exp_func_name_addr); + long funcAddr = ciet2_exp_func_is_addr == 0 ? ciet2_exp_func_offset + getWsa() : ciet2_exp_func_offset; + long ciet2_exp_ada_is_addr = Ciet2ExpFuncEntryTemplate.getCiet2_exp_ada_is_addr(inputStream, base); + long ciet2_exp_func_ada_offset = Ciet2ExpFuncEntryTemplate.getCiet2_exp_func_ada_offset(inputStream, base); + long funcAda = ciet2_exp_ada_is_addr == 0 ? ciet2_exp_func_ada_offset + getWsa() : ciet2_exp_func_ada_offset; + functions[i] = new DllFunction(funcName, funcAddr, null, funcAda); + } catch (IOException e) { + functions[i] = new DllFunction(e.toString(), 0, null, space.WILD_POINTER); + } + } + } else if (ciet2_version == 1) { + long ciet_func_count = CietTemplate.getCiet_func_count(inputStream, dlcbiewbcie); + long ciet_func_addr = CietTemplate.getCiet_func_addr(inputStream, dlcbiewbcie); + ciet_func_addr = space.readInt(ciet_func_addr); + functions = new DllFunction[(int)ciet_func_count]; + log.finer("count = " + ciet_func_count); + for (int i = 0; i < ciet_func_count; i++) { + long base = ciet_func_addr + (i * CietExpEntryTemplate.length()); + log.finer("base = " + hex(base)); + long ciet_is_addr = CietExpEntryTemplate.getCiet_is_addr(inputStream, base); + long ciet_is_function = CietExpEntryTemplate.getCiet_is_function(inputStream, base); + log.finer("ciet_is_function = " + hex(ciet_is_function)); + long ciet_exp_offset = CietExpEntryTemplate.getCiet_exp_offset(inputStream, base); + log.finer("ciet_exp_offset = " + hex(ciet_exp_offset)); + long ciet_exp_name_addr = CietExpEntryTemplate.getCiet_exp_name_addr(inputStream, base); + log.finer("ciet_exp_name_addr = " + hex(ciet_exp_name_addr) + " length = " + space.readUnsignedShort(ciet_exp_name_addr)); + String funcName = space.readEbcdicString(ciet_exp_name_addr); + log.finer("funcName = " + funcName); + long funcAddr = ciet_is_addr == 0 ? ciet_exp_offset + getWsa() : ciet_exp_offset; + log.finer("funcAddr = " + hex(funcAddr)); + log.finer("ciet_is_addr = " + hex(ciet_is_addr)); + functions[i] = new DllFunction(funcName, funcAddr, null, space.WILD_POINTER); + } + } else + throw new Error("expected ciet2_version 1 or 2 but instead found " + ciet2_version); + } else if (space.readEbcdicString(dlcbiewbcie, 8).equals("@@DL370$")) { + long dlloffexpfunc = DllcsectTemplate.getDlloffexpfunc(inputStream, dlcbiewbcie); + long dllexpfuncs = dlcbiewbcie + dlloffexpfunc; + long dllexpfuncscount = DllexpfuncsTemplate.getDllexpfuncscount(inputStream, dllexpfuncs); + if (dllexpfuncscount < 0 || dllexpfuncscount > 1000000) { + log.config("impossible dllexpfuncscount: " + dllexpfuncscount); + functions = new DllFunction[0]; + return functions; + } + functions = new DllFunction[(int)dllexpfuncscount]; + for (int i = 0; i < dllexpfuncscount; i++) { + long dllexpfuncsname = DllexpfuncsTemplate.getDllexpfuncsname(inputStream, dllexpfuncs); + long dllexpfuncsaddr = DllexpfuncsTemplate.getDllexpfuncsaddr(inputStream, dllexpfuncs); + String funcName = space.readEbcdicString(dlcbiewbcie + dllexpfuncsname); + functions[i] = new DllFunction(funcName, dllexpfuncsaddr, null, getWsa()); + // XXX this is naughty - we should handle arrays properly + dllexpfuncs += DllexpfuncsTemplate.getDllexpfuncsarray$length() / 8; + } + } else { + throw new Error("tbc"); + } + return functions; + } - /** - * From the given AddressSpace returns the named {@link com.ibm.dtfj.corereaders.zos.le.DllFunction} - * (or null if it can't be found). This caches previously found functions for speed. - * Note that this searches all the Dlls and returns the first match it finds so take care - * if multiple Dlls declare the same name! - * @param space the AddressSpace to search - * @param name the name of the required function - */ - public static DllFunction getFunction(AddressSpace space, String name) throws IOException { - DllFunction function = (DllFunction)space.getUserMap().get(name); - if (function != null) - return function; - Edb edb = Edb.getSampleEdb(space); - if (edb == null) - return null; - for (Dll dll = edb.getFirstDll(); dll != null; dll = dll.getNext()) { - function = dll.getFunction(name); - if (function != null) { - space.getUserMap().put(name, function); - return function; - } - } - return null; - } + /** + * From the given AddressSpace returns the named {@link com.ibm.dtfj.corereaders.zos.le.DllFunction} + * (or null if it can't be found). This caches previously found functions for speed. + * Note that this searches all the Dlls and returns the first match it finds so take care + * if multiple Dlls declare the same name! + * @param space the AddressSpace to search + * @param name the name of the required function + */ + public static DllFunction getFunction(AddressSpace space, String name) throws IOException { + DllFunction function = (DllFunction)space.getUserMap().get(name); + if (function != null) + return function; + Edb edb = Edb.getSampleEdb(space); + if (edb == null) + return null; + for (Dll dll = edb.getFirstDll(); dll != null; dll = dll.getNext()) { + function = dll.getFunction(name); + if (function != null) { + space.getUserMap().put(name, function); + return function; + } + } + return null; + } - /** - * Add the given {@link com.ibm.dtfj.corereaders.zos.le.DllFunction} to the set of functions for this - * AddressSpace. This can be used to add fake entries, eg see {@link com.ibm.dtfj.corereaders.zos.le.FunctionEmulator#recordCalledFunctions} - */ - public static void addFunction(AddressSpace space, String name, DllFunction function) { - space.getUserMap().put(name, function); - } + /** + * Add the given {@link com.ibm.dtfj.corereaders.zos.le.DllFunction} to the set of functions for this + * AddressSpace. This can be used to add fake entries, eg see {@link com.ibm.dtfj.corereaders.zos.le.FunctionEmulator#recordCalledFunctions} + */ + public static void addFunction(AddressSpace space, String name, DllFunction function) { + space.getUserMap().put(name, function); + } - private static String hex(long i) { - return Long.toHexString(i); - } + private static String hex(long i) { + return Long.toHexString(i); + } - private static String hex(int i) { - return Integer.toHexString(i); - } + private static String hex(int i) { + return Integer.toHexString(i); + } - public String toString() { - try { - return getName(); - } catch (IOException e) { - return "oops: " + e; - } - } + public String toString() { + try { + return getName(); + } catch (IOException e) { + return "oops: " + e; + } + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllFunction.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllFunction.java index 121f8aa9ce2..cf7f419e1e4 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllFunction.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllFunction.java @@ -27,26 +27,26 @@ */ public class DllFunction { - /** The name of the function */ - public String name; - /** The address of the function */ - public long address; - /** XXX */ - public String module; - /** Pointer to the WSA environment for this function (as typically passed in R5) */ - public long env; + /** The name of the function */ + public String name; + /** The address of the function */ + public long address; + /** XXX */ + public String module; + /** Pointer to the WSA environment for this function (as typically passed in R5) */ + public long env; - /** - * Create a new DllFunction. - * @param name the name of the function - * @param address the address of the function - * @param module XXX tbc - * @param env pointer to the WSA environment for this function - */ - public DllFunction(String name, long address, String module, long env) { - this.name = name; - this.address = address; - this.module = module; - this.env = env; - } + /** + * Create a new DllFunction. + * @param name the name of the function + * @param address the address of the function + * @param module XXX tbc + * @param env pointer to the WSA environment for this function + */ + public DllFunction(String name, long address, String module, long env) { + this.name = name; + this.address = address; + this.module = module; + this.env = env; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllVariable.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllVariable.java index 30cdd53d527..0bdeaa1bc40 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllVariable.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllVariable.java @@ -27,22 +27,22 @@ */ public class DllVariable { - /** The name of the variable */ - public String name; - /** The address of the variable */ - public long address; - /** The value of the variable */ - public long value; + /** The name of the variable */ + public String name; + /** The address of the variable */ + public long address; + /** The value of the variable */ + public long value; - /** - * Create a new DllVariable. - * @param name the name of the variable - * @param address the address of the variable - * @param value the value of the variable - */ - public DllVariable(String name, long address, long value) { - this.name = name; - this.address = address; - this.value = value; - } + /** + * Create a new DllVariable. + * @param name the name of the variable + * @param address the address of the variable + * @param value the value of the variable + */ + public DllVariable(String name, long address, long value) { + this.name = name; + this.address = address; + this.value = value; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllcsectTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllcsectTemplate.java index 32893837a3e..f3618885cb3 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllcsectTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllcsectTemplate.java @@ -29,28 +29,33 @@ public final class DllcsectTemplate { - public static int length() { - return 24; - } - - public static long getDlloffexpfunc(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - return inputStream.readInt(); - } - public static int getDlloffexpfunc$offset() { - return 16; - } - public static int getDlloffexpfunc$length() { - return 32; - } - public static long getDlloffexpvar(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 20); - return inputStream.readInt(); - } - public static int getDlloffexpvar$offset() { - return 20; - } - public static int getDlloffexpvar$length() { - return 32; - } + public static int length() { + return 24; + } + + public static long getDlloffexpfunc(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + return inputStream.readInt(); + } + + public static int getDlloffexpfunc$offset() { + return 16; + } + + public static int getDlloffexpfunc$length() { + return 32; + } + + public static long getDlloffexpvar(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 20); + return inputStream.readInt(); + } + + public static int getDlloffexpvar$offset() { + return 20; + } + + public static int getDlloffexpvar$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllexpfuncsTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllexpfuncsTemplate.java index a35ed586b80..5aa85ed15eb 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllexpfuncsTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllexpfuncsTemplate.java @@ -29,48 +29,59 @@ public final class DllexpfuncsTemplate { - public static int length() { - return 12; - } - - public static long getDllexpfuncscount(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readInt(); - } - public static int getDllexpfuncscount$offset() { - return 0; - } - public static int getDllexpfuncscount$length() { - return 32; - } - public static long getDllexpfuncsarray(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readLong(); - } - public static int getDllexpfuncsarray$offset() { - return 4; - } - public static int getDllexpfuncsarray$length() { - return 64; - } - public static long getDllexpfuncsname(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readInt(); - } - public static int getDllexpfuncsname$offset() { - return 4; - } - public static int getDllexpfuncsname$length() { - return 32; - } - public static long getDllexpfuncsaddr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getDllexpfuncsaddr$offset() { - return 8; - } - public static int getDllexpfuncsaddr$length() { - return 32; - } + public static int length() { + return 12; + } + + public static long getDllexpfuncscount(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readInt(); + } + + public static int getDllexpfuncscount$offset() { + return 0; + } + + public static int getDllexpfuncscount$length() { + return 32; + } + + public static long getDllexpfuncsarray(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readLong(); + } + + public static int getDllexpfuncsarray$offset() { + return 4; + } + + public static int getDllexpfuncsarray$length() { + return 64; + } + + public static long getDllexpfuncsname(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readInt(); + } + + public static int getDllexpfuncsname$offset() { + return 4; + } + + public static int getDllexpfuncsname$length() { + return 32; + } + + public static long getDllexpfuncsaddr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getDllexpfuncsaddr$offset() { + return 8; + } + + public static int getDllexpfuncsaddr$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllexpvarsTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllexpvarsTemplate.java index 1455b5aa7e2..a2417383325 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllexpvarsTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DllexpvarsTemplate.java @@ -29,48 +29,59 @@ public final class DllexpvarsTemplate { - public static int length() { - return 12; - } - - public static long getDllexpvarscount(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readInt(); - } - public static int getDllexpvarscount$offset() { - return 0; - } - public static int getDllexpvarscount$length() { - return 32; - } - public static long getDllexpvarsarray(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readLong(); - } - public static int getDllexpvarsarray$offset() { - return 4; - } - public static int getDllexpvarsarray$length() { - return 64; - } - public static long getDllexpvarsname(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readInt(); - } - public static int getDllexpvarsname$offset() { - return 4; - } - public static int getDllexpvarsname$length() { - return 32; - } - public static long getDllexpvarsqcon(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readInt(); - } - public static int getDllexpvarsqcon$offset() { - return 8; - } - public static int getDllexpvarsqcon$length() { - return 32; - } + public static int length() { + return 12; + } + + public static long getDllexpvarscount(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readInt(); + } + + public static int getDllexpvarscount$offset() { + return 0; + } + + public static int getDllexpvarscount$length() { + return 32; + } + + public static long getDllexpvarsarray(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readLong(); + } + + public static int getDllexpvarsarray$offset() { + return 4; + } + + public static int getDllexpvarsarray$length() { + return 64; + } + + public static long getDllexpvarsname(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readInt(); + } + + public static int getDllexpvarsname$offset() { + return 4; + } + + public static int getDllexpvarsname$length() { + return 32; + } + + public static long getDllexpvarsqcon(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readInt(); + } + + public static int getDllexpvarsqcon$offset() { + return 8; + } + + public static int getDllexpvarsqcon$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DsaStackFrame.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DsaStackFrame.java index 86528809d54..41f96f4cead 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DsaStackFrame.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/DsaStackFrame.java @@ -40,988 +40,988 @@ */ public class DsaStackFrame { - /** The address of this dsa */ - private long address; - /** Is this a down stack frame? */ - private boolean isDownStack; - /** Is the parent frame a down stack frame? (This is set before creating the parent frame) */ - private boolean isParentDownStack; - /** Is the parent frame a transition frame? */ - private boolean isParentTransitionFrame; - /** The address of the parent dsa */ - private long parentAddress; - /** The address at which the caller called us */ - private long parentCallingAddress; - /** The child dsa (if any) */ - private DsaStackFrame childDsa; - /** The registers. This will only be non-null for the frame at the top of the stack. */ - private RegisterSet registers; - /** The address of the function's entry point */ - private long entryPoint; - /** The offset from the entry point where we called the next function */ - private long entryOffset; - /** The name of the function */ - private String entryName; - /** The AddressSpace we belong to */ - private AddressSpace space; - /** The AddressSpaceImageInputStream */ - private AddressSpaceImageInputStream inputStream; - /** The Caa we are associated with */ - private Caa caa; - /** Dsa template - size depends on 32/64 bit mode */ - /*static*/ CeedsahpTemplate ceedsahpTemplate; - /** Hcom template - size depends on 32/64 bit mode */ - /*static*/ CeexhcomTemplate ceexhcomTemplate; - /** RCB template - size depends on 32/64 bit mode */ - /*static*/ CeexrcbTemplate ceexrcbTemplate; - /** Constant for Detecting a Transition on the Up Stack */ - static final long Ceedsahp_UpTran_Ind = 0xffffffffL; - /** Transition is stack swap */ - private static final long Ceedsahp_UpToDown = 2; - /** Transition is stack swap */ - private static final long Ceedsahp_DownToUp = 3; - /** BASR call */ - private static final long Hpcl_Basr_Call = 0; - /** BRAS call */ - private static final long Hpcl_Bras_Call = 1; - /** BRASL call */ - private static final long Hpcl_Brasl_Call = 3; - /** Up DSA Format */ - private static final int US_FORMAT = 0; - /** Down DSA Format */ - private static final int DS_FORMAT = 1; - /** Unknown DSA Format */ - private static final int UK_FORMAT = -1; - /** "CEE" */ - private static final int CEEEYECAT = 0xC3C5C5; - /** branch and set mode inst in CEL glue code */ - private static final short BASSM1415 = 0x0CEF; - /** load r14 inst in CEL glue code */ - private static final int L14DSAMODE = 0x58E0D06C; - /** Logger */ - private static Logger log = Logger.getLogger(DsaStackFrame.class.getName()); + /** The address of this dsa */ + private long address; + /** Is this a down stack frame? */ + private boolean isDownStack; + /** Is the parent frame a down stack frame? (This is set before creating the parent frame) */ + private boolean isParentDownStack; + /** Is the parent frame a transition frame? */ + private boolean isParentTransitionFrame; + /** The address of the parent dsa */ + private long parentAddress; + /** The address at which the caller called us */ + private long parentCallingAddress; + /** The child dsa (if any) */ + private DsaStackFrame childDsa; + /** The registers. This will only be non-null for the frame at the top of the stack. */ + private RegisterSet registers; + /** The address of the function's entry point */ + private long entryPoint; + /** The offset from the entry point where we called the next function */ + private long entryOffset; + /** The name of the function */ + private String entryName; + /** The AddressSpace we belong to */ + private AddressSpace space; + /** The AddressSpaceImageInputStream */ + private AddressSpaceImageInputStream inputStream; + /** The Caa we are associated with */ + private Caa caa; + /** Dsa template - size depends on 32/64 bit mode */ + /*static*/ CeedsahpTemplate ceedsahpTemplate; + /** Hcom template - size depends on 32/64 bit mode */ + /*static*/ CeexhcomTemplate ceexhcomTemplate; + /** RCB template - size depends on 32/64 bit mode */ + /*static*/ CeexrcbTemplate ceexrcbTemplate; + /** Constant for Detecting a Transition on the Up Stack */ + static final long Ceedsahp_UpTran_Ind = 0xffffffffL; + /** Transition is stack swap */ + private static final long Ceedsahp_UpToDown = 2; + /** Transition is stack swap */ + private static final long Ceedsahp_DownToUp = 3; + /** BASR call */ + private static final long Hpcl_Basr_Call = 0; + /** BRAS call */ + private static final long Hpcl_Bras_Call = 1; + /** BRASL call */ + private static final long Hpcl_Brasl_Call = 3; + /** Up DSA Format */ + private static final int US_FORMAT = 0; + /** Down DSA Format */ + private static final int DS_FORMAT = 1; + /** Unknown DSA Format */ + private static final int UK_FORMAT = -1; + /** "CEE" */ + private static final int CEEEYECAT = 0xC3C5C5; + /** branch and set mode inst in CEL glue code */ + private static final short BASSM1415 = 0x0CEF; + /** load r14 inst in CEL glue code */ + private static final int L14DSAMODE = 0x58E0D06C; + /** Logger */ + private static Logger log = Logger.getLogger(DsaStackFrame.class.getName()); - /** - * Create a new DsaStackFrame from the given dsa address and with the given stack direction. - */ - public DsaStackFrame(long address, boolean isDownStack, RegisterSet registers, AddressSpace space, Caa caa) throws IOException { - this.address = address; - this.isDownStack = isDownStack; - this.registers = registers; - this.space = space; - inputStream = space.getImageInputStream(); - this.caa = caa; - /* Create any templates we need if not already created */ - createTemplates(space); - /* Call the ceextbck method to calculate entry point, previous dsa etc */ - ceextbck(address, isDownStack, caa); - } + /** + * Create a new DsaStackFrame from the given dsa address and with the given stack direction. + */ + public DsaStackFrame(long address, boolean isDownStack, RegisterSet registers, AddressSpace space, Caa caa) throws IOException { + this.address = address; + this.isDownStack = isDownStack; + this.registers = registers; + this.space = space; + inputStream = space.getImageInputStream(); + this.caa = caa; + /* Create any templates we need if not already created */ + createTemplates(space); + /* Call the ceextbck method to calculate entry point, previous dsa etc */ + ceextbck(address, isDownStack, caa); + } - /** - * Create any templates we need if not already created. - * XXX Presumably we will never have mixed 32-bit and 64-bit address spaces? - */ - /*static*/ void createTemplates(AddressSpace space) { - if (ceedsahpTemplate == null) { - if (space.is64bit()) { - ceedsahpTemplate = new Ceedsahp64Template(); - ceexhcomTemplate = new Ceexhcom64Template(); - ceexrcbTemplate = new Ceexrcb64Template(); - } else { - ceedsahpTemplate = new Ceedsahp32Template(); - ceexhcomTemplate = new Ceexhcom32Template(); - ceexrcbTemplate = new Ceexrcb32Template(); - } - } - } + /** + * Create any templates we need if not already created. + * XXX Presumably we will never have mixed 32-bit and 64-bit address spaces? + */ + /*static*/ void createTemplates(AddressSpace space) { + if (ceedsahpTemplate == null) { + if (space.is64bit()) { + ceedsahpTemplate = new Ceedsahp64Template(); + ceexhcomTemplate = new Ceexhcom64Template(); + ceexrcbTemplate = new Ceexrcb64Template(); + } else { + ceedsahpTemplate = new Ceedsahp32Template(); + ceexhcomTemplate = new Ceexhcom32Template(); + ceexrcbTemplate = new Ceexrcb32Template(); + } + } + } - /** - * Returns the AddressSpace we belong to. - */ - public AddressSpace getAddressSpace() { - return space; - } + /** + * Returns the AddressSpace we belong to. + */ + public AddressSpace getAddressSpace() { + return space; + } - /** - * Returns the address of the DSA for this stack frame. - */ - public long getDsaAddress() { - return address; - } + /** + * Returns the address of the DSA for this stack frame. + */ + public long getDsaAddress() { + return address; + } - /** - * Returns the current register set (or null if there are no saved registers). - */ - public RegisterSet getRegisterSet() { - return registers; - } + /** + * Returns the current register set (or null if there are no saved registers). + */ + public RegisterSet getRegisterSet() { + return registers; + } - /** - * Returns a guess as to the given argument number. Note that there is no guarantee that - * the returned value is legitimate. The argument number might be greater than the number - * of arguments that the function takes for instance. In which case whatever happens to be - * on the stack will be returned regardless. The function might not obey the convention - * of storing its arguments on the stack*/ - /* - public int getArg(int argNumber) throws Exception { - if (downstack) { - return space.readInt(previous().address + 0x840 + (argNumber << 2)); - } else { - int r1 = previous().registers[1]; - return space.readInt(r1 + (argNumber << 2)); - } - } - */ + /** + * Returns a guess as to the given argument number. Note that there is no guarantee that + * the returned value is legitimate. The argument number might be greater than the number + * of arguments that the function takes for instance. In which case whatever happens to be + * on the stack will be returned regardless. The function might not obey the convention + * of storing its arguments on the stack*/ + /* + public int getArg(int argNumber) throws Exception { + if (downstack) { + return space.readInt(previous().address + 0x840 + (argNumber << 2)); + } else { + int r1 = previous().registers[1]; + return space.readInt(r1 + (argNumber << 2)); + } + } + */ - /** - * Returns the offset from the function entry point. This is the offset within the - * function's executable code where the call was made to the successor stack frame. - */ - public long getEntryOffset() { - if (registers != null) { - /* We have a failing register set so use the PSW from there */ - // XXX 64-bit dependency - return space.stripTopBit(registers.getPSW() & 0x7fffffffL) - getEntryPoint(); - //return (registers.getPSW() & 0xffffffffL) - getEntryPoint(); - } - if (childDsa != null) - return childDsa.parentCallingAddress - entryPoint; - return entryOffset; - } + /** + * Returns the offset from the function entry point. This is the offset within the + * function's executable code where the call was made to the successor stack frame. + */ + public long getEntryOffset() { + if (registers != null) { + /* We have a failing register set so use the PSW from there */ + // XXX 64-bit dependency + return space.stripTopBit(registers.getPSW() & 0x7fffffffL) - getEntryPoint(); + //return (registers.getPSW() & 0xffffffffL) - getEntryPoint(); + } + if (childDsa != null) + return childDsa.parentCallingAddress - entryPoint; + return entryOffset; + } - /** - * Returns the entry point address for the function belonging to this dsa. - */ - public long getEntryPoint() { - return entryPoint; - } + /** + * Returns the entry point address for the function belonging to this dsa. + */ + public long getEntryPoint() { + return entryPoint; + } - /** Returns the name of the function */ - public String getEntryName() { - return entryName; - } + /** Returns the name of the function */ + public String getEntryName() { + return entryName; + } - /** - * Returns the caller of this stack frame. - * @return the stack frame for the function that called this one or null if we have - * reached the bottom of the stack - */ - public DsaStackFrame getParentFrame() { - if (parentAddress == 0 || parentAddress == caa.ceecaaddsa()) - /* bottom of stack reached */ - return null; - try { - DsaStackFrame parent = new DsaStackFrame(parentAddress, isParentDownStack, null, space, caa); - parent.childDsa = this; - return parent; - } catch (IOException e) { - return null; - } - } + /** + * Returns the caller of this stack frame. + * @return the stack frame for the function that called this one or null if we have + * reached the bottom of the stack + */ + public DsaStackFrame getParentFrame() { + if (parentAddress == 0 || parentAddress == caa.ceecaaddsa()) + /* bottom of stack reached */ + return null; + try { + DsaStackFrame parent = new DsaStackFrame(parentAddress, isParentDownStack, null, space, caa); + parent.childDsa = this; + return parent; + } catch (IOException e) { + return null; + } + } - /** - * Returns the function call that this stack frame represents. - */ - public Function getFunction() { - // XXX need to share functions between different DSAs - return new Function(this); - } + /** + * Returns the function call that this stack frame represents. + */ + public Function getFunction() { + // XXX need to share functions between different DSAs + return new Function(this); + } - /** - * This method emulates the Ceektbck traceback macro. Most of the comments are from there - * including the following description: - * This module performs the processing of the CEETRCB low level - * service. This service determines the entry address, entry - * point name, compile unit address, compile unit name, calling - * instruction address, calling statement number, CIB address, - * and callers DSA address, given the DSA address for a routine. - */ - void ceextbck(long dsaptr, boolean isDownStack, Caa caa) throws IOException { - log.fine("ceextbck, dsaptr = " + hex(dsaptr) + " downstack = " + isDownStack); - /* stack direction of DSA */ - int dsa_format = isDownStack ? DS_FORMAT : US_FORMAT; - /* entry point */ - long entry_address = space.WILD_POINTER; + /** + * This method emulates the Ceektbck traceback macro. Most of the comments are from there + * including the following description: + * This module performs the processing of the CEETRCB low level + * service. This service determines the entry address, entry + * point name, compile unit address, compile unit name, calling + * instruction address, calling statement number, CIB address, + * and callers DSA address, given the DSA address for a routine. + */ + void ceextbck(long dsaptr, boolean isDownStack, Caa caa) throws IOException { + log.fine("ceextbck, dsaptr = " + hex(dsaptr) + " downstack = " + isDownStack); + /* stack direction of DSA */ + int dsa_format = isDownStack ? DS_FORMAT : US_FORMAT; + /* entry point */ + long entry_address = space.WILD_POINTER; - int dsaformat8 = dsa_format; // Not sure why they use a byte version sometimes - if (dsa_format == UK_FORMAT) { - throw new Error("tbc"); - } - int callers_dsa_format = dsaformat8; - boolean transition = verifyFormat(dsaptr, dsa_format); - if (dsaptr < 0) { - throw new Error("tbc"); - } - Ceexdsaf dsaf = new Ceexdsaf(space, dsaptr, dsa_format); - callers_dsa_format = dsaf.DSA_Format; - long callers_dsaptr = dsaf.DSA_Prev; - /* Set instance variables containing info about parent DSA */ - parentAddress = callers_dsaptr; - isParentDownStack = callers_dsa_format == DS_FORMAT; - /* Determine the CIB corresponding to this DSA, if any, and the caller's DSA */ - long cibptr = findCib(dsaptr); - long callers_cibptr = findCib(callers_dsaptr); - /* Determine the SFXM (Stack Frame Exit control block) corresponding to the DSA, - * if any, and the Caller's DSA */ - long sfxmptr = findSfxm(dsaptr, dsaformat8); - long callers_sfxmptr = findSfxm(callers_dsaptr, callers_dsa_format); + int dsaformat8 = dsa_format; // Not sure why they use a byte version sometimes + if (dsa_format == UK_FORMAT) { + throw new Error("tbc"); + } + int callers_dsa_format = dsaformat8; + boolean transition = verifyFormat(dsaptr, dsa_format); + if (dsaptr < 0) { + throw new Error("tbc"); + } + Ceexdsaf dsaf = new Ceexdsaf(space, dsaptr, dsa_format); + callers_dsa_format = dsaf.DSA_Format; + long callers_dsaptr = dsaf.DSA_Prev; + /* Set instance variables containing info about parent DSA */ + parentAddress = callers_dsaptr; + isParentDownStack = callers_dsa_format == DS_FORMAT; + /* Determine the CIB corresponding to this DSA, if any, and the caller's DSA */ + long cibptr = findCib(dsaptr); + long callers_cibptr = findCib(callers_dsaptr); + /* Determine the SFXM (Stack Frame Exit control block) corresponding to the DSA, + * if any, and the Caller's DSA */ + long sfxmptr = findSfxm(dsaptr, dsaformat8); + long callers_sfxmptr = findSfxm(callers_dsaptr, callers_dsa_format); - if (dsaformat8 == DS_FORMAT) { - processDsfmt(dsaptr, dsaformat8, callers_dsaptr, callers_dsa_format, transition, cibptr, callers_cibptr, sfxmptr); - } else { - if (!transition) { - int hdsp_signature = space.readInt(dsaptr + 72); // dsaptr->hdspdsasig - if ((hdsp_signature & 0xfffffff0) == 0x0808cee0) { // dispatcher eyecatch - /* CEEHDSP with XPLINK support uses CODENUM() for subroutines. - * This means R11 may not be the entry for the call to this routine. - * Get entry from a local VCON. */ - //entry_address = addr(CEEHDSP); - // XXX how do we get the address of CEEHDSP? - throw new Error("tbc"); - } else { - entry_address = CeedsaTemplate.getCeedsar15(inputStream, callers_dsaptr); - log.fine("upstack entry address = " + hex(entry_address)); - } - } else { - /* It is an UP-Transition */ - long ceedsatran = CeedsaTemplate.getCeedsatran(inputStream, dsaptr); - entry_address = Ceedsahp_transitionTemplate.getCeedsahp_tran_ep(inputStream, ceedsatran); - log.fine("upstack transition entry address = " + hex(entry_address)); - } - /* Test if this entry address is really valid by trying to access it */ - try { - space.readLong(entry_address); - } catch (IOException e) { - entry_address = 0; - } - boolean cel_enabled; - long signaturePtr = entry_address; - /* Determine if the routine is CEL Enabled by looking at - * the signature byte in the PPA1 */ - if (entry_address == 0) { - cel_enabled = false; - } else { - /* Have an Entry Point Address. Obtain the entry point vector. - * If the name offset ='00X or '01'X and the eyecatcher is - * 'CEE' then the entry point vector is valid */ - int signature = 0; // default is invalid - try { - signature = (int)CeexoepvTemplate.getOepv_eyecatch(inputStream, signaturePtr); - } catch (IOException e) {} - log.fine("signature = " + hex(signature)); - int msb = signature >>> 24; - if (((msb == 0) || (msb == 1)) && ((signature & 0xffffff) == CEEEYECAT)) { - /* get the ppa1 signature */ - try { - signature = getPpa1Sig(signaturePtr); - } catch (IOException e) { - signature = 0; - } - if ((signature & 0xff) == 0xce) { // PPA1EYE - cel_enabled = true; - } else { - cel_enabled = false; - } - } else { - /* - * Check whether this module is a wrapped - * transfer vector. - * If the module entry-point + 0 = X'47F0Fxxx' - * (a 'BR xxx(15)' instruction) - * Calculate the address of the signature: - * Module entry-point - * Plus 'xxx' from the BR instruction - * Minus X'14' (signature size) - * If signature address + 0 = 0 - * (i.e., no BR instruction) & - * signature address + 5 = X'C3C5C5' - * Get PPA1 address - * If PPA1 eyecatcher = X'CE' - * Valid wrapped transfer vector - */ - cel_enabled = false; - try { - signature = (int)CeexoepvTemplate.getOepv_oldep(inputStream, signaturePtr); - log.fine("oldep signature = " + hex(signature)); - int bcrinstr = signature >>> 12; - if (bcrinstr == 0x47f0f) { - int bcrdispl = signature & 0xfff; - int oepvLength = CeexoepvTemplate.length(); - assert oepvLength == 0x14 : oepvLength; - signaturePtr = signaturePtr + bcrdispl - oepvLength; - /* adjusted address. now re-read */ - signature = (int)CeexoepvTemplate.getOepv_oldep(inputStream, signaturePtr); - if (signature == 0) { - signature = (int)CeexoepvTemplate.getOepv_eyecatch(inputStream, signaturePtr); - if ((signature & 0xffffff) == CEEEYECAT) { - signature = getPpa1Sig(signaturePtr); - if ((signature & 0xff) == 0xce) { // PPA1EYE - cel_enabled = true; - log.fine("found a good ppa1 eyecatcher"); - } else { - throw new Error("tbc"); - } - } else { - throw new Error("tbc"); - } - } else { - signaturePtr = entry_address; - } - } else { - signaturePtr = entry_address; - } - } catch (IOException e) { - e.printStackTrace(); - throw new Error("tbc"); - } - } - } - boolean v2ppa = false; - if (cel_enabled) { - int oepv_cnameoffs = (int)CeexoepvTemplate.getOepv_cnameoffs(inputStream, signaturePtr); - if (oepv_cnameoffs == 1) - v2ppa = true; - } - /* determine callers calling address */ - long callers_instruction_address = getCallingAddr(callers_dsaptr, callers_dsa_format, dsaptr, dsaformat8, transition, callers_cibptr, callers_sfxmptr); - parentCallingAddress = callers_instruction_address; - /* - * If the routine is CEL enabled, determine the calling - * address if none was supplied, the callers instruction - * address, entry point name, member id, compile unit - * unit address, and compile unit name, from standard - * fields in the callers DSA and this routines PPAs. - */ - if (cel_enabled) { - /* If p_call_instruction_address is zero, try to determine - * the calling address. (I assume that p_call_instruction_address == 0 - * means the entry at the top of the stack which will be the only one - * with registers) */ - if (registers != null) { - long call_instruction_address = getCallingAddr(dsaptr, dsaformat8, 0, 0, false, cibptr, sfxmptr); - log.fine("found call_instruction_address at top of stack: 0x" + hex(call_instruction_address)); - } - int offset_to_name = getPpa1Nmo(signaturePtr); - if (offset_to_name == 0) { - throw new Error("tbc"); - } else { - /* offset or offset*2 to entry name obtained */ - long ppa1_epn_address; - // XXX should have ppa1 squirreled away somewhere - int ppa1offset = (int)CeexoepvTemplate.getOepv_ppa1offset(inputStream, signaturePtr); - long ppa1 = signaturePtr + ppa1offset; - if (v2ppa) { - ppa1_epn_address = ppa1 + offset_to_name*2; - } else { - ppa1_epn_address = ppa1 + offset_to_name; - } - entryName = space.readEbcdicString(ppa1_epn_address); - log.fine("read entry name: " + entryName); - } - } else { - entryName = "(unknown)"; - } - entryPoint = space.stripTopBit(entry_address); - } - } + if (dsaformat8 == DS_FORMAT) { + processDsfmt(dsaptr, dsaformat8, callers_dsaptr, callers_dsa_format, transition, cibptr, callers_cibptr, sfxmptr); + } else { + if (!transition) { + int hdsp_signature = space.readInt(dsaptr + 72); // dsaptr->hdspdsasig + if ((hdsp_signature & 0xfffffff0) == 0x0808cee0) { // dispatcher eyecatch + /* CEEHDSP with XPLINK support uses CODENUM() for subroutines. + * This means R11 may not be the entry for the call to this routine. + * Get entry from a local VCON. */ + //entry_address = addr(CEEHDSP); + // XXX how do we get the address of CEEHDSP? + throw new Error("tbc"); + } else { + entry_address = CeedsaTemplate.getCeedsar15(inputStream, callers_dsaptr); + log.fine("upstack entry address = " + hex(entry_address)); + } + } else { + /* It is an UP-Transition */ + long ceedsatran = CeedsaTemplate.getCeedsatran(inputStream, dsaptr); + entry_address = Ceedsahp_transitionTemplate.getCeedsahp_tran_ep(inputStream, ceedsatran); + log.fine("upstack transition entry address = " + hex(entry_address)); + } + /* Test if this entry address is really valid by trying to access it */ + try { + space.readLong(entry_address); + } catch (IOException e) { + entry_address = 0; + } + boolean cel_enabled; + long signaturePtr = entry_address; + /* Determine if the routine is CEL Enabled by looking at + * the signature byte in the PPA1 */ + if (entry_address == 0) { + cel_enabled = false; + } else { + /* Have an Entry Point Address. Obtain the entry point vector. + * If the name offset ='00X or '01'X and the eyecatcher is + * 'CEE' then the entry point vector is valid */ + int signature = 0; // default is invalid + try { + signature = (int)CeexoepvTemplate.getOepv_eyecatch(inputStream, signaturePtr); + } catch (IOException e) {} + log.fine("signature = " + hex(signature)); + int msb = signature >>> 24; + if (((msb == 0) || (msb == 1)) && ((signature & 0xffffff) == CEEEYECAT)) { + /* get the ppa1 signature */ + try { + signature = getPpa1Sig(signaturePtr); + } catch (IOException e) { + signature = 0; + } + if ((signature & 0xff) == 0xce) { // PPA1EYE + cel_enabled = true; + } else { + cel_enabled = false; + } + } else { + /* + * Check whether this module is a wrapped + * transfer vector. + * If the module entry-point + 0 = X'47F0Fxxx' + * (a 'BR xxx(15)' instruction) + * Calculate the address of the signature: + * Module entry-point + * Plus 'xxx' from the BR instruction + * Minus X'14' (signature size) + * If signature address + 0 = 0 + * (i.e., no BR instruction) & + * signature address + 5 = X'C3C5C5' + * Get PPA1 address + * If PPA1 eyecatcher = X'CE' + * Valid wrapped transfer vector + */ + cel_enabled = false; + try { + signature = (int)CeexoepvTemplate.getOepv_oldep(inputStream, signaturePtr); + log.fine("oldep signature = " + hex(signature)); + int bcrinstr = signature >>> 12; + if (bcrinstr == 0x47f0f) { + int bcrdispl = signature & 0xfff; + int oepvLength = CeexoepvTemplate.length(); + assert oepvLength == 0x14 : oepvLength; + signaturePtr = signaturePtr + bcrdispl - oepvLength; + /* adjusted address. now re-read */ + signature = (int)CeexoepvTemplate.getOepv_oldep(inputStream, signaturePtr); + if (signature == 0) { + signature = (int)CeexoepvTemplate.getOepv_eyecatch(inputStream, signaturePtr); + if ((signature & 0xffffff) == CEEEYECAT) { + signature = getPpa1Sig(signaturePtr); + if ((signature & 0xff) == 0xce) { // PPA1EYE + cel_enabled = true; + log.fine("found a good ppa1 eyecatcher"); + } else { + throw new Error("tbc"); + } + } else { + throw new Error("tbc"); + } + } else { + signaturePtr = entry_address; + } + } else { + signaturePtr = entry_address; + } + } catch (IOException e) { + e.printStackTrace(); + throw new Error("tbc"); + } + } + } + boolean v2ppa = false; + if (cel_enabled) { + int oepv_cnameoffs = (int)CeexoepvTemplate.getOepv_cnameoffs(inputStream, signaturePtr); + if (oepv_cnameoffs == 1) + v2ppa = true; + } + /* determine callers calling address */ + long callers_instruction_address = getCallingAddr(callers_dsaptr, callers_dsa_format, dsaptr, dsaformat8, transition, callers_cibptr, callers_sfxmptr); + parentCallingAddress = callers_instruction_address; + /* + * If the routine is CEL enabled, determine the calling + * address if none was supplied, the callers instruction + * address, entry point name, member id, compile unit + * unit address, and compile unit name, from standard + * fields in the callers DSA and this routines PPAs. + */ + if (cel_enabled) { + /* If p_call_instruction_address is zero, try to determine + * the calling address. (I assume that p_call_instruction_address == 0 + * means the entry at the top of the stack which will be the only one + * with registers) */ + if (registers != null) { + long call_instruction_address = getCallingAddr(dsaptr, dsaformat8, 0, 0, false, cibptr, sfxmptr); + log.fine("found call_instruction_address at top of stack: 0x" + hex(call_instruction_address)); + } + int offset_to_name = getPpa1Nmo(signaturePtr); + if (offset_to_name == 0) { + throw new Error("tbc"); + } else { + /* offset or offset*2 to entry name obtained */ + long ppa1_epn_address; + // XXX should have ppa1 squirreled away somewhere + int ppa1offset = (int)CeexoepvTemplate.getOepv_ppa1offset(inputStream, signaturePtr); + long ppa1 = signaturePtr + ppa1offset; + if (v2ppa) { + ppa1_epn_address = ppa1 + offset_to_name*2; + } else { + ppa1_epn_address = ppa1 + offset_to_name; + } + entryName = space.readEbcdicString(ppa1_epn_address); + log.fine("read entry name: " + entryName); + } + } else { + entryName = "(unknown)"; + } + entryPoint = space.stripTopBit(entry_address); + } + } - /** Extract information for a DSA on the down stack */ - void processDsfmt(long in_dsa, int in_dsafmt, long in_callerdsa, int in_caller_dsafmt, boolean in_dsatrans, long in_cibptr, long in_caller_cibptr, long in_sfxmptr) throws IOException { - /* Obtain Entry Point. PPA1, and PPA2 addresses */ - Ceexepaf epaf = new Ceexepaf(in_dsa, in_dsafmt); - entryPoint = space.stripTopBit(epaf.entry_address); - /* ceexepaf performs verification for down stack. if ppa1 address is not set, - * this is not cel enabled code */ - if (epaf.ppa1_addr != 0) { - /* Find calling address if none supplied, and the callers calling address */ - if (registers != null) { - long call_instruction_address = getCallingAddr(in_dsa, in_dsafmt, 0, 0, false, in_cibptr, 0); - log.fine("found call_instruction_address at top of stack: 0x" + hex(call_instruction_address)); - } - long callers_instruction_address = getCallingAddr(in_callerdsa, in_caller_dsafmt, in_dsa, in_dsafmt, in_dsatrans, in_caller_cibptr, in_sfxmptr); - parentCallingAddress = callers_instruction_address; - assert parentCallingAddress != 0; - Ceexppaf ppaf = new Ceexppaf(epaf.ppa1_addr, "NAM"); - entryName = ppaf.opt_ptr == 0 ? "(unknown)" : space.readEbcdicString(ppaf.opt_ptr); - log.fine("read entry name: " + entryName); - } else { - throw new Error("tbc"); - } - } + /** Extract information for a DSA on the down stack */ + void processDsfmt(long in_dsa, int in_dsafmt, long in_callerdsa, int in_caller_dsafmt, boolean in_dsatrans, long in_cibptr, long in_caller_cibptr, long in_sfxmptr) throws IOException { + /* Obtain Entry Point. PPA1, and PPA2 addresses */ + Ceexepaf epaf = new Ceexepaf(in_dsa, in_dsafmt); + entryPoint = space.stripTopBit(epaf.entry_address); + /* ceexepaf performs verification for down stack. if ppa1 address is not set, + * this is not cel enabled code */ + if (epaf.ppa1_addr != 0) { + /* Find calling address if none supplied, and the callers calling address */ + if (registers != null) { + long call_instruction_address = getCallingAddr(in_dsa, in_dsafmt, 0, 0, false, in_cibptr, 0); + log.fine("found call_instruction_address at top of stack: 0x" + hex(call_instruction_address)); + } + long callers_instruction_address = getCallingAddr(in_callerdsa, in_caller_dsafmt, in_dsa, in_dsafmt, in_dsatrans, in_caller_cibptr, in_sfxmptr); + parentCallingAddress = callers_instruction_address; + assert parentCallingAddress != 0; + Ceexppaf ppaf = new Ceexppaf(epaf.ppa1_addr, "NAM"); + entryName = ppaf.opt_ptr == 0 ? "(unknown)" : space.readEbcdicString(ppaf.opt_ptr); + log.fine("read entry name: " + entryName); + } else { + throw new Error("tbc"); + } + } - /** Reads the ppa1_sig field given an entry point */ - private int getPpa1Sig(long signaturePtr) throws IOException { - int ppa1offset = (int)CeexoepvTemplate.getOepv_ppa1offset(inputStream, signaturePtr); - long ppa1 = signaturePtr + ppa1offset; - int signature = (int)Ceexpp1bTemplate.getPpa1_sig(inputStream, ppa1); - log.fine("read ppa1 signature " + hex(signature) + " from entry point " + hex(signaturePtr)); - return signature; - } + /** Reads the ppa1_sig field given an entry point */ + private int getPpa1Sig(long signaturePtr) throws IOException { + int ppa1offset = (int)CeexoepvTemplate.getOepv_ppa1offset(inputStream, signaturePtr); + long ppa1 = signaturePtr + ppa1offset; + int signature = (int)Ceexpp1bTemplate.getPpa1_sig(inputStream, ppa1); + log.fine("read ppa1 signature " + hex(signature) + " from entry point " + hex(signaturePtr)); + return signature; + } - /** Reads the ppa1_nmo field given an entry point */ - private int getPpa1Nmo(long signaturePtr) throws IOException { - int ppa1offset = (int)CeexoepvTemplate.getOepv_ppa1offset(inputStream, signaturePtr); - long ppa1 = signaturePtr + ppa1offset; - int nmo = (int)Ceexpp1bTemplate.getPpa1_nmo(inputStream, ppa1); - nmo &= 0xff; // XXX the template stuff should be able to sort this out? - log.fine("read ppa1 nmo " + hex(nmo) + " from entry point " + hex(signaturePtr)); - return nmo; - } + /** Reads the ppa1_nmo field given an entry point */ + private int getPpa1Nmo(long signaturePtr) throws IOException { + int ppa1offset = (int)CeexoepvTemplate.getOepv_ppa1offset(inputStream, signaturePtr); + long ppa1 = signaturePtr + ppa1offset; + int nmo = (int)Ceexpp1bTemplate.getPpa1_nmo(inputStream, ppa1); + nmo &= 0xff; // XXX the template stuff should be able to sort this out? + log.fine("read ppa1 nmo " + hex(nmo) + " from entry point " + hex(signaturePtr)); + return nmo; + } - /** Determines if this is a transition DSA */ - boolean verifyFormat(long dsaptr, int dsa_format) throws IOException { - if (dsa_format == US_FORMAT) { - long ceedsabkc = CeedsaTemplate.getCeedsabkc(inputStream, dsaptr); - log.fine("read ceedsabkc " + hex(ceedsabkc)); - if (ceedsabkc == Ceedsahp_UpTran_Ind) { - long ceedsatran = CeedsaTemplate.getCeedsatran(inputStream, dsaptr); - log.fine("read ceedsatran " + hex(ceedsatran)); - long ceedsahp_trtype = Ceedsahp_transitionTemplate.getCeedsahp_trtype(inputStream, ceedsatran); - if (ceedsahp_trtype > 0 && ceedsahp_trtype <= 6) { - return true; - } - } - } else if (dsa_format == DS_FORMAT) { - long ceedsahpr7 = ceedsahpTemplate.getCeedsahpr7(inputStream, dsaptr); - if (ceedsahpr7 == 0) { - long ceedsahptran = ceedsahpTemplate.getCeedsahptran(inputStream, dsaptr); - long ceedsahp_trtype = Ceedsahp_transitionTemplate.getCeedsahp_trtype(inputStream, ceedsahptran); - if (ceedsahp_trtype > 0 && ceedsahp_trtype <= 6) { - return true; - } - } - } - return false; - } + /** Determines if this is a transition DSA */ + boolean verifyFormat(long dsaptr, int dsa_format) throws IOException { + if (dsa_format == US_FORMAT) { + long ceedsabkc = CeedsaTemplate.getCeedsabkc(inputStream, dsaptr); + log.fine("read ceedsabkc " + hex(ceedsabkc)); + if (ceedsabkc == Ceedsahp_UpTran_Ind) { + long ceedsatran = CeedsaTemplate.getCeedsatran(inputStream, dsaptr); + log.fine("read ceedsatran " + hex(ceedsatran)); + long ceedsahp_trtype = Ceedsahp_transitionTemplate.getCeedsahp_trtype(inputStream, ceedsatran); + if (ceedsahp_trtype > 0 && ceedsahp_trtype <= 6) { + return true; + } + } + } else if (dsa_format == DS_FORMAT) { + long ceedsahpr7 = ceedsahpTemplate.getCeedsahpr7(inputStream, dsaptr); + if (ceedsahpr7 == 0) { + long ceedsahptran = ceedsahpTemplate.getCeedsahptran(inputStream, dsaptr); + long ceedsahp_trtype = Ceedsahp_transitionTemplate.getCeedsahp_trtype(inputStream, ceedsahptran); + if (ceedsahp_trtype > 0 && ceedsahp_trtype <= 6) { + return true; + } + } + } + return false; + } - /** - * Determine the point at which a program lost control - */ - long getCallingAddr(long in_dsa, int in_dsafmt, long fo_dsa, int fo_dsafmt, boolean fo_dsatrans, long in_cib, long in_sfxm) throws IOException { - long callingaddr = space.WILD_POINTER; - long next_instruction_address = 0; - if (in_cib != 0) { - callingaddr = CeexcibTemplate.getCib_int(inputStream, in_cib); - log.fine("got calling address " + hex(callingaddr) + " from cib"); - } else { - /* do not have cib, check sfxm */ - if (in_sfxm != 0) { - throw new Error("tbc"); - } else { - /* do not have sfxm */ - if (in_dsafmt == US_FORMAT) { - next_instruction_address = CeedsaTemplate.getCeedsar14(inputStream, in_dsa); - } else { - /* Downstack DSA. The return address is in the callers DSA. If the - * callee dsa was supplied, obtain the return address from reg7. - * If no callee DSA, see if the CAA is also CEEKTBCK's CAA. If they - * are the same, this means that the DSA is on CEEKTBCK's BackChain. - * Will scan the DSA chain to find the DSA immediately before the - * input DSA. */ - if (fo_dsa == 0) { - /* No callee dsa supplied. If the input CAA is the same as CEEKTBCK's - * CAA then we can run the chain to locate the callee's DSA. */ + /** + * Determine the point at which a program lost control + */ + long getCallingAddr(long in_dsa, int in_dsafmt, long fo_dsa, int fo_dsafmt, boolean fo_dsatrans, long in_cib, long in_sfxm) throws IOException { + long callingaddr = space.WILD_POINTER; + long next_instruction_address = 0; + if (in_cib != 0) { + callingaddr = CeexcibTemplate.getCib_int(inputStream, in_cib); + log.fine("got calling address " + hex(callingaddr) + " from cib"); + } else { + /* do not have cib, check sfxm */ + if (in_sfxm != 0) { + throw new Error("tbc"); + } else { + /* do not have sfxm */ + if (in_dsafmt == US_FORMAT) { + next_instruction_address = CeedsaTemplate.getCeedsar14(inputStream, in_dsa); + } else { + /* Downstack DSA. The return address is in the callers DSA. If the + * callee dsa was supplied, obtain the return address from reg7. + * If no callee DSA, see if the CAA is also CEEKTBCK's CAA. If they + * are the same, this means that the DSA is on CEEKTBCK's BackChain. + * Will scan the DSA chain to find the DSA immediately before the + * input DSA. */ + if (fo_dsa == 0) { + /* No callee dsa supplied. If the input CAA is the same as CEEKTBCK's + * CAA then we can run the chain to locate the callee's DSA. */ - /* Can't do anything here! */ - } else { - /* If there is a former DSA, it will either be an Upstack Transition, - * DownStack Transition, or a DownStack. The next_instruction address - * will be obtained based on the tupe of DSA. */ - if (fo_dsafmt == US_FORMAT && fo_dsatrans) { - /* It is an UP-Transition */ - long ceedsatran = CeedsaTemplate.getCeedsatran(inputStream, fo_dsa); - next_instruction_address = Ceedsahp_transitionTemplate.getCeedsahp_retaddr(inputStream, ceedsatran); - } else { - if (fo_dsafmt == DS_FORMAT && fo_dsatrans) { - /* It is a DOWN-Transition */ - long ceedsahptran = ceedsahpTemplate.getCeedsahptran(inputStream, fo_dsa); - next_instruction_address = Ceedsahp_transitionTemplate.getCeedsahp_retaddr(inputStream, ceedsahptran); - } else { - next_instruction_address = ceedsahpTemplate.getCeedsahpr7(inputStream, fo_dsa); - } - } - } - } - } - /* Adjust next instruction address if a valid one was obtained. - * Adjustments will be different based on the stack direction */ - if (next_instruction_address != 0) { - if (!space.is64bit()) { - if (in_dsafmt == US_FORMAT && (next_instruction_address & 0x80000000) == 0) { - next_instruction_address &= 0xffffff; - } else { - next_instruction_address &= 0x7fffffff; - } - } - /* Check if the instruction address is within ceeosigr or ceeosigx. - * If so, the true calling address has been stored in the HCOM. */ - if (in_dsafmt == US_FORMAT) { - /* upstack nsi adjust */ - if (next_instruction_address == caa.getEdb().ceeedb_ceeosigr()) { - throw new Error("tbc"); - } - /* Assume calling instruction is a BALR type instruction which is - * 2 bytes long. Thus the calling instruction is 2 bytes ahead of - * the next instruction to be executed in the routine. - * - * Test for amode switching glue code at the next instruction address. - * If so, replace next instruction address with real return address - * saved in DSAMODE field of callers DSA. */ - try { - short rr_inst = space.readShort(next_instruction_address - 2); - if (rr_inst == BASSM1415) { - /* call done with BASSM 14,15 */ - int rx_inst = space.readInt(next_instruction_address); - if (rx_inst == L14DSAMODE) { - next_instruction_address = CeedsaTemplate.getCeedsamode(inputStream, in_dsa); - /* Assume calling instruction is a BALR type instruction - * which is 2 bytes long. Thus the calling instruction is - * 2 bytes ahead of the next instruction to be executed in - * the routine. Also, if the high order bit is zero, then - * address is amode 24, and the high order byte must be cleared. */ - if (!space.is64bit()) { - if ((next_instruction_address & 0x80000000) == 0) { - next_instruction_address &= 0xffffff; - } else { - next_instruction_address &= 0x7fffffff; - } - } - } - } - /* If next_instruction is NOP N '4700bddd'X, the routine uses - * OPLINK linkage convention */ - boolean fstlink_call = false; - int rx_inst = space.readInt(next_instruction_address); - if ((rx_inst >>> 16) == 0x4700) { - fstlink_call = true; - } - callingaddr = next_instruction_address - 2; - log.fine("found callingaddr = 0x" + hex(callingaddr)); - } catch (IOException e) { - log.fine("could not read next_instruction_address at " + hex(next_instruction_address)); - callingaddr = 0; - throw e; - } - } else { - /* downstack nsi adjust */ - long ceecaarcb = caa.ceecaarcb(); - long ceercb_ceeosigx = ceexrcbTemplate.getCeercb_ceeosigx(inputStream, ceecaarcb); - if (next_instruction_address == ceercb_ceeosigx) { - /* Get NSI from saved register7 in edb */ - throw new Error("tbc"); - } - /* read in noop. call instruction will be either: - * - BASR(0) - 2 byte length - * - BRAS(1) - 4 byte length - * - BRASL(2) - 6 byte length - */ - int rx_inst = space.readInt(next_instruction_address); - int Hpcl_Call_Type = (rx_inst >> 16) & 0xf; - if ((rx_inst >>> 20) != (space.is64bit() ? 0x070 : 0x470)) { - callingaddr = 0; - log.fine("did not find expected nop"); - } else if (Hpcl_Call_Type == Hpcl_Basr_Call) { - callingaddr = next_instruction_address - 2; - } else if (Hpcl_Call_Type == Hpcl_Bras_Call) { - callingaddr = next_instruction_address - 4; - } else if (Hpcl_Call_Type == Hpcl_Brasl_Call) { - callingaddr = next_instruction_address - 6; - } else { - callingaddr = 0; - log.fine("did not recognize call type " + Hpcl_Call_Type); - } - } - } else { - log.fine("next_instruction_address zero, cannot get calling address"); - } - } - return callingaddr; - } + /* Can't do anything here! */ + } else { + /* If there is a former DSA, it will either be an Upstack Transition, + * DownStack Transition, or a DownStack. The next_instruction address + * will be obtained based on the tupe of DSA. */ + if (fo_dsafmt == US_FORMAT && fo_dsatrans) { + /* It is an UP-Transition */ + long ceedsatran = CeedsaTemplate.getCeedsatran(inputStream, fo_dsa); + next_instruction_address = Ceedsahp_transitionTemplate.getCeedsahp_retaddr(inputStream, ceedsatran); + } else { + if (fo_dsafmt == DS_FORMAT && fo_dsatrans) { + /* It is a DOWN-Transition */ + long ceedsahptran = ceedsahpTemplate.getCeedsahptran(inputStream, fo_dsa); + next_instruction_address = Ceedsahp_transitionTemplate.getCeedsahp_retaddr(inputStream, ceedsahptran); + } else { + next_instruction_address = ceedsahpTemplate.getCeedsahpr7(inputStream, fo_dsa); + } + } + } + } + } + /* Adjust next instruction address if a valid one was obtained. + * Adjustments will be different based on the stack direction */ + if (next_instruction_address != 0) { + if (!space.is64bit()) { + if (in_dsafmt == US_FORMAT && (next_instruction_address & 0x80000000) == 0) { + next_instruction_address &= 0xffffff; + } else { + next_instruction_address &= 0x7fffffff; + } + } + /* Check if the instruction address is within ceeosigr or ceeosigx. + * If so, the true calling address has been stored in the HCOM. */ + if (in_dsafmt == US_FORMAT) { + /* upstack nsi adjust */ + if (next_instruction_address == caa.getEdb().ceeedb_ceeosigr()) { + throw new Error("tbc"); + } + /* Assume calling instruction is a BALR type instruction which is + * 2 bytes long. Thus the calling instruction is 2 bytes ahead of + * the next instruction to be executed in the routine. + * + * Test for amode switching glue code at the next instruction address. + * If so, replace next instruction address with real return address + * saved in DSAMODE field of callers DSA. */ + try { + short rr_inst = space.readShort(next_instruction_address - 2); + if (rr_inst == BASSM1415) { + /* call done with BASSM 14,15 */ + int rx_inst = space.readInt(next_instruction_address); + if (rx_inst == L14DSAMODE) { + next_instruction_address = CeedsaTemplate.getCeedsamode(inputStream, in_dsa); + /* Assume calling instruction is a BALR type instruction + * which is 2 bytes long. Thus the calling instruction is + * 2 bytes ahead of the next instruction to be executed in + * the routine. Also, if the high order bit is zero, then + * address is amode 24, and the high order byte must be cleared. */ + if (!space.is64bit()) { + if ((next_instruction_address & 0x80000000) == 0) { + next_instruction_address &= 0xffffff; + } else { + next_instruction_address &= 0x7fffffff; + } + } + } + } + /* If next_instruction is NOP N '4700bddd'X, the routine uses + * OPLINK linkage convention */ + boolean fstlink_call = false; + int rx_inst = space.readInt(next_instruction_address); + if ((rx_inst >>> 16) == 0x4700) { + fstlink_call = true; + } + callingaddr = next_instruction_address - 2; + log.fine("found callingaddr = 0x" + hex(callingaddr)); + } catch (IOException e) { + log.fine("could not read next_instruction_address at " + hex(next_instruction_address)); + callingaddr = 0; + throw e; + } + } else { + /* downstack nsi adjust */ + long ceecaarcb = caa.ceecaarcb(); + long ceercb_ceeosigx = ceexrcbTemplate.getCeercb_ceeosigx(inputStream, ceecaarcb); + if (next_instruction_address == ceercb_ceeosigx) { + /* Get NSI from saved register7 in edb */ + throw new Error("tbc"); + } + /* read in noop. call instruction will be either: + * - BASR(0) - 2 byte length + * - BRAS(1) - 4 byte length + * - BRASL(2) - 6 byte length + */ + int rx_inst = space.readInt(next_instruction_address); + int Hpcl_Call_Type = (rx_inst >> 16) & 0xf; + if ((rx_inst >>> 20) != (space.is64bit() ? 0x070 : 0x470)) { + callingaddr = 0; + log.fine("did not find expected nop"); + } else if (Hpcl_Call_Type == Hpcl_Basr_Call) { + callingaddr = next_instruction_address - 2; + } else if (Hpcl_Call_Type == Hpcl_Bras_Call) { + callingaddr = next_instruction_address - 4; + } else if (Hpcl_Call_Type == Hpcl_Brasl_Call) { + callingaddr = next_instruction_address - 6; + } else { + callingaddr = 0; + log.fine("did not recognize call type " + Hpcl_Call_Type); + } + } + } else { + log.fine("next_instruction_address zero, cannot get calling address"); + } + } + return callingaddr; + } - /** - * Scan CIB chain and return CIB address corresponding to the input dsa. - */ - long findCib(long in_dsa) { - try { - long cibh_ptr_cib = 0; - long ceecaaerrcm = caa.ceecaaerrcm(); - long cibhptr = ceexhcomTemplate.getHcom_cibh(inputStream, ceecaaerrcm); - while (cibhptr != 0) { - boolean cibh_in_use = CeexcibhTemplate.getCibh_in_use(inputStream, cibhptr) != 0; - cibh_ptr_cib = CeexcibhTemplate.getCibh_ptr_cib(inputStream, cibhptr); - long cib_sv1 = CeexcibTemplate.getCib_sv1(inputStream, cibh_ptr_cib); - if (cibh_in_use && cib_sv1 == in_dsa) - break; - cibhptr = CeexcibhTemplate.getCibh_back(inputStream, cibhptr); - } - if (cibhptr == 0) { - return 0; - } else { - log.fine("found a cib: " + hex(cibh_ptr_cib)); - return cibh_ptr_cib; - } - } catch (Exception e) { - throw new Error("oops: " + e); - } - } + /** + * Scan CIB chain and return CIB address corresponding to the input dsa. + */ + long findCib(long in_dsa) { + try { + long cibh_ptr_cib = 0; + long ceecaaerrcm = caa.ceecaaerrcm(); + long cibhptr = ceexhcomTemplate.getHcom_cibh(inputStream, ceecaaerrcm); + while (cibhptr != 0) { + boolean cibh_in_use = CeexcibhTemplate.getCibh_in_use(inputStream, cibhptr) != 0; + cibh_ptr_cib = CeexcibhTemplate.getCibh_ptr_cib(inputStream, cibhptr); + long cib_sv1 = CeexcibTemplate.getCib_sv1(inputStream, cibh_ptr_cib); + if (cibh_in_use && cib_sv1 == in_dsa) + break; + cibhptr = CeexcibhTemplate.getCibh_back(inputStream, cibhptr); + } + if (cibhptr == 0) { + return 0; + } else { + log.fine("found a cib: " + hex(cibh_ptr_cib)); + return cibh_ptr_cib; + } + } catch (Exception e) { + throw new Error("oops: " + e); + } + } - /** - * Scan SFXM chain and return SFXM corresponding to the input dsa. - */ - long findSfxm(long sfxm_dsa, int p_dsafmt) throws IOException { - final long HEPV_Entry_Sig = 0x00C300C500C500L; /* Entry Marker signature */ - long p_sfxm = 0; - Set visited = new HashSet<>(); - try { - if (p_dsafmt == US_FORMAT) { - /* processing UPstack DSA */ - log.fine("findSfxm processing upstack dsa"); - long hcom_exit_stk = ceexhcomTemplate.getHcom_exit_stk(inputStream, caa.ceecaaerrcm()); - log.fine("findSfxm hcom_exit_stk = 0x" + hex(hcom_exit_stk)); - for (long tptr = hcom_exit_stk; tptr != 0;) { - if (!visited.add(tptr)) { - log.fine("back-link cycle found in upstack dsm at " + hex(tptr)); - break; - } - /* If the SFXM is for an UPSTACK DSA and that DSA - * backchains to the input DSA then we have found - * the SFXM that we want. - * NOTE: An SFXM that belongs to an UPSTACK DSA starts - * with a couple of NOPRs and a BALR. An SFXM that - * belongs to a DOWNSTACK DSA starts with an XPLINK - * style entry marker. */ - long sfxm_code_eyecatch = CeexsfxmTemplate.getSfxm_code_eyecatch(inputStream, tptr); - if ((sfxm_code_eyecatch >>> 8) != HEPV_Entry_Sig) { - long sfxm_parm_sf = CeexsfxmTemplate.getSfxm_parm_sf(inputStream, tptr); - long ceedsabkc = CeedsaTemplate.getCeedsabkc(inputStream, sfxm_parm_sf); - if (ceedsabkc == sfxm_dsa) { - log.fine("found the upstack sfxm at " + hex(tptr)); - p_sfxm = tptr; - } - } - tptr = CeexsfxmTemplate.getSfxm_next(inputStream, tptr); - } - } else { - /* processing a DownStack DSA */ - log.fine("findSfxm processing downstack dsa"); - long hcom_exit_stk = ceexhcomTemplate.getHcom_exit_stk(inputStream, caa.ceecaaerrcm()); - log.fine("findSfxm hcom_exit_stk = 0x" + hex(hcom_exit_stk)); - int offset = CeexsfxmTemplate.getSfxm_code_return_pt$offset(); - long ceedsahpr7 = ceedsahpTemplate.getCeedsahpr7(inputStream, sfxm_dsa); - ceedsahpr7 = space.stripTopBit(ceedsahpr7); - for (long tptr = hcom_exit_stk; tptr != 0;) { - if (!visited.add(tptr)) { - log.fine("back-link cycle found in downstack dsm at " + hex(tptr)); - break; - } - if ((tptr + offset) == ceedsahpr7) { - /* Find the last SFXM by comparing Sfxm_Next with Sfxm_Save_R7. - * When they are not equal, we're at the last SFXM for this routine. */ - throw new Error("tbc"); - } else { - /* No match, go to next Sfxm */ - tptr = CeexsfxmTemplate.getSfxm_next(inputStream, tptr); - } - } - } - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new Error("oops: " + e); - } - return p_sfxm; - } + /** + * Scan SFXM chain and return SFXM corresponding to the input dsa. + */ + long findSfxm(long sfxm_dsa, int p_dsafmt) throws IOException { + final long HEPV_Entry_Sig = 0x00C300C500C500L; /* Entry Marker signature */ + long p_sfxm = 0; + Set visited = new HashSet<>(); + try { + if (p_dsafmt == US_FORMAT) { + /* processing UPstack DSA */ + log.fine("findSfxm processing upstack dsa"); + long hcom_exit_stk = ceexhcomTemplate.getHcom_exit_stk(inputStream, caa.ceecaaerrcm()); + log.fine("findSfxm hcom_exit_stk = 0x" + hex(hcom_exit_stk)); + for (long tptr = hcom_exit_stk; tptr != 0;) { + if (!visited.add(tptr)) { + log.fine("back-link cycle found in upstack dsm at " + hex(tptr)); + break; + } + /* If the SFXM is for an UPSTACK DSA and that DSA + * backchains to the input DSA then we have found + * the SFXM that we want. + * NOTE: An SFXM that belongs to an UPSTACK DSA starts + * with a couple of NOPRs and a BALR. An SFXM that + * belongs to a DOWNSTACK DSA starts with an XPLINK + * style entry marker. */ + long sfxm_code_eyecatch = CeexsfxmTemplate.getSfxm_code_eyecatch(inputStream, tptr); + if ((sfxm_code_eyecatch >>> 8) != HEPV_Entry_Sig) { + long sfxm_parm_sf = CeexsfxmTemplate.getSfxm_parm_sf(inputStream, tptr); + long ceedsabkc = CeedsaTemplate.getCeedsabkc(inputStream, sfxm_parm_sf); + if (ceedsabkc == sfxm_dsa) { + log.fine("found the upstack sfxm at " + hex(tptr)); + p_sfxm = tptr; + } + } + tptr = CeexsfxmTemplate.getSfxm_next(inputStream, tptr); + } + } else { + /* processing a DownStack DSA */ + log.fine("findSfxm processing downstack dsa"); + long hcom_exit_stk = ceexhcomTemplate.getHcom_exit_stk(inputStream, caa.ceecaaerrcm()); + log.fine("findSfxm hcom_exit_stk = 0x" + hex(hcom_exit_stk)); + int offset = CeexsfxmTemplate.getSfxm_code_return_pt$offset(); + long ceedsahpr7 = ceedsahpTemplate.getCeedsahpr7(inputStream, sfxm_dsa); + ceedsahpr7 = space.stripTopBit(ceedsahpr7); + for (long tptr = hcom_exit_stk; tptr != 0;) { + if (!visited.add(tptr)) { + log.fine("back-link cycle found in downstack dsm at " + hex(tptr)); + break; + } + if ((tptr + offset) == ceedsahpr7) { + /* Find the last SFXM by comparing Sfxm_Next with Sfxm_Save_R7. + * When they are not equal, we're at the last SFXM for this routine. */ + throw new Error("tbc"); + } else { + /* No match, go to next Sfxm */ + tptr = CeexsfxmTemplate.getSfxm_next(inputStream, tptr); + } + } + } + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new Error("oops: " + e); + } + return p_sfxm; + } - /** - * This class emulates the Ceexdsaf macro (Ph variant). Most of the comments are from Ceexdsaf. - * The purpose of this class is to derive the previous stackframe from the passed address and - * stackframe format. - */ - static class Ceexdsaf { - /** Desired output DSA address of previous frame */ - long DSA_Prev; - /** Format of previous frame */ - int DSA_Format; - /** The AddressSpaceImageInputStream */ - private AddressSpaceImageInputStream inputStream; + /** + * This class emulates the Ceexdsaf macro (Ph variant). Most of the comments are from Ceexdsaf. + * The purpose of this class is to derive the previous stackframe from the passed address and + * stackframe format. + */ + static class Ceexdsaf { + /** Desired output DSA address of previous frame */ + long DSA_Prev; + /** Format of previous frame */ + int DSA_Format; + /** The AddressSpaceImageInputStream */ + private AddressSpaceImageInputStream inputStream; - Ceexdsaf(AddressSpace space, long DSA_In, int dsa_fmt) throws IOException { - log.fine("enter Ceexdsaf for dsa " + hex(DSA_In)); - /* Create any templates we need if not already created */ - CeedsahpTemplate ceedsahpTemplate; - if (space.is64bit()) { - ceedsahpTemplate = new Ceedsahp64Template(); - } else { - ceedsahpTemplate = new Ceedsahp32Template(); - } - inputStream = space.getImageInputStream(); - boolean isTransitional; - DSA_Format = dsa_fmt; // Default to same as parent - try { - if (DSA_Format == Caa.CEECAASTACK_UP) { - /* Stack Format is UP. If passed DSA is a transitional, return - * Ceedsahp_Bkc from tx area. Else, old-style backchain */ - long ceedsabkc = CeedsaTemplate.getCeedsabkc(inputStream, DSA_In); - if (ceedsabkc == DsaStackFrame.Ceedsahp_UpTran_Ind) { - isTransitional = true; - /* If the transitional frame is for "DownToUp" (3), reset the - * stack format to Down and use the Ceedsahp_Bkc field. */ - long ceedsatran = CeedsaTemplate.getCeedsatran(inputStream, DSA_In); - long ceedsahp_trtype = Ceedsahp_transitionTemplate.getCeedsahp_trtype(inputStream, ceedsatran); - if (ceedsahp_trtype == Ceedsahp_DownToUp) { - DSA_Prev = Ceedsahp_transitionTemplate.getCeedsahp_bkc(inputStream, ceedsatran); - DSA_Format = Caa.CEECAASTACK_DOWN; - } else { - DSA_Prev = ceedsabkc; - } - } else { - /* Old-style backchain */ - DSA_Prev = ceedsabkc; - } - } else { - /* Stack Format is DOWN. If passed DSA is a transitional UptoDown (2), - * reset the DSA format to Up */ - long ceedsahpr7 = ceedsahpTemplate.getCeedsahpr7(inputStream, DSA_In); - if (ceedsahpr7 == 0) { - long ceedsahptran = ceedsahpTemplate.getCeedsahptran(inputStream, DSA_In); - long ceedsahp_trtype = Ceedsahp_transitionTemplate.getCeedsahp_trtype(inputStream, ceedsahptran); - if (ceedsahp_trtype == Ceedsahp_UpToDown) { - DSA_Format = Caa.CEECAASTACK_UP; - } - /* Now return Ceedsahp_Bkc from tx area. Else, XPLINK-style backchain */ - isTransitional = true; - DSA_Prev = Ceedsahp_transitionTemplate.getCeedsahp_bkc(inputStream, ceedsahptran); - } else { - /* Now do an XPL backchain. First we need the stackframe owner`s - * Entry Point. From this we can retrieve the SF`s DSA size. This - * is then added to the current DSA to locate the previous stackframe */ - long Entry_Temp = hpclEntryPoint(space, DSA_In, ceedsahpr7, ceedsahpTemplate); - if (Entry_Temp == 0) { - /* Unable to find entry. Leave with zero DSA as previous */ - DSA_Prev = 0; - } else { - /* Check if the stackframe owner uses Alloca. If so, use the saved - * backchain pointer in the DSA+0 to find previous DSA. If not, add - * current function`s DSA size to current DSA to find the previous */ - int dsaFlags = space.readInt(Entry_Temp - 4); - if ((dsaFlags & 4) == 4) { - DSA_Prev = ceedsahpTemplate.getCeedsahpr4(inputStream, DSA_In); - } else { - int dsaSize = dsaFlags & 0xfffffff0; - DSA_Prev = DSA_In + dsaSize; - } - } - } - } - /* Propagate IO exceptions, all others are fatal errors */ - } catch (IOException e) { - throw e; - } catch (Exception e) { - e.printStackTrace(); - throw new Error("oops: " + e); - } - } - } + Ceexdsaf(AddressSpace space, long DSA_In, int dsa_fmt) throws IOException { + log.fine("enter Ceexdsaf for dsa " + hex(DSA_In)); + /* Create any templates we need if not already created */ + CeedsahpTemplate ceedsahpTemplate; + if (space.is64bit()) { + ceedsahpTemplate = new Ceedsahp64Template(); + } else { + ceedsahpTemplate = new Ceedsahp32Template(); + } + inputStream = space.getImageInputStream(); + boolean isTransitional; + DSA_Format = dsa_fmt; // Default to same as parent + try { + if (DSA_Format == Caa.CEECAASTACK_UP) { + /* Stack Format is UP. If passed DSA is a transitional, return + * Ceedsahp_Bkc from tx area. Else, old-style backchain */ + long ceedsabkc = CeedsaTemplate.getCeedsabkc(inputStream, DSA_In); + if (ceedsabkc == DsaStackFrame.Ceedsahp_UpTran_Ind) { + isTransitional = true; + /* If the transitional frame is for "DownToUp" (3), reset the + * stack format to Down and use the Ceedsahp_Bkc field. */ + long ceedsatran = CeedsaTemplate.getCeedsatran(inputStream, DSA_In); + long ceedsahp_trtype = Ceedsahp_transitionTemplate.getCeedsahp_trtype(inputStream, ceedsatran); + if (ceedsahp_trtype == Ceedsahp_DownToUp) { + DSA_Prev = Ceedsahp_transitionTemplate.getCeedsahp_bkc(inputStream, ceedsatran); + DSA_Format = Caa.CEECAASTACK_DOWN; + } else { + DSA_Prev = ceedsabkc; + } + } else { + /* Old-style backchain */ + DSA_Prev = ceedsabkc; + } + } else { + /* Stack Format is DOWN. If passed DSA is a transitional UptoDown (2), + * reset the DSA format to Up */ + long ceedsahpr7 = ceedsahpTemplate.getCeedsahpr7(inputStream, DSA_In); + if (ceedsahpr7 == 0) { + long ceedsahptran = ceedsahpTemplate.getCeedsahptran(inputStream, DSA_In); + long ceedsahp_trtype = Ceedsahp_transitionTemplate.getCeedsahp_trtype(inputStream, ceedsahptran); + if (ceedsahp_trtype == Ceedsahp_UpToDown) { + DSA_Format = Caa.CEECAASTACK_UP; + } + /* Now return Ceedsahp_Bkc from tx area. Else, XPLINK-style backchain */ + isTransitional = true; + DSA_Prev = Ceedsahp_transitionTemplate.getCeedsahp_bkc(inputStream, ceedsahptran); + } else { + /* Now do an XPL backchain. First we need the stackframe owner`s + * Entry Point. From this we can retrieve the SF`s DSA size. This + * is then added to the current DSA to locate the previous stackframe */ + long Entry_Temp = hpclEntryPoint(space, DSA_In, ceedsahpr7, ceedsahpTemplate); + if (Entry_Temp == 0) { + /* Unable to find entry. Leave with zero DSA as previous */ + DSA_Prev = 0; + } else { + /* Check if the stackframe owner uses Alloca. If so, use the saved + * backchain pointer in the DSA+0 to find previous DSA. If not, add + * current function`s DSA size to current DSA to find the previous */ + int dsaFlags = space.readInt(Entry_Temp - 4); + if ((dsaFlags & 4) == 4) { + DSA_Prev = ceedsahpTemplate.getCeedsahpr4(inputStream, DSA_In); + } else { + int dsaSize = dsaFlags & 0xfffffff0; + DSA_Prev = DSA_In + dsaSize; + } + } + } + } + /* Propagate IO exceptions, all others are fatal errors */ + } catch (IOException e) { + throw e; + } catch (Exception e) { + e.printStackTrace(); + throw new Error("oops: " + e); + } + } + } - static long hpclEntryPoint(AddressSpace space, long DSA_In, long ceedsahpr7, CeedsahpTemplate ceedsahpTemplate) throws Exception { - log.fine("ceedsahpr7: " + hex(ceedsahpr7)); - AddressSpaceImageInputStream inputStream = space.getImageInputStream(); - /* We need to first check the Call Type to determine the Entry Point - * of the routine that owns the SF. Valid call types are: - * 00=BASR, 01=BRAS, and 03=BRASL - */ - int Hpcl_Call_Type = (space.readInt(ceedsahpr7) >> 16) & 0xf; - long Entry_Temp; - if (Hpcl_Call_Type == Hpcl_Basr_Call) { - /* Call Type BASR 7,6. Use Ceedsahpr6 to find entry */ - Entry_Temp = ceedsahpTemplate.getCeedsahpr6(inputStream, DSA_In); - log.fine("BASR 7,6: " + hex(Entry_Temp)); - } else if (Hpcl_Call_Type == Hpcl_Bras_Call) { - /* Call Type BRAS 7,xxx. Compute Entry by looking at instr offset */ - int offset = space.readShort(ceedsahpr7 - 2); - log.fine("offset: " + hex(offset)); - //if (offset < 0) - //throw new Error("is this supposed to be unsigned? " + offset); - Entry_Temp = ceedsahpr7 - 4 + (offset * 2); - log.fine("BRAS 7,xxx: " + hex(Entry_Temp) + (Entry_Temp < 0 ? " (neg)" : "") + " offset = " + offset); - } else if (Hpcl_Call_Type == Hpcl_Brasl_Call) { - /* Call Type BRASL 7,xxx. Compute Entry by looking at instr offset */ - int offset = space.readInt(ceedsahpr7 - 4); - Entry_Temp = ceedsahpr7 - 6 + (offset * 2); - log.fine("BRASL 7,xxx: " + hex(Entry_Temp)); - } else { - /* Unable to find entry */ - return 0; - } - if (space.readInt(Entry_Temp - 16) != 0x00c300c5) - //throw new Error("bad entry point eyecatcher: " + hex(space.readInt(Entry_Temp - 16))); - Entry_Temp = 0; - return Entry_Temp; - } + static long hpclEntryPoint(AddressSpace space, long DSA_In, long ceedsahpr7, CeedsahpTemplate ceedsahpTemplate) throws Exception { + log.fine("ceedsahpr7: " + hex(ceedsahpr7)); + AddressSpaceImageInputStream inputStream = space.getImageInputStream(); + /* We need to first check the Call Type to determine the Entry Point + * of the routine that owns the SF. Valid call types are: + * 00=BASR, 01=BRAS, and 03=BRASL + */ + int Hpcl_Call_Type = (space.readInt(ceedsahpr7) >> 16) & 0xf; + long Entry_Temp; + if (Hpcl_Call_Type == Hpcl_Basr_Call) { + /* Call Type BASR 7,6. Use Ceedsahpr6 to find entry */ + Entry_Temp = ceedsahpTemplate.getCeedsahpr6(inputStream, DSA_In); + log.fine("BASR 7,6: " + hex(Entry_Temp)); + } else if (Hpcl_Call_Type == Hpcl_Bras_Call) { + /* Call Type BRAS 7,xxx. Compute Entry by looking at instr offset */ + int offset = space.readShort(ceedsahpr7 - 2); + log.fine("offset: " + hex(offset)); + //if (offset < 0) + //throw new Error("is this supposed to be unsigned? " + offset); + Entry_Temp = ceedsahpr7 - 4 + (offset * 2); + log.fine("BRAS 7,xxx: " + hex(Entry_Temp) + (Entry_Temp < 0 ? " (neg)" : "") + " offset = " + offset); + } else if (Hpcl_Call_Type == Hpcl_Brasl_Call) { + /* Call Type BRASL 7,xxx. Compute Entry by looking at instr offset */ + int offset = space.readInt(ceedsahpr7 - 4); + Entry_Temp = ceedsahpr7 - 6 + (offset * 2); + log.fine("BRASL 7,xxx: " + hex(Entry_Temp)); + } else { + /* Unable to find entry */ + return 0; + } + if (space.readInt(Entry_Temp - 16) != 0x00c300c5) + //throw new Error("bad entry point eyecatcher: " + hex(space.readInt(Entry_Temp - 16))); + Entry_Temp = 0; + return Entry_Temp; + } - /** - * This class emulates the Ceexepaf macro. Note that it only does the downstack variant. - */ - class Ceexepaf { - /** The PPA1 address */ - long ppa1_addr; - /** The PPA2 address */ - long ppa2_addr; - /** The entry point address */ - long entry_address; + /** + * This class emulates the Ceexepaf macro. Note that it only does the downstack variant. + */ + class Ceexepaf { + /** The PPA1 address */ + long ppa1_addr; + /** The PPA2 address */ + long ppa2_addr; + /** The entry point address */ + long entry_address; - Ceexepaf(long DSA_In, int DSA_Format) throws IOException { - try { - /* Stack format is DOWN. If passed DSA is transitional, return Ceedsahpr6. Else, - * check call point info at R7 to determine the EP */ - long ceedsahpr7 = ceedsahpTemplate.getCeedsahpr7(inputStream, DSA_In); - if (ceedsahpr7 == 0) { - entry_address = ceedsahpTemplate.getCeedsahpr6(inputStream, DSA_In); - } else { - /* Not a transitional. Go get the XPLINK stackframe owner`s Entry Point. - * From this we can address the PPA1/PPA2 - */ + Ceexepaf(long DSA_In, int DSA_Format) throws IOException { + try { + /* Stack format is DOWN. If passed DSA is transitional, return Ceedsahpr6. Else, + * check call point info at R7 to determine the EP */ + long ceedsahpr7 = ceedsahpTemplate.getCeedsahpr7(inputStream, DSA_In); + if (ceedsahpr7 == 0) { + entry_address = ceedsahpTemplate.getCeedsahpr6(inputStream, DSA_In); + } else { + /* Not a transitional. Go get the XPLINK stackframe owner`s Entry Point. + * From this we can address the PPA1/PPA2 + */ - /* Share code with Ceexdsaf rather than repeating it */ - entry_address = hpclEntryPoint(space, DSA_In, ceedsahpr7, ceedsahpTemplate); - assert entry_address != 0; - } - log.fine("read entry_address 0x" + hex(entry_address)); - int hepv_prefix_length = CeexhepvTemplate.getHepv_entry_point$offset(); - long hepv = entry_address - hepv_prefix_length; - long hepv_ppa1_offset_p = CeexhepvTemplate.getHepv_ppa1_offset_p(inputStream, hepv); - ppa1_addr = hepv + hepv_ppa1_offset_p; - log.fine("ppa1 = 0x" + hex(ppa1_addr)); - long ppa1h_ppa2_off = Ceexhp1bTemplate.getPpa1h_ppa2_off(inputStream, ppa1_addr); - ppa2_addr = ppa1_addr + ppa1h_ppa2_off; - log.fine("ppa2 = 0x" + hex(ppa2_addr)); - } catch (IOException e) { - /* Go easy on dodgy stack entries for now */ - } catch (Exception e) { - e.printStackTrace(); - throw new Error("oops: " + e); - } - } - } + /* Share code with Ceexdsaf rather than repeating it */ + entry_address = hpclEntryPoint(space, DSA_In, ceedsahpr7, ceedsahpTemplate); + assert entry_address != 0; + } + log.fine("read entry_address 0x" + hex(entry_address)); + int hepv_prefix_length = CeexhepvTemplate.getHepv_entry_point$offset(); + long hepv = entry_address - hepv_prefix_length; + long hepv_ppa1_offset_p = CeexhepvTemplate.getHepv_ppa1_offset_p(inputStream, hepv); + ppa1_addr = hepv + hepv_ppa1_offset_p; + log.fine("ppa1 = 0x" + hex(ppa1_addr)); + long ppa1h_ppa2_off = Ceexhp1bTemplate.getPpa1h_ppa2_off(inputStream, ppa1_addr); + ppa2_addr = ppa1_addr + ppa1h_ppa2_off; + log.fine("ppa2 = 0x" + hex(ppa2_addr)); + } catch (IOException e) { + /* Go easy on dodgy stack entries for now */ + } catch (Exception e) { + e.printStackTrace(); + throw new Error("oops: " + e); + } + } + } - /** - * This class emulates the Ceexppaf macro. - */ - class Ceexppaf { - /** The output pointer */ - long opt_ptr; + /** + * This class emulates the Ceexppaf macro. + */ + class Ceexppaf { + /** The output pointer */ + long opt_ptr; - Ceexppaf(long ppa1_ptr, String opt_nam) throws IOException { - try { - int ppa1h_lgth = Ceexhp1bTemplate.length(); - assert ppa1h_lgth == 20 : ppa1h_lgth; - opt_ptr = ppa1_ptr + ppa1h_lgth; - if (opt_nam.equals("NAM")) { - /* No table pointer was provided so get the one from the rcb */ - long ceecaarcb = caa.ceecaarcb(); - log.fine("ceecaarcb = " + hex(ceecaarcb)); - long tabl_ptr = ceexrcbTemplate.getCeercb_ppa1tabl(inputStream, ceecaarcb); - log.fine("tabl_ptr = " + hex(tabl_ptr)); - long ppa1h_flag3 = Ceexhp1bTemplate.getPpa1h_flag3(inputStream, ppa1_ptr); - log.fine("ppa1h_flag3 = " + hex(ppa1h_flag3)); - int offset = space.readUnsignedByte(tabl_ptr + (ppa1h_flag3 & 0xff)); - opt_ptr += offset; - log.fine("found offset of " + offset + ", opt_ptr now " + hex(opt_ptr)); - } else { - throw new Error("unsupported option: " + opt_nam); - } - } catch (IOException e) { - /* Go easy on dodgy stack entries for now */ - opt_ptr = 0; - } catch (Exception e) { - e.printStackTrace(); - throw new Error("oops: " + e); - } - } - } + Ceexppaf(long ppa1_ptr, String opt_nam) throws IOException { + try { + int ppa1h_lgth = Ceexhp1bTemplate.length(); + assert ppa1h_lgth == 20 : ppa1h_lgth; + opt_ptr = ppa1_ptr + ppa1h_lgth; + if (opt_nam.equals("NAM")) { + /* No table pointer was provided so get the one from the rcb */ + long ceecaarcb = caa.ceecaarcb(); + log.fine("ceecaarcb = " + hex(ceecaarcb)); + long tabl_ptr = ceexrcbTemplate.getCeercb_ppa1tabl(inputStream, ceecaarcb); + log.fine("tabl_ptr = " + hex(tabl_ptr)); + long ppa1h_flag3 = Ceexhp1bTemplate.getPpa1h_flag3(inputStream, ppa1_ptr); + log.fine("ppa1h_flag3 = " + hex(ppa1h_flag3)); + int offset = space.readUnsignedByte(tabl_ptr + (ppa1h_flag3 & 0xff)); + opt_ptr += offset; + log.fine("found offset of " + offset + ", opt_ptr now " + hex(opt_ptr)); + } else { + throw new Error("unsupported option: " + opt_nam); + } + } catch (IOException e) { + /* Go easy on dodgy stack entries for now */ + opt_ptr = 0; + } catch (Exception e) { + e.printStackTrace(); + throw new Error("oops: " + e); + } + } + } - /** - * Returns the function name for the given entry point address. - * XXX This was borrowed from the old svcdump code. We really should reuse some of the - * code elsewhere in this class that obtains the name but it's currently horribly - * intertwined with other DSA logic. Might be possible to fake up a DSA? - */ - public static String getEntryPointName(AddressSpace space, long ep) throws IOException { - int eyecatcher; - Long mapKey = Long.valueOf(ep); - String function = (String)space.getUserMap().get(mapKey); - if (function != null) - return function; + /** + * Returns the function name for the given entry point address. + * XXX This was borrowed from the old svcdump code. We really should reuse some of the + * code elsewhere in this class that obtains the name but it's currently horribly + * intertwined with other DSA logic. Might be possible to fake up a DSA? + */ + public static String getEntryPointName(AddressSpace space, long ep) throws IOException { + int eyecatcher; + Long mapKey = Long.valueOf(ep); + String function = (String)space.getUserMap().get(mapKey); + if (function != null) + return function; - eyecatcher = space.readInt(ep + 4); - if (eyecatcher == 0xc3c5c5 || eyecatcher == 0x1c3c5c5) { - long ppa1 = ep + space.readInt(ep + 12); - int offset = space.readUnsignedByte(ppa1); - if (eyecatcher == 0x1c3c5c5) offset <<= 1; - function = space.readEbcdicString(ppa1 + offset); - } else if ((eyecatcher & 0xff0000) == 0xce0000) { - long ppa1 = ep; - int offset = eyecatcher >>> 24; - function = space.readEbcdicString(ppa1 + offset); - } else if ((space.readInt(ep) & 0xfffff000) == 0x47f0f000) { - int length = space.readUnsignedByte(ep + 4); - function = space.readEbcdicString(ep + 5, length); - for (int i = 0; i < function.length(); i++) { - char c = function.charAt(i); - if (!Character.isLetterOrDigit(c) && !Character.isSpaceChar(c)) { - function = "(unknown)"; - break; - } - } - } else { - long xplhdr = ep - 16; - long ceesig = space.readLong(xplhdr); - if (ceesig == 0x00C300C500C500F1L) { - int ppa1off = space.readInt(xplhdr + 8); - long ptrppa1 = xplhdr + ppa1off; - long ptrnam = ptrppa1 + 0x14; - int ppa1flags3 = space.readUnsignedByte(ptrppa1 + 10); - int ppa1flags4 = space.readUnsignedByte(ptrppa1 + 11); - /* step over all structures in ppa1 to get to name */ - /* state variable locator */ - if ((ppa1flags3 & 0x80) != 0) - ptrnam = ptrnam + 4; - /* Argument Area Length */ - if ((ppa1flags3 & 0x40) != 0) - ptrnam = ptrnam + 4; - /* FP reg save area locator */ - if ((ppa1flags3 & 0x20) != 0) - ptrnam = ptrnam + 4; - /* reserved */ - if ((ppa1flags3 & 0x10) != 0) - ptrnam = ptrnam + 4; - /* PPA1 member word */ - if ((ppa1flags3 & 0x08) != 0) - ptrnam = ptrnam + 4; - /* block debug info */ - if ((ppa1flags3 & 0x04) != 0) - ptrnam = ptrnam + 4; - /* Interface mapping flags */ - if ((ppa1flags3 & 0x02) != 0) - ptrnam = ptrnam + 4; - /* JAVA method locator table */ - if ((ppa1flags3 & 0x01) != 0) - ptrnam = ptrnam + 8; - /* if no name is present */ - if ((ppa1flags4 & 0x01) == 0) { - function = "(bad ppa1flags4)"; - } else { - function = space.readEbcdicString(ptrnam); - } - } else { - function = "(unknown)"; - } - } - space.getUserMap().put(mapKey, function); - return function; - } + eyecatcher = space.readInt(ep + 4); + if (eyecatcher == 0xc3c5c5 || eyecatcher == 0x1c3c5c5) { + long ppa1 = ep + space.readInt(ep + 12); + int offset = space.readUnsignedByte(ppa1); + if (eyecatcher == 0x1c3c5c5) offset <<= 1; + function = space.readEbcdicString(ppa1 + offset); + } else if ((eyecatcher & 0xff0000) == 0xce0000) { + long ppa1 = ep; + int offset = eyecatcher >>> 24; + function = space.readEbcdicString(ppa1 + offset); + } else if ((space.readInt(ep) & 0xfffff000) == 0x47f0f000) { + int length = space.readUnsignedByte(ep + 4); + function = space.readEbcdicString(ep + 5, length); + for (int i = 0; i < function.length(); i++) { + char c = function.charAt(i); + if (!Character.isLetterOrDigit(c) && !Character.isSpaceChar(c)) { + function = "(unknown)"; + break; + } + } + } else { + long xplhdr = ep - 16; + long ceesig = space.readLong(xplhdr); + if (ceesig == 0x00C300C500C500F1L) { + int ppa1off = space.readInt(xplhdr + 8); + long ptrppa1 = xplhdr + ppa1off; + long ptrnam = ptrppa1 + 0x14; + int ppa1flags3 = space.readUnsignedByte(ptrppa1 + 10); + int ppa1flags4 = space.readUnsignedByte(ptrppa1 + 11); + /* step over all structures in ppa1 to get to name */ + /* state variable locator */ + if ((ppa1flags3 & 0x80) != 0) + ptrnam = ptrnam + 4; + /* Argument Area Length */ + if ((ppa1flags3 & 0x40) != 0) + ptrnam = ptrnam + 4; + /* FP reg save area locator */ + if ((ppa1flags3 & 0x20) != 0) + ptrnam = ptrnam + 4; + /* reserved */ + if ((ppa1flags3 & 0x10) != 0) + ptrnam = ptrnam + 4; + /* PPA1 member word */ + if ((ppa1flags3 & 0x08) != 0) + ptrnam = ptrnam + 4; + /* block debug info */ + if ((ppa1flags3 & 0x04) != 0) + ptrnam = ptrnam + 4; + /* Interface mapping flags */ + if ((ppa1flags3 & 0x02) != 0) + ptrnam = ptrnam + 4; + /* JAVA method locator table */ + if ((ppa1flags3 & 0x01) != 0) + ptrnam = ptrnam + 8; + /* if no name is present */ + if ((ppa1flags4 & 0x01) == 0) { + function = "(bad ppa1flags4)"; + } else { + function = space.readEbcdicString(ptrnam); + } + } else { + function = "(unknown)"; + } + } + space.getUserMap().put(mapKey, function); + return function; + } - private static String hex(long i) { - return Long.toHexString(i); - } + private static String hex(long i) { + return Long.toHexString(i); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Edb.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Edb.java index 806bce20d64..c86d53f5d30 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Edb.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Edb.java @@ -39,130 +39,130 @@ public class Edb { - /** The address of the EDB structure */ - private long address; - /** The AddressSpace we belong to */ - private AddressSpace space; - /** The AddressSpaceImageInputStream */ - private AddressSpaceImageInputStream inputStream; - /** Environment variables for this enclave */ - private Properties envVars; - /** Edb template - size depends on 32/64 bit mode */ - /*static*/ CeexedbTemplate ceexedbTemplate; - /** Logger */ - private static Logger log = Logger.getLogger(Edb.class.getName()); - - /** Constructs a new Edb given the address of the edb structure */ - public Edb(long address, AddressSpace space) { - this.address = address; - this.space = space; - inputStream = space.getImageInputStream(); - /* Create any templates we need if not already created */ - createTemplates(space); - } - - /** - * Create any templates we need if not already created. - */ - /*static*/ void createTemplates(AddressSpace space) { - if (ceexedbTemplate == null) { - if (space.is64bit()) { - ceexedbTemplate = new Ceexedb64Template(); - } else { - ceexedbTemplate = new Ceexedb32Template(); - } - } - } - - /** - * Returns the address of this edb. - */ - public long address() { - return address; - } - - /** - * Returns the ceeosigr address - * @throws IOException if an error occurred reading from the address space - */ - public long ceeedb_ceeosigr() throws IOException { - return ceexedbTemplate.getCeeedb_ceeosigr(inputStream, address); - } - - /** - * Returns the ceeedbdba - * @throws IOException if an error occurred reading from the address space - */ - public long ceeedbdba() throws IOException { - return ceexedbTemplate.getCeeedbdba(inputStream, address); - } - - /** - * Returns a "sample" Edb for the given address space. Note that for certain applications - * (CICS?) there can be more than one Edb per address space. Returns null if there is no Edb. - */ - public static Edb getSampleEdb(AddressSpace space) { - Caa[] caas = Caa.getCaas(space); - /* XXX this needs fixing. The first couple of Caas can point to strange Edbs. - * Don't understand it yet. */ - for (int i = 0; i < caas.length; i++) { - Edb edb = caas[i].getEdb(); - log.fine("found edb " + edb + " for caa " + caas[i]); - try { - if (edb.getFirstDll() != null) { - log.fine("edb has a dll: " + edb.getFirstDll()); - return edb; - } - } catch (IOException e) { - log.fine("caught exception: " + e); - } - } - log.fine("no sample edb found"); - return null; - } - - /** - * Returns the first in the chain of Dlls (or null if there aren't any). - * @throws IOException if an error occurred reading from the address space - */ - public Dll getFirstDll() throws IOException { - long ceeedb_dlcb_first = ceexedbTemplate.getCeeedb_dlcb_first(inputStream, address); - log.fine("ceeedb_dlcb_first = " + hex(ceeedb_dlcb_first)); - return ceeedb_dlcb_first == 0 ? null : new Dll(ceeedb_dlcb_first, space); - } - - /** - * Return a java.util.Properties object containing the environment variables. - */ - public Properties getEnvVars() throws IOException { - if (envVars != null) - return envVars; - envVars = new Properties(); - long ceeedbenvar = ceexedbTemplate.getCeeedbenvar(inputStream, address); - for (long env = 0; (env = space.readWord(ceeedbenvar)) != 0; ceeedbenvar += space.getWordLength()) { - String name = space.readEbcdicCString(env); - int eq = name.indexOf('='); - if (eq > 0) { - String key = name.substring(0, eq); - String value = name.substring(eq + 1); - envVars.put(key, value); - } else { - // no equals sign, so not a complete property pair, just return the key - envVars.put(name, ""); - } - } - return envVars; - } - - private static String hex(long i) { - return Long.toHexString(i); - } - - private static String hex(int i) { - return Integer.toHexString(i); - } - - public String toString() { - return hex(address); - } + /** The address of the EDB structure */ + private long address; + /** The AddressSpace we belong to */ + private AddressSpace space; + /** The AddressSpaceImageInputStream */ + private AddressSpaceImageInputStream inputStream; + /** Environment variables for this enclave */ + private Properties envVars; + /** Edb template - size depends on 32/64 bit mode */ + /*static*/ CeexedbTemplate ceexedbTemplate; + /** Logger */ + private static Logger log = Logger.getLogger(Edb.class.getName()); + + /** Constructs a new Edb given the address of the edb structure */ + public Edb(long address, AddressSpace space) { + this.address = address; + this.space = space; + inputStream = space.getImageInputStream(); + /* Create any templates we need if not already created */ + createTemplates(space); + } + + /** + * Create any templates we need if not already created. + */ + /*static*/ void createTemplates(AddressSpace space) { + if (ceexedbTemplate == null) { + if (space.is64bit()) { + ceexedbTemplate = new Ceexedb64Template(); + } else { + ceexedbTemplate = new Ceexedb32Template(); + } + } + } + + /** + * Returns the address of this edb. + */ + public long address() { + return address; + } + + /** + * Returns the ceeosigr address + * @throws IOException if an error occurred reading from the address space + */ + public long ceeedb_ceeosigr() throws IOException { + return ceexedbTemplate.getCeeedb_ceeosigr(inputStream, address); + } + + /** + * Returns the ceeedbdba + * @throws IOException if an error occurred reading from the address space + */ + public long ceeedbdba() throws IOException { + return ceexedbTemplate.getCeeedbdba(inputStream, address); + } + + /** + * Returns a "sample" Edb for the given address space. Note that for certain applications + * (CICS?) there can be more than one Edb per address space. Returns null if there is no Edb. + */ + public static Edb getSampleEdb(AddressSpace space) { + Caa[] caas = Caa.getCaas(space); + /* XXX this needs fixing. The first couple of Caas can point to strange Edbs. + * Don't understand it yet. */ + for (int i = 0; i < caas.length; i++) { + Edb edb = caas[i].getEdb(); + log.fine("found edb " + edb + " for caa " + caas[i]); + try { + if (edb.getFirstDll() != null) { + log.fine("edb has a dll: " + edb.getFirstDll()); + return edb; + } + } catch (IOException e) { + log.fine("caught exception: " + e); + } + } + log.fine("no sample edb found"); + return null; + } + + /** + * Returns the first in the chain of Dlls (or null if there aren't any). + * @throws IOException if an error occurred reading from the address space + */ + public Dll getFirstDll() throws IOException { + long ceeedb_dlcb_first = ceexedbTemplate.getCeeedb_dlcb_first(inputStream, address); + log.fine("ceeedb_dlcb_first = " + hex(ceeedb_dlcb_first)); + return ceeedb_dlcb_first == 0 ? null : new Dll(ceeedb_dlcb_first, space); + } + + /** + * Return a java.util.Properties object containing the environment variables. + */ + public Properties getEnvVars() throws IOException { + if (envVars != null) + return envVars; + envVars = new Properties(); + long ceeedbenvar = ceexedbTemplate.getCeeedbenvar(inputStream, address); + for (long env = 0; (env = space.readWord(ceeedbenvar)) != 0; ceeedbenvar += space.getWordLength()) { + String name = space.readEbcdicCString(env); + int eq = name.indexOf('='); + if (eq > 0) { + String key = name.substring(0, eq); + String value = name.substring(eq + 1); + envVars.put(key, value); + } else { + // no equals sign, so not a complete property pair, just return the key + envVars.put(name, ""); + } + } + return envVars; + } + + private static String hex(long i) { + return Long.toHexString(i); + } + + private static String hex(int i) { + return Integer.toHexString(i); + } + + public String toString() { + return hex(address); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Function.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Function.java index 429a39fb137..ed97b6d8d3b 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Function.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/Function.java @@ -27,33 +27,33 @@ */ public class Function { - /** The name of the function */ - private String name; + /** The name of the function */ + private String name; - Function(DsaStackFrame dsa) { - name = dsa.getEntryName(); - } + Function(DsaStackFrame dsa) { + name = dsa.getEntryName(); + } - /** - * Returns the name of the function. This does not include the library name. - */ - public String getName() { - return name; - } + /** + * Returns the name of the function. This does not include the library name. + */ + public String getName() { + return name; + } - /** - * Returns the name of the program unit. This represents for instance the name of the C - * file in which this function resides. - */ - public String getProgramUnit() { - throw new Error("tbc"); - } + /** + * Returns the name of the program unit. This represents for instance the name of the C + * file in which this function resides. + */ + public String getProgramUnit() { + throw new Error("tbc"); + } - /** - * Returns the address of the entry point. The entry point of a function is where - * the executable code begins. - */ - public long getEntryPoint() { - throw new Error("tbc"); - } + /** + * Returns the address of the entry point. The entry point of a function is where + * the executable code begins. + */ + public long getEntryPoint() { + throw new Error("tbc"); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/SmcbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/SmcbTemplate.java index f10844bb43f..59d2053f472 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/SmcbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/le/SmcbTemplate.java @@ -29,18 +29,20 @@ public final class SmcbTemplate { - public static int length() { - return 564; - } + public static int length() { + return 564; + } - public static long getSmcb_dsbos(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 364); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getSmcb_dsbos$offset() { - return 364; - } - public static int getSmcb_dsbos$length() { - return 32; - } + public static long getSmcb_dsbos(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 364); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getSmcb_dsbos$offset() { + return 364; + } + + public static int getSmcb_dsbos$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/BpxzotcbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/BpxzotcbTemplate.java index 391f3eb55fb..d6f57befae0 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/BpxzotcbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/BpxzotcbTemplate.java @@ -29,32 +29,37 @@ public final class BpxzotcbTemplate { - public static int length() { - return 352; - } - - public static long getOtcbptregsinusta(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 30); - inputStream.setBitOffset(1); - long result = inputStream.readBits(1); - result <<= 63; - result >>= 63; - return result; - } - public static int getOtcbptregsinusta$offset() { - return 30; - } - public static int getOtcbptregsinusta$length() { - return 1; - } - public static long getOtcbcofptr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 56); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getOtcbcofptr$offset() { - return 56; - } - public static int getOtcbcofptr$length() { - return 32; - } + public static int length() { + return 352; + } + + public static long getOtcbptregsinusta(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 30); + inputStream.setBitOffset(1); + long result = inputStream.readBits(1); + result <<= 63; + result >>= 63; + return result; + } + + public static int getOtcbptregsinusta$offset() { + return 30; + } + + public static int getOtcbptregsinusta$length() { + return 1; + } + + public static long getOtcbcofptr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 56); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getOtcbcofptr$offset() { + return 56; + } + + public static int getOtcbcofptr$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/BpxzustaTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/BpxzustaTemplate.java index ad1ad5df2b8..8a131a953f5 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/BpxzustaTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/BpxzustaTemplate.java @@ -29,28 +29,33 @@ public final class BpxzustaTemplate { - public static int length() { - return 256; - } - - public static long getUstapswg(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - throw new Error("request for long value for field ustapswg which has length of 16"); - } - public static int getUstapswg$offset() { - return 16; - } - public static int getUstapswg$length() { - return 128; - } - public static long getUstagrs(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 32); - throw new Error("request for long value for field ustagrs which has length of 64"); - } - public static int getUstagrs$offset() { - return 32; - } - public static int getUstagrs$length() { - return 512; - } + public static int length() { + return 256; + } + + public static long getUstapswg(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + throw new Error("request for long value for field ustapswg which has length of 16"); + } + + public static int getUstapswg$offset() { + return 16; + } + + public static int getUstapswg$length() { + return 128; + } + + public static long getUstagrs(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 32); + throw new Error("request for long value for field ustagrs which has length of 64"); + } + + public static int getUstagrs$offset() { + return 32; + } + + public static int getUstagrs$length() { + return 512; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/CeexcvtTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/CeexcvtTemplate.java index 9edaada4b8f..a58e644dedf 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/CeexcvtTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/CeexcvtTemplate.java @@ -29,18 +29,20 @@ public final class CeexcvtTemplate { - public static int length() { - return 1270; - } + public static int length() { + return 1270; + } - public static long getCvtoslv3(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 1267); - return inputStream.readByte(); - } - public static int getCvtoslv3$offset() { - return 1267; - } - public static int getCvtoslv3$length() { - return 8; - } + public static long getCvtoslv3(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 1267); + return inputStream.readByte(); + } + + public static int getCvtoslv3$offset() { + return 1267; + } + + public static int getCvtoslv3$length() { + return 8; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhaascbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhaascbTemplate.java index 36d9e7aa202..0bb47caa07a 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhaascbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhaascbTemplate.java @@ -29,18 +29,20 @@ public final class IhaascbTemplate { - public static int length() { - return 384; - } + public static int length() { + return 384; + } - public static long getAscbasxb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 108); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getAscbasxb$offset() { - return 108; - } - public static int getAscbasxb$length() { - return 32; - } + public static long getAscbasxb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 108); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getAscbasxb$offset() { + return 108; + } + + public static int getAscbasxb$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhaasxbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhaasxbTemplate.java index c601176ad5f..636ec0f7bb3 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhaasxbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhaasxbTemplate.java @@ -29,28 +29,33 @@ public final class IhaasxbTemplate { - public static int length() { - return 264; - } - - public static long getAsxbftcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getAsxbftcb$offset() { - return 4; - } - public static int getAsxbftcb$length() { - return 32; - } - public static long getAsxbltcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 8); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getAsxbltcb$offset() { - return 8; - } - public static int getAsxbltcb$length() { - return 32; - } + public static int length() { + return 264; + } + + public static long getAsxbftcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getAsxbftcb$offset() { + return 4; + } + + public static int getAsxbftcb$length() { + return 32; + } + + public static long getAsxbltcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 8); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getAsxbltcb$offset() { + return 8; + } + + public static int getAsxbltcb$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhapsaTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhapsaTemplate.java index 6d59cc7614f..8bfe07b1adf 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhapsaTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhapsaTemplate.java @@ -29,28 +29,33 @@ public final class IhapsaTemplate { - public static int length() { - return 4096; - } - - public static long getFlccvt(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getFlccvt$offset() { - return 16; - } - public static int getFlccvt$length() { - return 32; - } - public static long getPsaaold(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 548); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getPsaaold$offset() { - return 548; - } - public static int getPsaaold$length() { - return 32; - } + public static int length() { + return 4096; + } + + public static long getFlccvt(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getFlccvt$offset() { + return 16; + } + + public static int getFlccvt$length() { + return 32; + } + + public static long getPsaaold(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 548); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getPsaaold$offset() { + return 548; + } + + public static int getPsaaold$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IharbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IharbTemplate.java index a3cab9b4acf..833be2360ed 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IharbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IharbTemplate.java @@ -29,39 +29,47 @@ public final class IharbTemplate { - public static int length() { - return 176; - } + public static int length() { + return 176; + } - public static long getRbopsw(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 16); - return inputStream.readLong(); - } - public static int getRbopsw$offset() { - return 16; - } - public static int getRbopsw$length() { - return 64; - } - public static long getRblinkXrblnkRblinkb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 29); - long result = inputStream.readBits(24); - return result; - } - public static int getRblinkXrblnkRblinkb$offset() { - return 29; - } - public static int getRblinkXrblnkRblinkb$length() { - return 24; - } - public static long getRbgrsave(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 32); - throw new Error("request for long value for field rbgrsave which has length of 64"); - } - public static int getRbgrsave$offset() { - return 32; - } - public static int getRbgrsave$length() { - return 512; - } + public static long getRbopsw(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 16); + return inputStream.readLong(); + } + + public static int getRbopsw$offset() { + return 16; + } + + public static int getRbopsw$length() { + return 64; + } + + public static long getRblinkXrblnkRblinkb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 29); + long result = inputStream.readBits(24); + return result; + } + + public static int getRblinkXrblnkRblinkb$offset() { + return 29; + } + + public static int getRblinkXrblnkRblinkb$length() { + return 24; + } + + public static long getRbgrsave(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 32); + throw new Error("request for long value for field rbgrsave which has length of 64"); + } + + public static int getRbgrsave$offset() { + return 32; + } + + public static int getRbgrsave$length() { + return 512; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Ihartm2aTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Ihartm2aTemplate.java index a358df412b8..60d48726d5a 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Ihartm2aTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Ihartm2aTemplate.java @@ -29,28 +29,33 @@ public final class Ihartm2aTemplate { - public static int length() { - return 1744; - } - - public static long getRtm2ereg(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 60); - throw new Error("request for long value for field rtm2ereg which has length of 64"); - } - public static int getRtm2ereg$offset() { - return 60; - } - public static int getRtm2ereg$length() { - return 512; - } - public static long getRtm2apsw(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 124); - throw new Error("request for long value for field rtm2apsw which has length of 16"); - } - public static int getRtm2apsw$offset() { - return 124; - } - public static int getRtm2apsw$length() { - return 128; - } + public static int length() { + return 1744; + } + + public static long getRtm2ereg(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 60); + throw new Error("request for long value for field rtm2ereg which has length of 64"); + } + + public static int getRtm2ereg$offset() { + return 60; + } + + public static int getRtm2ereg$length() { + return 512; + } + + public static long getRtm2apsw(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 124); + throw new Error("request for long value for field rtm2apsw which has length of 16"); + } + + public static int getRtm2apsw$offset() { + return 124; + } + + public static int getRtm2apsw$length() { + return 128; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhastcbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhastcbTemplate.java index 548f9e82d19..c91b8b8890d 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhastcbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IhastcbTemplate.java @@ -29,58 +29,72 @@ public final class IhastcbTemplate { - public static int length() { - return 1048; - } - - public static long getStcblsdp(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 116); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getStcblsdp$offset() { - return 116; - } - public static int getStcblsdp$length() { - return 32; - } - public static long getStcbestk(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 128); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getStcbestk$offset() { - return 128; - } - public static int getStcbestk$length() { - return 32; - } - public static long getStcbotcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 216); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getStcbotcb$offset() { - return 216; - } - public static int getStcbotcb$length() { - return 32; - } - public static long getStcbg64h(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 416); - throw new Error("request for long value for field stcbg64h which has length of 64"); - } - public static int getStcbg64h$offset() { - return 416; - } - public static int getStcbg64h$length() { - return 512; - } - public static long getStcblaa(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 516); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getStcblaa$offset() { - return 516; - } - public static int getStcblaa$length() { - return 32; - } + public static int length() { + return 1048; + } + + public static long getStcblsdp(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 116); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getStcblsdp$offset() { + return 116; + } + + public static int getStcblsdp$length() { + return 32; + } + + public static long getStcbestk(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 128); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getStcbestk$offset() { + return 128; + } + + public static int getStcbestk$length() { + return 32; + } + + public static long getStcbotcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 216); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getStcbotcb$offset() { + return 216; + } + + public static int getStcbotcb$length() { + return 32; + } + + public static long getStcbg64h(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 416); + throw new Error("request for long value for field stcbg64h which has length of 64"); + } + + public static int getStcbg64h$offset() { + return 416; + } + + public static int getStcbg64h$length() { + return 512; + } + + public static long getStcblaa(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 516); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getStcblaa$offset() { + return 516; + } + + public static int getStcblaa$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IkjrbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IkjrbTemplate.java index a7356fd1eec..71b1bce20ce 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IkjrbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IkjrbTemplate.java @@ -29,22 +29,24 @@ public final class IkjrbTemplate { - public static int length() { - return 208; - } + public static int length() { + return 208; + } - public static long getRbftp(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 10); - inputStream.setBitOffset(0); - long result = inputStream.readBits(3); - result <<= 61; - result >>= 61; - return result; - } - public static int getRbftp$offset() { - return 10; - } - public static int getRbftp$length() { - return 3; - } + public static long getRbftp(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 10); + inputStream.setBitOffset(0); + long result = inputStream.readBits(3); + result <<= 61; + result >>= 61; + return result; + } + + public static int getRbftp$offset() { + return 10; + } + + public static int getRbftp$length() { + return 3; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IkjtcbTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IkjtcbTemplate.java index 7d2a66cb1df..30fdfb00824 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IkjtcbTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/IkjtcbTemplate.java @@ -29,68 +29,85 @@ public final class IkjtcbTemplate { - public static int length() { - return 344; - } - - public static long getTcbrbp(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getTcbrbp$offset() { - return 0; - } - public static int getTcbrbp$length() { - return 32; - } - public static long getTcbgrs(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 48); - throw new Error("request for long value for field tcbgrs which has length of 64"); - } - public static int getTcbgrs$offset() { - return 48; - } - public static int getTcbgrs$length() { - return 512; - } - public static long getTcbtcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 116); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getTcbtcb$offset() { - return 116; - } - public static int getTcbtcb$length() { - return 32; - } - public static long getTcbrtwa(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 224); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getTcbrtwa$offset() { - return 224; - } - public static int getTcbrtwa$length() { - return 32; - } - public static long getTcbstcb(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 312); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getTcbstcb$offset() { - return 312; - } - public static int getTcbstcb$length() { - return 32; - } - public static long getTcbcelap(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 324); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getTcbcelap$offset() { - return 324; - } - public static int getTcbcelap$length() { - return 32; - } + public static int length() { + return 344; + } + + public static long getTcbrbp(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getTcbrbp$offset() { + return 0; + } + + public static int getTcbrbp$length() { + return 32; + } + + public static long getTcbgrs(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 48); + throw new Error("request for long value for field tcbgrs which has length of 64"); + } + + public static int getTcbgrs$offset() { + return 48; + } + + public static int getTcbgrs$length() { + return 512; + } + + public static long getTcbtcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 116); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getTcbtcb$offset() { + return 116; + } + + public static int getTcbtcb$length() { + return 32; + } + + public static long getTcbrtwa(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 224); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getTcbrtwa$offset() { + return 224; + } + + public static int getTcbrtwa$length() { + return 32; + } + + public static long getTcbstcb(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 312); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getTcbstcb$offset() { + return 312; + } + + public static int getTcbstcb$length() { + return 32; + } + + public static long getTcbcelap(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 324); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getTcbcelap$offset() { + return 324; + } + + public static int getTcbcelap$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lse.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lse.java index 8c91e94a716..67b1e4975ef 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lse.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lse.java @@ -36,108 +36,108 @@ public class Lse { - /** The AddressSpace we belong to */ - private AddressSpace space; - /** The AddressSpace ImageInputStream */ - private AddressSpaceImageInputStream inputStream; - /** The address of our lse structure */ - private long address; - private long lsesptr; - /** PC STATE entry type */ - public static final int LSEDPC = 5; - /** PC STATE entry type */ - public static final int LSED1PC = 13; - /** BAKR STATE entry type */ - public static final int LSED1BAKR = 12; - - /** - * Create a new Linkage Stack Entry - */ - public Lse(AddressSpace space, long address) { - this.space = space; - inputStream = space.getImageInputStream(); - this.address = address; - lsesptr = address + LseslsedTemplate.length(); - } - - /** - * Returns the address of this Lse - */ - public long address() { - return address; - } - - /** - * Returns the entry type - */ - public int lsestyp7() throws IOException { - return (int)LseslsedTemplate.getLsestyp7(inputStream, lsesptr + LsestateTemplate.getLses_ed$offset()); - } - - /** - * Returns the entry type - */ - public int lses1typ7() throws IOException { - return (int)Lses1lsed1Template.getLses1typ7(inputStream, lsesptr + Lsestate1Template.getLses1_ed1$offset()); - } - - /** - * Returns the target routine indication - */ - public long lsestarg() throws IOException { - return LsestateTemplate.getLsestarg(inputStream, lsesptr); - } - - /** - * Returns the psw - */ - public long lsespsw() throws IOException { - return LsestateTemplate.getLsespsw(inputStream, lsesptr); - } - - /** - * Returns the psw - */ - public long lses1pswh() throws IOException { - return Lsestate1Template.getLses1pswh(inputStream, lsesptr); - } - - /** - * Returns the given GPR - * @param gpr the index of the GPR to return. Must be in the range 0-15. - */ - public long lsesgrs(int gpr) throws IOException { - if (gpr < 0 || gpr > 15) - throw new IndexOutOfBoundsException("gpr out of range 0-15: " + gpr); - return space.readLong(lsesptr + LsestateTemplate.getLsesgrs$offset() + gpr*4); - } - - /** - * Returns the given GPR - * @param gpr the index of the GPR to return. Must be in the range 0-15. - */ - public long lses1grs(int gpr) throws IOException { - if (gpr < 0 || gpr > 15) - throw new IndexOutOfBoundsException("gpr out of range 0-15: " + gpr); - return space.readLong(lsesptr + Lsestate1Template.getLses1grs$offset() + gpr*8); - } - - /** - * Returns the pasn of the calling program - */ - public int lses1pasn() throws IOException { - return (int)Lsestate1Template.getLses1pasn(inputStream, lsesptr); - } - - /** - * Returns true if this is Z/Architecture (ie the variant with all the 1's) - */ - public boolean isZArchitecture() throws IOException { - long entrysize = LsedTemplate.getLsednes(inputStream, address); - return entrysize == Lsestate1Template.length(); - } - - private static String hex(long n) { - return Long.toHexString(n); - } + /** The AddressSpace we belong to */ + private AddressSpace space; + /** The AddressSpace ImageInputStream */ + private AddressSpaceImageInputStream inputStream; + /** The address of our lse structure */ + private long address; + private long lsesptr; + /** PC STATE entry type */ + public static final int LSEDPC = 5; + /** PC STATE entry type */ + public static final int LSED1PC = 13; + /** BAKR STATE entry type */ + public static final int LSED1BAKR = 12; + + /** + * Create a new Linkage Stack Entry + */ + public Lse(AddressSpace space, long address) { + this.space = space; + inputStream = space.getImageInputStream(); + this.address = address; + lsesptr = address + LseslsedTemplate.length(); + } + + /** + * Returns the address of this Lse + */ + public long address() { + return address; + } + + /** + * Returns the entry type + */ + public int lsestyp7() throws IOException { + return (int)LseslsedTemplate.getLsestyp7(inputStream, lsesptr + LsestateTemplate.getLses_ed$offset()); + } + + /** + * Returns the entry type + */ + public int lses1typ7() throws IOException { + return (int)Lses1lsed1Template.getLses1typ7(inputStream, lsesptr + Lsestate1Template.getLses1_ed1$offset()); + } + + /** + * Returns the target routine indication + */ + public long lsestarg() throws IOException { + return LsestateTemplate.getLsestarg(inputStream, lsesptr); + } + + /** + * Returns the psw + */ + public long lsespsw() throws IOException { + return LsestateTemplate.getLsespsw(inputStream, lsesptr); + } + + /** + * Returns the psw + */ + public long lses1pswh() throws IOException { + return Lsestate1Template.getLses1pswh(inputStream, lsesptr); + } + + /** + * Returns the given GPR + * @param gpr the index of the GPR to return. Must be in the range 0-15. + */ + public long lsesgrs(int gpr) throws IOException { + if (gpr < 0 || gpr > 15) + throw new IndexOutOfBoundsException("gpr out of range 0-15: " + gpr); + return space.readLong(lsesptr + LsestateTemplate.getLsesgrs$offset() + gpr*4); + } + + /** + * Returns the given GPR + * @param gpr the index of the GPR to return. Must be in the range 0-15. + */ + public long lses1grs(int gpr) throws IOException { + if (gpr < 0 || gpr > 15) + throw new IndexOutOfBoundsException("gpr out of range 0-15: " + gpr); + return space.readLong(lsesptr + Lsestate1Template.getLses1grs$offset() + gpr*8); + } + + /** + * Returns the pasn of the calling program + */ + public int lses1pasn() throws IOException { + return (int)Lsestate1Template.getLses1pasn(inputStream, lsesptr); + } + + /** + * Returns true if this is Z/Architecture (ie the variant with all the 1's) + */ + public boolean isZArchitecture() throws IOException { + long entrysize = LsedTemplate.getLsednes(inputStream, address); + return entrysize == Lsestate1Template.length(); + } + + private static String hex(long n) { + return Long.toHexString(n); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LsedTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LsedTemplate.java index 0c94231ef77..1f22e190052 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LsedTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LsedTemplate.java @@ -29,21 +29,23 @@ public final class LsedTemplate { - public static int length() { - return 8; - } + public static int length() { + return 8; + } - public static long getLsednes(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - long result = inputStream.readBits(16); - result <<= 48; - result >>= 48; - return result; - } - public static int getLsednes$offset() { - return 4; - } - public static int getLsednes$length() { - return 16; - } + public static long getLsednes(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + long result = inputStream.readBits(16); + result <<= 48; + result >>= 48; + return result; + } + + public static int getLsednes$offset() { + return 4; + } + + public static int getLsednes$length() { + return 16; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lses1lsed1Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lses1lsed1Template.java index e525da0d23b..f76d053cc8b 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lses1lsed1Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lses1lsed1Template.java @@ -29,22 +29,24 @@ public final class Lses1lsed1Template { - public static int length() { - return 8; - } + public static int length() { + return 8; + } - public static long getLses1typ7(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - inputStream.setBitOffset(2); - long result = inputStream.readBits(6); - result <<= 58; - result >>= 58; - return result; - } - public static int getLses1typ7$offset() { - return 0; - } - public static int getLses1typ7$length() { - return 6; - } + public static long getLses1typ7(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + inputStream.setBitOffset(2); + long result = inputStream.readBits(6); + result <<= 58; + result >>= 58; + return result; + } + + public static int getLses1typ7$offset() { + return 0; + } + + public static int getLses1typ7$length() { + return 6; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LseslsedTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LseslsedTemplate.java index 6d3c1877f11..cc2c18d0867 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LseslsedTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LseslsedTemplate.java @@ -29,22 +29,24 @@ public final class LseslsedTemplate { - public static int length() { - return 8; - } + public static int length() { + return 8; + } - public static long getLsestyp7(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - inputStream.setBitOffset(2); - long result = inputStream.readBits(6); - result <<= 58; - result >>= 58; - return result; - } - public static int getLsestyp7$offset() { - return 0; - } - public static int getLsestyp7$length() { - return 6; - } + public static long getLsestyp7(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + inputStream.setBitOffset(2); + long result = inputStream.readBits(6); + result <<= 58; + result >>= 58; + return result; + } + + public static int getLsestyp7$offset() { + return 0; + } + + public static int getLsestyp7$length() { + return 6; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lsestate1Template.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lsestate1Template.java index 4adbff65d73..24e4452b25e 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lsestate1Template.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Lsestate1Template.java @@ -29,51 +29,62 @@ public final class Lsestate1Template { - public static int length() { - return 296; - } - - public static long getLses1grs(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - throw new Error("request for long value for field lses1grs which has length of 128"); - } - public static int getLses1grs$offset() { - return 0; - } - public static int getLses1grs$length() { - return 1024; - } - public static long getLses1pasn(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 134); - long result = inputStream.readBits(16); - result <<= 48; - result >>= 48; - return result; - } - public static int getLses1pasn$offset() { - return 134; - } - public static int getLses1pasn$length() { - return 16; - } - public static long getLses1pswh(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 136); - return inputStream.readLong(); - } - public static int getLses1pswh$offset() { - return 136; - } - public static int getLses1pswh$length() { - return 64; - } - public static long getLses1_ed1(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 288); - return inputStream.readLong(); - } - public static int getLses1_ed1$offset() { - return 288; - } - public static int getLses1_ed1$length() { - return 64; - } + public static int length() { + return 296; + } + + public static long getLses1grs(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + throw new Error("request for long value for field lses1grs which has length of 128"); + } + + public static int getLses1grs$offset() { + return 0; + } + + public static int getLses1grs$length() { + return 1024; + } + + public static long getLses1pasn(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 134); + long result = inputStream.readBits(16); + result <<= 48; + result >>= 48; + return result; + } + + public static int getLses1pasn$offset() { + return 134; + } + + public static int getLses1pasn$length() { + return 16; + } + + public static long getLses1pswh(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 136); + return inputStream.readLong(); + } + + public static int getLses1pswh$offset() { + return 136; + } + + public static int getLses1pswh$length() { + return 64; + } + + public static long getLses1_ed1(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 288); + return inputStream.readLong(); + } + + public static int getLses1_ed1$offset() { + return 288; + } + + public static int getLses1_ed1$length() { + return 64; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LsestateTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LsestateTemplate.java index 22dcd032c68..97656d2ca0d 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LsestateTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/LsestateTemplate.java @@ -29,48 +29,59 @@ public final class LsestateTemplate { - public static int length() { - return 168; - } - - public static long getLsesgrs(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 0); - throw new Error("request for long value for field lsesgrs which has length of 64"); - } - public static int getLsesgrs$offset() { - return 0; - } - public static int getLsesgrs$length() { - return 512; - } - public static long getLsespsw(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 136); - return inputStream.readLong(); - } - public static int getLsespsw$offset() { - return 136; - } - public static int getLsespsw$length() { - return 64; - } - public static long getLsestarg(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 148); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getLsestarg$offset() { - return 148; - } - public static int getLsestarg$length() { - return 32; - } - public static long getLses_ed(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 160); - return inputStream.readLong(); - } - public static int getLses_ed$offset() { - return 160; - } - public static int getLses_ed$length() { - return 64; - } + public static int length() { + return 168; + } + + public static long getLsesgrs(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 0); + throw new Error("request for long value for field lsesgrs which has length of 64"); + } + + public static int getLsesgrs$offset() { + return 0; + } + + public static int getLsesgrs$length() { + return 512; + } + + public static long getLsespsw(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 136); + return inputStream.readLong(); + } + + public static int getLsespsw$offset() { + return 136; + } + + public static int getLsespsw$length() { + return 64; + } + + public static long getLsestarg(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 148); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getLsestarg$offset() { + return 148; + } + + public static int getLsestarg$length() { + return 32; + } + + public static long getLses_ed(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 160); + return inputStream.readLong(); + } + + public static int getLses_ed$offset() { + return 160; + } + + public static int getLses_ed$length() { + return 64; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/OtcbcopyonforkTemplate.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/OtcbcopyonforkTemplate.java index d3e62fb4b2d..5bf315201c1 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/OtcbcopyonforkTemplate.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/OtcbcopyonforkTemplate.java @@ -29,18 +29,20 @@ public final class OtcbcopyonforkTemplate { - public static int length() { - return 168; - } + public static int length() { + return 168; + } - public static long getOtcbustaptr(ImageInputStream inputStream, long address) throws IOException { - inputStream.seek(address + 4); - return inputStream.readUnsignedInt() & 0xffffffffL; - } - public static int getOtcbustaptr$offset() { - return 4; - } - public static int getOtcbustaptr$length() { - return 32; - } + public static long getOtcbustaptr(ImageInputStream inputStream, long address) throws IOException { + inputStream.seek(address + 4); + return inputStream.readUnsignedInt() & 0xffffffffL; + } + + public static int getOtcbustaptr$offset() { + return 4; + } + + public static int getOtcbustaptr$length() { + return 32; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/RegisterSet.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/RegisterSet.java index 4245842f34b..cba294bcb1e 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/RegisterSet.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/RegisterSet.java @@ -29,32 +29,32 @@ */ public class RegisterSet { - long[] registers = new long[16]; - long psw; - String whereFound; - /** Logger */ - private static Logger log = Logger.getLogger(RegisterSet.class.getName()); + long[] registers = new long[16]; + long psw; + String whereFound; + /** Logger */ + private static Logger log = Logger.getLogger(RegisterSet.class.getName()); - /** - * Return an array of the register values. XXX I haven't considered 64-bit machines - * yet - do they use the same number of registers? The values contain what you'd expect, - * eg getRegisters()[0] contains GPR0 and so on. - */ - public long[] getRegisters() { - throw new Error("tbc"); - } + /** + * Return an array of the register values. XXX I haven't considered 64-bit machines + * yet - do they use the same number of registers? The values contain what you'd expect, + * eg getRegisters()[0] contains GPR0 and so on. + */ + public long[] getRegisters() { + throw new Error("tbc"); + } - /** - * Get the value of the specified register. - */ - public long getRegister(int index) { - return registers[index]; - } + /** + * Get the value of the specified register. + */ + public long getRegister(int index) { + return registers[index]; + } - /** - * Get the value of the specified register for use as an address. - */ - public long getRegisterAsAddress(int index) { + /** + * Get the value of the specified register for use as an address. + */ + public long getRegisterAsAddress(int index) { int addressMode = (int)(this.getPSW() >>> 31) & 3; switch (addressMode) { case 0: @@ -66,54 +66,54 @@ public long getRegisterAsAddress(int index) { case 3: } return registers[index]; - } + } - /** - * Sets the specified register. - * @param index the register whose value is to be set - * @param value the value to set it to - */ - public void setRegister(int index, long value) { - registers[index] = value; - log.fine("set register " + index + " to 0x" + hex(value)); - } + /** + * Sets the specified register. + * @param index the register whose value is to be set + * @param value the value to set it to + */ + public void setRegister(int index, long value) { + registers[index] = value; + log.fine("set register " + index + " to 0x" + hex(value)); + } - /** - * Returns the PSW. XXX How big is the PSW on a 64-bit machine? - */ - public long getPSW() { - assert psw != 0; - return psw; - } + /** + * Returns the PSW. XXX How big is the PSW on a 64-bit machine? + */ + public long getPSW() { + assert psw != 0; + return psw; + } - /** - * Sets the PSW. - */ - public void setPSW(long psw) { - this.psw = psw; - log.fine("set psw to 0x" + hex(psw)); - } + /** + * Sets the PSW. + */ + public void setPSW(long psw) { + this.psw = psw; + log.fine("set psw to 0x" + hex(psw)); + } - /** - * Sets the whereFound string. - */ - public void setWhereFound(String whereFound) { - this.whereFound = whereFound; - } + /** + * Sets the whereFound string. + */ + public void setWhereFound(String whereFound) { + this.whereFound = whereFound; + } - /** - * Returns a string indicating where the registers were found. This is mainly for - * debugging purposes. - */ - public String whereFound() { - return whereFound; - } + /** + * Returns a string indicating where the registers were found. This is mainly for + * debugging purposes. + */ + public String whereFound() { + return whereFound; + } - private static String hex(int i) { - return Integer.toHexString(i); - } + private static String hex(int i) { + return Integer.toHexString(i); + } - private static String hex(long i) { - return Long.toHexString(i); - } + private static String hex(long i) { + return Long.toHexString(i); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Tcb.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Tcb.java index cb53ff067cc..505fb4c5375 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Tcb.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/mvs/Tcb.java @@ -41,365 +41,365 @@ public class Tcb { - /** The AddressSpace we belong to */ - private AddressSpace space; - /** The AddressSpace ImageInputStream */ - private AddressSpaceImageInputStream inputStream; - /** The address of our tcb structure */ - private long address; - /** The Linkage Stack */ - private Lse[] linkageStack; - /** Map AddressSpace to its array of Tcbs */ - private static Hashtable tcbMap = new Hashtable(); - /** PRB */ - private static final int RBFTPRB = 0; - private static final int FastPathPCLow = 0x1307; - private static final int OmvsPcLow = 0x1300; - /** Logger */ - private static Logger log = Logger.getLogger(Tcb.class.getName()); + /** The AddressSpace we belong to */ + private AddressSpace space; + /** The AddressSpace ImageInputStream */ + private AddressSpaceImageInputStream inputStream; + /** The address of our tcb structure */ + private long address; + /** The Linkage Stack */ + private Lse[] linkageStack; + /** Map AddressSpace to its array of Tcbs */ + private static Hashtable tcbMap = new Hashtable(); + /** PRB */ + private static final int RBFTPRB = 0; + private static final int FastPathPCLow = 0x1307; + private static final int OmvsPcLow = 0x1300; + /** Logger */ + private static Logger log = Logger.getLogger(Tcb.class.getName()); - /** - * Returns an array containing all of the Tcbs in the given - * {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressSpace}. Returns null if - * this address space contains no Tcbs. - */ - public static Tcb[] getTcbs(AddressSpace space) { - if (space == null) { - return null; - } - AddressSpaceImageInputStream inputStream = space.getImageInputStream(); - if (space.getRootAddressSpace() == null) { - return null; - } - AddressSpaceImageInputStream rootInputStream = space.getRootAddressSpace().getImageInputStream(); - Tcb[] tcbs = (Tcb[])tcbMap.get(space); - if (tcbs != null) { - return tcbs; - } - log.fine("creating Tcb array for asid " + space); - Vector v = new Vector(); - try { - /* - * We go from the PSA to the ASCB and then the ASXB which contains pointers - * to the first and last TCBs - */ - long psaaold = IhapsaTemplate.getPsaaold(rootInputStream, 0); - if (psaaold == 0) { - log.fine("psaaold is zero so no tcbs in asid " + space); - return null; - } - long ascbasxb = IhaascbTemplate.getAscbasxb(rootInputStream, psaaold); - long asxbftcb = IhaasxbTemplate.getAsxbftcb(inputStream, ascbasxb); - long asxbltcb = IhaasxbTemplate.getAsxbltcb(inputStream, ascbasxb); - if (asxbftcb == asxbltcb) { - log.fine("first and last tcb pointers are equal so no tcbs in asid " + space); - return null; - } - /* Now follow the TCB chain creating objects for each */ - for (Tcb tcb = new Tcb(space, asxbftcb); ; tcb = new Tcb(space, tcb.tcbtcb())) { - v.add(tcb); - if (tcb.address() == asxbltcb) - break; - } - } catch (Exception e) { - if (log.isLoggable(Level.FINER)) - e.printStackTrace(); - log.fine("exception: " + e); - return null; - } - /* Add the array of TCBs to the map */ - tcbs = (Tcb[])v.toArray(new Tcb[0]); - tcbMap.put(space, tcbs); + /** + * Returns an array containing all of the Tcbs in the given + * {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressSpace}. Returns null if + * this address space contains no Tcbs. + */ + public static Tcb[] getTcbs(AddressSpace space) { + if (space == null) { + return null; + } + AddressSpaceImageInputStream inputStream = space.getImageInputStream(); + if (space.getRootAddressSpace() == null) { + return null; + } + AddressSpaceImageInputStream rootInputStream = space.getRootAddressSpace().getImageInputStream(); + Tcb[] tcbs = (Tcb[])tcbMap.get(space); + if (tcbs != null) { + return tcbs; + } + log.fine("creating Tcb array for asid " + space); + Vector v = new Vector(); + try { + /* + * We go from the PSA to the ASCB and then the ASXB which contains pointers + * to the first and last TCBs + */ + long psaaold = IhapsaTemplate.getPsaaold(rootInputStream, 0); + if (psaaold == 0) { + log.fine("psaaold is zero so no tcbs in asid " + space); + return null; + } + long ascbasxb = IhaascbTemplate.getAscbasxb(rootInputStream, psaaold); + long asxbftcb = IhaasxbTemplate.getAsxbftcb(inputStream, ascbasxb); + long asxbltcb = IhaasxbTemplate.getAsxbltcb(inputStream, ascbasxb); + if (asxbftcb == asxbltcb) { + log.fine("first and last tcb pointers are equal so no tcbs in asid " + space); + return null; + } + /* Now follow the TCB chain creating objects for each */ + for (Tcb tcb = new Tcb(space, asxbftcb); ; tcb = new Tcb(space, tcb.tcbtcb())) { + v.add(tcb); + if (tcb.address() == asxbltcb) + break; + } + } catch (Exception e) { + if (log.isLoggable(Level.FINER)) + e.printStackTrace(); + log.fine("exception: " + e); + return null; + } + /* Add the array of TCBs to the map */ + tcbs = (Tcb[])v.toArray(new Tcb[0]); + tcbMap.put(space, tcbs); - return tcbs; - } + return tcbs; + } - /** - * Returns the address of this Tcb - */ - public long address() { - return address; - } + /** + * Returns the address of this Tcb + */ + public long address() { + return address; + } - /** - * Returns the AddressSpace we belong to - */ - public AddressSpace space() { - return space; - } + /** + * Returns the AddressSpace we belong to + */ + public AddressSpace space() { + return space; + } - /** - * Create a new Tcb for the given address space. - * @param space the {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressSpace} to which this Tcb belongs - * @param address the address of this Tcb - */ - public Tcb(AddressSpace space, long address) { - log.fine("creating Tcb at address " + hex(address)); - this.space = space; - this.address = address; - inputStream = space.getImageInputStream(); - } + /** + * Create a new Tcb for the given address space. + * @param space the {@link com.ibm.dtfj.corereaders.zos.dumpreader.AddressSpace} to which this Tcb belongs + * @param address the address of this Tcb + */ + public Tcb(AddressSpace space, long address) { + log.fine("creating Tcb at address " + hex(address)); + this.space = space; + this.address = address; + inputStream = space.getImageInputStream(); + } - /** - * Return the celap pointer for this Tcb. - * @throws IOException if an error occurred reading from the address space - */ - public long tcbcelap() throws IOException { - return IkjtcbTemplate.getTcbcelap(inputStream, address); - } + /** + * Return the celap pointer for this Tcb. + * @throws IOException if an error occurred reading from the address space + */ + public long tcbcelap() throws IOException { + return IkjtcbTemplate.getTcbcelap(inputStream, address); + } - /** - * Return the rtwa pointer for this Tcb. - * @throws IOException if an error occurred reading from the address space - */ - public long tcbrtwa() throws IOException { - return IkjtcbTemplate.getTcbrtwa(inputStream, address); - } + /** + * Return the rtwa pointer for this Tcb. + * @throws IOException if an error occurred reading from the address space + */ + public long tcbrtwa() throws IOException { + return IkjtcbTemplate.getTcbrtwa(inputStream, address); + } - /** - * Return the rbp pointer for this Tcb. - * @throws IOException if an error occurred reading from the address space - */ - public long tcbrbp() throws IOException { - return IkjtcbTemplate.getTcbrbp(inputStream, address); - } + /** + * Return the rbp pointer for this Tcb. + * @throws IOException if an error occurred reading from the address space + */ + public long tcbrbp() throws IOException { + return IkjtcbTemplate.getTcbrbp(inputStream, address); + } - /** - * Return the stcb pointer for this Tcb. - * @throws IOException if an error occurred reading from the address space - */ - public long tcbstcb() throws IOException { - return IkjtcbTemplate.getTcbstcb(inputStream, address); - } + /** + * Return the stcb pointer for this Tcb. + * @throws IOException if an error occurred reading from the address space + */ + public long tcbstcb() throws IOException { + return IkjtcbTemplate.getTcbstcb(inputStream, address); + } - /** - * Return the pointer to the next Tcb in the queue - * @throws IOException if an error occurred reading from the address space - */ - public long tcbtcb() throws IOException { - return IkjtcbTemplate.getTcbtcb(inputStream, address); - } + /** + * Return the pointer to the next Tcb in the queue + * @throws IOException if an error occurred reading from the address space + */ + public long tcbtcb() throws IOException { + return IkjtcbTemplate.getTcbtcb(inputStream, address); + } - /** - * Get registers from the TCB itself. The registers are in the TCB and the PSW - * comes from the RB. - */ - public RegisterSet getRegisters() throws IOException { - log.fine("getRegisters"); - RegisterSet regs = new RegisterSet(); - try { - long tcbgrs = address + IkjtcbTemplate.getTcbgrs$offset(); - for (int i = 0; i < 16; i++) { - regs.setRegister(i, space.readUnsignedInt(tcbgrs + i*4)); - } - regs.setPSW(IharbTemplate.getRbopsw(inputStream, tcbrbp())); - if (space.is64bit()) { - /* Or in the top half from the stcb */ - long stcbg64h = tcbstcb() + IhastcbTemplate.getStcbg64h$offset(); - for (int i = 0; i < 16; i++) { - long high = space.readUnsignedInt(stcbg64h + i*4); - regs.setRegister(i, regs.getRegister(i) | (high << 32)); - } - } - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new Error("oops: " + e); - } - return regs; - } + /** + * Get registers from the TCB itself. The registers are in the TCB and the PSW + * comes from the RB. + */ + public RegisterSet getRegisters() throws IOException { + log.fine("getRegisters"); + RegisterSet regs = new RegisterSet(); + try { + long tcbgrs = address + IkjtcbTemplate.getTcbgrs$offset(); + for (int i = 0; i < 16; i++) { + regs.setRegister(i, space.readUnsignedInt(tcbgrs + i*4)); + } + regs.setPSW(IharbTemplate.getRbopsw(inputStream, tcbrbp())); + if (space.is64bit()) { + /* Or in the top half from the stcb */ + long stcbg64h = tcbstcb() + IhastcbTemplate.getStcbg64h$offset(); + for (int i = 0; i < 16; i++) { + long high = space.readUnsignedInt(stcbg64h + i*4); + regs.setRegister(i, regs.getRegister(i) | (high << 32)); + } + } + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new Error("oops: " + e); + } + return regs; + } - /** - * Try and get the registers by simulating the BPXGMSTA service. (XXX I think this is - * probably the best place to implement this kernel call?) - */ - public RegisterSet getRegistersFromBPXGMSTA() throws IOException { - RegisterSet regs = new RegisterSet(); - /* Following comments are from bpxgmsta.plx: - * - * BPXGMSTA accesses the dump to get data necessary to - * extract PSW and GPRs relevant to the input TCB. - * - * 1) Single RB on the input TCB RB chain - * a) If current linkage stack is empty, registers are extracted - * from the input TCB and PSW is extracted from the current - * RB. - * b) If linkage stack is present, and non-fast path Kernel - * call has been issued, registers and PSW are extracted - * from USTA, which can be accessed via the input TCB. - * c) For all other cases, first entry of the linkage stack - * contains the registers and PSW from the last point - * where LE/C had control. - * 2) multiple RBs on the input TCB RB chain - * a) PSW is extracted from the oldest RB on the chain, which - * is the first RB added to the chain. And the adjacent - * RB to the oldest RB contains the registers from the last - * point where LE/C had control. - * 3) Any other scenario not covered by above cases are - * considered to be very unlikely to occur. - */ - try { - long rbp = tcbrbp(); - long rbsecptr = 0; /* The last RB read */ - long save2rbptr = 0; /* The second to last RB read */ - log.fine("for tcb " + hex(address) + ", rbp = " + hex(rbp)); - int countRbs = 0; - do { - log.fine("currently looking at rbp 0x" + hex(rbp)); - save2rbptr = rbsecptr; - rbsecptr = rbp; - rbp = IharbTemplate.getRblinkXrblnkRblinkb(inputStream, rbp); - countRbs++; - } while (rbp != address); - log.fine("found " + countRbs + " rbs"); - /* - * If only a single RB exist in the RB chain, GPRs and PSW must - * be obtained from the linkage stack. If the linkage stack is - * empty, then GPRs and PSW must be obtained from TCB and RB - * respectively. - * Else if multiple RB exist in the RB chain, obtain GPRs from - * the oldest PRB and PSW from the RB next to it. - */ - if (countRbs == 1) { - getLinkageStack(); - if (linkageStack.length == 0) { - /* - * This case represents waiting in LE or suspended by - * dumping. TCB is ready to run but not yet dispatched. - * Target GPRs in TCB and target PSW is in RB. - */ - log.fine("empty linkage stack, get registers from TCB"); - regs = getRegisters(); - regs.setWhereFound("BPXGMSTA/TCB"); - } else { - /* Most likely a stacking PC. use first linkage stack entry which - * contains GPRs and PSW from the last point where LE/C had control. */ - long stcbotcb = IhastcbTemplate.getStcbotcb(inputStream, tcbstcb()); - boolean otcbptregsinusta = false; - if (stcbotcb != 0) { - otcbptregsinusta = BpxzotcbTemplate.getOtcbptregsinusta(inputStream, stcbotcb) != 0; - } - if (otcbptregsinusta && stcbotcb != 0) { - long otcbcofptr = BpxzotcbTemplate.getOtcbcofptr(inputStream, stcbotcb); - throw new Error("tbc"); - } else { - log.fine("try first linkage stack entry"); - /* map to 1st linkage stack entry. Get pointer to start of register savearea in - * state entry. 1st entry must be either PC or BAKR status entry since linkage stack - * can't be empty. If the first LSE indicates this is a OMVS syscall and not a - * fastpath syscall get the registers from the usta. */ - Lse lse = linkageStack[linkageStack.length - 1]; - /* Check the first LSE on the stack for the OMVS non-fastpath - * syscall range */ - assert stcbotcb != 0; - long otcbcofptr = BpxzotcbTemplate.getOtcbcofptr(inputStream, stcbotcb); - long otcbustaptr = OtcbcopyonforkTemplate.getOtcbustaptr(inputStream, otcbcofptr); + /** + * Try and get the registers by simulating the BPXGMSTA service. (XXX I think this is + * probably the best place to implement this kernel call?) + */ + public RegisterSet getRegistersFromBPXGMSTA() throws IOException { + RegisterSet regs = new RegisterSet(); + /* Following comments are from bpxgmsta.plx: + * + * BPXGMSTA accesses the dump to get data necessary to + * extract PSW and GPRs relevant to the input TCB. + * + * 1) Single RB on the input TCB RB chain + * a) If current linkage stack is empty, registers are extracted + * from the input TCB and PSW is extracted from the current + * RB. + * b) If linkage stack is present, and non-fast path Kernel + * call has been issued, registers and PSW are extracted + * from USTA, which can be accessed via the input TCB. + * c) For all other cases, first entry of the linkage stack + * contains the registers and PSW from the last point + * where LE/C had control. + * 2) multiple RBs on the input TCB RB chain + * a) PSW is extracted from the oldest RB on the chain, which + * is the first RB added to the chain. And the adjacent + * RB to the oldest RB contains the registers from the last + * point where LE/C had control. + * 3) Any other scenario not covered by above cases are + * considered to be very unlikely to occur. + */ + try { + long rbp = tcbrbp(); + long rbsecptr = 0; /* The last RB read */ + long save2rbptr = 0; /* The second to last RB read */ + log.fine("for tcb " + hex(address) + ", rbp = " + hex(rbp)); + int countRbs = 0; + do { + log.fine("currently looking at rbp 0x" + hex(rbp)); + save2rbptr = rbsecptr; + rbsecptr = rbp; + rbp = IharbTemplate.getRblinkXrblnkRblinkb(inputStream, rbp); + countRbs++; + } while (rbp != address); + log.fine("found " + countRbs + " rbs"); + /* + * If only a single RB exist in the RB chain, GPRs and PSW must + * be obtained from the linkage stack. If the linkage stack is + * empty, then GPRs and PSW must be obtained from TCB and RB + * respectively. + * Else if multiple RB exist in the RB chain, obtain GPRs from + * the oldest PRB and PSW from the RB next to it. + */ + if (countRbs == 1) { + getLinkageStack(); + if (linkageStack.length == 0) { + /* + * This case represents waiting in LE or suspended by + * dumping. TCB is ready to run but not yet dispatched. + * Target GPRs in TCB and target PSW is in RB. + */ + log.fine("empty linkage stack, get registers from TCB"); + regs = getRegisters(); + regs.setWhereFound("BPXGMSTA/TCB"); + } else { + /* Most likely a stacking PC. use first linkage stack entry which + * contains GPRs and PSW from the last point where LE/C had control. */ + long stcbotcb = IhastcbTemplate.getStcbotcb(inputStream, tcbstcb()); + boolean otcbptregsinusta = false; + if (stcbotcb != 0) { + otcbptregsinusta = BpxzotcbTemplate.getOtcbptregsinusta(inputStream, stcbotcb) != 0; + } + if (otcbptregsinusta && stcbotcb != 0) { + long otcbcofptr = BpxzotcbTemplate.getOtcbcofptr(inputStream, stcbotcb); + throw new Error("tbc"); + } else { + log.fine("try first linkage stack entry"); + /* map to 1st linkage stack entry. Get pointer to start of register savearea in + * state entry. 1st entry must be either PC or BAKR status entry since linkage stack + * can't be empty. If the first LSE indicates this is a OMVS syscall and not a + * fastpath syscall get the registers from the usta. */ + Lse lse = linkageStack[linkageStack.length - 1]; + /* Check the first LSE on the stack for the OMVS non-fastpath + * syscall range */ + assert stcbotcb != 0; + long otcbcofptr = BpxzotcbTemplate.getOtcbcofptr(inputStream, stcbotcb); + long otcbustaptr = OtcbcopyonforkTemplate.getOtcbustaptr(inputStream, otcbcofptr); log.fine("lse type "+lse.lses1typ7()); - if ((lse.lsestyp7() == Lse.LSEDPC || lse.lses1typ7() == Lse.LSED1PC) && lse.lsestarg() < FastPathPCLow && lse.lsestarg() >= OmvsPcLow && otcbustaptr != 0) { - /* If this is a slowpath syscall get the USTA regs */ - long ustagrs = otcbustaptr + BpxzustaTemplate.getUstagrs$offset(); - /* This is a bit of a hack to adjust the usta pointer according to - * the OS level. Eventually we should let the template stuff handle - * multiple variants of structures. Usta psw increased in HBB7708. */ - long cvt = IhapsaTemplate.getFlccvt(inputStream, 0); - long cvtoslv3 = CeexcvtTemplate.getCvtoslv3(inputStream, cvt); - if ((cvtoslv3 & 2) != 0) { - log.fine("new level of OS (0x" + hex(cvtoslv3) + ")"); - } else { - log.fine("old level of OS (0x" + hex(cvtoslv3) + ") so adjust usta pointer"); - ustagrs -= 8; // take into account smaller psw - } - for (int i = 0; i < 16; i++) { - regs.setRegister(i, space.readUnsignedInt(ustagrs + i*4)); - } - long ustapsw = otcbustaptr + BpxzustaTemplate.getUstapswg$offset(); - regs.setPSW(space.readLong(ustapsw)); - regs.setWhereFound("BPXGMSTA/USTA"); - } else { - log.fine("try last linkage stack entry"); - /* last entry in linkage stack. Calculate the address of the - * last LSE on the chain */ - lse = linkageStack[0]; - if (lse.lses1typ7() == Lse.LSED1PC || lse.lses1typ7() == Lse.LSED1BAKR) { - /* Esame PC entry */ - regs.setPSW(lse.lses1pswh()); - for (int i = 0; i < 16; i++) { - regs.setRegister(i, lse.lses1grs(i)); - } - } else { - regs.setPSW(lse.lsespsw()); - for (int i = 0; i < 16; i++) { - regs.setRegister(i, lse.lsesgrs(i)); - } - } - regs.setWhereFound("BPXGMSTA/Linkage"); - } - } - } - } else { - long rbftp = IkjrbTemplate.getRbftp(inputStream, rbsecptr); - if (rbftp == RBFTPRB) { - regs.setPSW(IharbTemplate.getRbopsw(inputStream, rbsecptr)); - long rbgrsave_offset = IharbTemplate.getRbgrsave$offset(); - for (int i = 0; i < 16; i++) { - regs.setRegister(i, space.readUnsignedInt(save2rbptr + rbgrsave_offset + i*4)); - } - regs.setWhereFound("BPXGMSTA/RBFTPRB"); - } else { - throw new Error("tbc"); - } - } - } catch (Exception e) { - e.printStackTrace(); - throw new Error("oops: " + e); - } - return regs; - } + if ((lse.lsestyp7() == Lse.LSEDPC || lse.lses1typ7() == Lse.LSED1PC) && lse.lsestarg() < FastPathPCLow && lse.lsestarg() >= OmvsPcLow && otcbustaptr != 0) { + /* If this is a slowpath syscall get the USTA regs */ + long ustagrs = otcbustaptr + BpxzustaTemplate.getUstagrs$offset(); + /* This is a bit of a hack to adjust the usta pointer according to + * the OS level. Eventually we should let the template stuff handle + * multiple variants of structures. Usta psw increased in HBB7708. */ + long cvt = IhapsaTemplate.getFlccvt(inputStream, 0); + long cvtoslv3 = CeexcvtTemplate.getCvtoslv3(inputStream, cvt); + if ((cvtoslv3 & 2) != 0) { + log.fine("new level of OS (0x" + hex(cvtoslv3) + ")"); + } else { + log.fine("old level of OS (0x" + hex(cvtoslv3) + ") so adjust usta pointer"); + ustagrs -= 8; // take into account smaller psw + } + for (int i = 0; i < 16; i++) { + regs.setRegister(i, space.readUnsignedInt(ustagrs + i*4)); + } + long ustapsw = otcbustaptr + BpxzustaTemplate.getUstapswg$offset(); + regs.setPSW(space.readLong(ustapsw)); + regs.setWhereFound("BPXGMSTA/USTA"); + } else { + log.fine("try last linkage stack entry"); + /* last entry in linkage stack. Calculate the address of the + * last LSE on the chain */ + lse = linkageStack[0]; + if (lse.lses1typ7() == Lse.LSED1PC || lse.lses1typ7() == Lse.LSED1BAKR) { + /* Esame PC entry */ + regs.setPSW(lse.lses1pswh()); + for (int i = 0; i < 16; i++) { + regs.setRegister(i, lse.lses1grs(i)); + } + } else { + regs.setPSW(lse.lsespsw()); + for (int i = 0; i < 16; i++) { + regs.setRegister(i, lse.lsesgrs(i)); + } + } + regs.setWhereFound("BPXGMSTA/Linkage"); + } + } + } + } else { + long rbftp = IkjrbTemplate.getRbftp(inputStream, rbsecptr); + if (rbftp == RBFTPRB) { + regs.setPSW(IharbTemplate.getRbopsw(inputStream, rbsecptr)); + long rbgrsave_offset = IharbTemplate.getRbgrsave$offset(); + for (int i = 0; i < 16; i++) { + regs.setRegister(i, space.readUnsignedInt(save2rbptr + rbgrsave_offset + i*4)); + } + regs.setWhereFound("BPXGMSTA/RBFTPRB"); + } else { + throw new Error("tbc"); + } + } + } catch (Exception e) { + e.printStackTrace(); + throw new Error("oops: " + e); + } + return regs; + } - /** - * Return the linkage stack as an array of Lse entries. The length of the array will be zero - * if the linkage stack is empty. The top of the stack (as represented by stcblsdp) is the - * first element in the array and the end of the stack (also sometimes referred to as - * the first entry, aka stcbestk) is the last element in the array. - */ - public Lse[] getLinkageStack() throws IOException { - if (linkageStack != null) - return linkageStack; - try { - long stcb = tcbstcb(); - long stcbestk = IhastcbTemplate.getStcbestk(inputStream, stcb); - long stcblsdp = IhastcbTemplate.getStcblsdp(inputStream, stcb); - if (stcbestk == stcblsdp) { - log.fine("linkage stack empty"); - linkageStack = new Lse[0]; - return linkageStack; - } - long entrysize = LsedTemplate.getLsednes(inputStream, stcbestk); - if (entrysize <= 0) { - log.fine("linkage stack empty"); - linkageStack = new Lse[0]; - return linkageStack; - } - // XXX maybe this should be an exception? - assert entrysize == LsestateTemplate.length() || entrysize == Lsestate1Template.length() : entrysize; - assert (stcblsdp - stcbestk) % entrysize == 0 : (stcblsdp - stcbestk) % entrysize; - int numEntries = (int)((stcblsdp - stcbestk) / entrysize); - assert numEntries >= 0 && numEntries < 100 : numEntries; - linkageStack = new Lse[numEntries]; - long lsedptr = stcblsdp - entrysize; - for (int i = 0; i < numEntries; i++) { - linkageStack[i] = new Lse(space, lsedptr); - lsedptr -= entrysize; - } - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new Error("oops: " + e); - } - return linkageStack; - } + /** + * Return the linkage stack as an array of Lse entries. The length of the array will be zero + * if the linkage stack is empty. The top of the stack (as represented by stcblsdp) is the + * first element in the array and the end of the stack (also sometimes referred to as + * the first entry, aka stcbestk) is the last element in the array. + */ + public Lse[] getLinkageStack() throws IOException { + if (linkageStack != null) + return linkageStack; + try { + long stcb = tcbstcb(); + long stcbestk = IhastcbTemplate.getStcbestk(inputStream, stcb); + long stcblsdp = IhastcbTemplate.getStcblsdp(inputStream, stcb); + if (stcbestk == stcblsdp) { + log.fine("linkage stack empty"); + linkageStack = new Lse[0]; + return linkageStack; + } + long entrysize = LsedTemplate.getLsednes(inputStream, stcbestk); + if (entrysize <= 0) { + log.fine("linkage stack empty"); + linkageStack = new Lse[0]; + return linkageStack; + } + // XXX maybe this should be an exception? + assert entrysize == LsestateTemplate.length() || entrysize == Lsestate1Template.length() : entrysize; + assert (stcblsdp - stcbestk) % entrysize == 0 : (stcblsdp - stcbestk) % entrysize; + int numEntries = (int)((stcblsdp - stcbestk) / entrysize); + assert numEntries >= 0 && numEntries < 100 : numEntries; + linkageStack = new Lse[numEntries]; + long lsedptr = stcblsdp - entrysize; + for (int i = 0; i < numEntries; i++) { + linkageStack[i] = new Lse(space, lsedptr); + lsedptr -= entrysize; + } + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new Error("oops: " + e); + } + return linkageStack; + } - private static String hex(long n) { - return Long.toHexString(n); - } + private static String hex(long n) { + return Long.toHexString(n); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/AbstractHashMap.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/AbstractHashMap.java index f8bef926e6d..4d49ffa2b41 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/AbstractHashMap.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/AbstractHashMap.java @@ -35,277 +35,277 @@ public abstract class AbstractHashMap implements Serializable { - static final int INITIAL_SIZE = 17; - /** The array of keys */ - long[] keys = new long[INITIAL_SIZE]; - /** The length of the keys array */ - int tableSize = INITIAL_SIZE; - /** The number of slots currently in use */ - int slotsInUse; - /** The number of deleted slots */ - int deletedSlots; - /** The state of each slot */ - byte[] state = new byte[INITIAL_SIZE]; - static final byte EMPTY = 0; - static final byte OCCUPIED = 1; - static final byte DELETED = 2; - /** Doing rehash */ - private boolean inRehash; - /** Logger */ - private static Logger log = Logger.getLogger(AbstractHashMap.class.getName()); - private static final boolean debug = log.isLoggable(Level.FINER); - private static int callsToGetIndex; - private static int callsToGetIndexSuccess; - private static int loopsInGetIndex; - private static int loopsBecauseNotEqual; - private static int loopsBecauseDeleted; - private static int callsToRehash; + static final int INITIAL_SIZE = 17; + /** The array of keys */ + long[] keys = new long[INITIAL_SIZE]; + /** The length of the keys array */ + int tableSize = INITIAL_SIZE; + /** The number of slots currently in use */ + int slotsInUse; + /** The number of deleted slots */ + int deletedSlots; + /** The state of each slot */ + byte[] state = new byte[INITIAL_SIZE]; + static final byte EMPTY = 0; + static final byte OCCUPIED = 1; + static final byte DELETED = 2; + /** Doing rehash */ + private boolean inRehash; + /** Logger */ + private static Logger log = Logger.getLogger(AbstractHashMap.class.getName()); + private static final boolean debug = log.isLoggable(Level.FINER); + private static int callsToGetIndex; + private static int callsToGetIndexSuccess; + private static int loopsInGetIndex; + private static int loopsBecauseNotEqual; + private static int loopsBecauseDeleted; + private static int callsToRehash; - /** - * This method must be overridden by subclasses to return the array of values. Used - * during rehashing. - * @return the array of values - */ - abstract Object getValuesArray(); + /** + * This method must be overridden by subclasses to return the array of values. Used + * during rehashing. + * @return the array of values + */ + abstract Object getValuesArray(); - /** - * This method must be overridden by subclasses to allocate a new empty array of values - * of the given size. Used during rehashing. - * @param newSize the size of the value array to allocate - */ - abstract void allocNewValuesArray(int newSize); + /** + * This method must be overridden by subclasses to allocate a new empty array of values + * of the given size. Used during rehashing. + * @param newSize the size of the value array to allocate + */ + abstract void allocNewValuesArray(int newSize); - /** - * This method must be overridden by subclasses which must then do a put operation for - * the given key and the value at the given offset in the oldvalues array. It is used - * during rehashing to rebuild the map. - * @param key the key to do the put on - * @param oldvalues the old array of values - * @param offset the offset into the oldvalues array - */ - abstract void put(long key, Object oldvalues, int offset); + /** + * This method must be overridden by subclasses which must then do a put operation for + * the given key and the value at the given offset in the oldvalues array. It is used + * during rehashing to rebuild the map. + * @param key the key to do the put on + * @param oldvalues the old array of values + * @param offset the offset into the oldvalues array + */ + abstract void put(long key, Object oldvalues, int offset); - /** - * Rebuild the hash table. - */ - void rehash() { - inRehash = true; - if (debug) { - callsToRehash++; - log.finer("rehashing, current size " + tableSize + " slots in use " + slotsInUse + " deleted " + deletedSlots); - printStats(); - } - /* Save the old fields */ - long[] oldkeys = keys; - Object oldvalues = getValuesArray(); - byte[] oldstate = state; - if (tableNeedsResize()) { - /* The new table size must be a prime number */ - tableSize <<= 1; - while (!isprime(++tableSize)); - if (debug) log.finer("new table size is " + tableSize); - } - /* Allocate the new fields */ - keys = new long[tableSize]; - allocNewValuesArray(tableSize); - state = new byte[tableSize]; - /* Repopulate */ - slotsInUse = 0; - deletedSlots = 0; - for (int i = 0; i < oldkeys.length; i++) { - if (oldstate[i] == OCCUPIED) { - put(oldkeys[i], oldvalues, i); - } - } - inRehash = false; - } + /** + * Rebuild the hash table. + */ + void rehash() { + inRehash = true; + if (debug) { + callsToRehash++; + log.finer("rehashing, current size " + tableSize + " slots in use " + slotsInUse + " deleted " + deletedSlots); + printStats(); + } + /* Save the old fields */ + long[] oldkeys = keys; + Object oldvalues = getValuesArray(); + byte[] oldstate = state; + if (tableNeedsResize()) { + /* The new table size must be a prime number */ + tableSize <<= 1; + while (!isprime(++tableSize)); + if (debug) log.finer("new table size is " + tableSize); + } + /* Allocate the new fields */ + keys = new long[tableSize]; + allocNewValuesArray(tableSize); + state = new byte[tableSize]; + /* Repopulate */ + slotsInUse = 0; + deletedSlots = 0; + for (int i = 0; i < oldkeys.length; i++) { + if (oldstate[i] == OCCUPIED) { + put(oldkeys[i], oldvalues, i); + } + } + inRehash = false; + } - /** - * Get the index for the given key. - * @return the index or -1 if it cannot be found - */ - int getIndex(long key) { - if (debug) callsToGetIndex++; - for (int i = 0; i < tableSize; i++) { - int index = h(key & 0x7fffffffffffffffL, i); - if (state[index] == EMPTY) { - return -1; - } else if (state[index] == OCCUPIED && keys[index] == key) { - if (debug) callsToGetIndexSuccess++; - return index; - } - if (debug) { - loopsInGetIndex++; - if (state[index] == OCCUPIED) - loopsBecauseNotEqual++; - else - loopsBecauseDeleted++; - } - } - return -1; - } + /** + * Get the index for the given key. + * @return the index or -1 if it cannot be found + */ + int getIndex(long key) { + if (debug) callsToGetIndex++; + for (int i = 0; i < tableSize; i++) { + int index = h(key & 0x7fffffffffffffffL, i); + if (state[index] == EMPTY) { + return -1; + } else if (state[index] == OCCUPIED && keys[index] == key) { + if (debug) callsToGetIndexSuccess++; + return index; + } + if (debug) { + loopsInGetIndex++; + if (state[index] == OCCUPIED) + loopsBecauseNotEqual++; + else + loopsBecauseDeleted++; + } + } + return -1; + } - /** - * Log some useful stats - */ - private static void printStats() { - log.finer("callsToGetIndex = " + callsToGetIndex); - log.finer("callsToGetIndexSuccess = " + callsToGetIndexSuccess); - log.finer("loopsInGetIndex = " + loopsInGetIndex); - log.finer("loopsBecauseNotEqual = " + loopsBecauseNotEqual); - log.finer("loopsBecauseDeleted = " + loopsBecauseDeleted); - log.finer("callsToRehash = " + callsToRehash); - } + /** + * Log some useful stats + */ + private static void printStats() { + log.finer("callsToGetIndex = " + callsToGetIndex); + log.finer("callsToGetIndexSuccess = " + callsToGetIndexSuccess); + log.finer("loopsInGetIndex = " + loopsInGetIndex); + log.finer("loopsBecauseNotEqual = " + loopsBecauseNotEqual); + log.finer("loopsBecauseDeleted = " + loopsBecauseDeleted); + log.finer("callsToRehash = " + callsToRehash); + } - /** - * Remove the given key from the map and return its old index. - * @return the index or -1 if it cannot be found - */ - int removeIndex(long key) { - int index = getIndex(key); - if (index != -1) { - state[index] = DELETED; - deletedSlots++; - slotsInUse--; - } - return index; - } + /** + * Remove the given key from the map and return its old index. + * @return the index or -1 if it cannot be found + */ + int removeIndex(long key) { + int index = getIndex(key); + if (index != -1) { + state[index] = DELETED; + deletedSlots++; + slotsInUse--; + } + return index; + } - /** - * Does the table need resizing? This occurs if the table is more than 2/3 full. - */ - private boolean tableNeedsResize() { - return slotsInUse > ((tableSize * 2) / 3); - } + /** + * Does the table need resizing? This occurs if the table is more than 2/3 full. + */ + private boolean tableNeedsResize() { + return slotsInUse > ((tableSize * 2) / 3); + } - /** - * Check to see if we need to rehash. This occurs when the table is more than 2/3 full. - */ - void checkRehash() { - if (tableNeedsResize() || deletedSlots > (tableSize / 3)) { - if (!inRehash) - rehash(); - } - } + /** + * Check to see if we need to rehash. This occurs when the table is more than 2/3 full. + */ + void checkRehash() { + if (tableNeedsResize() || deletedSlots > (tableSize / 3)) { + if (!inRehash) + rehash(); + } + } - /** - * Return the index to be used for the next put operation. Similar to getIndex except that - * it marks the slot as occupied and increments the use count. - * @return the index to be used for this put operation - */ - int putIndex(long key) { - for (int i = 0; i < tableSize; i++) { - int index = h(key & 0x7fffffffffffffffL, i); - if (state[index] != OCCUPIED) { - keys[index] = key; - if (state[index] == DELETED) - deletedSlots--; - state[index] = OCCUPIED; - ++slotsInUse; - return index; - } else if (keys[index] == key) { - return index; - } - } - throw new Error("table full! key = " + key + " tableSize = " + tableSize + " slotsInUse = " + slotsInUse); - } + /** + * Return the index to be used for the next put operation. Similar to getIndex except that + * it marks the slot as occupied and increments the use count. + * @return the index to be used for this put operation + */ + int putIndex(long key) { + for (int i = 0; i < tableSize; i++) { + int index = h(key & 0x7fffffffffffffffL, i); + if (state[index] != OCCUPIED) { + keys[index] = key; + if (state[index] == DELETED) + deletedSlots--; + state[index] = OCCUPIED; + ++slotsInUse; + return index; + } else if (keys[index] == key) { + return index; + } + } + throw new Error("table full! key = " + key + " tableSize = " + tableSize + " slotsInUse = " + slotsInUse); + } - /** - * Internal class used to implement IntEnumeration. - * @hidden - */ - private class KeyEnum implements IntEnumeration { + /** + * Internal class used to implement IntEnumeration. + * @hidden + */ + private class KeyEnum implements IntEnumeration { - int index = 0; - boolean hasMore = true; + int index = 0; + boolean hasMore = true; - KeyEnum() { - reset(); - } + KeyEnum() { + reset(); + } - void next() { - while (index < tableSize && state[index] != OCCUPIED) index++; - if (index == tableSize) hasMore = false; - } + void next() { + while (index < tableSize && state[index] != OCCUPIED) index++; + if (index == tableSize) hasMore = false; + } - public boolean hasMoreElements() { - return hasMore; - } + public boolean hasMoreElements() { + return hasMore; + } - public Object nextElement() { - return Long.valueOf(nextInt()); - } + public Object nextElement() { + return Long.valueOf(nextInt()); + } - public long nextInt() { - long key = keys[index++]; - next(); - return key; - } + public long nextInt() { + long key = keys[index++]; + next(); + return key; + } - public long peekInt() { - return keys[index]; - } + public long peekInt() { + return keys[index]; + } - public void reset() { - index = 0; - hasMore = true; - next(); - } - } + public void reset() { + index = 0; + hasMore = true; + next(); + } + } - /** - * Return an enumeration of the keys in this map. {@link IntEnumeration} is similar to - * Enumeration except that it also provides a nextInt() method to return a primitive value. - */ - public IntEnumeration getKeys() { - return new KeyEnum(); - } + /** + * Return an enumeration of the keys in this map. {@link IntEnumeration} is similar to + * Enumeration except that it also provides a nextInt() method to return a primitive value. + */ + public IntEnumeration getKeys() { + return new KeyEnum(); + } - /** - * Return an array containing the keys. - */ - public long[] getKeysArray() { - long[] akeys = new long[slotsInUse]; - for (int i = 0, j = 0; i < tableSize; i++) { - if (state[i] == OCCUPIED) - akeys[j++] = keys[i]; - } - return akeys; - } + /** + * Return an array containing the keys. + */ + public long[] getKeysArray() { + long[] akeys = new long[slotsInUse]; + for (int i = 0, j = 0; i < tableSize; i++) { + if (state[i] == OCCUPIED) + akeys[j++] = keys[i]; + } + return akeys; + } - /** - * The double hashing method. - */ - private int h(long k, int i) { - long l = h1(k) + ((long)i * (long)h2(k)); - return (int)(l % tableSize); - } + /** + * The double hashing method. + */ + private int h(long k, int i) { + long l = h1(k) + ((long)i * (long)h2(k)); + return (int)(l % tableSize); + } - private int h1(long k) { - return (int)(k % tableSize); - } + private int h1(long k) { + return (int)(k % tableSize); + } - private int h2(long k) { - return (int)(1 + (k % (tableSize - 2))); - } + private int h2(long k) { + return (int)(1 + (k % (tableSize - 2))); + } - private static final int[] smallPrimes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; + private static final int[] smallPrimes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; - /** - * Does exactly what it says on the tin. - */ - private static boolean isprime(int x) { - int div = 0, stop; - for (int i = 0; i < smallPrimes.length; ++i ) { - div = smallPrimes[i]; - if (x % div == 0) - return false; - } - for ( stop = x; x / stop < stop; stop >>= 1 ) ; - stop <<= 1; - for (div += 2; div < stop; div += 2) - if ( x % div == 0 ) - return false; - return true; - } + /** + * Does exactly what it says on the tin. + */ + private static boolean isprime(int x) { + int div = 0, stop; + for (int i = 0; i < smallPrimes.length; ++i ) { + div = smallPrimes[i]; + if (x % div == 0) + return false; + } + for ( stop = x; x / stop < stop; stop >>= 1 ) ; + stop <<= 1; + for (div += 2; div < stop; div += 2) + if ( x % div == 0 ) + return false; + return true; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/AbstractLruCache.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/AbstractLruCache.java index 63eebcf46be..77ec2de8caa 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/AbstractLruCache.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/AbstractLruCache.java @@ -34,103 +34,103 @@ public abstract class AbstractLruCache extends AbstractHashMap { - /** The maximum size of the cache */ - int maxSize; - /** The index of the first (most recently used) entry in the list */ - int head = -1; - /** The index of the last (least recently used) entry in the list */ - int tail = -1; - /** The array of next pointers */ - int[] next = new int[INITIAL_SIZE]; - /** The array of prev pointers */ - int[] prev = new int[INITIAL_SIZE]; + /** The maximum size of the cache */ + int maxSize; + /** The index of the first (most recently used) entry in the list */ + int head = -1; + /** The index of the last (least recently used) entry in the list */ + int tail = -1; + /** The array of next pointers */ + int[] next = new int[INITIAL_SIZE]; + /** The array of prev pointers */ + int[] prev = new int[INITIAL_SIZE]; - /** - * Create a new AbstractLruCache. - * @param maxSize the maximum size the cache can grow to - */ - protected AbstractLruCache(int maxSize) { - this.maxSize = maxSize; - } + /** + * Create a new AbstractLruCache. + * @param maxSize the maximum size the cache can grow to + */ + protected AbstractLruCache(int maxSize) { + this.maxSize = maxSize; + } - /** - * Overridden method which the subclass must also override to allocate new values array. - * We also reallocate the next and prev - * arrays at this point (just prior to repopulating the cache). - */ - void allocNewValuesArray(int newSize) { - next = new int[newSize]; - prev = new int[newSize]; - head = tail = -1; - } + /** + * Overridden method which the subclass must also override to allocate new values array. + * We also reallocate the next and prev + * arrays at this point (just prior to repopulating the cache). + */ + void allocNewValuesArray(int newSize) { + next = new int[newSize]; + prev = new int[newSize]; + head = tail = -1; + } - /** - * Returns the index for the value mapped by the given key. Also promotes this key to the most - * recently used. - * @return the index or -1 if it cannot be found - */ - protected int getIndexAndPromote(long key) { - int index = getIndex(key) ; - if (index != -1) { - if (head != index) { - /* - * Not currently the head so unlink from where we are now... - */ - int n = next[index]; - int p = prev[index]; - next[p] = n; - if (n != -1) { - prev[n] = prev[index]; - } else { - tail = p; - } - /* - * ... and make us the new head - */ - prev[index] = -1; - next[index] = head; - prev[head] = index; - head = index; - } - return index; - } - return -1; - } + /** + * Returns the index for the value mapped by the given key. Also promotes this key to the most + * recently used. + * @return the index or -1 if it cannot be found + */ + protected int getIndexAndPromote(long key) { + int index = getIndex(key) ; + if (index != -1) { + if (head != index) { + /* + * Not currently the head so unlink from where we are now... + */ + int n = next[index]; + int p = prev[index]; + next[p] = n; + if (n != -1) { + prev[n] = prev[index]; + } else { + tail = p; + } + /* + * ... and make us the new head + */ + prev[index] = -1; + next[index] = head; + prev[head] = index; + head = index; + } + return index; + } + return -1; + } - /** - * Get the index for a put operation. Takes care of promotion and removing the LRU entry - * if necessary. - */ - protected int putIndexAndPromote(long key) { - int index = getIndex(key); - if (index == -1) { - /* Not currently present */ - if (slotsInUse < maxSize) { - /* Don't need to chuck anything out */ - index = putIndex(key); - /* Make us the new head */ - prev[index] = -1; - next[index] = head; - if (slotsInUse == 1) { - tail = index; - } else { - prev[head] = index; - } - head = index; - return index; - } else { - /* Cache is full - chuck out the LRU */ - state[tail] = DELETED; - deletedSlots++; - slotsInUse--; - tail = prev[tail]; - next[tail] = -1; - /* Try again now there's room */ - return putIndexAndPromote(key); - } - } else { - /* Just replace current value */ - return index; - } - } + /** + * Get the index for a put operation. Takes care of promotion and removing the LRU entry + * if necessary. + */ + protected int putIndexAndPromote(long key) { + int index = getIndex(key); + if (index == -1) { + /* Not currently present */ + if (slotsInUse < maxSize) { + /* Don't need to chuck anything out */ + index = putIndex(key); + /* Make us the new head */ + prev[index] = -1; + next[index] = head; + if (slotsInUse == 1) { + tail = index; + } else { + prev[head] = index; + } + head = index; + return index; + } else { + /* Cache is full - chuck out the LRU */ + state[tail] = DELETED; + deletedSlots++; + slotsInUse--; + tail = prev[tail]; + next[tail] = -1; + /* Try again now there's room */ + return putIndexAndPromote(key); + } + } else { + /* Just replace current value */ + return index; + } + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/BitStream.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/BitStream.java index f3b6acdbc62..102d57d9609 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/BitStream.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/BitStream.java @@ -48,485 +48,485 @@ */ public final class BitStream implements Serializable { - private int[] bits; - /** Index into the bits array */ - private int index; - /** Offset of bit in the current int */ - private int bitOffset; - /** Indicates whether we are currently reading or writing */ - private boolean writing = true; - /** The current int we are reading from */ - private int currentWord; - - /** - * Create a new BitStream with a default size of 100 bytes. - */ - public BitStream() { - this(25); - } - - /** - * Create a new BitStream containing the given number of ints. The BitStream is - * implemented as an array of ints which will grow if necessary. - * @param numInts the initial size of the array of ints - */ - public BitStream(int numInts) { - bits = new int[numInts]; - } - - /** - * Rewinds the stream ready for reading. - */ - public void rewind() { - index = 0; - bitOffset = 0; - writing = false; - currentWord = bits[index]; - } - - /** - * Resets the stream so that it may be used again for writing. - */ - public void reset() { - rewind(); - bits[0] = 0; - writing = true; - } - - /** - * Write the number "n" into "len" bits in the current word. - */ - private void writeIntInWord(int n, int len) { - assert len > 0 : len; - if (len < 32) - n &= ((1 << len) - 1); - int b = bits[index]; - b |= (n << (32 - (bitOffset + len))); - bits[index] = b; - bitOffset += len; - } - - /** - * Write a number into the given number of bits. - * @param n the number to write - * @param len the number of bits to write the number to - */ - public void writeLongBits(long n, int len) { - assert len < 64 : len; - writeIntBits((int)(n >> 32), len - 32); - writeIntBits((int)n, 32); - } - - /** - * Write a number into the given number of bits. Note that there is no requirement - * that the given number be small enough to fit, the number written will be masked - * appropriately. - * @param n the number to write - * @param len the number of bits to write the number to - */ - public void writeIntBits(int n, int len) { - assert len > 0 && len <= 32 : len; - if (len < (32 - bitOffset)) { - writeIntInWord(n, len); - } else { - int firstlen = 32 - bitOffset; - int secondlen = len + bitOffset - 32; - if (firstlen > 0) { - writeIntInWord(n >>> secondlen, firstlen); - } - if (secondlen > 0) { - nextWord(); - bits[index] = 0; - writeIntInWord(n, secondlen); - } - } - } - - /** - * Move to the next full word boundary. - */ - public void nextWord() { - index++; - if (index >= bits.length) { - int[] tmp = new int[bits.length * 2]; - System.arraycopy(bits, 0, tmp, 0, bits.length); - bits = tmp; - } else if (writing) - bits[index] = 0; - currentWord = bits[index]; - bitOffset = 0; - } - - /** - * Returns the current word index - */ - public int getIndex() { - return index; - } - - /** - * Sets the word index to the given value. This also resets the bit offset to the - * beginning of the word. This method must only be used when reading to start reading - * a number stream from a saved position. - */ - public void setIndex(int index) { - assert !writing; - this.index = index; - currentWord = bits[index]; - bitOffset = 0; - } - - /** - * Reads an int in the current word from the given number of bits. - */ - private int readIntInWord(int len) { - int n = (currentWord >> (32 - (bitOffset + len))); - if (len < 32) - n &= ((1 << len) - 1); - bitOffset += len; - return n; - } - - /** - * Read an int from given number of bits. - * @param len the number of bits to read the number from - */ - public int readIntBits(int len) { - assert len > 0 && len <= 32 : len; - if (len < (32 - bitOffset)) { - return readIntInWord(len); - } else { - int firstlen = 32 - bitOffset; - int secondlen = len + bitOffset - 32; - int first = 0; - if (firstlen > 0) { - first = readIntInWord(firstlen); - } - int second = 0; - if (secondlen > 0) { - nextWord(); - second = readIntInWord(secondlen); - } - return (first << secondlen) | second; - } - } - - /** - * Read a long from given number of bits. - * @param len the number of bits to read the number from - */ - public long readLongBits(int len) { - assert len < 64 : len; - if (len <= 32) - return readIntBits(len); - long upper = readIntBits(len - 32); - assert upper >= 0 : upper; - long lower = readIntBits(32); - return (upper << 32) | (lower & 0xffffffffL); - } - - /** - * Returns the log2 of the given number. - */ - public static int log2(int n) { - int bit = 0; - while ((n & 0xffffff00 ) != 0) { - bit += 8; - n >>>= 8; - } - return bit + log2bytes[n]; - } - - private static final int log2bytes[] = { - -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - }; - - /** - * Outputs the unsigned integer using delta coding. Delta coding gives better results - * than gamma when larger numbers are more frequent. - * @return the number of bits used - */ - public int writeDelta(int n) { - int msb = log2(++n ); - int r = writeGamma(msb); - if (msb != 0) - writeIntBits(n, msb); - return r + msb; - } - - /** - * Outputs the given unsigned integer using gamma coding. Gamma coding is good when you - * know small numbers are much more frequent than large numbers. - * @return the number of bits used - */ - public int writeGamma(int n) { - int msb = log2(++n); - int r = writeUnary(msb); - if (msb != 0) - writeIntBits(n, msb); - return r + msb; - } - - /** - * Outputs the given unsigned integer as a unary number. Unary numbers are good for - * small integers. - * @return the number of bits used - */ - public int writeUnary(int n) { - for (int i = 0; i < n; i++) - writeIntBits(1, 1); - writeIntBits(0, 1); - return n + 1; - } - - /** - * Reads a delta coded integer. - */ - public int readDelta() { - int msb = readGamma(); - return msb == 0 ? 0 : ( (1 << msb) | readIntBits(msb) ) - 1; - } - - /** - * Reads a gamma coded integer. - */ - public int readGamma() { - int msb = readUnary(); - return msb == 0 ? 0 : ( (1 << msb) | readIntBits(msb) ) - 1; - } - - final static int[] nextUnsetBit = new int[256]; - - static { - for (int i = 0; i < 256; i++) { - nextUnsetBit[i] = -1; - for (int j = 0; j < 8; j++) { - if (((0x80 >> j) & i) == 0) { - nextUnsetBit[i] = j; - break; - } - } - } - } - - /** - * Read a unary coded integer. - */ - - /* - * XXX inefficient - needs to be improved like this: - * - * for - * get next whole word (shift left current, shift right next, or) - * for each byte in word - * get count from lookup table and add to sum - * if count not 8 - * break - */ - public int readUnary() { - int word = currentWord; - int offset = bitOffset; - int result = 0; - while (offset <= 24) { - int b = nextUnsetBit[(word >> (24 - offset)) & 0xff]; - if (b != -1) { - bitOffset = offset + b + 1; - return result + b; - } - offset += 8; - result += 8; - } - for (;; result++, offset++) { - if (offset == 32) { - nextWord(); - word = currentWord; - offset = 0; - } - if ((word & (0x80000000 >>> offset)) == 0) { - bitOffset = offset + 1; - return result; - } - } - } - - /** - * Write a number using variable byte code. This is good when you have lots of - * medium size numbers. - * @return the number of bits used - */ - public int writeVariableByte(int n) { - return writevb(n, true); - } - - private int writevb(int n, boolean end) { - int r = 0; - if (n >= 0x80 || n < 0) - r += writevb(n >>> 7, false); - n &= 0x7f; - if (end) n |= 0x80; - writeIntBits(n, 8); - return r + 8; - } - - /** - * Read a number using variable byte code. - */ - public int readVariableByte() { - for (int n = 0;; n <<= 7) { - int b = readIntBits(8); - n |= (b & 0x7f); - if ((b & 0x80) != 0) - return n; - } - } - - /** - * Write a number using Golomb-Rice coding. Good all rounder if you choose - * the right value of k, absolute rubbish otherwise! - * @param n the unsigned number to write - * @param k the number of bits to use for the remainder - * @return the number of bits used - */ - public int writeGolombRice(int n, int k) { - int r = writeUnary(n >>> k); - writeIntBits(n, k); - return r + k; - } - - /** - * Read a number using Golomb-Rice coding. - * @param k the number of bits to use for the remainder - */ - public int readGolombRice(int k) { - int n = readUnary() << k; - return n | readIntBits(k); - } - - /** - * Give a rough estimate of how many bytes of storage we use. This is the actual storage - * allocated so may be more that what is in use at any one time. - */ - public int memoryUsage() { - return bits.length * 4; - } - - /** - * This method is provided to test the BitStream. We need to change this to use unit - * tests at some point. - */ - public static void main(String[] args) { - final int DELTA = 1; - final int GAMMA = 2; - final int FIXED_BITS = 3; - final int VARIABLE_BYTE = 4; - final int GOLOMB = 5; - final int MAX = 5; - final int COUNT = 8000; - BitStream bs = new BitStream(); - Random rand = new Random(0); - - if (args.length != 0) { - /* Print some stats to give an idea which encoding is best */ - for (int i = 0; i < 4000; i++) { - System.out.println("" + i + ": gamma " + bs.writeGamma(i) + " delta " + bs.writeDelta(i) + " variable " + bs.writeVariableByte(i) + " g(2) " + bs.writeGolombRice(i, 2) + " g(3) " + bs.writeGolombRice(i, 3) + " g(5) " + bs.writeGolombRice(i, 5) + " g(7) " + bs.writeGolombRice(i, 7) + " g(8) " + bs.writeGolombRice(i, 8)); - bs.reset(); - } - return; - } - - for (int i = 0; i < 10; i++) { - bs.reset(); - int[] trueNumbers = new int[COUNT]; - byte[] codes = new byte[COUNT]; - byte[] numBits = new byte[COUNT]; - for (int j = 0; j < COUNT; j++) { - int bits = rand.nextInt(31); - int max = 1 << bits; - //int n = rand.nextInt(max); - int n = rand.nextInt(); - trueNumbers[j] = n; - codes[j] = (byte)(rand.nextInt(MAX) + 1); - switch (codes[j]) { - case DELTA: - System.out.println("doing " + j + " n " + n + " code " + codes[j]); - bs.writeDelta(n); - break; - case GAMMA: - System.out.println("doing " + j + " n " + n + " code " + codes[j]); - bs.writeGamma(n); - break; - case FIXED_BITS: - numBits[j] = (byte)(rand.nextInt(32) + 1); - bs.writeIntBits(n, numBits[j]); - int mask = (int)((1L << numBits[j]) - 1); - trueNumbers[j] &= mask; - System.out.println("doing " + j + " n " + n + " code " + codes[j] + " bits " + numBits[j]); - break; - case VARIABLE_BYTE: - System.out.println("doing " + j + " n " + n + " code " + codes[j]); - bs.writeVariableByte(n); - break; - case GOLOMB: - numBits[j] = (byte)(rand.nextInt(8) + 15); - System.out.println("doing " + j + " n " + n + " code " + codes[j] + " k " + numBits[j]); - bs.writeGolombRice(n, numBits[j]); - break; - } - } - System.out.println("done write for " + i); - bs.rewind(); - for (int j = 0; j < COUNT; j++) { - int n = trueNumbers[j]; - int k; - switch (codes[j]) { - case DELTA: - k = bs.readDelta(); - System.out.println("doing " + j + " k " + k + " code " + codes[j]); - if (k != n) - throw new Error("delta: expected " + n + " but got " + k); - break; - case GAMMA: - k = bs.readGamma(); - System.out.println("doing " + j + " k " + k + " code " + codes[j]); - if (k != n) - throw new Error("gamma: expected " + n + " but got " + k); - break; - case FIXED_BITS: - k = bs.readIntBits(numBits[j]); - System.out.println("doing " + j + " k " + k + " code " + codes[j] + " bits " + numBits[j]); - if (k != n) - throw new Error("fixed bits: expected " + n + " but got " + k); - break; - case VARIABLE_BYTE: - k = bs.readVariableByte(); - System.out.println("doing " + j + " k " + k + " code " + codes[j]); - if (k != n) - throw new Error("variable byte: expected " + n + " but got " + k); - break; - case GOLOMB: - k = bs.readGolombRice(numBits[j]); - System.out.println("doing " + j + " k " + k + " code " + codes[j]); - if (k != n) - throw new Error("golomb: expected " + n + " but got " + k); - break; - } - } - System.out.println("done " + i); - } - } + private int[] bits; + /** Index into the bits array */ + private int index; + /** Offset of bit in the current int */ + private int bitOffset; + /** Indicates whether we are currently reading or writing */ + private boolean writing = true; + /** The current int we are reading from */ + private int currentWord; + + /** + * Create a new BitStream with a default size of 100 bytes. + */ + public BitStream() { + this(25); + } + + /** + * Create a new BitStream containing the given number of ints. The BitStream is + * implemented as an array of ints which will grow if necessary. + * @param numInts the initial size of the array of ints + */ + public BitStream(int numInts) { + bits = new int[numInts]; + } + + /** + * Rewinds the stream ready for reading. + */ + public void rewind() { + index = 0; + bitOffset = 0; + writing = false; + currentWord = bits[index]; + } + + /** + * Resets the stream so that it may be used again for writing. + */ + public void reset() { + rewind(); + bits[0] = 0; + writing = true; + } + + /** + * Write the number "n" into "len" bits in the current word. + */ + private void writeIntInWord(int n, int len) { + assert len > 0 : len; + if (len < 32) + n &= ((1 << len) - 1); + int b = bits[index]; + b |= (n << (32 - (bitOffset + len))); + bits[index] = b; + bitOffset += len; + } + + /** + * Write a number into the given number of bits. + * @param n the number to write + * @param len the number of bits to write the number to + */ + public void writeLongBits(long n, int len) { + assert len < 64 : len; + writeIntBits((int)(n >> 32), len - 32); + writeIntBits((int)n, 32); + } + + /** + * Write a number into the given number of bits. Note that there is no requirement + * that the given number be small enough to fit, the number written will be masked + * appropriately. + * @param n the number to write + * @param len the number of bits to write the number to + */ + public void writeIntBits(int n, int len) { + assert len > 0 && len <= 32 : len; + if (len < (32 - bitOffset)) { + writeIntInWord(n, len); + } else { + int firstlen = 32 - bitOffset; + int secondlen = len + bitOffset - 32; + if (firstlen > 0) { + writeIntInWord(n >>> secondlen, firstlen); + } + if (secondlen > 0) { + nextWord(); + bits[index] = 0; + writeIntInWord(n, secondlen); + } + } + } + + /** + * Move to the next full word boundary. + */ + public void nextWord() { + index++; + if (index >= bits.length) { + int[] tmp = new int[bits.length * 2]; + System.arraycopy(bits, 0, tmp, 0, bits.length); + bits = tmp; + } else if (writing) + bits[index] = 0; + currentWord = bits[index]; + bitOffset = 0; + } + + /** + * Returns the current word index + */ + public int getIndex() { + return index; + } + + /** + * Sets the word index to the given value. This also resets the bit offset to the + * beginning of the word. This method must only be used when reading to start reading + * a number stream from a saved position. + */ + public void setIndex(int index) { + assert !writing; + this.index = index; + currentWord = bits[index]; + bitOffset = 0; + } + + /** + * Reads an int in the current word from the given number of bits. + */ + private int readIntInWord(int len) { + int n = (currentWord >> (32 - (bitOffset + len))); + if (len < 32) + n &= ((1 << len) - 1); + bitOffset += len; + return n; + } + + /** + * Read an int from given number of bits. + * @param len the number of bits to read the number from + */ + public int readIntBits(int len) { + assert len > 0 && len <= 32 : len; + if (len < (32 - bitOffset)) { + return readIntInWord(len); + } else { + int firstlen = 32 - bitOffset; + int secondlen = len + bitOffset - 32; + int first = 0; + if (firstlen > 0) { + first = readIntInWord(firstlen); + } + int second = 0; + if (secondlen > 0) { + nextWord(); + second = readIntInWord(secondlen); + } + return (first << secondlen) | second; + } + } + + /** + * Read a long from given number of bits. + * @param len the number of bits to read the number from + */ + public long readLongBits(int len) { + assert len < 64 : len; + if (len <= 32) + return readIntBits(len); + long upper = readIntBits(len - 32); + assert upper >= 0 : upper; + long lower = readIntBits(32); + return (upper << 32) | (lower & 0xffffffffL); + } + + /** + * Returns the log2 of the given number. + */ + public static int log2(int n) { + int bit = 0; + while ((n & 0xffffff00 ) != 0) { + bit += 8; + n >>>= 8; + } + return bit + log2bytes[n]; + } + + private static final int log2bytes[] = { + -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + }; + + /** + * Outputs the unsigned integer using delta coding. Delta coding gives better results + * than gamma when larger numbers are more frequent. + * @return the number of bits used + */ + public int writeDelta(int n) { + int msb = log2(++n ); + int r = writeGamma(msb); + if (msb != 0) + writeIntBits(n, msb); + return r + msb; + } + + /** + * Outputs the given unsigned integer using gamma coding. Gamma coding is good when you + * know small numbers are much more frequent than large numbers. + * @return the number of bits used + */ + public int writeGamma(int n) { + int msb = log2(++n); + int r = writeUnary(msb); + if (msb != 0) + writeIntBits(n, msb); + return r + msb; + } + + /** + * Outputs the given unsigned integer as a unary number. Unary numbers are good for + * small integers. + * @return the number of bits used + */ + public int writeUnary(int n) { + for (int i = 0; i < n; i++) + writeIntBits(1, 1); + writeIntBits(0, 1); + return n + 1; + } + + /** + * Reads a delta coded integer. + */ + public int readDelta() { + int msb = readGamma(); + return msb == 0 ? 0 : ( (1 << msb) | readIntBits(msb) ) - 1; + } + + /** + * Reads a gamma coded integer. + */ + public int readGamma() { + int msb = readUnary(); + return msb == 0 ? 0 : ( (1 << msb) | readIntBits(msb) ) - 1; + } + + final static int[] nextUnsetBit = new int[256]; + + static { + for (int i = 0; i < 256; i++) { + nextUnsetBit[i] = -1; + for (int j = 0; j < 8; j++) { + if (((0x80 >> j) & i) == 0) { + nextUnsetBit[i] = j; + break; + } + } + } + } + + /** + * Read a unary coded integer. + */ + + /* + * XXX inefficient - needs to be improved like this: + * + * for + * get next whole word (shift left current, shift right next, or) + * for each byte in word + * get count from lookup table and add to sum + * if count not 8 + * break + */ + public int readUnary() { + int word = currentWord; + int offset = bitOffset; + int result = 0; + while (offset <= 24) { + int b = nextUnsetBit[(word >> (24 - offset)) & 0xff]; + if (b != -1) { + bitOffset = offset + b + 1; + return result + b; + } + offset += 8; + result += 8; + } + for (;; result++, offset++) { + if (offset == 32) { + nextWord(); + word = currentWord; + offset = 0; + } + if ((word & (0x80000000 >>> offset)) == 0) { + bitOffset = offset + 1; + return result; + } + } + } + + /** + * Write a number using variable byte code. This is good when you have lots of + * medium size numbers. + * @return the number of bits used + */ + public int writeVariableByte(int n) { + return writevb(n, true); + } + + private int writevb(int n, boolean end) { + int r = 0; + if (n >= 0x80 || n < 0) + r += writevb(n >>> 7, false); + n &= 0x7f; + if (end) n |= 0x80; + writeIntBits(n, 8); + return r + 8; + } + + /** + * Read a number using variable byte code. + */ + public int readVariableByte() { + for (int n = 0;; n <<= 7) { + int b = readIntBits(8); + n |= (b & 0x7f); + if ((b & 0x80) != 0) + return n; + } + } + + /** + * Write a number using Golomb-Rice coding. Good all rounder if you choose + * the right value of k, absolute rubbish otherwise! + * @param n the unsigned number to write + * @param k the number of bits to use for the remainder + * @return the number of bits used + */ + public int writeGolombRice(int n, int k) { + int r = writeUnary(n >>> k); + writeIntBits(n, k); + return r + k; + } + + /** + * Read a number using Golomb-Rice coding. + * @param k the number of bits to use for the remainder + */ + public int readGolombRice(int k) { + int n = readUnary() << k; + return n | readIntBits(k); + } + + /** + * Give a rough estimate of how many bytes of storage we use. This is the actual storage + * allocated so may be more that what is in use at any one time. + */ + public int memoryUsage() { + return bits.length * 4; + } + + /** + * This method is provided to test the BitStream. We need to change this to use unit + * tests at some point. + */ + public static void main(String[] args) { + final int DELTA = 1; + final int GAMMA = 2; + final int FIXED_BITS = 3; + final int VARIABLE_BYTE = 4; + final int GOLOMB = 5; + final int MAX = 5; + final int COUNT = 8000; + BitStream bs = new BitStream(); + Random rand = new Random(0); + + if (args.length != 0) { + /* Print some stats to give an idea which encoding is best */ + for (int i = 0; i < 4000; i++) { + System.out.println("" + i + ": gamma " + bs.writeGamma(i) + " delta " + bs.writeDelta(i) + " variable " + bs.writeVariableByte(i) + " g(2) " + bs.writeGolombRice(i, 2) + " g(3) " + bs.writeGolombRice(i, 3) + " g(5) " + bs.writeGolombRice(i, 5) + " g(7) " + bs.writeGolombRice(i, 7) + " g(8) " + bs.writeGolombRice(i, 8)); + bs.reset(); + } + return; + } + + for (int i = 0; i < 10; i++) { + bs.reset(); + int[] trueNumbers = new int[COUNT]; + byte[] codes = new byte[COUNT]; + byte[] numBits = new byte[COUNT]; + for (int j = 0; j < COUNT; j++) { + int bits = rand.nextInt(31); + int max = 1 << bits; + //int n = rand.nextInt(max); + int n = rand.nextInt(); + trueNumbers[j] = n; + codes[j] = (byte)(rand.nextInt(MAX) + 1); + switch (codes[j]) { + case DELTA: + System.out.println("doing " + j + " n " + n + " code " + codes[j]); + bs.writeDelta(n); + break; + case GAMMA: + System.out.println("doing " + j + " n " + n + " code " + codes[j]); + bs.writeGamma(n); + break; + case FIXED_BITS: + numBits[j] = (byte)(rand.nextInt(32) + 1); + bs.writeIntBits(n, numBits[j]); + int mask = (int)((1L << numBits[j]) - 1); + trueNumbers[j] &= mask; + System.out.println("doing " + j + " n " + n + " code " + codes[j] + " bits " + numBits[j]); + break; + case VARIABLE_BYTE: + System.out.println("doing " + j + " n " + n + " code " + codes[j]); + bs.writeVariableByte(n); + break; + case GOLOMB: + numBits[j] = (byte)(rand.nextInt(8) + 15); + System.out.println("doing " + j + " n " + n + " code " + codes[j] + " k " + numBits[j]); + bs.writeGolombRice(n, numBits[j]); + break; + } + } + System.out.println("done write for " + i); + bs.rewind(); + for (int j = 0; j < COUNT; j++) { + int n = trueNumbers[j]; + int k; + switch (codes[j]) { + case DELTA: + k = bs.readDelta(); + System.out.println("doing " + j + " k " + k + " code " + codes[j]); + if (k != n) + throw new Error("delta: expected " + n + " but got " + k); + break; + case GAMMA: + k = bs.readGamma(); + System.out.println("doing " + j + " k " + k + " code " + codes[j]); + if (k != n) + throw new Error("gamma: expected " + n + " but got " + k); + break; + case FIXED_BITS: + k = bs.readIntBits(numBits[j]); + System.out.println("doing " + j + " k " + k + " code " + codes[j] + " bits " + numBits[j]); + if (k != n) + throw new Error("fixed bits: expected " + n + " but got " + k); + break; + case VARIABLE_BYTE: + k = bs.readVariableByte(); + System.out.println("doing " + j + " k " + k + " code " + codes[j]); + if (k != n) + throw new Error("variable byte: expected " + n + " but got " + k); + break; + case GOLOMB: + k = bs.readGolombRice(numBits[j]); + System.out.println("doing " + j + " k " + k + " code " + codes[j]); + if (k != n) + throw new Error("golomb: expected " + n + " but got " + k); + break; + } + } + System.out.println("done " + i); + } + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/CharConversion.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/CharConversion.java index e9400e4de30..faa0ae123e5 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/CharConversion.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/CharConversion.java @@ -29,162 +29,162 @@ */ public class CharConversion { - /** - * Convert the given String to ebcdic bytes - * @param s the String to be converted - * @return the ebcdic byte array - */ - public static byte[] getEbcdicBytes(String s) { - try { - byte[] b = s.getBytes("8859_1"); - for (int i = 0; i < b.length; i++) { - b[i] = (byte)charToByteTable_str.charAt(b[i] < 0 ? b[i] + 256 : b[i]); - } - return b; - } catch (UnsupportedEncodingException e) { - // This should never happen - throw new Error("No 8859_1 encoding!"); - } - } + /** + * Convert the given String to ebcdic bytes + * @param s the String to be converted + * @return the ebcdic byte array + */ + public static byte[] getEbcdicBytes(String s) { + try { + byte[] b = s.getBytes("8859_1"); + for (int i = 0; i < b.length; i++) { + b[i] = (byte)charToByteTable_str.charAt(b[i] < 0 ? b[i] + 256 : b[i]); + } + return b; + } catch (UnsupportedEncodingException e) { + // This should never happen + throw new Error("No 8859_1 encoding!"); + } + } - /** - * Convert an array of ebcdic bytes to a String - * @param buf the array of ebcdic bytes - * @param offset the offset within the array where the bytes to be converted start - * @param length the number of bytes to convert - * @return the converted String - */ - public static String getEbcdicString(byte[] buf, int offset, int length) { - for (int i = 0; i < length; i++) { - buf[offset + i] = (byte)byteToCharTable_str.charAt(buf[offset + i] + 128); - } - try { - return new String(buf, offset, length, "8859_1"); - } catch (UnsupportedEncodingException e) { - // This should never happen - throw new Error("No 8859_1 encoding!"); - } - } + /** + * Convert an array of ebcdic bytes to a String + * @param buf the array of ebcdic bytes + * @param offset the offset within the array where the bytes to be converted start + * @param length the number of bytes to convert + * @return the converted String + */ + public static String getEbcdicString(byte[] buf, int offset, int length) { + for (int i = 0; i < length; i++) { + buf[offset + i] = (byte)byteToCharTable_str.charAt(buf[offset + i] + 128); + } + try { + return new String(buf, offset, length, "8859_1"); + } catch (UnsupportedEncodingException e) { + // This should never happen + throw new Error("No 8859_1 encoding!"); + } + } - /** - * Convert an array of ebcdic bytes to a String - * @param buf the array of ebcdic bytes - * @return the converted String - */ - public static String getEbcdicString(byte[] buf) { - return getEbcdicString(buf, 0, buf.length); - } + /** + * Convert an array of ebcdic bytes to a String + * @param buf the array of ebcdic bytes + * @return the converted String + */ + public static String getEbcdicString(byte[] buf) { + return getEbcdicString(buf, 0, buf.length); + } - /** - * Null terminates the given array. - * @param buf the array to be null terminated - * @return a copy of the array but with an extra zero byte at the end - */ - public static byte[] nullTerminate(byte[] buf) { - byte[] nbuf = new byte[buf.length + 1]; - System.arraycopy(buf, 0, nbuf, 0, buf.length); - return nbuf; - } + /** + * Null terminates the given array. + * @param buf the array to be null terminated + * @return a copy of the array but with an extra zero byte at the end + */ + public static byte[] nullTerminate(byte[] buf) { + byte[] nbuf = new byte[buf.length + 1]; + System.arraycopy(buf, 0, nbuf, 0, buf.length); + return nbuf; + } - private final static String byteToCharTable_str = + private final static String byteToCharTable_str = - "\u00D8\u0061\u0062\u0063\u0064\u0065\u0066\u0067" + // 0x80 - 0x87 - "\u0068\u0069\u00AB\u00BB\u00F0\u00FD\u00FE\u00B1" + // 0x88 - 0x8F - "\u00B0\u006A\u006B\u006C\u006D\u006E\u006F\u0070" + // 0x90 - 0x97 - "\u0071\u0072\u00AA\u00BA\u00E6\u00B8\u00C6\u00A4" + // 0x98 - 0x9F - "\u00B5\u007E\u0073\u0074\u0075\u0076\u0077\u0078" + // 0xA0 - 0xA7 - "\u0079\u007A\u00A1\u00BF\u00D0\u005B\u00DE\u00AE" + // 0xA8 - 0xAF - "\u00AC\u00A3\u00A5\u00B7\u00A9\u00A7\u00B6\u00BC" + // 0xB0 - 0xB7 - "\u00BD\u00BE\u00DD\u00A8\u00AF\u005D\u00B4\u00D7" + // 0xB8 - 0xBF - "\u007B\u0041\u0042\u0043\u0044\u0045\u0046\u0047" + // 0xC0 - 0xC7 - "\u0048\u0049\u00AD\u00F4\u00F6\u00F2\u00F3\u00F5" + // 0xC8 - 0xCF - "\u007D\u004A\u004B\u004C\u004D\u004E\u004F\u0050" + // 0xD0 - 0xD7 - "\u0051\u0052\u00B9\u00FB\u00FC\u00F9\u00FA\u00FF" + // 0xD8 - 0xDF - "\\\u00F7\u0053\u0054\u0055\u0056\u0057\u0058" + // 0xE0 - 0xE7 - "\u0059\u005A\u00B2\u00D4\u00D6\u00D2\u00D3\u00D5" + // 0xE8 - 0xEF - "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037" + // 0xF0 - 0xF7 - "\u0038\u0039\u00B3\u00DB\u00DC\u00D9\u00DA\u009F" + // 0xF8 - 0xFF - "\u0000\u0001\u0002\u0003\u009C\u0009\u0086\u007F" + // 0x00 - 0x07 - "\u0097\u008D\u008E\u000B\u000C\r\u000E\u000F" + // 0x08 - 0x0F - "\u0010\u0011\u0012\u0013\u009D\n\u0008\u0087" + // 0x10 - 0x17 - "\u0018\u0019\u0092\u008F\u001C\u001D\u001E\u001F" + // 0x18 - 0x1F - "\u0080\u0081\u0082\u0083\u0084\u0085\u0017\u001B" + // 0x20 - 0x27 - "\u0088\u0089\u008A\u008B\u008C\u0005\u0006\u0007" + // 0x28 - 0x2F - "\u0090\u0091\u0016\u0093\u0094\u0095\u0096\u0004" + // 0x30 - 0x37 - "\u0098\u0099\u009A\u009B\u0014\u0015\u009E\u001A" + // 0x38 - 0x3F - "\u0020\u00A0\u00E2\u00E4\u00E0\u00E1\u00E3\u00E5" + // 0x40 - 0x47 - "\u00E7\u00F1\u00A2\u002E\u003C\u0028\u002B\u007C" + // 0x48 - 0x4F - "\u0026\u00E9\u00EA\u00EB\u00E8\u00ED\u00EE\u00EF" + // 0x50 - 0x57 - "\u00EC\u00DF\u0021\u0024\u002A\u0029\u003B\u005E" + // 0x58 - 0x5F - "\u002D\u002F\u00C2\u00C4\u00C0\u00C1\u00C3\u00C5" + // 0x60 - 0x67 - "\u00C7\u00D1\u00A6\u002C\u0025\u005F\u003E\u003F" + // 0x68 - 0x6F - "\u00F8\u00C9\u00CA\u00CB\u00C8\u00CD\u00CE\u00CF" + // 0x70 - 0x77 - "\u00CC\u0060\u003A\u0023\u0040\u0027\u003D\""; // 0x78 - 0x7F + "\u00D8\u0061\u0062\u0063\u0064\u0065\u0066\u0067" + // 0x80 - 0x87 + "\u0068\u0069\u00AB\u00BB\u00F0\u00FD\u00FE\u00B1" + // 0x88 - 0x8F + "\u00B0\u006A\u006B\u006C\u006D\u006E\u006F\u0070" + // 0x90 - 0x97 + "\u0071\u0072\u00AA\u00BA\u00E6\u00B8\u00C6\u00A4" + // 0x98 - 0x9F + "\u00B5\u007E\u0073\u0074\u0075\u0076\u0077\u0078" + // 0xA0 - 0xA7 + "\u0079\u007A\u00A1\u00BF\u00D0\u005B\u00DE\u00AE" + // 0xA8 - 0xAF + "\u00AC\u00A3\u00A5\u00B7\u00A9\u00A7\u00B6\u00BC" + // 0xB0 - 0xB7 + "\u00BD\u00BE\u00DD\u00A8\u00AF\u005D\u00B4\u00D7" + // 0xB8 - 0xBF + "\u007B\u0041\u0042\u0043\u0044\u0045\u0046\u0047" + // 0xC0 - 0xC7 + "\u0048\u0049\u00AD\u00F4\u00F6\u00F2\u00F3\u00F5" + // 0xC8 - 0xCF + "\u007D\u004A\u004B\u004C\u004D\u004E\u004F\u0050" + // 0xD0 - 0xD7 + "\u0051\u0052\u00B9\u00FB\u00FC\u00F9\u00FA\u00FF" + // 0xD8 - 0xDF + "\\\u00F7\u0053\u0054\u0055\u0056\u0057\u0058" + // 0xE0 - 0xE7 + "\u0059\u005A\u00B2\u00D4\u00D6\u00D2\u00D3\u00D5" + // 0xE8 - 0xEF + "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037" + // 0xF0 - 0xF7 + "\u0038\u0039\u00B3\u00DB\u00DC\u00D9\u00DA\u009F" + // 0xF8 - 0xFF + "\u0000\u0001\u0002\u0003\u009C\u0009\u0086\u007F" + // 0x00 - 0x07 + "\u0097\u008D\u008E\u000B\u000C\r\u000E\u000F" + // 0x08 - 0x0F + "\u0010\u0011\u0012\u0013\u009D\n\u0008\u0087" + // 0x10 - 0x17 + "\u0018\u0019\u0092\u008F\u001C\u001D\u001E\u001F" + // 0x18 - 0x1F + "\u0080\u0081\u0082\u0083\u0084\u0085\u0017\u001B" + // 0x20 - 0x27 + "\u0088\u0089\u008A\u008B\u008C\u0005\u0006\u0007" + // 0x28 - 0x2F + "\u0090\u0091\u0016\u0093\u0094\u0095\u0096\u0004" + // 0x30 - 0x37 + "\u0098\u0099\u009A\u009B\u0014\u0015\u009E\u001A" + // 0x38 - 0x3F + "\u0020\u00A0\u00E2\u00E4\u00E0\u00E1\u00E3\u00E5" + // 0x40 - 0x47 + "\u00E7\u00F1\u00A2\u002E\u003C\u0028\u002B\u007C" + // 0x48 - 0x4F + "\u0026\u00E9\u00EA\u00EB\u00E8\u00ED\u00EE\u00EF" + // 0x50 - 0x57 + "\u00EC\u00DF\u0021\u0024\u002A\u0029\u003B\u005E" + // 0x58 - 0x5F + "\u002D\u002F\u00C2\u00C4\u00C0\u00C1\u00C3\u00C5" + // 0x60 - 0x67 + "\u00C7\u00D1\u00A6\u002C\u0025\u005F\u003E\u003F" + // 0x68 - 0x6F + "\u00F8\u00C9\u00CA\u00CB\u00C8\u00CD\u00CE\u00CF" + // 0x70 - 0x77 + "\u00CC\u0060\u003A\u0023\u0040\u0027\u003D\""; // 0x78 - 0x7F - private final static String charToByteTable_str = + private final static String charToByteTable_str = - "\u0000\u0001\u0002\u0003\u0037\u002D\u002E\u002F" + - "\u0016\u0005\u0015\u000B\u000C\r\u000E\u000F" + - "\u0010\u0011\u0012\u0013\u003C\u003D\u0032\u0026" + - "\u0018\u0019\u003F\u0027\u001C\u001D\u001E\u001F" + - "\u0040\u005A\u007F\u007B\u005B\u006C\u0050\u007D" + - "\u004D\u005D\\\u004E\u006B\u0060\u004B\u0061" + - "\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7" + - "\u00F8\u00F9\u007A\u005E\u004C\u007E\u006E\u006F" + - "\u007C\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7" + - "\u00C8\u00C9\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6" + - "\u00D7\u00D8\u00D9\u00E2\u00E3\u00E4\u00E5\u00E6" + - "\u00E7\u00E8\u00E9\u00AD\u00E0\u00BD\u005F\u006D" + - "\u0079\u0081\u0082\u0083\u0084\u0085\u0086\u0087" + - "\u0088\u0089\u0091\u0092\u0093\u0094\u0095\u0096" + - "\u0097\u0098\u0099\u00A2\u00A3\u00A4\u00A5\u00A6" + - "\u00A7\u00A8\u00A9\u00C0\u004F\u00D0\u00A1\u0007" + - "\u0020\u0021\"\u0023\u0024\u0025\u0006\u0017" + - "\u0028\u0029\u002A\u002B\u002C\t\n\u001B" + - "\u0030\u0031\u001A\u0033\u0034\u0035\u0036\u0008" + - "\u0038\u0039\u003A\u003B\u0004\u0014\u003E\u00FF" + - "\u0041\u00AA\u004A\u00B1\u009F\u00B2\u006A\u00B5" + - "\u00BB\u00B4\u009A\u008A\u00B0\u00CA\u00AF\u00BC" + - "\u0090\u008F\u00EA\u00FA\u00BE\u00A0\u00B6\u00B3" + - "\u009D\u00DA\u009B\u008B\u00B7\u00B8\u00B9\u00AB" + - "\u0064\u0065\u0062\u0066\u0063\u0067\u009E\u0068" + - "\u0074\u0071\u0072\u0073\u0078\u0075\u0076\u0077" + - "\u00AC\u0069\u00ED\u00EE\u00EB\u00EF\u00EC\u00BF" + - "\u0080\u00FD\u00FE\u00FB\u00FC\u00BA\u00AE\u0059" + - "\u0044\u0045\u0042\u0046\u0043\u0047\u009C\u0048" + - "\u0054\u0051\u0052\u0053\u0058\u0055\u0056\u0057" + - "\u008C\u0049\u00CD\u00CE\u00CB\u00CF\u00CC\u00E1" + - "\u0070\u00DD\u00DE\u00DB\u00DC\u008D\u008E\u00DF" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"; + "\u0000\u0001\u0002\u0003\u0037\u002D\u002E\u002F" + + "\u0016\u0005\u0015\u000B\u000C\r\u000E\u000F" + + "\u0010\u0011\u0012\u0013\u003C\u003D\u0032\u0026" + + "\u0018\u0019\u003F\u0027\u001C\u001D\u001E\u001F" + + "\u0040\u005A\u007F\u007B\u005B\u006C\u0050\u007D" + + "\u004D\u005D\\\u004E\u006B\u0060\u004B\u0061" + + "\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7" + + "\u00F8\u00F9\u007A\u005E\u004C\u007E\u006E\u006F" + + "\u007C\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7" + + "\u00C8\u00C9\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6" + + "\u00D7\u00D8\u00D9\u00E2\u00E3\u00E4\u00E5\u00E6" + + "\u00E7\u00E8\u00E9\u00AD\u00E0\u00BD\u005F\u006D" + + "\u0079\u0081\u0082\u0083\u0084\u0085\u0086\u0087" + + "\u0088\u0089\u0091\u0092\u0093\u0094\u0095\u0096" + + "\u0097\u0098\u0099\u00A2\u00A3\u00A4\u00A5\u00A6" + + "\u00A7\u00A8\u00A9\u00C0\u004F\u00D0\u00A1\u0007" + + "\u0020\u0021\"\u0023\u0024\u0025\u0006\u0017" + + "\u0028\u0029\u002A\u002B\u002C\t\n\u001B" + + "\u0030\u0031\u001A\u0033\u0034\u0035\u0036\u0008" + + "\u0038\u0039\u003A\u003B\u0004\u0014\u003E\u00FF" + + "\u0041\u00AA\u004A\u00B1\u009F\u00B2\u006A\u00B5" + + "\u00BB\u00B4\u009A\u008A\u00B0\u00CA\u00AF\u00BC" + + "\u0090\u008F\u00EA\u00FA\u00BE\u00A0\u00B6\u00B3" + + "\u009D\u00DA\u009B\u008B\u00B7\u00B8\u00B9\u00AB" + + "\u0064\u0065\u0062\u0066\u0063\u0067\u009E\u0068" + + "\u0074\u0071\u0072\u0073\u0078\u0075\u0076\u0077" + + "\u00AC\u0069\u00ED\u00EE\u00EB\u00EF\u00EC\u00BF" + + "\u0080\u00FD\u00FE\u00FB\u00FC\u00BA\u00AE\u0059" + + "\u0044\u0045\u0042\u0046\u0043\u0047\u009C\u0048" + + "\u0054\u0051\u0052\u0053\u0058\u0055\u0056\u0057" + + "\u008C\u0049\u00CD\u00CE\u00CB\u00CF\u00CC\u00E1" + + "\u0070\u00DD\u00DE\u00DB\u00DC\u008D\u008E\u00DF" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"; } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/Clib.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/Clib.java index 9bf789328c5..be5eb226320 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/Clib.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/Clib.java @@ -37,118 +37,118 @@ public class Clib { - /** - * This method is a wrapper around fopen. - * @param filename the name of the file to open as a null-terminated ebcdic byte array - * @param mode the open mode which must be a null-terminated ebcdic byte array. See the - * C library fopen documentation for more details - * @return the FILE stream pointer from fopen cast to a long - */ - public static long fopen(byte[] filename, byte[]mode) { - return rawFopen(filename, mode); - } - - private static native long rawFopen(byte[] filename, byte[]mode); - - /** - * This method is a slightly friendlier version of the native fopen call (the - * parameters are Strings rather than byte arrays otherwise everything is the same). - */ - public static long fopen(String filename, String mode) { - return fopen(CharConversion.nullTerminate(CharConversion.getEbcdicBytes(filename)), CharConversion.nullTerminate(CharConversion.getEbcdicBytes(mode))); - } - - /** - * This method is a wrapper around fgetpos. Here we make use of the knowledge that a C - * fpos_t on z/OS is actually an array of 8 ints. - * @param fp the stream obtained from an earlier call to fopen - * @param pos this must be an array of 8 ints. The position indicator is stored in - * this array. The same array contents may be passed to a subsequent fsetpos call. - * @return the return code from the fgetpos call (zero if successful) - */ - public static int fgetpos(long fp, int[] pos) { - assert pos.length == 8 : pos.length; - assert fp != 0; - return rawFgetpos(fp, pos); - } - - private static native int rawFgetpos(long fp, int[] pos); - - /** - * This method is a wrapper around fsetpos. - * @param fp the stream obtained from an earlier call to fopen - * @param pos this must be an array of 8 ints whose contents were obtained in a previous - * call to fgetpos. - * @return the return code from the fsetpos call (zero if successful) - */ - public static int fsetpos(long fp, int[] pos) { - assert pos.length == 8 : pos.length; - assert fp != 0; - return rawFsetpos(fp, pos); - } - - private static native int rawFsetpos(long fp, int[] pos); - - /** - * This method is a wrapper around fseek. (Note: this hasn't been tested for seeks - * over 2GB yet). - * @param fp the stream obtained from an earlier call to fopen - * @param offset the offset to seek to - * @param whence specifies where to seek from - * @return the return code from the fseek call (zero if successful) - */ - public static int fseek(long fp, long offset, int whence) { - assert fp != 0; - return rawFseek(fp, offset, whence); - } - - private static native int rawFseek(long fp, long offset, int whence); - - /** fseek whence argument to indicate that offset is from the beginning of the file */ - public static final int SEEK_SET = 0; - - /** fseek whence argument to indicate that offset is from the current position of the - * file pointer */ - public static final int SEEK_CUR = 1; - - /** fseek whence argument to indicate that offset is from the end of the file */ - public static final int SEEK_END = 2; - - /** - * This method is a wrapper around fread. - * @param buf the buffer to contain the read data - * @param size the size of each element - * @param count the number of elements to read - * @param fp the stream obtained from an earlier call to fopen - * @return the number of elements read - */ - public static int fread(byte[] buf, int size, int count, long fp) { - assert size * count <= buf.length; - assert fp != 0; - return rawFread(buf, size, count, fp); - } - - private static native int rawFread(byte[] buf, int size, int count, long fp); - - /** - * This method is a wrapper around perror. - * @param prefix the message prefix as a null-terminated ebcdic byte array - * @return the FILE stream pointer from fopen cast to a long - */ - public static void perror(byte[] prefix) { - rawPerror(prefix); - } - - private static native void rawPerror(byte[] prefix); - - /** - * Friendlier version of the native perror call that accepts a String parameter. - */ - public static void perror(String prefix) { - perror(CharConversion.nullTerminate(CharConversion.getEbcdicBytes(prefix))); - } - - static String hex(int n) { - return Integer.toHexString(n); - } + /** + * This method is a wrapper around fopen. + * @param filename the name of the file to open as a null-terminated ebcdic byte array + * @param mode the open mode which must be a null-terminated ebcdic byte array. See the + * C library fopen documentation for more details + * @return the FILE stream pointer from fopen cast to a long + */ + public static long fopen(byte[] filename, byte[] mode) { + return rawFopen(filename, mode); + } + + private static native long rawFopen(byte[] filename, byte[] mode); + + /** + * This method is a slightly friendlier version of the native fopen call (the + * parameters are Strings rather than byte arrays otherwise everything is the same). + */ + public static long fopen(String filename, String mode) { + return fopen(CharConversion.nullTerminate(CharConversion.getEbcdicBytes(filename)), CharConversion.nullTerminate(CharConversion.getEbcdicBytes(mode))); + } + + /** + * This method is a wrapper around fgetpos. Here we make use of the knowledge that a C + * fpos_t on z/OS is actually an array of 8 ints. + * @param fp the stream obtained from an earlier call to fopen + * @param pos this must be an array of 8 ints. The position indicator is stored in + * this array. The same array contents may be passed to a subsequent fsetpos call. + * @return the return code from the fgetpos call (zero if successful) + */ + public static int fgetpos(long fp, int[] pos) { + assert pos.length == 8 : pos.length; + assert fp != 0; + return rawFgetpos(fp, pos); + } + + private static native int rawFgetpos(long fp, int[] pos); + + /** + * This method is a wrapper around fsetpos. + * @param fp the stream obtained from an earlier call to fopen + * @param pos this must be an array of 8 ints whose contents were obtained in a previous + * call to fgetpos. + * @return the return code from the fsetpos call (zero if successful) + */ + public static int fsetpos(long fp, int[] pos) { + assert pos.length == 8 : pos.length; + assert fp != 0; + return rawFsetpos(fp, pos); + } + + private static native int rawFsetpos(long fp, int[] pos); + + /** + * This method is a wrapper around fseek. (Note: this hasn't been tested for seeks + * over 2GB yet). + * @param fp the stream obtained from an earlier call to fopen + * @param offset the offset to seek to + * @param whence specifies where to seek from + * @return the return code from the fseek call (zero if successful) + */ + public static int fseek(long fp, long offset, int whence) { + assert fp != 0; + return rawFseek(fp, offset, whence); + } + + private static native int rawFseek(long fp, long offset, int whence); + + /** fseek whence argument to indicate that offset is from the beginning of the file */ + public static final int SEEK_SET = 0; + + /** fseek whence argument to indicate that offset is from the current position of the + * file pointer */ + public static final int SEEK_CUR = 1; + + /** fseek whence argument to indicate that offset is from the end of the file */ + public static final int SEEK_END = 2; + + /** + * This method is a wrapper around fread. + * @param buf the buffer to contain the read data + * @param size the size of each element + * @param count the number of elements to read + * @param fp the stream obtained from an earlier call to fopen + * @return the number of elements read + */ + public static int fread(byte[] buf, int size, int count, long fp) { + assert size * count <= buf.length; + assert fp != 0; + return rawFread(buf, size, count, fp); + } + + private static native int rawFread(byte[] buf, int size, int count, long fp); + + /** + * This method is a wrapper around perror. + * @param prefix the message prefix as a null-terminated ebcdic byte array + * @return the FILE stream pointer from fopen cast to a long + */ + public static void perror(byte[] prefix) { + rawPerror(prefix); + } + + private static native void rawPerror(byte[] prefix); + + /** + * Friendlier version of the native perror call that accepts a String parameter. + */ + public static void perror(String prefix) { + perror(CharConversion.nullTerminate(CharConversion.getEbcdicBytes(prefix))); + } + + static String hex(int n) { + return Integer.toHexString(n); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/CompressedRecordArray.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/CompressedRecordArray.java index 53c75fad95e..3809fa24deb 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/CompressedRecordArray.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/CompressedRecordArray.java @@ -75,427 +75,427 @@ public final class CompressedRecordArray implements Serializable { - /** Log2 of the size of each block */ - private int blockSizeLog2; - /** Size of each block */ - private int blockSize; - /** Size of each record array */ - private int recordSize; - /** The index into bitStreamIndex */ - private int index; - /** Index into the bit stream */ - private int[] bitStreamIndex = new int[16]; - /** The current block we are writing into */ - private int[][] currentBlock; - /** Index of record in this block */ - private int currentBlockIndex; - /** The bit stream where most of the data is actually stored */ - private BitStream bits = new BitStream(); - /* - * Following are all working variables that could be local but are made - * global to save on GC. - */ - private boolean[][] isNegative; - private int[] lastValue; - private int[] maxDelta; - private boolean[] allSameDelta; - private boolean[] allPositive; - private byte[] encoding; - /** Set to true when closed and ready for reading */ - private boolean closed = false; - /** Total number of records written */ - private int numRecords; - /* Possible encoding types: */ - private static final int GOLOMB2 = 0; - private static final int GOLOMB7 = 1; - private static final int GOLOMB8 = 2; - private static final int VARIABLE_BYTE = 3; - /* Following are for stat collecting only */ - private static int numGolomb2; - private static int numGolomb7; - private static int numGolomb8; - private static int numVariableByte; - private static int numAllSameDelta; - private static int numNotAllSameDelta; - private static int numNegative; - private static int numAllPositive; + /** Log2 of the size of each block */ + private int blockSizeLog2; + /** Size of each block */ + private int blockSize; + /** Size of each record array */ + private int recordSize; + /** The index into bitStreamIndex */ + private int index; + /** Index into the bit stream */ + private int[] bitStreamIndex = new int[16]; + /** The current block we are writing into */ + private int[][] currentBlock; + /** Index of record in this block */ + private int currentBlockIndex; + /** The bit stream where most of the data is actually stored */ + private BitStream bits = new BitStream(); + /* + * Following are all working variables that could be local but are made + * global to save on GC. + */ + private boolean[][] isNegative; + private int[] lastValue; + private int[] maxDelta; + private boolean[] allSameDelta; + private boolean[] allPositive; + private byte[] encoding; + /** Set to true when closed and ready for reading */ + private boolean closed = false; + /** Total number of records written */ + private int numRecords; + /* Possible encoding types: */ + private static final int GOLOMB2 = 0; + private static final int GOLOMB7 = 1; + private static final int GOLOMB8 = 2; + private static final int VARIABLE_BYTE = 3; + /* Following are for stat collecting only */ + private static int numGolomb2; + private static int numGolomb7; + private static int numGolomb8; + private static int numVariableByte; + private static int numAllSameDelta; + private static int numNotAllSameDelta; + private static int numNegative; + private static int numAllPositive; - /** - * Create a new CompressedRecordArray. A size of 5 for blockSizeLog2 gives good results. - * @param blockSizeLog2 the number of records in each block expressed as a power of 2 - * @param recordSize the number of ints in each record - */ - public CompressedRecordArray(int blockSizeLog2, int recordSize) { - this.blockSizeLog2 = blockSizeLog2; - blockSize = 1 << blockSizeLog2; - this.recordSize = recordSize; - currentBlock = new int[blockSize][recordSize]; - isNegative = new boolean[blockSize][recordSize]; - lastValue = new int[recordSize]; - maxDelta = new int[recordSize]; - allSameDelta = new boolean[recordSize]; - allPositive = new boolean[recordSize]; - encoding = new byte[recordSize]; - } + /** + * Create a new CompressedRecordArray. A size of 5 for blockSizeLog2 gives good results. + * @param blockSizeLog2 the number of records in each block expressed as a power of 2 + * @param recordSize the number of ints in each record + */ + public CompressedRecordArray(int blockSizeLog2, int recordSize) { + this.blockSizeLog2 = blockSizeLog2; + blockSize = 1 << blockSizeLog2; + this.recordSize = recordSize; + currentBlock = new int[blockSize][recordSize]; + isNegative = new boolean[blockSize][recordSize]; + lastValue = new int[recordSize]; + maxDelta = new int[recordSize]; + allSameDelta = new boolean[recordSize]; + allPositive = new boolean[recordSize]; + encoding = new byte[recordSize]; + } - /** - * Add a new record. Data is copied from the given array. - * @param record an array of ints which forms the record to be added - */ - public void add(int[] record) { - assert !closed; - for (int i = 0; i < recordSize; i++) { - currentBlock[currentBlockIndex][i] = record[i]; - } - if (++currentBlockIndex == blockSize) { - flushCurrentBlock(); - currentBlockIndex = 0; - } - numRecords++; - } + /** + * Add a new record. Data is copied from the given array. + * @param record an array of ints which forms the record to be added + */ + public void add(int[] record) { + assert !closed; + for (int i = 0; i < recordSize; i++) { + currentBlock[currentBlockIndex][i] = record[i]; + } + if (++currentBlockIndex == blockSize) { + flushCurrentBlock(); + currentBlockIndex = 0; + } + numRecords++; + } - /** - * Close this CompressedRecordArray. This must be called before any reading is done - * and no more records may be added afterwards. - */ - public void close() { - flushCurrentBlock(); - bits.rewind(); - closed = true; - } + /** + * Close this CompressedRecordArray. This must be called before any reading is done + * and no more records may be added afterwards. + */ + public void close() { + flushCurrentBlock(); + bits.rewind(); + closed = true; + } - /** - * Flush the current block - */ - private void flushCurrentBlock() { - /* - * Save the current index for this block - */ - bitStreamIndex[index++] = bits.getIndex(); - if (index == bitStreamIndex.length) { - int[] tmp = new int[index * 2]; - System.arraycopy(bitStreamIndex, 0, tmp, 0, index); - bitStreamIndex = tmp; - } - /* - * Output the compressed block to the bit stream - */ - compressBlock(); - /* - * Realign bit stream at the next word - */ - bits.nextWord(); - } + /** + * Flush the current block + */ + private void flushCurrentBlock() { + /* + * Save the current index for this block + */ + bitStreamIndex[index++] = bits.getIndex(); + if (index == bitStreamIndex.length) { + int[] tmp = new int[index * 2]; + System.arraycopy(bitStreamIndex, 0, tmp, 0, index); + bitStreamIndex = tmp; + } + /* + * Output the compressed block to the bit stream + */ + compressBlock(); + /* + * Realign bit stream at the next word + */ + bits.nextWord(); + } - /** - * Compress the current block of records - */ - private void compressBlock() { - /* - * Normalize data by converting to deltas and then making numbers absolute. We also - * gather some stats to help decide which encoding to use. We store deltas (ie the - * difference between consecutive values) rather than the values themselves because - * we are often storing structured data where a value is increasing (or decreasing) - * with each record. If this is not the case, it does no harm to store deltas anyway. - */ - for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { - lastValue[recordIndex] = currentBlock[0][recordIndex]; - maxDelta[recordIndex] = 0; - allSameDelta[recordIndex] = true; - allPositive[recordIndex] = true; - int lastDelta = 0; - for (int blockIndex = 1; blockIndex < currentBlockIndex; blockIndex++) { - int delta = currentBlock[blockIndex][recordIndex] - lastValue[recordIndex]; - if (delta < 0) { - /* - * Found a negative delta. Make absolute and also set the allPositive - * flag to indicate we need to store sign bits. - */ - isNegative[blockIndex][recordIndex] = true; - delta = -delta; - allPositive[recordIndex] = false; - numNegative++; - } else { - isNegative[blockIndex][recordIndex] = false; - } - if (delta > maxDelta[recordIndex]) - maxDelta[recordIndex] = delta; - if (blockIndex > 1 && delta != lastDelta) { - /* - * Not all deltas are the same so reset the flag. - */ - allSameDelta[recordIndex] = false; - numNotAllSameDelta++; - } - /* - * Save the last value and also replace the current value with its delta. - */ - lastValue[recordIndex] = currentBlock[blockIndex][recordIndex]; - lastDelta = delta; - currentBlock[blockIndex][recordIndex] = delta; - } - if (allPositive[recordIndex]) - numAllPositive++; - if (allSameDelta[recordIndex]) - numAllSameDelta++; - } - /* - * Now figure out what encoding to use and output the block header. - */ - for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { - /* We can skip the sign bit if all are positive */ - bits.writeIntBits(allPositive[recordIndex] ? 1 : 0, 1); - /* We can skip most of the record altogether if all delta values are the same */ - bits.writeIntBits(allSameDelta[recordIndex] ? 1 : 0, 1); - /* There's probably a more mathematical way but this will do for now */ - if (maxDelta[recordIndex] < 24) { - encoding[recordIndex] = GOLOMB2; - numGolomb2++; - } else if (maxDelta[recordIndex] < 384) { - encoding[recordIndex] = GOLOMB7; - numGolomb7++; - } else if (maxDelta[recordIndex] < 2048) { - encoding[recordIndex] = GOLOMB8; - numGolomb8++; - } else { - encoding[recordIndex] = VARIABLE_BYTE; - numVariableByte++; - } - bits.writeIntBits(encoding[recordIndex], 2); - } - /* - * Ok, now we can output the block data itself. - */ - for (int blockIndex = 0; blockIndex < currentBlockIndex; blockIndex++) { - for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { - /* The first record always uses variable byte */ - if (blockIndex == 0) { - bits.writeVariableByte(currentBlock[blockIndex][recordIndex]); - /* Only output remainder if not the same as first delta */ - } else if (blockIndex == 1 || !allSameDelta[recordIndex]) { - /* Output the sign bit if any */ - if (!allPositive[recordIndex]) { - bits.writeIntBits(isNegative[blockIndex][recordIndex] ? 1 : 0, 1); - } - switch (encoding[recordIndex]) { - case GOLOMB2: - bits.writeGolombRice(currentBlock[blockIndex][recordIndex], 2); - break; - case GOLOMB7: - bits.writeGolombRice(currentBlock[blockIndex][recordIndex], 7); - break; - case GOLOMB8: - bits.writeGolombRice(currentBlock[blockIndex][recordIndex], 8); - break; - case VARIABLE_BYTE: - bits.writeVariableByte(currentBlock[blockIndex][recordIndex]); - break; - } - } - } - } - } + /** + * Compress the current block of records + */ + private void compressBlock() { + /* + * Normalize data by converting to deltas and then making numbers absolute. We also + * gather some stats to help decide which encoding to use. We store deltas (ie the + * difference between consecutive values) rather than the values themselves because + * we are often storing structured data where a value is increasing (or decreasing) + * with each record. If this is not the case, it does no harm to store deltas anyway. + */ + for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { + lastValue[recordIndex] = currentBlock[0][recordIndex]; + maxDelta[recordIndex] = 0; + allSameDelta[recordIndex] = true; + allPositive[recordIndex] = true; + int lastDelta = 0; + for (int blockIndex = 1; blockIndex < currentBlockIndex; blockIndex++) { + int delta = currentBlock[blockIndex][recordIndex] - lastValue[recordIndex]; + if (delta < 0) { + /* + * Found a negative delta. Make absolute and also set the allPositive + * flag to indicate we need to store sign bits. + */ + isNegative[blockIndex][recordIndex] = true; + delta = -delta; + allPositive[recordIndex] = false; + numNegative++; + } else { + isNegative[blockIndex][recordIndex] = false; + } + if (delta > maxDelta[recordIndex]) + maxDelta[recordIndex] = delta; + if (blockIndex > 1 && delta != lastDelta) { + /* + * Not all deltas are the same so reset the flag. + */ + allSameDelta[recordIndex] = false; + numNotAllSameDelta++; + } + /* + * Save the last value and also replace the current value with its delta. + */ + lastValue[recordIndex] = currentBlock[blockIndex][recordIndex]; + lastDelta = delta; + currentBlock[blockIndex][recordIndex] = delta; + } + if (allPositive[recordIndex]) + numAllPositive++; + if (allSameDelta[recordIndex]) + numAllSameDelta++; + } + /* + * Now figure out what encoding to use and output the block header. + */ + for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { + /* We can skip the sign bit if all are positive */ + bits.writeIntBits(allPositive[recordIndex] ? 1 : 0, 1); + /* We can skip most of the record altogether if all delta values are the same */ + bits.writeIntBits(allSameDelta[recordIndex] ? 1 : 0, 1); + /* There's probably a more mathematical way but this will do for now */ + if (maxDelta[recordIndex] < 24) { + encoding[recordIndex] = GOLOMB2; + numGolomb2++; + } else if (maxDelta[recordIndex] < 384) { + encoding[recordIndex] = GOLOMB7; + numGolomb7++; + } else if (maxDelta[recordIndex] < 2048) { + encoding[recordIndex] = GOLOMB8; + numGolomb8++; + } else { + encoding[recordIndex] = VARIABLE_BYTE; + numVariableByte++; + } + bits.writeIntBits(encoding[recordIndex], 2); + } + /* + * Ok, now we can output the block data itself. + */ + for (int blockIndex = 0; blockIndex < currentBlockIndex; blockIndex++) { + for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { + /* The first record always uses variable byte */ + if (blockIndex == 0) { + bits.writeVariableByte(currentBlock[blockIndex][recordIndex]); + /* Only output remainder if not the same as first delta */ + } else if (blockIndex == 1 || !allSameDelta[recordIndex]) { + /* Output the sign bit if any */ + if (!allPositive[recordIndex]) { + bits.writeIntBits(isNegative[blockIndex][recordIndex] ? 1 : 0, 1); + } + switch (encoding[recordIndex]) { + case GOLOMB2: + bits.writeGolombRice(currentBlock[blockIndex][recordIndex], 2); + break; + case GOLOMB7: + bits.writeGolombRice(currentBlock[blockIndex][recordIndex], 7); + break; + case GOLOMB8: + bits.writeGolombRice(currentBlock[blockIndex][recordIndex], 8); + break; + case VARIABLE_BYTE: + bits.writeVariableByte(currentBlock[blockIndex][recordIndex]); + break; + } + } + } + } + } - /** - * Get the given record number. To save on GC overhead the user supplies the - * int array to copy the record into. - * @param recordNumber the sequential number of the record to read - * @param record the array to copy the record into - */ - public void get(int recordNumber, int[] record) { - assert closed ; - assert recordNumber < numRecords; - /* - * First position the bit stream at the block header - */ - index = recordNumber >> blockSizeLog2; - bits.setIndex(bitStreamIndex[index]); + /** + * Get the given record number. To save on GC overhead the user supplies the + * int array to copy the record into. + * @param recordNumber the sequential number of the record to read + * @param record the array to copy the record into + */ + public void get(int recordNumber, int[] record) { + assert closed ; + assert recordNumber < numRecords; + /* + * First position the bit stream at the block header + */ + index = recordNumber >> blockSizeLog2; + bits.setIndex(bitStreamIndex[index]); - /* Get the index within the block */ - int desiredBlockIndex = recordNumber & (blockSize - 1); + /* Get the index within the block */ + int desiredBlockIndex = recordNumber & (blockSize - 1); - /* - * Read the block header containing flags plus the encoding. - */ - for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { - allPositive[recordIndex] = (bits.readIntBits(1) == 1); - allSameDelta[recordIndex] = (bits.readIntBits(1) == 1); - encoding[recordIndex] = (byte)bits.readIntBits(2); - } + /* + * Read the block header containing flags plus the encoding. + */ + for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { + allPositive[recordIndex] = (bits.readIntBits(1) == 1); + allSameDelta[recordIndex] = (bits.readIntBits(1) == 1); + encoding[recordIndex] = (byte)bits.readIntBits(2); + } - /* - * Now scan through decompressing as we go until we reach the desired record - */ - for (int blockIndex = 0; blockIndex <= desiredBlockIndex; blockIndex++) { - for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { - /* The first record always uses variable byte */ - if (blockIndex == 0) { - currentBlock[blockIndex][recordIndex] = bits.readVariableByte(); - /* Only read remainder if not the same as first delta */ - } else if (blockIndex == 1 || !allSameDelta[recordIndex]) { - int delta = 0; - boolean isNegative = false; - /* Input the sign bit if any */ - if (!allPositive[recordIndex]) { - isNegative = (bits.readIntBits(1) == 1); - } - /* - * Read the delta using the appropriate encoding. - */ - switch (encoding[recordIndex]) { - case GOLOMB2: - delta = bits.readGolombRice(2); - break; - case GOLOMB7: - delta = bits.readGolombRice(7); - break; - case GOLOMB8: - delta = bits.readGolombRice(8); - break; - case VARIABLE_BYTE: - delta = bits.readVariableByte(); - break; - } - /* Apply sign bit */ - if (isNegative) - delta = -delta; - /* Add delta to previous value to restore original value */ - currentBlock[blockIndex][recordIndex] = currentBlock[blockIndex-1][recordIndex] + delta; - /* Reuse the lastValue array to hold the last delta */ - lastValue[recordIndex] = delta; - } else { - /* - * All the deltas are the same from the second record on so just reuse - * the delta we saved in lastValue. - */ - currentBlock[blockIndex][recordIndex] = currentBlock[blockIndex-1][recordIndex] + lastValue[recordIndex]; - } - } - } - /* - * Finally copy the restored record into the supplied array. - */ - for (int i = 0; i < recordSize; i++) { - record[i] = currentBlock[desiredBlockIndex][i]; - } - } + /* + * Now scan through decompressing as we go until we reach the desired record + */ + for (int blockIndex = 0; blockIndex <= desiredBlockIndex; blockIndex++) { + for (int recordIndex = 0; recordIndex < recordSize; recordIndex++) { + /* The first record always uses variable byte */ + if (blockIndex == 0) { + currentBlock[blockIndex][recordIndex] = bits.readVariableByte(); + /* Only read remainder if not the same as first delta */ + } else if (blockIndex == 1 || !allSameDelta[recordIndex]) { + int delta = 0; + boolean isNegative = false; + /* Input the sign bit if any */ + if (!allPositive[recordIndex]) { + isNegative = (bits.readIntBits(1) == 1); + } + /* + * Read the delta using the appropriate encoding. + */ + switch (encoding[recordIndex]) { + case GOLOMB2: + delta = bits.readGolombRice(2); + break; + case GOLOMB7: + delta = bits.readGolombRice(7); + break; + case GOLOMB8: + delta = bits.readGolombRice(8); + break; + case VARIABLE_BYTE: + delta = bits.readVariableByte(); + break; + } + /* Apply sign bit */ + if (isNegative) + delta = -delta; + /* Add delta to previous value to restore original value */ + currentBlock[blockIndex][recordIndex] = currentBlock[blockIndex-1][recordIndex] + delta; + /* Reuse the lastValue array to hold the last delta */ + lastValue[recordIndex] = delta; + } else { + /* + * All the deltas are the same from the second record on so just reuse + * the delta we saved in lastValue. + */ + currentBlock[blockIndex][recordIndex] = currentBlock[blockIndex-1][recordIndex] + lastValue[recordIndex]; + } + } + } + /* + * Finally copy the restored record into the supplied array. + */ + for (int i = 0; i < recordSize; i++) { + record[i] = currentBlock[desiredBlockIndex][i]; + } + } - /** - * Give a rough estimate of how many bytes of storage we use. This is the actual storage - * allocated so may be more that what is in use at any one time. - */ - public int memoryUsage() { - return bits.memoryUsage() + (bitStreamIndex.length * 4) + (blockSize * recordSize * 4 * 2) - + (recordSize * (4 + 4 + 1 + 1 + 1)); - } + /** + * Give a rough estimate of how many bytes of storage we use. This is the actual storage + * allocated so may be more that what is in use at any one time. + */ + public int memoryUsage() { + return bits.memoryUsage() + (bitStreamIndex.length * 4) + (blockSize * recordSize * 4 * 2) + + (recordSize * (4 + 4 + 1 + 1 + 1)); + } - /** - * This method is provided to test the CompressedRecordArray. We need to change this to use - * unit tests at some point. - * @exclude - * @throws Exception if anything bad happens - */ - public static void main(String[] args) throws Exception { - if (args.length != 0) { - fpostest(args[0]); - return; - } - for (int blockSizeLog2 = 0; blockSizeLog2 < 10; blockSizeLog2++) { - int blockSize = 1 << blockSizeLog2; - for (int recordSize = 1; recordSize < 20; recordSize++) { - System.out.println("doing blockSize " + blockSize + " recordSize " + recordSize); - CompressedRecordArray ra = new CompressedRecordArray(blockSizeLog2, recordSize); - int[] record = new int[recordSize]; - for (int i = 0; i < blockSize*10 + recordSize; i++) { - for (int j = 0; j < recordSize; j++) { - int value = i*i*j; - if ((recordSize % 3) == 0 && (j % 3) == 0) - // this should give all same deltas - value = i * blockSize * recordSize; - else if ((j % 5) == 0) - value = -value; - record[j] = value; - } - ra.add(record); - } - ra.close(); - for (int i = 0; i < blockSize*10 + recordSize; i++) { - ra.get(i, record); - for (int j = 0; j < recordSize; j++) { - int value = i*i*j; - if ((recordSize % 3) == 0 && (j % 3) == 0) - // this should give all same deltas - value = i * blockSize * recordSize; - else if ((j % 5) == 0) - value = -value; - if (record[j] != value) - throw new Error("found " + record[j] + " expected " + value); - } - } - } - } - System.out.println("numGolomb2 = " + numGolomb2); - System.out.println("numGolomb7 = " + numGolomb7); - System.out.println("numGolomb8 = " + numGolomb8); - System.out.println("numVariableByte = " + numVariableByte); - System.out.println("numAllSameDelta = " + numAllSameDelta); - System.out.println("numNotAllSameDelta = " + numNotAllSameDelta); - System.out.println("numNegative = " + numNegative); - System.out.println("numAllPositive = " + numAllPositive); - } + /** + * This method is provided to test the CompressedRecordArray. We need to change this to use + * unit tests at some point. + * @exclude + * @throws Exception if anything bad happens + */ + public static void main(String[] args) throws Exception { + if (args.length != 0) { + fpostest(args[0]); + return; + } + for (int blockSizeLog2 = 0; blockSizeLog2 < 10; blockSizeLog2++) { + int blockSize = 1 << blockSizeLog2; + for (int recordSize = 1; recordSize < 20; recordSize++) { + System.out.println("doing blockSize " + blockSize + " recordSize " + recordSize); + CompressedRecordArray ra = new CompressedRecordArray(blockSizeLog2, recordSize); + int[] record = new int[recordSize]; + for (int i = 0; i < blockSize*10 + recordSize; i++) { + for (int j = 0; j < recordSize; j++) { + int value = i*i*j; + if ((recordSize % 3) == 0 && (j % 3) == 0) + // this should give all same deltas + value = i * blockSize * recordSize; + else if ((j % 5) == 0) + value = -value; + record[j] = value; + } + ra.add(record); + } + ra.close(); + for (int i = 0; i < blockSize*10 + recordSize; i++) { + ra.get(i, record); + for (int j = 0; j < recordSize; j++) { + int value = i*i*j; + if ((recordSize % 3) == 0 && (j % 3) == 0) + // this should give all same deltas + value = i * blockSize * recordSize; + else if ((j % 5) == 0) + value = -value; + if (record[j] != value) + throw new Error("found " + record[j] + " expected " + value); + } + } + } + } + System.out.println("numGolomb2 = " + numGolomb2); + System.out.println("numGolomb7 = " + numGolomb7); + System.out.println("numGolomb8 = " + numGolomb8); + System.out.println("numVariableByte = " + numVariableByte); + System.out.println("numAllSameDelta = " + numAllSameDelta); + System.out.println("numNotAllSameDelta = " + numNotAllSameDelta); + System.out.println("numNegative = " + numNegative); + System.out.println("numAllPositive = " + numAllPositive); + } - /** - * This is the test method I wrote to measure the performance on some real life data. - * See the discussion in the class overview for more info. - * @throws Exception if the file can't be found - */ - private static void fpostest(String filename) throws Exception { - File file = new File(filename); - byte[] bytes = new byte[(int)file.length()]; - FileInputStream fis = new FileInputStream(file); - BufferedInputStream bis = new BufferedInputStream(fis); - DataInputStream dis = new DataInputStream(bis); - dis.readFully(bytes); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - dis = new DataInputStream(bais); - int[] record = new int[8]; - for (int blockSizeLog2 = 0; blockSizeLog2 < 10; blockSizeLog2++) { - dis.reset(); - final long then = System.nanoTime(); - CompressedRecordArray ra = new CompressedRecordArray(blockSizeLog2, 8); - boolean eof = false; - for (int r = 0;; r++) { - for (int i = 0; i < 8; i++) { - try { - record[i] = dis.readInt(); - } catch (EOFException e) { - eof = true; - break; - } - } - if (eof) break; - ra.add(record); - } - ra.close(); - dis.reset(); - eof = false; - for (int r = 0;; r++) { - for (int i = 0; i < 8; i++) { - try { - int n = dis.readInt(); - if (i == 0) - ra.get(r, record); - if (record[i] != n) - throw new Error("data mismatch!"); - } catch (EOFException e) { - eof = true; - break; - } - } - if (eof) break; - } - final long duration = System.nanoTime() - then; - System.out.println("block size " + (1 << blockSizeLog2) + " uses " + ra.memoryUsage() + " took " + duration + " ns"); - } - } + /** + * This is the test method I wrote to measure the performance on some real life data. + * See the discussion in the class overview for more info. + * @throws Exception if the file can't be found + */ + private static void fpostest(String filename) throws Exception { + File file = new File(filename); + byte[] bytes = new byte[(int)file.length()]; + FileInputStream fis = new FileInputStream(file); + BufferedInputStream bis = new BufferedInputStream(fis); + DataInputStream dis = new DataInputStream(bis); + dis.readFully(bytes); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + dis = new DataInputStream(bais); + int[] record = new int[8]; + for (int blockSizeLog2 = 0; blockSizeLog2 < 10; blockSizeLog2++) { + dis.reset(); + final long then = System.nanoTime(); + CompressedRecordArray ra = new CompressedRecordArray(blockSizeLog2, 8); + boolean eof = false; + for (int r = 0;; r++) { + for (int i = 0; i < 8; i++) { + try { + record[i] = dis.readInt(); + } catch (EOFException e) { + eof = true; + break; + } + } + if (eof) break; + ra.add(record); + } + ra.close(); + dis.reset(); + eof = false; + for (int r = 0;; r++) { + for (int i = 0; i < 8; i++) { + try { + int n = dis.readInt(); + if (i == 0) + ra.get(r, record); + if (record[i] != n) + throw new Error("data mismatch!"); + } catch (EOFException e) { + eof = true; + break; + } + } + if (eof) break; + } + final long duration = System.nanoTime() - then; + System.out.println("block size " + (1 << blockSizeLog2) + " uses " + ra.memoryUsage() + " took " + duration + " ns"); + } + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/IntEnumeration.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/IntEnumeration.java index f5f8010ca2d..844533d93de 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/IntEnumeration.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/IntEnumeration.java @@ -29,9 +29,8 @@ * to enumerate integer values rather than incur the overhead of allocating Integer objects. */ public interface IntEnumeration extends Enumeration { - /** - * Return the next integer value. - */ - public long nextInt(); + /** + * Return the next integer value. + */ + public long nextInt(); } - diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/IntegerMap.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/IntegerMap.java index 97e510d3742..dbfa6dcf9c1 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/IntegerMap.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/IntegerMap.java @@ -33,111 +33,111 @@ public final class IntegerMap extends AbstractHashMap { - /** The array of values */ - long[] values = new long[INITIAL_SIZE]; + /** The array of values */ + long[] values = new long[INITIAL_SIZE]; - /** - * Overridden method to return values array. - */ - Object getValuesArray() { - return values; - } + /** + * Overridden method to return values array. + */ + Object getValuesArray() { + return values; + } - /** - * Overridden method to allocate new values array. - */ - void allocNewValuesArray(int newSize) { - values = new long[newSize]; - } + /** + * Overridden method to allocate new values array. + */ + void allocNewValuesArray(int newSize) { + values = new long[newSize]; + } - /** - * Overridden method to repopulate with key plus value at given offset. - */ - void put(long key, Object oldvalues, int offset) { - long[] v = (long[])oldvalues; - put(key, v[offset]); - } + /** + * Overridden method to repopulate with key plus value at given offset. + */ + void put(long key, Object oldvalues, int offset) { + long[] v = (long[])oldvalues; + put(key, v[offset]); + } - /** - * Returns the value mapped by the given key. - * @return the value or -1 if it cannot be found - */ - public long get(long key) { - int index = getIndex(key) ; - return index == -1 ? -1 : values[index]; - } + /** + * Returns the value mapped by the given key. + * @return the value or -1 if it cannot be found + */ + public long get(long key) { + int index = getIndex(key) ; + return index == -1 ? -1 : values[index]; + } - /** - * Add the key/value pair to the map. The value must not be -1. - */ - public void put(long key, long value) { - values[putIndex(key)] = value; - checkRehash(); - } + /** + * Add the key/value pair to the map. The value must not be -1. + */ + public void put(long key, long value) { + values[putIndex(key)] = value; + checkRehash(); + } - /** - * Remove the key from the map and return the old value. - */ - public long remove(long key) { - int index = removeIndex(key) ; - return index == -1 ? -1 : values[index]; - } + /** + * Remove the key from the map and return the old value. + */ + public long remove(long key) { + int index = removeIndex(key) ; + return index == -1 ? -1 : values[index]; + } - public int memoryUsage() { - return tableSize * 17; - } + public int memoryUsage() { + return tableSize * 17; + } - private boolean doCheck = true; + private boolean doCheck = true; - /** - * Test method. - */ - private void test() { - Random rand = new Random(23); - HashMap check = new HashMap(); - for (int i = 0; i < 500000; i++) { - long key = rand.nextLong(); - long value = rand.nextLong(); - boolean remove = ((i % 3) == 0); - if (get(key) != -1) { - continue; - } - put(key, value); - if (doCheck) { - check.put(Long.valueOf(key), Long.valueOf(value)); - if (get(key) != value) { - throw new Error("found " + get(key) + " expected " + value); - } - if (remove) { - remove(key); - check.remove(Long.valueOf(key)); - } - } - } - if (doCheck) { - Long[] keys = (Long[])check.keySet().toArray(new Long[0]); - for (int i = 0; i < keys.length; i++) { - long key = keys[i].longValue(); - long value = ((Long)check.get(keys[i])).longValue(); - if (get(key) != value) { - throw new Error("at " + i + " found " + get(key) + " expected " + value + " key " + key); - } - } - } - } + /** + * Test method. + */ + private void test() { + Random rand = new Random(23); + HashMap check = new HashMap(); + for (int i = 0; i < 500000; i++) { + long key = rand.nextLong(); + long value = rand.nextLong(); + boolean remove = ((i % 3) == 0); + if (get(key) != -1) { + continue; + } + put(key, value); + if (doCheck) { + check.put(Long.valueOf(key), Long.valueOf(value)); + if (get(key) != value) { + throw new Error("found " + get(key) + " expected " + value); + } + if (remove) { + remove(key); + check.remove(Long.valueOf(key)); + } + } + } + if (doCheck) { + Long[] keys = (Long[])check.keySet().toArray(new Long[0]); + for (int i = 0; i < keys.length; i++) { + long key = keys[i].longValue(); + long value = ((Long)check.get(keys[i])).longValue(); + if (get(key) != value) { + throw new Error("at " + i + " found " + get(key) + " expected " + value + " key " + key); + } + } + } + } - /** - * Run some basic tests on this class. - * - * @exclude - */ - public static void main(String args[]) { - IntegerMap map = new IntegerMap(); - map.test(); - for (IntEnumeration e = map.getKeys(); e.hasMoreElements(); ) { - long key = e.nextInt(); - if (map.get(key) == -1) throw new Error("uh oh"); - } - System.out.println("finished!"); - } + /** + * Run some basic tests on this class. + * + * @exclude + */ + public static void main(String args[]) { + IntegerMap map = new IntegerMap(); + map.test(); + for (IntEnumeration e = map.getKeys(); e.hasMoreElements(); ) { + long key = e.nextInt(); + if (map.get(key) == -1) throw new Error("uh oh"); + } + System.out.println("finished!"); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/ObjectLruCache.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/ObjectLruCache.java index 75ad8953eb6..754b63ee35d 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/ObjectLruCache.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/ObjectLruCache.java @@ -30,59 +30,59 @@ public final class ObjectLruCache extends AbstractLruCache { - /** The array of values */ - Object[] values = new Object[INITIAL_SIZE]; + /** The array of values */ + Object[] values = new Object[INITIAL_SIZE]; - /** - * Create a new ObjectLruCache. - * @param maxSize the maximum size the cache can grow to - */ - public ObjectLruCache(int maxSize) { - super(maxSize); - } + /** + * Create a new ObjectLruCache. + * @param maxSize the maximum size the cache can grow to + */ + public ObjectLruCache(int maxSize) { + super(maxSize); + } - /** - * Overridden method to return values array. - */ - Object getValuesArray() { - return values; - } + /** + * Overridden method to return values array. + */ + Object getValuesArray() { + return values; + } - /** - * Overridden method to allocate new values array. - */ - void allocNewValuesArray(int newSize) { - super.allocNewValuesArray(newSize); - values = new Object[newSize]; - } + /** + * Overridden method to allocate new values array. + */ + void allocNewValuesArray(int newSize) { + super.allocNewValuesArray(newSize); + values = new Object[newSize]; + } - /** - * Overridden method to repopulate with key plus value at given offset. - */ - void put(long key, Object oldvalues, int offset) { - Object[] v = (Object[])oldvalues; - put(key, v[offset]); - } + /** + * Overridden method to repopulate with key plus value at given offset. + */ + void put(long key, Object oldvalues, int offset) { + Object[] v = (Object[])oldvalues; + put(key, v[offset]); + } - /** - * Returns the value mapped by the given key. Also promotes this key to the most - * recently used. - * @return the value or null if it cannot be found - */ - public Object get(long key) { - int index = getIndexAndPromote(key) ; - if (index != -1) { - return values[index]; - } - return null; - } + /** + * Returns the value mapped by the given key. Also promotes this key to the most + * recently used. + * @return the value or null if it cannot be found + */ + public Object get(long key) { + int index = getIndexAndPromote(key) ; + if (index != -1) { + return values[index]; + } + return null; + } - /** - * Add the key/value pair to the map. - */ - public void put(long key, Object value) { - int index = putIndexAndPromote(key) ; - values[index] = value; - checkRehash(); - } + /** + * Add the key/value pair to the map. + */ + public void put(long key, Object value) { + int index = putIndexAndPromote(key) ; + values[index] = value; + checkRehash(); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/ObjectMap.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/ObjectMap.java index 19ebaa01f02..b58f8c59ab1 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/ObjectMap.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/zos/util/ObjectMap.java @@ -30,70 +30,70 @@ public final class ObjectMap extends AbstractHashMap { - /** The array of values */ - Object[] values = new Object[INITIAL_SIZE]; + /** The array of values */ + Object[] values = new Object[INITIAL_SIZE]; - /** - * Overridden method to return values array. - */ - Object getValuesArray() { - return values; - } + /** + * Overridden method to return values array. + */ + Object getValuesArray() { + return values; + } - /** - * Overridden method to allocate new values array. - */ - void allocNewValuesArray(int newSize) { - values = new Object[newSize]; - } + /** + * Overridden method to allocate new values array. + */ + void allocNewValuesArray(int newSize) { + values = new Object[newSize]; + } - /** - * Overridden method to repopulate with key plus value at given offset. - */ - void put(long key, Object oldvalues, int offset) { - Object[] v = (Object[])oldvalues; - put(key, v[offset]); - } + /** + * Overridden method to repopulate with key plus value at given offset. + */ + void put(long key, Object oldvalues, int offset) { + Object[] v = (Object[])oldvalues; + put(key, v[offset]); + } - /** - * Returns the value mapped by the given key. - * @return the value or null if it cannot be found - */ - public Object get(long key) { - int index = getIndex(key) ; - return index == -1 ? null : values[index]; - } + /** + * Returns the value mapped by the given key. + * @return the value or null if it cannot be found + */ + public Object get(long key) { + int index = getIndex(key) ; + return index == -1 ? null : values[index]; + } - /** - * Add the key/value pair to the map. - */ - public void put(long key, Object value) { - values[putIndex(key)] = value; - checkRehash(); - } + /** + * Add the key/value pair to the map. + */ + public void put(long key, Object value) { + values[putIndex(key)] = value; + checkRehash(); + } - /** - * Remove the key from the map and return the old value. - */ - public Object remove(long key) { - int index = removeIndex(key) ; - return index == -1 ? null : values[index]; - } + /** + * Remove the key from the map and return the old value. + */ + public Object remove(long key) { + int index = removeIndex(key) ; + return index == -1 ? null : values[index]; + } - /** - * Returns an array containing the values where the returned runtime array type is derived from - * the given array (or the given array is simply reused if there is room). - */ - public Object[] toArray(Object[] a) { - if (a.length < slotsInUse) - a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), slotsInUse); - for (int i = 0, j = 0; i < tableSize; i++) { - if (state[i] == OCCUPIED) { - a[j++] = values[i]; - } - } - if (a.length > slotsInUse) - a[slotsInUse] = null; - return a; - } + /** + * Returns an array containing the values where the returned runtime array type is derived from + * the given array (or the given array is simply reused if there is room). + */ + public Object[] toArray(Object[] a) { + if (a.length < slotsInUse) + a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), slotsInUse); + for (int i = 0, j = 0; i < tableSize; i++) { + if (state[i] == OCCUPIED) { + a[j++] = values[i]; + } + } + if (a.length > slotsInUse) + a[slotsInUse] = null; + return a; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/CorruptDataException.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/CorruptDataException.java index be4719c8d2a..20237042b10 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/CorruptDataException.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/CorruptDataException.java @@ -38,13 +38,13 @@ public class CorruptDataException extends DTFJException { * @param data the corruptData */ public CorruptDataException(CorruptData data) { - super(data==null ? "" : data.toString()); + super(data == null ? "" : data.toString()); - if (data == null) { - throw new IllegalArgumentException("data must not be null"); - } - corruptData = data; - } + if (data == null) { + throw new IllegalArgumentException("data must not be null"); + } + corruptData = data; + } /** * Get more info about the corrupted data @@ -52,7 +52,7 @@ public CorruptDataException(CorruptData data) { * @return the CorruptData object */ public CorruptData getCorruptData() { - return corruptData; - } + return corruptData; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/DTFJException.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/DTFJException.java index 4a4322a29a6..2fbf866233a 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/DTFJException.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/DTFJException.java @@ -36,13 +36,13 @@ public class DTFJException extends Exception { * @param description */ public DTFJException(String description) { - super(description); - } + super(description); + } - /** - * Build exception with no description - */ - public DTFJException() { - super(); - } + /** + * Build exception with no description + */ + public DTFJException() { + super(); + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/DataUnavailable.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/DataUnavailable.java index bc2d08409b4..95857c50c60 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/DataUnavailable.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/DataUnavailable.java @@ -40,9 +40,9 @@ public DataUnavailable(String description) { super(description); } - /** - * Build exception with no description - */ + /** + * Build exception with no description + */ public DataUnavailable() { super(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/Image.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/Image.java index 19e8597dbe8..2cd46500d8a 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/Image.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/Image.java @@ -43,7 +43,7 @@ public interface Image { * described by this Image * * @see ImageAddressSpace - * @see CorruptData + * @see CorruptData */ public Iterator getAddressSpaces(); @@ -147,32 +147,32 @@ public interface Image { */ public Iterator getIPAddresses() throws DataUnavailable; - /** - *

        Close this image and any associated resources.

        - * - *

        Some kinds of Image require the generation of temporary resources, for example temporary files created - * when reading core files and libraries from .zip archives. Ordinarily, these resources are deleted at JVM shutdown, - * but DTFJ applications may want to free them earlier. This method should only be called when the Image is no - * longer needed. After this method has been called, any objects associated with the image will be in an invalid state.

        - * - * @since 1.4 - */ - public void close(); - - /** - * Gets the OS specific properties for this image. - * - * @return a set of OS specific properties - * @since 1.7 - */ - public Properties getProperties(); - - /** - * A unique identifier for the source of this image - * @return URI for this image or null if this was not used when the image was created. - * @since 1.10 - */ - public URI getSource(); + /** + *

        Close this image and any associated resources.

        + * + *

        Some kinds of Image require the generation of temporary resources, for example temporary files created + * when reading core files and libraries from .zip archives. Ordinarily, these resources are deleted at JVM shutdown, + * but DTFJ applications may want to free them earlier. This method should only be called when the Image is no + * longer needed. After this method has been called, any objects associated with the image will be in an invalid state.

        + * + * @since 1.4 + */ + public void close(); + + /** + * Gets the OS specific properties for this image. + * + * @return a set of OS specific properties + * @since 1.7 + */ + public Properties getProperties(); + + /** + * A unique identifier for the source of this image + * @return URI for this image or null if this was not used when the image was created. + * @since 1.10 + */ + public URI getSource(); /** * Get the value of the JVM's high-resolution timer when the image was created. diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageAddressSpace.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageAddressSpace.java index 68ec0b5f112..778cb44b325 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageAddressSpace.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageAddressSpace.java @@ -34,23 +34,23 @@ */ public interface ImageAddressSpace { - /** - * Get the process within this address space that caused the image to be created. - * @return the process within this address space which caused - * the image to be created, if any. Return null if no individual - * process triggered the creation of the image. - */ - public ImageProcess getCurrentProcess(); + /** + * Get the process within this address space that caused the image to be created. + * @return the process within this address space which caused + * the image to be created, if any. Return null if no individual + * process triggered the creation of the image. + */ + public ImageProcess getCurrentProcess(); - /** - * Get the set of processes within the address space. - * @return an iterator which provides all of the processes - * within a given address space. - * - * @see ImageProcess - * @see CorruptData - */ - public Iterator getProcesses(); + /** + * Get the set of processes within the address space. + * @return an iterator which provides all of the processes + * within a given address space. + * + * @see ImageProcess + * @see CorruptData + */ + public Iterator getProcesses(); /** * Return the byte order of this address space. @@ -59,34 +59,34 @@ public interface ImageAddressSpace { */ public ByteOrder getByteOrder(); - /** - * A factory method for creating pointers into this address space. - * @param address the address to point to. - * @return an ImagePointer for the specified address. - */ - public ImagePointer getPointer(long address); + /** + * A factory method for creating pointers into this address space. + * @param address the address to point to. + * @return an ImagePointer for the specified address. + */ + public ImagePointer getPointer(long address); - /** - * Get the raw memory in the address space. - * - * @return An iterator of all the ImageSections in the address. Their union will be the total process address space. - * @see ImageSection - */ - public Iterator getImageSections(); + /** + * Get the raw memory in the address space. + * + * @return An iterator of all the ImageSections in the address. Their union will be the total process address space. + * @see ImageSection + */ + public Iterator getImageSections(); - /** - * Gets the system wide identifier for the address space - * - * @return address space ID - * @since 1.7 - */ - public String getID() throws DataUnavailable, CorruptDataException; + /** + * Gets the system wide identifier for the address space + * + * @return address space ID + * @since 1.7 + */ + public String getID() throws DataUnavailable, CorruptDataException; - /** - * Gets the OS specific properties for this address space. - * - * @return a set of OS specific properties - * @since 1.7 - */ - public Properties getProperties(); + /** + * Gets the OS specific properties for this address space. + * + * @return a set of OS specific properties + * @since 1.7 + */ + public Properties getProperties(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageModule.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageModule.java index 2913c30b8b2..e658d190320 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageModule.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageModule.java @@ -30,54 +30,54 @@ */ public interface ImageModule { - /** - * Get the file name of the shared library. - * @return the file name of the shared library. - * - * @throws CorruptDataException If the module is corrupt and the - * original file cannot be determined. - */ - public String getName() throws CorruptDataException; + /** + * Get the file name of the shared library. + * @return the file name of the shared library. + * + * @throws CorruptDataException If the module is corrupt and the + * original file cannot be determined. + */ + public String getName() throws CorruptDataException; - /** - * Get the collection of sections that make up this library. - * @return a collection of sections that make up this library. - * - * @see ImageSection - * @see CorruptData - */ - public Iterator getSections(); + /** + * Get the collection of sections that make up this library. + * @return a collection of sections that make up this library. + * + * @see ImageSection + * @see CorruptData + */ + public Iterator getSections(); - /** - * Provides a collection of symbols defined by the library. This - * list is likely incomplete as many symbols may be private, - * symbols may have been stripped from the library, or symbols may - * not by available in the image. - * - * @return a collection of symbols which are defined by this library. - * - * @see ImageSymbol - * @see CorruptData - */ - public Iterator getSymbols(); + /** + * Provides a collection of symbols defined by the library. This + * list is likely incomplete as many symbols may be private, + * symbols may have been stripped from the library, or symbols may + * not by available in the image. + * + * @return a collection of symbols which are defined by this library. + * + * @see ImageSymbol + * @see CorruptData + */ + public Iterator getSymbols(); - /** - * Get the table of properties associated with this module. - * @return a table of properties associated with this module. - * Values typically defined in this table include: - *
          - *
        • "version" -- version information about the module
        • - *
        - * @throws CorruptDataException - */ - public Properties getProperties() throws CorruptDataException; + /** + * Get the table of properties associated with this module. + * @return a table of properties associated with this module. + * Values typically defined in this table include: + *
          + *
        • "version" -- version information about the module
        • + *
        + * @throws CorruptDataException + */ + public Properties getProperties() throws CorruptDataException; - /** - * Get the address at which the module or executable was loaded. - * - * @return the address - * @throws CorruptDataException - * @throws DataUnavailable - */ - public long getLoadAddress() throws CorruptDataException, DataUnavailable; + /** + * Get the address at which the module or executable was loaded. + * + * @return the address + * @throws CorruptDataException + * @throws DataUnavailable + */ + public long getLoadAddress() throws CorruptDataException, DataUnavailable; } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImagePointer.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImagePointer.java index da3cd8b9fd0..31fb0d26e65 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImagePointer.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImagePointer.java @@ -32,116 +32,116 @@ */ public interface ImagePointer { - /** - *

        Get the unwrapped address, represented as a Java long.

        - *

        Use caution when comparing addresses, as some addresses may be - * negative.

        - *

        Note that, on segmented memory architectures, it may not be - * possible to represent all addresses accurately as integers.

        - * @return the unwrapped address, represented as a 64-bit integer. - */ - public long getAddress(); - - /** - * Get the address space to which this pointer belongs. - * @return the address space to which this pointer belongs. - */ - public ImageAddressSpace getAddressSpace(); - - /** - * Build a new image pointer offset from this one by the given amount. - * @param offset Offset in bytes. - * @return a new ImagePointer based at getAddress() + offset - */ - public ImagePointer add(long offset); - - /** - * Tests memory execute permission. - * @return true if this memory address is within an executable page. - * @throws DataUnavailable - */ - public boolean isExecutable() throws DataUnavailable; - - /** - * Tests memory read/write permission. - * @return true if this memory address is read-only. False otherwise. - * @throws DataUnavailable - */ - public boolean isReadOnly() throws DataUnavailable; - - /** - * Tests memory shared permission. - * @return true if this memory address is shared between processes. - * @throws DataUnavailable - */ - public boolean isShared() throws DataUnavailable; - - /** - * Get the value at the given offset from this pointer. To determine the number of bytes to skip after this - * call to read the next value, use ImageProcess.getPointerSize(). Note: to create an - * ImagePointer using an absolute address use com.ibm.dtfj.image.ImageAddressSpace.getPointer() - * @param index an offset (in bytes) from the current position - * @return the 32 or 64-bit pointer stored at getAddress() + index - * @throws MemoryAccessException if the memory cannot be read - * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted - * @see ImageProcess#getPointerSize() - * @see ImageAddressSpace#getPointer(long) - */ - public ImagePointer getPointerAt(long index) throws MemoryAccessException, CorruptDataException; - - /** - * Get the value at the given offset from this pointer. - * @param index an offset (in bytes) from the current position - * @return the 64-bit long stored at getAddress() + index - * @throws MemoryAccessException if the memory cannot be read - * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted - */ - public long getLongAt(long index) throws MemoryAccessException, CorruptDataException; - - /** - * Get the value at the given offset from this pointer. - * @param index an offset (in bytes) from the current position - * @return the 32-bit int stored at getAddress() + index - * @throws MemoryAccessException if the memory cannot be read - * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted - */ - public int getIntAt(long index) throws MemoryAccessException, CorruptDataException; - - /** - * Get the value at the given offset from this pointer. - * @param index an offset (in bytes) from the current position - * @return the 16-bit short stored at getAddress() + index - * @throws MemoryAccessException if the memory cannot be read - * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted - */ - public short getShortAt(long index) throws MemoryAccessException, CorruptDataException; - - /** - * Get the value at the given offset from this pointer. - * @param index an offset (in bytes) from the current position - * @return the 8-bit byte stored at getAddress() + index - * @throws MemoryAccessException if the memory cannot be read - * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted - */ - public byte getByteAt(long index) throws MemoryAccessException, CorruptDataException; - - /** - * Get the value at the given offset from this pointer. - * @param index an offset (in bytes) from the current position - * @return the 32-bit float stored at getAddress() + index - * @throws MemoryAccessException if the memory cannot be read - * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted - */ - public float getFloatAt(long index) throws MemoryAccessException, CorruptDataException; - - /** - * Get the value at the given offset from this pointer. - * @param index an offset (in bytes) from the current position - * @return the 64-bit double stored at getAddress() + index - * @throws MemoryAccessException if the memory cannot be read - * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted - */ - public double getDoubleAt(long index) throws MemoryAccessException, CorruptDataException; + /** + *

        Get the unwrapped address, represented as a Java long.

        + *

        Use caution when comparing addresses, as some addresses may be + * negative.

        + *

        Note that, on segmented memory architectures, it may not be + * possible to represent all addresses accurately as integers.

        + * @return the unwrapped address, represented as a 64-bit integer. + */ + public long getAddress(); + + /** + * Get the address space to which this pointer belongs. + * @return the address space to which this pointer belongs. + */ + public ImageAddressSpace getAddressSpace(); + + /** + * Build a new image pointer offset from this one by the given amount. + * @param offset Offset in bytes. + * @return a new ImagePointer based at getAddress() + offset + */ + public ImagePointer add(long offset); + + /** + * Tests memory execute permission. + * @return true if this memory address is within an executable page. + * @throws DataUnavailable + */ + public boolean isExecutable() throws DataUnavailable; + + /** + * Tests memory read/write permission. + * @return true if this memory address is read-only. False otherwise. + * @throws DataUnavailable + */ + public boolean isReadOnly() throws DataUnavailable; + + /** + * Tests memory shared permission. + * @return true if this memory address is shared between processes. + * @throws DataUnavailable + */ + public boolean isShared() throws DataUnavailable; + + /** + * Get the value at the given offset from this pointer. To determine the number of bytes to skip after this + * call to read the next value, use ImageProcess.getPointerSize(). Note: to create an + * ImagePointer using an absolute address use com.ibm.dtfj.image.ImageAddressSpace.getPointer() + * @param index an offset (in bytes) from the current position + * @return the 32 or 64-bit pointer stored at getAddress() + index + * @throws MemoryAccessException if the memory cannot be read + * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted + * @see ImageProcess#getPointerSize() + * @see ImageAddressSpace#getPointer(long) + */ + public ImagePointer getPointerAt(long index) throws MemoryAccessException, CorruptDataException; + + /** + * Get the value at the given offset from this pointer. + * @param index an offset (in bytes) from the current position + * @return the 64-bit long stored at getAddress() + index + * @throws MemoryAccessException if the memory cannot be read + * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted + */ + public long getLongAt(long index) throws MemoryAccessException, CorruptDataException; + + /** + * Get the value at the given offset from this pointer. + * @param index an offset (in bytes) from the current position + * @return the 32-bit int stored at getAddress() + index + * @throws MemoryAccessException if the memory cannot be read + * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted + */ + public int getIntAt(long index) throws MemoryAccessException, CorruptDataException; + + /** + * Get the value at the given offset from this pointer. + * @param index an offset (in bytes) from the current position + * @return the 16-bit short stored at getAddress() + index + * @throws MemoryAccessException if the memory cannot be read + * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted + */ + public short getShortAt(long index) throws MemoryAccessException, CorruptDataException; + + /** + * Get the value at the given offset from this pointer. + * @param index an offset (in bytes) from the current position + * @return the 8-bit byte stored at getAddress() + index + * @throws MemoryAccessException if the memory cannot be read + * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted + */ + public byte getByteAt(long index) throws MemoryAccessException, CorruptDataException; + + /** + * Get the value at the given offset from this pointer. + * @param index an offset (in bytes) from the current position + * @return the 32-bit float stored at getAddress() + index + * @throws MemoryAccessException if the memory cannot be read + * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted + */ + public float getFloatAt(long index) throws MemoryAccessException, CorruptDataException; + + /** + * Get the value at the given offset from this pointer. + * @param index an offset (in bytes) from the current position + * @return the 64-bit double stored at getAddress() + index + * @throws MemoryAccessException if the memory cannot be read + * @throws CorruptDataException if the memory should be in the image, but is missing or corrupted + */ + public double getDoubleAt(long index) throws MemoryAccessException, CorruptDataException; /** * @param obj @@ -150,16 +150,16 @@ public interface ImagePointer { public boolean equals(Object obj); public int hashCode(); - /** - * Get the OS-specific properties for this address - * @return a table of OS-specific properties for this address. - * Values which are commonly available include - *
          - *
        • "readable" -- whether the memory address can be read from
        • - *
        • "writable" -- whether the memory address can be written to
        • - *
        • "executable" -- whether data in the memory address can be executed
        • - *
        - * @since 1.11 - */ + /** + * Get the OS-specific properties for this address + * @return a table of OS-specific properties for this address. + * Values which are commonly available include + *
          + *
        • "readable" -- whether the memory address can be read from
        • + *
        • "writable" -- whether the memory address can be written to
        • + *
        • "executable" -- whether data in the memory address can be executed
        • + *
        + * @since 1.11 + */ public Properties getProperties(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageProcess.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageProcess.java index 4e81727d4e0..0689797052f 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageProcess.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageProcess.java @@ -30,140 +30,140 @@ */ public interface ImageProcess { - /** - * Fetch the command line for this process. This may be the exact command line - * the user issued, or it may be a reconstructed command line based on - * argv[] and argc. - * - * @return the command line for the process - * - * @exception DataUnavailable if the information cannot be provided - * @throws CorruptDataException - */ - public String getCommandLine() throws DataUnavailable, CorruptDataException; + /** + * Fetch the command line for this process. This may be the exact command line + * the user issued, or it may be a reconstructed command line based on + * argv[] and argc. + * + * @return the command line for the process + * + * @exception DataUnavailable if the information cannot be provided + * @throws CorruptDataException + */ + public String getCommandLine() throws DataUnavailable, CorruptDataException; - /** - * Get the environment variables for this process. - * @return the environment variables for this process - * - * @exception DataUnavailable if the information cannot be provided - * @throws CorruptDataException - */ - public Properties getEnvironment() throws DataUnavailable, CorruptDataException; + /** + * Get the environment variables for this process. + * @return the environment variables for this process + * + * @exception DataUnavailable if the information cannot be provided + * @throws CorruptDataException + */ + public Properties getEnvironment() throws DataUnavailable, CorruptDataException; - /** - * Get the system-wide identifier for the process. - * @return a system-wide identifier for the process (e.g. a process id (pid) on Unix like - * systems) - * - * @exception DataUnavailable if the information cannot be provided - * @throws CorruptDataException - */ - public String getID() throws DataUnavailable, CorruptDataException; + /** + * Get the system-wide identifier for the process. + * @return a system-wide identifier for the process (e.g. a process id (pid) on Unix like + * systems) + * + * @exception DataUnavailable if the information cannot be provided + * @throws CorruptDataException + */ + public String getID() throws DataUnavailable, CorruptDataException; - /** - * Get the set of shared libraries which are loaded in this process. - * @return an iterator to iterate over the shared libraries which are loaded in this - * process - * - * @exception DataUnavailable if the information cannot be provided - * @throws CorruptDataException - * - * @see ImageModule - * @see CorruptData - */ - public Iterator getLibraries() throws DataUnavailable, CorruptDataException; + /** + * Get the set of shared libraries which are loaded in this process. + * @return an iterator to iterate over the shared libraries which are loaded in this + * process + * + * @exception DataUnavailable if the information cannot be provided + * @throws CorruptDataException + * + * @see ImageModule + * @see CorruptData + */ + public Iterator getLibraries() throws DataUnavailable, CorruptDataException; - /** - * Get the module representing the executable within the image. - * @return the module representing the executable within the image (as opposed to - * modules representing libraries) - * - * @exception DataUnavailable if the information cannot be provided - * @throws CorruptDataException - * - * @see ImageModule - */ - public ImageModule getExecutable() throws DataUnavailable, CorruptDataException; + /** + * Get the module representing the executable within the image. + * @return the module representing the executable within the image (as opposed to + * modules representing libraries) + * + * @exception DataUnavailable if the information cannot be provided + * @throws CorruptDataException + * + * @see ImageModule + */ + public ImageModule getExecutable() throws DataUnavailable, CorruptDataException; - /** - * Get the set of image threads in the image. - * @return an iterator to iterate over each ImageThread in the image - * - * There is not necessarily any relationship between JavaThreads and - * ImageThreads. A JVM implementation may use an n:m mapping of JavaThreads to - * ImageThreads, and not all ImageThreads are necessarily attached. - * - * @see ImageThread - * @see CorruptData - */ - public Iterator getThreads(); + /** + * Get the set of image threads in the image. + * @return an iterator to iterate over each ImageThread in the image + * + * There is not necessarily any relationship between JavaThreads and + * ImageThreads. A JVM implementation may use an n:m mapping of JavaThreads to + * ImageThreads, and not all ImageThreads are necessarily attached. + * + * @see ImageThread + * @see CorruptData + */ + public Iterator getThreads(); - /** - * Find the thread which triggered the creation of the image - * - * @return the ImageThread which caused the image to be created, or - * null if the image was not created due to a specific thread - * @throws CorruptDataException - * - * @see ImageThread - */ - public ImageThread getCurrentThread() throws CorruptDataException; + /** + * Find the thread which triggered the creation of the image + * + * @return the ImageThread which caused the image to be created, or + * null if the image was not created due to a specific thread + * @throws CorruptDataException + * + * @see ImageThread + */ + public ImageThread getCurrentThread() throws CorruptDataException; - /** - * Get the set of the known ManagedRuntime environments in the image. - * @return an iterator to iterate over all of the known ManagedRuntime - * environments in the image. - * - * In a typical image, there will be only one runtime, and it will be - * an instance of JavaRuntime. However any user of this API should be aware - * that there is a possibility that other runtimes may exist in the image - * - * @see com.ibm.dtfj.runtime.ManagedRuntime - * @see com.ibm.dtfj.java.JavaRuntime - * @see CorruptData - */ - public Iterator getRuntimes(); + /** + * Get the set of the known ManagedRuntime environments in the image. + * @return an iterator to iterate over all of the known ManagedRuntime + * environments in the image. + * + * In a typical image, there will be only one runtime, and it will be + * an instance of JavaRuntime. However any user of this API should be aware + * that there is a possibility that other runtimes may exist in the image + * + * @see com.ibm.dtfj.runtime.ManagedRuntime + * @see com.ibm.dtfj.java.JavaRuntime + * @see CorruptData + */ + public Iterator getRuntimes(); - /** - * Get the OS signal number in this process which triggered the creation - * of this image. - * @return the OS signal number in this process which triggered the creation - * of this image, or 0 if the image was not created because of a signal in this - * process - * - * @exception DataUnavailable if the information cannot be provided - * @throws CorruptDataException - */ - public int getSignalNumber() throws DataUnavailable, CorruptDataException; + /** + * Get the OS signal number in this process which triggered the creation + * of this image. + * @return the OS signal number in this process which triggered the creation + * of this image, or 0 if the image was not created because of a signal in this + * process + * + * @exception DataUnavailable if the information cannot be provided + * @throws CorruptDataException + */ + public int getSignalNumber() throws DataUnavailable, CorruptDataException; - /** - * Get the name of the OS signal in this process which triggered the - * creation of this image. - * @return the name of the OS signal in this process which triggered the - * creation of this image, or null if the image was not created because of a - * signal in this process - * - * @exception DataUnavailable if the information cannot be provided - * @throws CorruptDataException - */ - public String getSignalName() throws DataUnavailable, CorruptDataException; + /** + * Get the name of the OS signal in this process which triggered the + * creation of this image. + * @return the name of the OS signal in this process which triggered the + * creation of this image, or null if the image was not created because of a + * signal in this process + * + * @exception DataUnavailable if the information cannot be provided + * @throws CorruptDataException + */ + public String getSignalName() throws DataUnavailable, CorruptDataException; - /** - * Determine the pointer size used by this process. - * Currently supported values are 31, 32 or 64. - * In the future, other pointer sizes may also be supported. - * - * @return the size of a pointer, in bits - */ - public int getPointerSize(); + /** + * Determine the pointer size used by this process. + * Currently supported values are 31, 32 or 64. + * In the future, other pointer sizes may also be supported. + * + * @return the size of a pointer, in bits + */ + public int getPointerSize(); /** - * Gets the OS specific properties for this process. - * - * @return a set of OS specific properties - * @since 1.7 - */ - public Properties getProperties(); + * Gets the OS specific properties for this process. + * + * @return a set of OS specific properties + * @since 1.7 + */ + public Properties getProperties(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageRegister.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageRegister.java index 7b8f6c896f0..81e6dcf48b6 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageRegister.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageRegister.java @@ -27,22 +27,22 @@ */ public interface ImageRegister { - /** - * Get the name of the register. - * - * @return The conventional name of the register - */ - public String getName(); + /** + * Get the name of the register. + * + * @return The conventional name of the register + */ + public String getName(); - /** - * Get the value of the register. - * - * @return An integral or floating point type which contains the value of the register. The returned value may be - * an instance of any subclass of Number. On 32-bit and 31-bit platforms the value is usually an Integer, and on - * 64-bit platforms the value is usually a Long. On x86 architectures with MMX, the XMM registers are returned as - * BigInteger. - * @throws CorruptDataException - */ - public Number getValue() throws CorruptDataException; + /** + * Get the value of the register. + * + * @return An integral or floating point type which contains the value of the register. The returned value may be + * an instance of any subclass of Number. On 32-bit and 31-bit platforms the value is usually an Integer, and on + * 64-bit platforms the value is usually a Long. On x86 architectures with MMX, the XMM registers are returned as + * BigInteger. + * @throws CorruptDataException + */ + public Number getValue() throws CorruptDataException; } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageSection.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageSection.java index 32c5929675a..e2d41667a75 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageSection.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageSection.java @@ -30,67 +30,67 @@ public interface ImageSection { - /** - * Gets the base address (the lowest) of memory in this section. - * - * @return Base address pointer. - */ - public ImagePointer getBaseAddress(); + /** + * Gets the base address (the lowest) of memory in this section. + * + * @return Base address pointer. + */ + public ImagePointer getBaseAddress(); - /** - * Gets the size of the memory section. - * - * @return Size of section in bytes. - */ - public long getSize(); + /** + * Gets the size of the memory section. + * + * @return Size of section in bytes. + */ + public long getSize(); - /** - * Gets the name of this section. - * - * Some memory sections are named. For example, the executable data in a module is typically called ".text". - * - * For memory sections without a specific name, a placeholder string will be returned. This method will never - * return null. - * - * @return non-null name String. - */ - public String getName(); + /** + * Gets the name of this section. + * + * Some memory sections are named. For example, the executable data in a module is typically called ".text". + * + * For memory sections without a specific name, a placeholder string will be returned. This method will never + * return null. + * + * @return non-null name String. + */ + public String getName(); - /** - * Tests executable permission on memory section. - * - * @return true if the memory pages in this section are marked executable. False otherwise. - * @throws DataUnavailable - */ - public boolean isExecutable() throws DataUnavailable; + /** + * Tests executable permission on memory section. + * + * @return true if the memory pages in this section are marked executable. False otherwise. + * @throws DataUnavailable + */ + public boolean isExecutable() throws DataUnavailable; - /** - * Tests read permission on memory section. - * - * @return true if the memory pages in this section are marked read-only. False otherwise. - * @throws DataUnavailable - */ - public boolean isReadOnly() throws DataUnavailable; + /** + * Tests read permission on memory section. + * + * @return true if the memory pages in this section are marked read-only. False otherwise. + * @throws DataUnavailable + */ + public boolean isReadOnly() throws DataUnavailable; - /** - * Tests shared permission on memory section. - * - * @return true if this section is shared between processes. False otherwise. - * @throws DataUnavailable - */ - public boolean isShared() throws DataUnavailable; + /** + * Tests shared permission on memory section. + * + * @return true if this section is shared between processes. False otherwise. + * @throws DataUnavailable + */ + public boolean isShared() throws DataUnavailable; - /** - * Get the OS-specific properties for this section. - * @return a table of OS-specific properties for this section. - * Values which are commonly available include - *
          - *
        • "readable" -- whether the memory section can be read from
        • - *
        • "writable" -- whether the memory section can be written to
        • - *
        • "executable" -- whether data in the memory section can be executed
        • - *
        - * @since 1.11 - */ - public Properties getProperties(); + /** + * Get the OS-specific properties for this section. + * @return a table of OS-specific properties for this section. + * Values which are commonly available include + *
          + *
        • "readable" -- whether the memory section can be read from
        • + *
        • "writable" -- whether the memory section can be written to
        • + *
        • "executable" -- whether data in the memory section can be executed
        • + *
        + * @since 1.11 + */ + public Properties getProperties(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageStackFrame.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageStackFrame.java index dfbc06af8e7..10a7bf3db32 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageStackFrame.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageStackFrame.java @@ -27,49 +27,49 @@ */ public interface ImageStackFrame { - /** - * Get the address of the current instruction within - * the procedure being executed. - * @return the address of the current instruction within - * the procedure being executed, or null if not available. - *

        - * Use this address with caution, as it is provided only - * as a best guess. It may not be correct, or even within - * readable memory - * @throws CorruptDataException - */ - public ImagePointer getProcedureAddress() throws CorruptDataException; + /** + * Get the address of the current instruction within + * the procedure being executed. + * @return the address of the current instruction within + * the procedure being executed, or null if not available. + *

        + * Use this address with caution, as it is provided only + * as a best guess. It may not be correct, or even within + * readable memory + * @throws CorruptDataException + */ + public ImagePointer getProcedureAddress() throws CorruptDataException; - /** - * Get the base pointer of the stack frame. - * @return the base pointer of the stack frame - * @throws CorruptDataException - */ - public ImagePointer getBasePointer() throws CorruptDataException; + /** + * Get the base pointer of the stack frame. + * @return the base pointer of the stack frame + * @throws CorruptDataException + */ + public ImagePointer getBasePointer() throws CorruptDataException; - /** - * Returns a string describing the procedure at this stack - * frame. Implementations should use the following template - * so that procedure names are reported consistently: - *

        - public *

        libname(sourcefile)::entrypoint±offset
        - *

        - * Any portion of the template may be omitted if it is not available - *

        - *
        e.g.
        - *
        system32(source.c)::WaitForSingleObject+14
        - *
        system32::WaitForSingleObject-4
        - *
        (source.c)::WaitForSingleObject
        - *
        ::WaitForSingleObject+14
        - *
        system32+1404
        - *
        system32::TWindow::open(int,void*)+14
        - *
        - * - * @return a string naming the function executing in this - * stack frame. If the name is not known for legitimate - * reasons, DTFJ will return a synthetic name. - * @throws CorruptDataException - */ - public String getProcedureName() throws CorruptDataException; + /** + * Returns a string describing the procedure at this stack + * frame. Implementations should use the following template + * so that procedure names are reported consistently: + *

        + public *

        libname(sourcefile)::entrypoint±offset
        + *

        + * Any portion of the template may be omitted if it is not available + *

        + *
        e.g.
        + *
        system32(source.c)::WaitForSingleObject+14
        + *
        system32::WaitForSingleObject-4
        + *
        (source.c)::WaitForSingleObject
        + *
        ::WaitForSingleObject+14
        + *
        system32+1404
        + *
        system32::TWindow::open(int,void*)+14
        + *
        + * + * @return a string naming the function executing in this + * stack frame. If the name is not known for legitimate + * reasons, DTFJ will return a synthetic name. + * @throws CorruptDataException + */ + public String getProcedureName() throws CorruptDataException; } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageThread.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageThread.java index ee2263092d6..7cc17dd0bfd 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageThread.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/ImageThread.java @@ -31,63 +31,63 @@ */ public interface ImageThread { - /** - * Fetch a unique identifier for the thread. - * In many operating systems, threads have more than one identifier (e.g. - * a thread id, a handle, a pointer to VM structures associated with the thread). - * In this case, one of these identifiers will be chosen as the canonical - * one. The other identifiers would be returned by getProperties() - * - * @return a process-wide identifier for the thread (e.g. a tid number) - * @throws CorruptDataException - */ - public String getID() throws CorruptDataException; + /** + * Fetch a unique identifier for the thread. + * In many operating systems, threads have more than one identifier (e.g. + * a thread id, a handle, a pointer to VM structures associated with the thread). + * In this case, one of these identifiers will be chosen as the canonical + * one. The other identifiers would be returned by getProperties() + * + * @return a process-wide identifier for the thread (e.g. a tid number) + * @throws CorruptDataException + */ + public String getID() throws CorruptDataException; - /** - * Get the set of stack frames on this thread. - * @return an iterator to walk the native stack frames in order from - * top-of-stack (that is, the most recent frame) to bottom-of-stack. Throws - * DataUnavailable if native stack frames are not available on this platform. - * - * @throws DataUnavailable If native stack frames are not available on this platform - * @see ImageStackFrame - * @see CorruptData - * - */ - public Iterator getStackFrames() throws DataUnavailable; + /** + * Get the set of stack frames on this thread. + * @return an iterator to walk the native stack frames in order from + * top-of-stack (that is, the most recent frame) to bottom-of-stack. Throws + * DataUnavailable if native stack frames are not available on this platform. + * + * @throws DataUnavailable If native stack frames are not available on this platform + * @see ImageStackFrame + * @see CorruptData + * + */ + public Iterator getStackFrames() throws DataUnavailable; - /** - * Get the set of image sections which make up the stack. - * @return a collection of ImageSections which make up the stack. On - * most platforms this consists of a single entry, but on some platforms - * the thread's stack may consist of non-contiguous sections - * - * @see ImageSection - * @see CorruptData - */ - public Iterator getStackSections(); + /** + * Get the set of image sections which make up the stack. + * @return a collection of ImageSections which make up the stack. On + * most platforms this consists of a single entry, but on some platforms + * the thread's stack may consist of non-contiguous sections + * + * @see ImageSection + * @see CorruptData + */ + public Iterator getStackSections(); - /** - * Get the register contents. - * @return an iterator to iterate over the state of the CPU registers - * when the image was created. The collection may be empty if the register - * state is not available for this thread. - * - * If the CPU supports partial registers (e.g. AH, AL, AX, EAX, RAX on - * AMD64), only the largest version of the register will be included - * - * @see ImageRegister - */ - public Iterator getRegisters(); + /** + * Get the register contents. + * @return an iterator to iterate over the state of the CPU registers + * when the image was created. The collection may be empty if the register + * state is not available for this thread. + * + * If the CPU supports partial registers (e.g. AH, AL, AX, EAX, RAX on + * AMD64), only the largest version of the register will be included + * + * @see ImageRegister + */ + public Iterator getRegisters(); - /** - * Get the OS-specific properties for this thread. - * @return a table of OS-specific properties for this thread. - * Values which are commonly available include - *
          - *
        • "priority" -- the priority of the thread
        • - *
        • "policy" -- the scheduling policy of the thread
        • - *
        - */ - public Properties getProperties(); + /** + * Get the OS-specific properties for this thread. + * @return a table of OS-specific properties for this thread. + * Values which are commonly available include + *
          + *
        • "priority" -- the priority of the thread
        • + *
        • "policy" -- the scheduling policy of the thread
        • + *
        + */ + public Properties getProperties(); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/MemoryAccessException.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/MemoryAccessException.java index 2a11c8dcd08..e018d809d8b 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/MemoryAccessException.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/MemoryAccessException.java @@ -31,30 +31,30 @@ public class MemoryAccessException extends DTFJException { private ImagePointer badPointer; - /** - * Build exception for the given location and description - * @param badPointer the location which caused the access exception - * @param description text description - */ - public MemoryAccessException(ImagePointer badPointer, String description) { - super(description); - this.badPointer = badPointer; - } + /** + * Build exception for the given location and description + * @param badPointer the location which caused the access exception + * @param description text description + */ + public MemoryAccessException(ImagePointer badPointer, String description) { + super(description); + this.badPointer = badPointer; + } - /** - * Build exception for the given location and description - * @param badPointer the location which caused the access exception - */ - public MemoryAccessException(ImagePointer badPointer) { - super(); - this.badPointer = badPointer; - } + /** + * Build exception for the given location and description + * @param badPointer the location which caused the access exception + */ + public MemoryAccessException(ImagePointer badPointer) { + super(); + this.badPointer = badPointer; + } - /** - * Get a pointer into the image where the access failed. - * @return The pointer into the image where the access failed - */ - public ImagePointer getPointer() { - return badPointer; - } + /** + * Get a pointer into the image where the access failed. + * @return The pointer into the image where the access failed + */ + public ImagePointer getPointer() { + return badPointer; + } } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaClassLoader.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaClassLoader.java index 34680fbe916..65a33223e8b 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaClassLoader.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaClassLoader.java @@ -43,54 +43,54 @@ */ public interface JavaClassLoader { - /** - * Get the set of classes which are defined in this JavaClassLoader. - * @return an iterator over the collection of classes which are defined - * in this JavaClassLoader - * - * @see JavaClass - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getDefinedClasses(); + /** + * Get the set of classes which are defined in this JavaClassLoader. + * @return an iterator over the collection of classes which are defined + * in this JavaClassLoader + * + * @see JavaClass + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getDefinedClasses(); - /** - * When a ClassLoader successfully delegates a findClass() request to - * another ClassLoader, the result of the delegation must be cached within - * the internal structure so that the VM does not make repeated requests - * for the same class. - * - * @return an iterator over the collection of classes which are defined - * in this JavaClassLoader or which were found by delegation to - * other JavaClassLoaders - * - * @see JavaClass - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getCachedClasses(); + /** + * When a ClassLoader successfully delegates a findClass() request to + * another ClassLoader, the result of the delegation must be cached within + * the internal structure so that the VM does not make repeated requests + * for the same class. + * + * @return an iterator over the collection of classes which are defined + * in this JavaClassLoader or which were found by delegation to + * other JavaClassLoaders + * + * @see JavaClass + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getCachedClasses(); - /** - * Find a named class within this class loader. The class may have been - * defined in this class loader, or this class loader may have delegated - * the load to another class loader and cached the result. - * - * @param name of the class to find. Packages should be separated by - * '/' instead of '.' - * @return the JavaClass instance, or null if it is not found - * @throws CorruptDataException - */ - public JavaClass findClass(String name) throws CorruptDataException; + /** + * Find a named class within this class loader. The class may have been + * defined in this class loader, or this class loader may have delegated + * the load to another class loader and cached the result. + * + * @param name of the class to find. Packages should be separated by + * '/' instead of '.' + * @return the JavaClass instance, or null if it is not found + * @throws CorruptDataException + */ + public JavaClass findClass(String name) throws CorruptDataException; - /** - * Get the java.lang.ClassLoader instance associated with this class loader. - * @return a JavaObject representing the java.lang.ClassLoader instance - * associated with this class loader, or null if there is no Java class - * loader associated with this low-level class loader. - * @throws CorruptDataException - * - * @see JavaObject - * @see ClassLoader - */ - public JavaObject getObject() throws CorruptDataException; + /** + * Get the java.lang.ClassLoader instance associated with this class loader. + * @return a JavaObject representing the java.lang.ClassLoader instance + * associated with this class loader, or null if there is no Java class + * loader associated with this low-level class loader. + * @throws CorruptDataException + * + * @see JavaObject + * @see ClassLoader + */ + public JavaObject getObject() throws CorruptDataException; /** * @param obj diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaHeap.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaHeap.java index 2832ea7cd33..eeb329dbf64 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaHeap.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaHeap.java @@ -35,31 +35,31 @@ */ public interface JavaHeap { - /** - * Get the set of contiguous memory regions which form this heap. - * @return an iterator over the collection of contiguous memory regions - * which form this heap - * - * @see com.ibm.dtfj.image.ImageSection - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getSections(); + /** + * Get the set of contiguous memory regions which form this heap. + * @return an iterator over the collection of contiguous memory regions + * which form this heap + * + * @see com.ibm.dtfj.image.ImageSection + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getSections(); - /** - * Get a brief textual description of this heap. - * @return a brief textual description of this heap - */ - public String getName(); + /** + * Get a brief textual description of this heap. + * @return a brief textual description of this heap + */ + public String getName(); - /** - * Get the set of objects which are stored in this heap. - * @return an iterator over the collection of objects which - * are stored in this heap - * - * @see JavaObject - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getObjects(); + /** + * Get the set of objects which are stored in this heap. + * @return an iterator over the collection of objects which + * are stored in this heap + * + * @see JavaObject + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getObjects(); /** * @param obj diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMember.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMember.java index 3376de13958..6d24ced8f03 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMember.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMember.java @@ -35,34 +35,34 @@ public interface JavaMember { /** * Get the set of modifiers for this field or method - a set of bits * @return the modifiers for this field or method. The values for the constants representing - * the modifiers can be obtained from java.lang.reflect.Modifier. + * the modifiers can be obtained from java.lang.reflect.Modifier. * @throws CorruptDataException - * - */ - public int getModifiers() throws CorruptDataException; + * + */ + public int getModifiers() throws CorruptDataException; - /** - * Get the class which declares this field or method - * @return the JavaClass which declared this field or method - * @throws CorruptDataException - * @throws DataUnavailable - */ - public JavaClass getDeclaringClass() throws CorruptDataException, DataUnavailable; + /** + * Get the class which declares this field or method + * @return the JavaClass which declared this field or method + * @throws CorruptDataException + * @throws DataUnavailable + */ + public JavaClass getDeclaringClass() throws CorruptDataException, DataUnavailable; - /** - * Get the name of the field or method - * @return the name of the field or method - * @throws CorruptDataException - */ - public String getName() throws CorruptDataException; + /** + * Get the name of the field or method + * @return the name of the field or method + * @throws CorruptDataException + */ + public String getName() throws CorruptDataException; - /** - * Get the signature of the field or method - * @return the signature of the field or method. - * e.g. "(Ljava/lang/String;)V" - * @throws CorruptDataException - */ - public String getSignature() throws CorruptDataException; + /** + * Get the signature of the field or method + * @return the signature of the field or method. + * e.g. "(Ljava/lang/String;)V" + * @throws CorruptDataException + */ + public String getSignature() throws CorruptDataException; /** * @param obj diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMethod.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMethod.java index 3a8d6db65a5..316793439d8 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMethod.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMethod.java @@ -29,33 +29,33 @@ */ public interface JavaMethod extends JavaMember { - /** - * Get the set of ImageSections containing the bytecode of this method. - * @return an iterator over a collection of ImageSections. - * Each ImageSection contains data (usually bytecodes) used - * in executing this method in interpreted mode. - *

        - * The collection may be empty for native methods, or - * pre-compiled methods. - *

        - * Typically, the collection will contain no more than one - * section, but this is not guaranteed. - * - * @see com.ibm.dtfj.image.ImageSection - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getBytecodeSections(); + /** + * Get the set of ImageSections containing the bytecode of this method. + * @return an iterator over a collection of ImageSections. + * Each ImageSection contains data (usually bytecodes) used + * in executing this method in interpreted mode. + *

        + * The collection may be empty for native methods, or + * pre-compiled methods. + *

        + * Typically, the collection will contain no more than one + * section, but this is not guaranteed. + * + * @see com.ibm.dtfj.image.ImageSection + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getBytecodeSections(); - /** - * Get the set of ImageSections containing the compiled code of this method. - * @return an iterator over a collection of ImageSections. - * Each ImageSection contains data (usually executable code) used - * in executing this method in compiled mode. - * - * @see com.ibm.dtfj.image.ImageSection - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getCompiledSections(); + /** + * Get the set of ImageSections containing the compiled code of this method. + * @return an iterator over a collection of ImageSections. + * Each ImageSection contains data (usually executable code) used + * in executing this method in compiled mode. + * + * @see com.ibm.dtfj.image.ImageSection + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getCompiledSections(); /** * @param obj diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMonitor.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMonitor.java index c5ba183e7d1..6cdbe0a7304 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMonitor.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaMonitor.java @@ -32,53 +32,53 @@ */ public interface JavaMonitor { - /** - * Get the object associated with this monitor. - * @return the object associated with this monitor, or null if this is a raw monitor or a valid object could not be retrieved. - */ - public JavaObject getObject(); + /** + * Get the object associated with this monitor. + * @return the object associated with this monitor, or null if this is a raw monitor or a valid object could not be retrieved. + */ + public JavaObject getObject(); - /** - * Note that the name of a JavaMonitor is not necessarily meaningful but is provided here as it is - * usually present in the running VM. If there is no name for the monitor a synthetic name will be - * created by DTFJ. - * - * @return the name of the monitor (never null) - * @throws CorruptDataException - */ - public String getName() throws CorruptDataException; + /** + * Note that the name of a JavaMonitor is not necessarily meaningful but is provided here as it is + * usually present in the running VM. If there is no name for the monitor a synthetic name will be + * created by DTFJ. + * + * @return the name of the monitor (never null) + * @throws CorruptDataException + */ + public String getName() throws CorruptDataException; - /** - * Get the thread which currently owns the monitor - * @return the owner of the monitor, or null if the monitor is unowned - * @throws CorruptDataException - */ - public JavaThread getOwner() throws CorruptDataException; + /** + * Get the thread which currently owns the monitor + * @return the owner of the monitor, or null if the monitor is unowned + * @throws CorruptDataException + */ + public JavaThread getOwner() throws CorruptDataException; - /** - * Get the set of threads waiting to enter the monitor - * @return an iterator over the collection of threads waiting to enter this monitor - * - * @see JavaThread - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getEnterWaiters(); + /** + * Get the set of threads waiting to enter the monitor + * @return an iterator over the collection of threads waiting to enter this monitor + * + * @see JavaThread + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getEnterWaiters(); - /** - * Get the set of threads waiting to be notified on the monitor (in the Object.wait method) - * @return an iterator over the collection of threads waiting to be notified on - * this monitor - * - * @see JavaThread - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getNotifyWaiters(); + /** + * Get the set of threads waiting to be notified on the monitor (in the Object.wait method) + * @return an iterator over the collection of threads waiting to be notified on + * this monitor + * + * @see JavaThread + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getNotifyWaiters(); - /** - * Get the identifier for this monitor - * @return The pointer which uniquely identifies this monitor in memory. - */ - public ImagePointer getID(); + /** + * Get the identifier for this monitor + * @return The pointer which uniquely identifies this monitor in memory. + */ + public ImagePointer getID(); /** * @param obj diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaReference.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaReference.java index 1fbfa3bf707..f151c6bd9d3 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaReference.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaReference.java @@ -33,119 +33,119 @@ public interface JavaReference { /** Unknown heap root type */ - int HEAP_ROOT_UNKNOWN = 0; - /** JNI global reference heap root */ - int HEAP_ROOT_JNI_GLOBAL = 1; - /** System class heap root */ - int HEAP_ROOT_SYSTEM_CLASS = 2; - /** Monitor heap root */ - int HEAP_ROOT_MONITOR = 3; - /** Stack local heap root */ - int HEAP_ROOT_STACK_LOCAL = 4; - /** JNI local reference heap root */ - int HEAP_ROOT_JNI_LOCAL = 5; - /** Thread heap root */ - int HEAP_ROOT_THREAD = 6; - /** Other heap root type */ - int HEAP_ROOT_OTHER = 7; - /** Finalizable object heap root */ - int HEAP_ROOT_FINALIZABLE_OBJ = 8; - /** Unfinalized object heap root */ - int HEAP_ROOT_UNFINALIZED_OBJ = 9; - /** Classloader heap root */ - int HEAP_ROOT_CLASSLOADER = 10; - /** Stringtable heap root */ - int HEAP_ROOT_STRINGTABLE = 11; + int HEAP_ROOT_UNKNOWN = 0; + /** JNI global reference heap root */ + int HEAP_ROOT_JNI_GLOBAL = 1; + /** System class heap root */ + int HEAP_ROOT_SYSTEM_CLASS = 2; + /** Monitor heap root */ + int HEAP_ROOT_MONITOR = 3; + /** Stack local heap root */ + int HEAP_ROOT_STACK_LOCAL = 4; + /** JNI local reference heap root */ + int HEAP_ROOT_JNI_LOCAL = 5; + /** Thread heap root */ + int HEAP_ROOT_THREAD = 6; + /** Other heap root type */ + int HEAP_ROOT_OTHER = 7; + /** Finalizable object heap root */ + int HEAP_ROOT_FINALIZABLE_OBJ = 8; + /** Unfinalized object heap root */ + int HEAP_ROOT_UNFINALIZED_OBJ = 9; + /** Classloader heap root */ + int HEAP_ROOT_CLASSLOADER = 10; + /** Stringtable heap root */ + int HEAP_ROOT_STRINGTABLE = 11; - /** Unknown reference type */ - int REFERENCE_UNKNOWN = 0; - /** Reference from an object to its class */ - int REFERENCE_CLASS = 1; // - /** Reference from an object to the value of one of its instance fields */ - int REFERENCE_FIELD = 2; - /** Reference from an array to one of its elements */ - int REFERENCE_ARRAY_ELEMENT = 3; - /** Reference from a class to its class loader */ - int REFERENCE_CLASS_LOADER = 4; - /** Reference from a class to its signers array */ - int REFERENCE_SIGNERS = 5; - /** Reference from a class to its protection domain */ - int REFERENCE_PROTECTION_DOMAIN = 6; - /** Reference from a class to one of its interfaces */ - int REFERENCE_INTERFACE = 7; - /** Reference from a class to the value of one of its static fields */ - int REFERENCE_STATIC_FIELD = 8; - /** Reference from a class to a resolved entry in the constant pool */ - int REFERENCE_CONSTANT_POOL = 9; - /** Reference from a class to its superclass */ - int REFERENCE_SUPERCLASS = 10; - /** Reference from a classloader object to its loaded classes */ - int REFERENCE_LOADED_CLASS = 11; - /** Reference from a class to its java.lang.Class instance */ - int REFERENCE_CLASS_OBJECT = 12; + /** Unknown reference type */ + int REFERENCE_UNKNOWN = 0; + /** Reference from an object to its class */ + int REFERENCE_CLASS = 1; // + /** Reference from an object to the value of one of its instance fields */ + int REFERENCE_FIELD = 2; + /** Reference from an array to one of its elements */ + int REFERENCE_ARRAY_ELEMENT = 3; + /** Reference from a class to its class loader */ + int REFERENCE_CLASS_LOADER = 4; + /** Reference from a class to its signers array */ + int REFERENCE_SIGNERS = 5; + /** Reference from a class to its protection domain */ + int REFERENCE_PROTECTION_DOMAIN = 6; + /** Reference from a class to one of its interfaces */ + int REFERENCE_INTERFACE = 7; + /** Reference from a class to the value of one of its static fields */ + int REFERENCE_STATIC_FIELD = 8; + /** Reference from a class to a resolved entry in the constant pool */ + int REFERENCE_CONSTANT_POOL = 9; + /** Reference from a class to its superclass */ + int REFERENCE_SUPERCLASS = 10; + /** Reference from a classloader object to its loaded classes */ + int REFERENCE_LOADED_CLASS = 11; + /** Reference from a class to its java.lang.Class instance */ + int REFERENCE_CLASS_OBJECT = 12; /** Reference from a JavaObject representing a Class to the associated JavaClass */ - int REFERENCE_ASSOCIATED_CLASS = 13; - int REFERENCE_UNUSED_14 = 14; + int REFERENCE_ASSOCIATED_CLASS = 13; + int REFERENCE_UNUSED_14 = 14; - /** Reachability of target object via this reference is unknown */ - int REACHABILITY_UNKNOWN = 0; - /** Reachability of target object via this reference is Strong */ - int REACHABILITY_STRONG = 1; - /** Reachability of target object via this reference is Soft */ - int REACHABILITY_SOFT = 2; - /** Reachability of target object via this reference is Weak */ - int REACHABILITY_WEAK = 3; - /** Reachability of target object via this reference is Phantom */ - int REACHABILITY_PHANTOM = 4; + /** Reachability of target object via this reference is unknown */ + int REACHABILITY_UNKNOWN = 0; + /** Reachability of target object via this reference is Strong */ + int REACHABILITY_STRONG = 1; + /** Reachability of target object via this reference is Soft */ + int REACHABILITY_SOFT = 2; + /** Reachability of target object via this reference is Weak */ + int REACHABILITY_WEAK = 3; + /** Reachability of target object via this reference is Phantom */ + int REACHABILITY_PHANTOM = 4; - /** - * Get the root type, as defined in the JVMTI specification. - * - * @return an integer representing the root type, see the HEAP_ROOT_ static fields. - */ - public int getRootType() throws CorruptDataException; + /** + * Get the root type, as defined in the JVMTI specification. + * + * @return an integer representing the root type, see the HEAP_ROOT_ static fields. + */ + public int getRootType() throws CorruptDataException; - /** - * Get the reference type, as defined in the JVMTI specification. - * @return an integer representing the reference type, see the REFERENCE_ static fields. - */ - public int getReferenceType() throws CorruptDataException; + /** + * Get the reference type, as defined in the JVMTI specification. + * @return an integer representing the reference type, see the REFERENCE_ static fields. + */ + public int getReferenceType() throws CorruptDataException; - /** - * Get the reachability of the target object via this specific reference. - * @return an integer representing the reachability, see the REACHABILITY_ static fields. - */ - public int getReachability() throws CorruptDataException; + /** + * Get the reachability of the target object via this specific reference. + * @return an integer representing the reachability, see the REACHABILITY_ static fields. + */ + public int getReachability() throws CorruptDataException; - /** - * Get a string describing the reference type. - * Implementers should not depend on the contents or identity of this string. - * e.g. JNI Weak global reference, Instance field 'MyClass.value', Constant pool string constant - * @return a String describing the reference type - */ - public String getDescription(); + /** + * Get a string describing the reference type. + * Implementers should not depend on the contents or identity of this string. + * e.g. JNI Weak global reference, Instance field 'MyClass.value', Constant pool string constant + * @return a String describing the reference type + */ + public String getDescription(); - /** - * Does this reference point to an object in the heap? - * @return true if the target of this root is an object - */ - public boolean isObjectReference() throws DataUnavailable, CorruptDataException; + /** + * Does this reference point to an object in the heap? + * @return true if the target of this root is an object + */ + public boolean isObjectReference() throws DataUnavailable, CorruptDataException; - /** - * Does this reference point to a class? - * @return true if the target of this root is a class - */ - public boolean isClassReference() throws DataUnavailable, CorruptDataException; + /** + * Does this reference point to a class? + * @return true if the target of this root is a class + */ + public boolean isClassReference() throws DataUnavailable, CorruptDataException; - /** - * Get the object referred to by this reference. - * @return a JavaObject or a JavaClass - */ - public Object getTarget() throws DataUnavailable, CorruptDataException; + /** + * Get the object referred to by this reference. + * @return a JavaObject or a JavaClass + */ + public Object getTarget() throws DataUnavailable, CorruptDataException; - /** - * Get the source of this reference if available. - * @return a JavaClass, JavaObject, JavaStackFrame or null if unknown - */ - public Object getSource() throws DataUnavailable, CorruptDataException; + /** + * Get the source of this reference if available. + * @return a JavaClass, JavaObject, JavaStackFrame or null if unknown + */ + public Object getSource() throws DataUnavailable, CorruptDataException; } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaRuntime.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaRuntime.java index 342a1ca01a0..b2603366f7b 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaRuntime.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaRuntime.java @@ -36,145 +36,145 @@ */ public interface JavaRuntime extends ManagedRuntime { - /** - * Get the object that represents the virtual machine - * @return the address of the JavaVM structure which represents this JVM instance in JNI - * @throws CorruptDataException - */ - public ImagePointer getJavaVM() throws CorruptDataException; - - /** - * Get a system property of the virtual machine. - * - * @param key the name of the property to retrieve - * @return the value of the requested system property from this VM - * @throws DataUnavailable if the system properties are not available - * @throws CorruptDataException - */ - public default String getSystemProperty(String key) throws DataUnavailable, CorruptDataException { - throw new DataUnavailable("System properties are not available for this runtime"); - } - - /** - * Fetch the JavaVMInitArgs which were used to create this VM. - * See JNI_CreateJavaVM in the JNI Specification for more details. - * - * @return the JavaVMInitArgs which were used to create this VM. - * @throws DataUnavailable if the arguments are not available - * @throws CorruptDataException - */ - public JavaVMInitArgs getJavaVMInitArgs() throws DataUnavailable, CorruptDataException; - - /** - * Get the set of class loaders active in this VM - * @return an iterator of all of the class loaders within this JavaVM - * - * @see JavaClassLoader - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getJavaClassLoaders(); - - /** - * Get the set of Java threads known by the VM - * @return an iterator of the JavaThreads in the runtime - * - * @see JavaThread - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getThreads(); - - /** - * This is short cut method. The same result can be found by iterating over all - * methods in all class loaders in all classes. - * - * @return an iterator over all of the JavaMethods in the JavaRuntime which - * have been compiled - * - * @see JavaMethod - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getCompiledMethods(); - - /** - * Provides access to the collection of monitors used in the JavaVM. This - * collection includes both monitors associated with managed objects (e.g. object - * monitors) and monitors associated with internal control structures (e.g. - * raw monitors) - * - * @return an iterator over the collection of monitors - * - * @see JavaMonitor - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getMonitors(); - - /** - * Get the set of heaps known by the VM - * @return an iterator for all of the Java heaps within this runtime. Heaps - * may be specific to this JavaVM instance, or may be shared between multiple - * JavaVM instances - * - * @see JavaHeap - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getHeaps(); - - /** - * Get the set of object and class roots known to the VM. - * Stack frame roots are not included in the set, they can be retrieved using JavaStackFrame.getHeapRoots(). - * - * @return an iterator over the collection of JavaReferences representing the known global heap roots within this runtime. - * - * @see JavaReference - * @see JavaStackFrame - * @see com.ibm.dtfj.image.CorruptData - * - */ - public Iterator getHeapRoots(); - - /** - * Fetches implementation specific trace buffers, like the verbose GC buffer - * or the Universal Trace Engine (UTE) buffer - * - * @param bufferName a String naming the buffer to be fetched - * @param formatted true if formatting should be performed on the buffer, or - * false if the raw buffer contents should be returned - * @return an implementation specific result, depending on the parameters - * @throws CorruptDataException - */ - public Object getTraceBuffer(String bufferName, boolean formatted) throws CorruptDataException; - - /** - * Gets the object located at address address in the heap. - * @param address the ImagePointer instance representing the start address of object in the heap; - * @return the JavaObject instance representing the located object. - * @throws IllegalArgumentException if address is outside the heap's boundaries, or if it doesn't point to the start location of an object; - * @throws MemoryAccessException if address is in the heap but it's not accessible from the dump; - * @throws CorruptDataException if any data needed to build the returned instance of JavaObject is corrupt. - * @throws DataUnavailable if any data needed to build the returned instance of JavaObject is not available. - * @see com.ibm.dtfj.java.JavaObject - */ - public JavaObject getObjectAtAddress(ImagePointer address) throws CorruptDataException, IllegalArgumentException, MemoryAccessException, DataUnavailable; - - /** - * Returns iterator of the top-level memory categories used by this - * Java runtime. - * - * @return Iterator of memory categories - * @see JavaRuntimeMemoryCategory CorruptData - * @since 1.5 - */ - public Iterator getMemoryCategories() throws DataUnavailable; - - /** - * Returns an iterator of JavaRuntimeMemorySection objects corresponding to the blocks of memory allocated by the JavaRuntime. - * - * @param includeFreed If true, iterator will iterate over blocks of memory that have been freed, but haven't been re-used yet. - * @return Iterator of memory sections. - * @see JavaRuntimeMemorySection CorruptData - * @since 1.5 - */ - public Iterator getMemorySections(boolean includeFreed) throws DataUnavailable; + /** + * Get the object that represents the virtual machine + * @return the address of the JavaVM structure which represents this JVM instance in JNI + * @throws CorruptDataException + */ + public ImagePointer getJavaVM() throws CorruptDataException; + + /** + * Get a system property of the virtual machine. + * + * @param key the name of the property to retrieve + * @return the value of the requested system property from this VM + * @throws DataUnavailable if the system properties are not available + * @throws CorruptDataException + */ + public default String getSystemProperty(String key) throws DataUnavailable, CorruptDataException { + throw new DataUnavailable("System properties are not available for this runtime"); + } + + /** + * Fetch the JavaVMInitArgs which were used to create this VM. + * See JNI_CreateJavaVM in the JNI Specification for more details. + * + * @return the JavaVMInitArgs which were used to create this VM. + * @throws DataUnavailable if the arguments are not available + * @throws CorruptDataException + */ + public JavaVMInitArgs getJavaVMInitArgs() throws DataUnavailable, CorruptDataException; + + /** + * Get the set of class loaders active in this VM + * @return an iterator of all of the class loaders within this JavaVM + * + * @see JavaClassLoader + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getJavaClassLoaders(); + + /** + * Get the set of Java threads known by the VM + * @return an iterator of the JavaThreads in the runtime + * + * @see JavaThread + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getThreads(); + + /** + * This is short cut method. The same result can be found by iterating over all + * methods in all class loaders in all classes. + * + * @return an iterator over all of the JavaMethods in the JavaRuntime which + * have been compiled + * + * @see JavaMethod + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getCompiledMethods(); + + /** + * Provides access to the collection of monitors used in the JavaVM. This + * collection includes both monitors associated with managed objects (e.g. object + * monitors) and monitors associated with internal control structures (e.g. + * raw monitors) + * + * @return an iterator over the collection of monitors + * + * @see JavaMonitor + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getMonitors(); + + /** + * Get the set of heaps known by the VM + * @return an iterator for all of the Java heaps within this runtime. Heaps + * may be specific to this JavaVM instance, or may be shared between multiple + * JavaVM instances + * + * @see JavaHeap + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getHeaps(); + + /** + * Get the set of object and class roots known to the VM. + * Stack frame roots are not included in the set, they can be retrieved using JavaStackFrame.getHeapRoots(). + * + * @return an iterator over the collection of JavaReferences representing the known global heap roots within this runtime. + * + * @see JavaReference + * @see JavaStackFrame + * @see com.ibm.dtfj.image.CorruptData + * + */ + public Iterator getHeapRoots(); + + /** + * Fetches implementation specific trace buffers, like the verbose GC buffer + * or the Universal Trace Engine (UTE) buffer + * + * @param bufferName a String naming the buffer to be fetched + * @param formatted true if formatting should be performed on the buffer, or + * false if the raw buffer contents should be returned + * @return an implementation specific result, depending on the parameters + * @throws CorruptDataException + */ + public Object getTraceBuffer(String bufferName, boolean formatted) throws CorruptDataException; + + /** + * Gets the object located at address address in the heap. + * @param address the ImagePointer instance representing the start address of object in the heap; + * @return the JavaObject instance representing the located object. + * @throws IllegalArgumentException if address is outside the heap's boundaries, or if it doesn't point to the start location of an object; + * @throws MemoryAccessException if address is in the heap but it's not accessible from the dump; + * @throws CorruptDataException if any data needed to build the returned instance of JavaObject is corrupt. + * @throws DataUnavailable if any data needed to build the returned instance of JavaObject is not available. + * @see com.ibm.dtfj.java.JavaObject + */ + public JavaObject getObjectAtAddress(ImagePointer address) throws CorruptDataException, IllegalArgumentException, MemoryAccessException, DataUnavailable; + + /** + * Returns iterator of the top-level memory categories used by this + * Java runtime. + * + * @return Iterator of memory categories + * @see JavaRuntimeMemoryCategory CorruptData + * @since 1.5 + */ + public Iterator getMemoryCategories() throws DataUnavailable; + + /** + * Returns an iterator of JavaRuntimeMemorySection objects corresponding to the blocks of memory allocated by the JavaRuntime. + * + * @param includeFreed If true, iterator will iterate over blocks of memory that have been freed, but haven't been re-used yet. + * @return Iterator of memory sections. + * @see JavaRuntimeMemorySection CorruptData + * @since 1.5 + */ + public Iterator getMemorySections(boolean includeFreed) throws DataUnavailable; /** * @param obj diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaStackFrame.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaStackFrame.java index ffb0c24d229..20d5aae5257 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaStackFrame.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaStackFrame.java @@ -31,29 +31,29 @@ * Represents a frame on a Java thread stack. */ public interface JavaStackFrame { - /** - * Get a pointer to the base of this stack frame - * @return the base pointer of the stack frame - * @throws CorruptDataException - */ - public ImagePointer getBasePointer() throws CorruptDataException; + /** + * Get a pointer to the base of this stack frame + * @return the base pointer of the stack frame + * @throws CorruptDataException + */ + public ImagePointer getBasePointer() throws CorruptDataException; /** - * Get the location at which the method owning this frame is currently executing - * @return a location object describing where the frame - * is executing + * Get the location at which the method owning this frame is currently executing + * @return a location object describing where the frame + * is executing * @throws CorruptDataException - * - * @see JavaLocation - * - */ - public JavaLocation getLocation() throws CorruptDataException; + * + * @see JavaLocation + * + */ + public JavaLocation getLocation() throws CorruptDataException; - /** - * Get the set of object roots from this stack frame. + /** + * Get the set of object roots from this stack frame. * - * @return an iterator of JavaReferences - */ + * @return an iterator of JavaReferences + */ public Iterator getHeapRoots(); /** diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaThread.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaThread.java index effaa7181b8..3214d592abd 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaThread.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/JavaThread.java @@ -70,106 +70,106 @@ public interface JavaThread { /** The thread is in a vendor specific state */ int STATE_VENDOR_3 = 0x40000000; - /** - * Get the address of the JNIEnv structure which represents this thread instance in JNI. - * @return the address of the JNIEnv structure which represents this thread instance in JNI - * @throws CorruptDataException - */ - public ImagePointer getJNIEnv() throws CorruptDataException; + /** + * Get the address of the JNIEnv structure which represents this thread instance in JNI. + * @return the address of the JNIEnv structure which represents this thread instance in JNI + * @throws CorruptDataException + */ + public ImagePointer getJNIEnv() throws CorruptDataException; - /** - * Get the Java priority of the thread. - * @return the Java priority of the thread (a number between 1 and 10 inclusive) - * @throws CorruptDataException - * - * @see Thread#getPriority() - */ - public int getPriority() throws CorruptDataException; + /** + * Get the Java priority of the thread. + * @return the Java priority of the thread (a number between 1 and 10 inclusive) + * @throws CorruptDataException + * + * @see Thread#getPriority() + */ + public int getPriority() throws CorruptDataException; - /** - * Fetch the java.lang.Thread associated with this thread. If the thread is in the process - * of being attached, this may return null. - * - * @return the a JavaObject representing the java.lang.Thread associated with this thread - * @throws CorruptDataException - * - * @see JavaObject - * @see Thread - */ - public JavaObject getObject() throws CorruptDataException; + /** + * Fetch the java.lang.Thread associated with this thread. If the thread is in the process + * of being attached, this may return null. + * + * @return the a JavaObject representing the java.lang.Thread associated with this thread + * @throws CorruptDataException + * + * @see JavaObject + * @see Thread + */ + public JavaObject getObject() throws CorruptDataException; - /** - * Get the state of the thread when the image was created. - * @return the state of the thread when the image was created. - * The result is a bit vector, and uses the states defined by - * the JVMTI specification. - * @throws CorruptDataException - */ - public int getState() throws CorruptDataException; + /** + * Get the state of the thread when the image was created. + * @return the state of the thread when the image was created. + * The result is a bit vector, and uses the states defined by + * the JVMTI specification. + * @throws CorruptDataException + */ + public int getState() throws CorruptDataException; - /** - * Represents the joining point between the Java view of execution and the corresponding native view. - * This method is where the mapping from Java into native threading resources is provided. - * - * @return the ImageThread which this ManagedThread is currently bound to. - * @throws CorruptDataException If the underlying resource describing the native representation of the thread - * is damaged - * @throws DataUnavailable If no mapping is provided due to missing or limited underlying resources (this - * exception added in DTFJ 1.1) - * - * @see ImageThread - */ - public ImageThread getImageThread() throws CorruptDataException, DataUnavailable; + /** + * Represents the joining point between the Java view of execution and the corresponding native view. + * This method is where the mapping from Java into native threading resources is provided. + * + * @return the ImageThread which this ManagedThread is currently bound to. + * @throws CorruptDataException If the underlying resource describing the native representation of the thread + * is damaged + * @throws DataUnavailable If no mapping is provided due to missing or limited underlying resources (this + * exception added in DTFJ 1.1) + * + * @see ImageThread + */ + public ImageThread getImageThread() throws CorruptDataException, DataUnavailable; - /** - * Get the set of ImageSections which make up the managed stack. - * @return a collection of ImageSections which make up the managed stack. - *

        - * Some Runtime implementations may also use parts of the ImageThread's stack - * for ManagesStackFrames - * - * @see ImageSection - * @see ImageThread#getStackSections() - * @see com.ibm.dtfj.image.CorruptData - */ - public Iterator getStackSections(); + /** + * Get the set of ImageSections which make up the managed stack. + * @return a collection of ImageSections which make up the managed stack. + *

        + * Some Runtime implementations may also use parts of the ImageThread's stack + * for ManagesStackFrames + * + * @see ImageSection + * @see ImageThread#getStackSections() + * @see com.ibm.dtfj.image.CorruptData + */ + public Iterator getStackSections(); - /** - * Get the set of stack frames. - * @return an iterator to walk the managed stack frames in order from - * top-of-stack (that is, the most recent frame) to bottom-of-stack - * - * @see JavaStackFrame - * @see com.ibm.dtfj.image.CorruptData - * - */ - public Iterator getStackFrames(); + /** + * Get the set of stack frames. + * @return an iterator to walk the managed stack frames in order from + * top-of-stack (that is, the most recent frame) to bottom-of-stack + * + * @see JavaStackFrame + * @see com.ibm.dtfj.image.CorruptData + * + */ + public Iterator getStackFrames(); - /** - * Return the name of the thread. - * - * Usually this is derived from the object associated with the thread, but if the - * name cannot be derived this way (e.g. there is no object associated with the thread) - * DTFJ will synthesize a name for the thread. - * - * @return the name of the thread - * @throws CorruptDataException - */ - public String getName() throws CorruptDataException; + /** + * Return the name of the thread. + * + * Usually this is derived from the object associated with the thread, but if the + * name cannot be derived this way (e.g. there is no object associated with the thread) + * DTFJ will synthesize a name for the thread. + * + * @return the name of the thread + * @throws CorruptDataException + */ + public String getName() throws CorruptDataException; - /** - * For threads that are in STATE_BLOCKED_ON_MONITOR_ENTER this method returns the JavaObject who's monitor they are blocked on. - * For threads that are in STATE_IN_OBJECT_WAIT this method returns the JavaObject that Object.wait() was called on. - * For threads that are in STATE_PARKED this method returns the JavaObject that was passed as the "blocker" object to the java.util.concurrent.LockSupport.park() call. It may return null if no blocker object was passed. - * For threads in any other state this call will return null. - * The state of the thread can be determined by calling JavaThread.getState() - * - * @return the object this thread is waiting on or null. - * @throws CorruptDataException - * @throws DataUnavailable - * @since 1.6 - */ - public JavaObject getBlockingObject() throws CorruptDataException, DataUnavailable; + /** + * For threads that are in STATE_BLOCKED_ON_MONITOR_ENTER this method returns the JavaObject who's monitor they are blocked on. + * For threads that are in STATE_IN_OBJECT_WAIT this method returns the JavaObject that Object.wait() was called on. + * For threads that are in STATE_PARKED this method returns the JavaObject that was passed as the "blocker" object to the java.util.concurrent.LockSupport.park() call. It may return null if no blocker object was passed. + * For threads in any other state this call will return null. + * The state of the thread can be determined by calling JavaThread.getState() + * + * @return the object this thread is waiting on or null. + * @throws CorruptDataException + * @throws DataUnavailable + * @since 1.6 + */ + public JavaObject getBlockingObject() throws CorruptDataException, DataUnavailable; /** * @param obj diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaAbstractClass.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaAbstractClass.java index a0123e1efaa..f3a9f57d796 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaAbstractClass.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaAbstractClass.java @@ -232,18 +232,18 @@ protected void addSuperclassReference (Collection coll) { } protected void addClassObjectReference (Collection coll) { - JavaReference jRef = null; - - try { - com.ibm.dtfj.java.JavaObject classObject = this.getObject(); - - if(null != classObject) { - jRef = new JavaReference(_javaVM,this,classObject,"Class object",JavaReference.REFERENCE_CLASS_OBJECT,JavaReference.HEAP_ROOT_UNKNOWN, JavaReference.REACHABILITY_STRONG); - coll.add(jRef); - } - } catch (CorruptDataException e) { - coll.add(e.getCorruptData()); - } + JavaReference jRef = null; + + try { + com.ibm.dtfj.java.JavaObject classObject = this.getObject(); + + if (null != classObject) { + jRef = new JavaReference(_javaVM,this,classObject,"Class object",JavaReference.REFERENCE_CLASS_OBJECT,JavaReference.HEAP_ROOT_UNKNOWN, JavaReference.REACHABILITY_STRONG); + coll.add(jRef); + } + } catch (CorruptDataException e) { + coll.add(e.getCorruptData()); + } } private JavaField getProtectionDomainField(JavaClass clazz) throws CorruptDataException { diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaReference.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaReference.java index 8d28c05381a..7eca09596c3 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaReference.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaReference.java @@ -102,24 +102,24 @@ public JavaReference(JavaRuntime javaVM, Object source, Object target, String de /* target is a class. */ _resolution = ResolutionType_CLASS; } else if ((JavaReference.HEAP_ROOT_JNI_GLOBAL == _roottype) || - (JavaReference.HEAP_ROOT_JNI_LOCAL == _roottype) || - (JavaReference.HEAP_ROOT_MONITOR == _roottype) || - (JavaReference.HEAP_ROOT_OTHER == _roottype) || - (JavaReference.HEAP_ROOT_STACK_LOCAL == _roottype) || - (JavaReference.HEAP_ROOT_THREAD == _roottype) || - (JavaReference.HEAP_ROOT_FINALIZABLE_OBJ == _roottype) || - (JavaReference.HEAP_ROOT_UNFINALIZED_OBJ == _roottype) || - (JavaReference.HEAP_ROOT_CLASSLOADER == _roottype) || - (JavaReference.HEAP_ROOT_STRINGTABLE == _roottype) || - (JavaReference.REFERENCE_ARRAY_ELEMENT == _referencetype) || - (JavaReference.REFERENCE_CLASS_LOADER == _referencetype) || - (JavaReference.REFERENCE_CONSTANT_POOL == _referencetype) || - (JavaReference.REFERENCE_FIELD == _referencetype) || - (JavaReference.REFERENCE_INTERFACE == _referencetype) || - (JavaReference.REFERENCE_PROTECTION_DOMAIN == _referencetype) || - (JavaReference.REFERENCE_SIGNERS == _referencetype) || - (JavaReference.REFERENCE_STATIC_FIELD == _referencetype) || - (JavaReference.REFERENCE_CLASS_OBJECT == _referencetype)) { + (JavaReference.HEAP_ROOT_JNI_LOCAL == _roottype) || + (JavaReference.HEAP_ROOT_MONITOR == _roottype) || + (JavaReference.HEAP_ROOT_OTHER == _roottype) || + (JavaReference.HEAP_ROOT_STACK_LOCAL == _roottype) || + (JavaReference.HEAP_ROOT_THREAD == _roottype) || + (JavaReference.HEAP_ROOT_FINALIZABLE_OBJ == _roottype) || + (JavaReference.HEAP_ROOT_UNFINALIZED_OBJ == _roottype) || + (JavaReference.HEAP_ROOT_CLASSLOADER == _roottype) || + (JavaReference.HEAP_ROOT_STRINGTABLE == _roottype) || + (JavaReference.REFERENCE_ARRAY_ELEMENT == _referencetype) || + (JavaReference.REFERENCE_CLASS_LOADER == _referencetype) || + (JavaReference.REFERENCE_CONSTANT_POOL == _referencetype) || + (JavaReference.REFERENCE_FIELD == _referencetype) || + (JavaReference.REFERENCE_INTERFACE == _referencetype) || + (JavaReference.REFERENCE_PROTECTION_DOMAIN == _referencetype) || + (JavaReference.REFERENCE_SIGNERS == _referencetype) || + (JavaReference.REFERENCE_STATIC_FIELD == _referencetype) || + (JavaReference.REFERENCE_CLASS_OBJECT == _referencetype)) { /* target is an object. */ _resolution = ResolutionType_OBJECT; } else { @@ -196,24 +196,24 @@ public Object getTarget() throws DataUnavailable, CorruptDataException { } _resolution = ResolutionType_CLASS; } else if ((JavaReference.HEAP_ROOT_JNI_GLOBAL == _roottype) || - (JavaReference.HEAP_ROOT_JNI_LOCAL == _roottype) || - (JavaReference.HEAP_ROOT_MONITOR == _roottype) || - (JavaReference.HEAP_ROOT_OTHER == _roottype) || - (JavaReference.HEAP_ROOT_STACK_LOCAL == _roottype) || - (JavaReference.HEAP_ROOT_THREAD == _roottype) || - (JavaReference.HEAP_ROOT_FINALIZABLE_OBJ == _roottype) || - (JavaReference.HEAP_ROOT_UNFINALIZED_OBJ == _roottype) || - (JavaReference.HEAP_ROOT_CLASSLOADER == _roottype) || - (JavaReference.HEAP_ROOT_STRINGTABLE == _roottype) || - (JavaReference.REFERENCE_ARRAY_ELEMENT == _referencetype) || - (JavaReference.REFERENCE_CLASS_LOADER == _referencetype) || - (JavaReference.REFERENCE_CONSTANT_POOL == _referencetype) || - (JavaReference.REFERENCE_FIELD == _referencetype) || - (JavaReference.REFERENCE_INTERFACE == _referencetype) || - (JavaReference.REFERENCE_PROTECTION_DOMAIN == _referencetype) || - (JavaReference.REFERENCE_SIGNERS == _referencetype) || - (JavaReference.REFERENCE_STATIC_FIELD == _referencetype) || - (JavaReference.REFERENCE_CLASS_OBJECT == _referencetype)) { + (JavaReference.HEAP_ROOT_JNI_LOCAL == _roottype) || + (JavaReference.HEAP_ROOT_MONITOR == _roottype) || + (JavaReference.HEAP_ROOT_OTHER == _roottype) || + (JavaReference.HEAP_ROOT_STACK_LOCAL == _roottype) || + (JavaReference.HEAP_ROOT_THREAD == _roottype) || + (JavaReference.HEAP_ROOT_FINALIZABLE_OBJ == _roottype) || + (JavaReference.HEAP_ROOT_UNFINALIZED_OBJ == _roottype) || + (JavaReference.HEAP_ROOT_CLASSLOADER == _roottype) || + (JavaReference.HEAP_ROOT_STRINGTABLE == _roottype) || + (JavaReference.REFERENCE_ARRAY_ELEMENT == _referencetype) || + (JavaReference.REFERENCE_CLASS_LOADER == _referencetype) || + (JavaReference.REFERENCE_CONSTANT_POOL == _referencetype) || + (JavaReference.REFERENCE_FIELD == _referencetype) || + (JavaReference.REFERENCE_INTERFACE == _referencetype) || + (JavaReference.REFERENCE_PROTECTION_DOMAIN == _referencetype) || + (JavaReference.REFERENCE_SIGNERS == _referencetype) || + (JavaReference.REFERENCE_STATIC_FIELD == _referencetype) || + (JavaReference.REFERENCE_CLASS_OBJECT == _referencetype)) { // this is an object reference, so create a object to represent the target. ImagePointer pointer = _javaVM.pointerInAddressSpace(_address); try { diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaRuntime.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaRuntime.java index 3f586684d09..053348f5e69 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaRuntime.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/java/j9/JavaRuntime.java @@ -519,7 +519,7 @@ public int bytesPerPointer() { // CMVC 156226 - DTFJ exception: XML and core file pointer sizes differ (zOS) int s = _containingProc.getPointerSize(); - int s2 = ((com.ibm.dtfj.image.j9.ImageAddressSpace)(_address.getAddressSpace())).bytesPerPointer(); + int s2 = ((com.ibm.dtfj.image.j9.ImageAddressSpace)(_address.getAddressSpace())).bytesPerPointer(); if (s == 64 || s == 32 || s == 31) { return (s + 7) / 8; } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/javacore/builder/javacore/ImageBuilder.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/javacore/builder/javacore/ImageBuilder.java index 5302377ba43..35dd09cc116 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/javacore/builder/javacore/ImageBuilder.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/javacore/builder/javacore/ImageBuilder.java @@ -88,7 +88,7 @@ public Image getImage() { * @param osType */ public void setOSType(String osType) { - fImage.setOSType(osType); + fImage.setOSType(osType); } /** diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/javacore/parser/j9/section/memory/MemoryTagParser.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/javacore/parser/j9/section/memory/MemoryTagParser.java index 0cb58686e22..ec7096296d2 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/javacore/parser/j9/section/memory/MemoryTagParser.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/javacore/parser/j9/section/memory/MemoryTagParser.java @@ -75,4 +75,3 @@ public void processLine(String source, int startingOffset) { addTag(T_1STSEGMENT, lineRule); } } - diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/PHDJavaObject.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/PHDJavaObject.java index 6262a5acefb..9714746d614 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/PHDJavaObject.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/PHDJavaObject.java @@ -374,7 +374,7 @@ public JavaReference next() { } else { refType = PHDJavaReference.REFERENCE_FIELD; } - cls1 = heap.getJavaRuntime().findClass(ref); + cls1 = heap.getJavaRuntime().findClass(ref); } if (cls1 != null) { return new PHDJavaReference( diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/PHDJavaReference.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/PHDJavaReference.java index 9de10f6cff8..a794e3b8515 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/PHDJavaReference.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/PHDJavaReference.java @@ -47,55 +47,55 @@ class PHDJavaReference implements JavaReference { this.ref = ref; this.root = root; switch (ref) { - /** Unknown reference type */ + /** Unknown reference type */ case REFERENCE_UNKNOWN: desc = "Unknown reference"; break; - /** Reference from an object to its class */ + /** Reference from an object to its class */ case REFERENCE_CLASS: desc = "Class reference"; break; - /** Reference from an object to the value of one of its instance fields */ + /** Reference from an object to the value of one of its instance fields */ case REFERENCE_FIELD: desc = "Field reference"; break; - /** Reference from an array to one of its elements */ + /** Reference from an array to one of its elements */ case REFERENCE_ARRAY_ELEMENT: desc = "Array element reference"; break; - /** Reference from a class to its class loader */ + /** Reference from a class to its class loader */ case REFERENCE_CLASS_LOADER: desc = "Class loader reference"; break; - /** Reference from a class to its signers array */ + /** Reference from a class to its signers array */ case REFERENCE_SIGNERS: desc = "Signers reference"; break; - /** Reference from a class to its protection domain */ + /** Reference from a class to its protection domain */ case REFERENCE_PROTECTION_DOMAIN: desc = "Protection domain reference"; break; - /** Reference from a class to one of its interfaces */ + /** Reference from a class to one of its interfaces */ case REFERENCE_INTERFACE: desc = "Interface reference"; break; - /** Reference from a class to the value of one of its static fields */ + /** Reference from a class to the value of one of its static fields */ case REFERENCE_STATIC_FIELD: desc = "Static field reference"; break; - /** Reference from a class to a resolved entry in the constant pool */ + /** Reference from a class to a resolved entry in the constant pool */ case REFERENCE_CONSTANT_POOL: desc = "Constant pool reference"; break; - /** Reference from a class to its superclass */ + /** Reference from a class to its superclass */ case REFERENCE_SUPERCLASS: desc = "Superclass reference"; break; - /** Reference from a classloader object to its loaded classes */ + /** Reference from a classloader object to its loaded classes */ case REFERENCE_LOADED_CLASS: desc = "Loaded class reference"; break; - /** Reference from a class to its java.lang.Class instance */ + /** Reference from a class to its java.lang.Class instance */ case REFERENCE_CLASS_OBJECT: desc = "Class object reference"; break; diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/parser/Base.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/parser/Base.java index 092b84bc2a8..a28e247ad97 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/parser/Base.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/parser/Base.java @@ -139,4 +139,3 @@ void parseOptions(String args[]) { } } } - diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/parser/HeapdumpWriter.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/parser/HeapdumpWriter.java index 572264f1869..1ca2c5b9fb6 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/parser/HeapdumpWriter.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/parser/HeapdumpWriter.java @@ -134,10 +134,10 @@ else if (refsSize == 3) void addToCache(int classAddress) { /* May consider this as a future change to the spec... - for (int i = 0; i < 4; i++) { - if (classAddressCache[i] == classAddress) - return; - } + for (int i = 0; i < 4; i++) { + if (classAddressCache[i] == classAddress) + return; + } */ classAddressCache[classAddressCacheIndex] = classAddress; classAddressCacheIndex = (classAddressCacheIndex + 1) % 4; diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/util/BitStream.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/util/BitStream.java index abe4f68e718..af27cd42c98 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/util/BitStream.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/util/BitStream.java @@ -104,7 +104,7 @@ public void writeIntBits(int n, int len, int wordOff, int bitOff) { public void nextWord(boolean write) { wordOffset++; if (wordOffset >= bits.length) { - int[] tmp = new int[(bits.length * 3 + 1) / 2]; + int[] tmp = new int[(bits.length * 3 + 1) / 2]; System.arraycopy(bits, 0, tmp, 0, bits.length); bits = tmp; } else if (write) { diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/util/LongEnumeration.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/util/LongEnumeration.java index 55afde016f7..ca708143db3 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/util/LongEnumeration.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/phd/util/LongEnumeration.java @@ -48,4 +48,3 @@ public interface LongEnumeration extends Enumeration { */ public int numberOfElements(); } - diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/FileManager.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/FileManager.java index 33e64a7929b..a6bd0cbcbf5 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/FileManager.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/FileManager.java @@ -213,4 +213,3 @@ protected String genJavacoreName(String[] s, int inc, int componentToInc) { return sb.toString(); } } - diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/FileSniffer.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/FileSniffer.java index 4b13705de53..1f1165d46f9 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/FileSniffer.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/FileSniffer.java @@ -54,10 +54,10 @@ public class FileSniffer { private static final int USERDUMP_2 = 0x44554D50; //DR1 and DR2 are z/OS core file identifiers - private static final int DR1 = 0xc4d9f140; - private static final int DR2 = 0xc4d9f240; + private static final int DR1 = 0xc4d9f140; + private static final int DR2 = 0xc4d9f240; - //XCOFF identifiers + //XCOFF identifiers private static final int CORE_DUMP_XX_VERSION = 0xFEEDDB2; private static final int CORE_DUMP_X_VERSION = 0xFEEDDB1; @@ -65,34 +65,34 @@ public class FileSniffer { private static final int MACHO_64 = 0xFEEDFACF; private static final int MACHO_64_REV = 0xCFFAEDFE; - private static int[] coreid = new int[]{ELF, MINIDUMP, DR1, DR2}; + private static int[] coreid = new int[]{ELF, MINIDUMP, DR1, DR2}; - //PHD identifier - private static final String PHD_HEADER = "portable heap dump"; - private static final int PHD_HEADER_SIZE = PHD_HEADER.length() + 2; //UTF-8 string so need to add 2 length bytes + //PHD identifier + private static final String PHD_HEADER = "portable heap dump"; + private static final int PHD_HEADER_SIZE = PHD_HEADER.length() + 2; //UTF-8 string so need to add 2 length bytes - //zip file identifier - private static final int ZIP_ID = 0x04034b50; + //zip file identifier + private static final int ZIP_ID = 0x04034b50; - //the format for a core file - public enum CoreFormatType { - ELF, - MINIDUMP, - MVS, - XCOFF, - USERDUMP, - MACHO, - UNKNOWN - } + //the format for a core file + public enum CoreFormatType { + ELF, + MINIDUMP, + MVS, + XCOFF, + USERDUMP, + MACHO, + UNKNOWN + } - /** - * Determine the format of the core file. - * - * @param iis stream to the core file - * @return format - * @throws IOException re-thrown - */ - public static CoreFormatType getCoreFormat(ImageInputStream iis) throws IOException { + /** + * Determine the format of the core file. + * + * @param iis stream to the core file + * @return format + * @throws IOException re-thrown + */ + public static CoreFormatType getCoreFormat(ImageInputStream iis) throws IOException { try { int header = iis.readInt(); int header2 = iis.readInt(); @@ -334,12 +334,12 @@ private static String readUTF(ImageInputStream iis, int maxlen) throws IOExcepti * A. Local file header: - local file header signature 4 bytes (0x04034b50) - version needed to extract 2 bytes - general purpose bit flag 2 bytes - compression method 2 bytes - last mod file time 2 bytes - last mod file date 2 bytes + local file header signature 4 bytes (0x04034b50) + version needed to extract 2 bytes + general purpose bit flag 2 bytes + compression method 2 bytes + last mod file time 2 bytes + last mod file date 2 bytes */ public static boolean isZipFile(ImageInputStream iis) throws IOException { ByteOrder byteOrder = iis.getByteOrder(); diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/MultipleCandidateException.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/MultipleCandidateException.java index e39f919bb07..ec84de322ea 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/MultipleCandidateException.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/utils/file/MultipleCandidateException.java @@ -68,4 +68,3 @@ public File getFile() { } } - diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/java/diagnostics/utils/commands/ICommand.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/java/diagnostics/utils/commands/ICommand.java index bbd55bd8c3d..c2907aea4b9 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/java/diagnostics/utils/commands/ICommand.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/java/diagnostics/utils/commands/ICommand.java @@ -53,9 +53,9 @@ public interface ICommand { */ public Collection getCommandDescriptions(); - /** - * @return Strings containing command names - */ + /** + * @return Strings containing command names + */ public Collection getCommandNames(); /** diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/jvm/j9/dump/indexsupport/NodeFrame.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/jvm/j9/dump/indexsupport/NodeFrame.java index 58e2c0296fb..bbc8c10bea0 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/jvm/j9/dump/indexsupport/NodeFrame.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/jvm/j9/dump/indexsupport/NodeFrame.java @@ -51,7 +51,7 @@ public NodeFrame(JavaThread thread, Attributes attributes) } } try { - _frame = thread.addNewStackFrame(arguments, method, pc, lineNumber); + _frame = thread.addNewStackFrame(arguments, method, pc, lineNumber); } catch(IllegalArgumentException e){ // skip bad frame (subsequent error tag will indicate corrupt stack) diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/jvm/j9/dump/indexsupport/XMLIndexReader.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/jvm/j9/dump/indexsupport/XMLIndexReader.java index b0486299fc3..ab91cb77087 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/jvm/j9/dump/indexsupport/XMLIndexReader.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/jvm/j9/dump/indexsupport/XMLIndexReader.java @@ -139,27 +139,27 @@ public Image parseIndexWithDump(InputStream input, ICoreFileReader core, ImageIn } public void startElement(String uri, - String localName, - String qName, - Attributes attributes) - throws SAXException - { + String localName, + String qName, + Attributes attributes) + throws SAXException + { _checkScrapeBuffer(); IParserNode node = ((IParserNode)(_elements.peek())).nodeToPushAfterStarting(uri, localName, qName, attributes); assert (null != node) : "Node should not be null when starting new tag: " + qName; _elements.push(node); - } + } public void endElement(String uri, - String localName, - String qName) - throws SAXException - { + String localName, + String qName) + throws SAXException + { _checkScrapeBuffer(); // pop whatever we were parsing and notify them that we are discarding them IParserNode formerTop = (IParserNode) _elements.pop(); formerTop.didFinishParsing(); - } + } private void _checkScrapeBuffer() { @@ -184,7 +184,7 @@ public IParserNode nodeToPushAfterStarting(String uri, String localName, String next = NodeUnexpectedTag.unexpectedTag(qName, attributes); } return next; - } + } public void stringWasParsed(String string) { From fc0a498cbc1a909fd3f95460560962111e56f18f Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 16:20:04 -0400 Subject: [PATCH 11/16] Tidy up whitespace in openj9.dtfjview * remove trailing whitespace * indent with tabs consistently * collapse sequences of two or more blank lines * remove extra trailing blank lines Signed-off-by: Keith W. Campbell --- .../com/ibm/jvm/dtfjview/CombinedContext.java | 4 +- .../jvm/dtfjview/ConsoleOutputChannel.java | 8 +- .../com/ibm/jvm/dtfjview/DTFJView.java | 8 +- .../com/ibm/jvm/dtfjview/ExitCodes.java | 17 +- .../ibm/jvm/dtfjview/FileOutputChannel.java | 21 +- .../jvm/dtfjview/JdmpviewContextManager.java | 22 +- .../jvm/dtfjview/JdmpviewInitException.java | 4 +- .../ibm/jvm/dtfjview/JdmpviewPrintStream.java | 8 +- .../classes/com/ibm/jvm/dtfjview/Output.java | 29 +- .../jvm/dtfjview/OutputChannelRedirector.java | 4 +- .../classes/com/ibm/jvm/dtfjview/Session.java | 156 +++++----- .../ibm/jvm/dtfjview/SessionProperties.java | 19 +- .../ibm/jvm/dtfjview/SystemProperties.java | 10 +- .../classes/com/ibm/jvm/dtfjview/Version.java | 8 +- .../commands/BaseJdmpviewCommand.java | 66 ++--- .../ibm/jvm/dtfjview/commands/CdCommand.java | 10 +- .../jvm/dtfjview/commands/CloseCommand.java | 2 +- .../dtfjview/commands/DeadlockCommand.java | 82 +++--- .../dtfjview/commands/ExceptionHandler.java | 21 +- .../jvm/dtfjview/commands/FindCommand.java | 4 +- .../dtfjview/commands/FindNextCommand.java | 9 +- .../dtfjview/commands/HeapdumpCommand.java | 276 +++++++++--------- .../jvm/dtfjview/commands/HelpCommand.java | 12 +- .../jvm/dtfjview/commands/HexdumpCommand.java | 6 +- .../ibm/jvm/dtfjview/commands/PwdCommand.java | 6 +- .../jvm/dtfjview/commands/ScrollCommand.java | 12 +- .../commands/SimpleRedirectorCommand.java | 14 +- .../jvm/dtfjview/commands/WhatisCommand.java | 53 ++-- .../commands/helpers/ClassOutput.java | 75 +++-- .../dtfjview/commands/helpers/Exceptions.java | 6 +- .../commands/helpers/JUCMonitorNode.java | 6 +- .../commands/helpers/MonitorNode.java | 10 +- .../commands/helpers/MonitorState.java | 12 +- .../dtfjview/commands/helpers/NodeList.java | 33 +-- .../commands/helpers/StateToString.java | 22 +- .../dtfjview/commands/helpers/ThreadData.java | 6 +- .../jvm/dtfjview/commands/helpers/Utils.java | 173 ++++++----- .../infocommands/InfoClassCommand.java | 75 +++-- .../infocommands/InfoHeapCommand.java | 45 ++- .../infocommands/InfoJitmCommand.java | 33 +-- .../infocommands/InfoLockCommand.java | 35 ++- .../infocommands/InfoMemoryCommand.java | 30 +- .../infocommands/InfoMmapCommand.java | 29 +- .../infocommands/InfoProcCommand.java | 51 ++-- .../commands/infocommands/InfoSymCommand.java | 15 +- .../infocommands/InfoSystemCommand.java | 18 +- .../commands/setcommands/SetCommand.java | 4 +- .../setcommands/SetHeapdumpCommand.java | 30 +- .../setcommands/SetLoggingCommand.java | 38 +-- .../commands/showcommands/ShowCommand.java | 6 +- .../showcommands/ShowHeapdumpCommand.java | 15 +- .../showcommands/ShowLoggingCommand.java | 8 +- .../dtfjview/commands/xcommands/XCommand.java | 48 +-- .../commands/xcommands/XDCommand.java | 22 +- .../commands/xcommands/XJCommand.java | 56 ++-- .../commands/xcommands/XKCommand.java | 41 ++- .../commands/xcommands/XXCommand.java | 20 +- .../dtfjview/heapdump/HeapDumpFormatter.java | 22 +- .../dtfjview/heapdump/HeapDumpSettings.java | 38 +-- .../heapdump/LongArrayReferenceIterator.java | 12 +- .../heapdump/LongListReferenceIterator.java | 11 +- .../dtfjview/heapdump/ReferenceIterator.java | 12 +- .../classic/ClassicHeapDumpFormatter.java | 90 +++--- .../heapdump/portable/ClassRecord.java | 30 +- .../heapdump/portable/LongObjectRecord.java | 28 +- .../portable/LongPrimitiveArrayRecord.java | 36 +-- .../heapdump/portable/MediumObjectRecord.java | 24 +- .../heapdump/portable/ObjectArrayRecord.java | 8 +- .../heapdump/portable/ObjectRecord.java | 24 +- .../portable/PortableHeapDumpClassCache.java | 4 +- .../portable/PortableHeapDumpFormatter.java | 56 ++-- .../portable/PortableHeapDumpHeader.java | 15 +- .../portable/PortableHeapDumpRecord.java | 20 +- .../portable/PrimitiveArrayRecord.java | 20 +- .../heapdump/portable/ShortObjectRecord.java | 14 +- .../jvm/dtfjview/spi/ICombinedContext.java | 18 +- .../ibm/jvm/dtfjview/spi/IOutputChannel.java | 12 +- .../ibm/jvm/dtfjview/spi/IOutputManager.java | 19 +- .../com/ibm/jvm/dtfjview/spi/ISession.java | 20 +- .../dtfjview/spi/ISessionContextManager.java | 12 +- .../jvm/dtfjview/tools/CommandException.java | 21 +- .../com/ibm/jvm/dtfjview/tools/ITool.java | 18 +- .../ibm/jvm/dtfjview/tools/ParsedCommand.java | 16 +- .../com/ibm/jvm/dtfjview/tools/Tool.java | 6 +- .../ibm/jvm/dtfjview/tools/ToolsRegistry.java | 32 +- .../dtfjview/tools/impl/CharsFromTool.java | 14 +- .../jvm/dtfjview/tools/impl/CharsToTool.java | 12 +- .../jvm/dtfjview/tools/impl/CmdFileTool.java | 18 +- .../ibm/jvm/dtfjview/tools/impl/GrepTool.java | 73 +++-- .../ibm/jvm/dtfjview/tools/impl/HelpTool.java | 22 +- .../jvm/dtfjview/tools/impl/HistoryTool.java | 33 +-- .../jvm/dtfjview/tools/impl/OutFileTool.java | 22 +- .../jvm/dtfjview/tools/impl/TokensTool.java | 32 +- .../tools/utils/BlockPostmatchHandle.java | 4 +- .../tools/utils/BlockPrematchHandle.java | 6 +- .../jvm/dtfjview/tools/utils/FileUtils.java | 8 +- .../dtfjview/tools/utils/IMatchHandle.java | 4 +- .../tools/utils/IPostmatchHandle.java | 2 +- .../dtfjview/tools/utils/IPrematchHandle.java | 8 +- .../dtfjview/tools/utils/IStringModifier.java | 4 +- .../jvm/dtfjview/tools/utils/MatchHandle.java | 10 +- .../tools/utils/MaxLinesPrematchHandle.java | 4 +- .../tools/utils/OutputStreamModifier.java | 2 +- .../tools/utils/RegExprMatchHandle.java | 2 +- .../dtfjview/tools/utils/StringModifier.java | 7 +- .../dtfjview/tools/utils/StringReceiver.java | 2 +- 106 files changed, 1375 insertions(+), 1405 deletions(-) diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/CombinedContext.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/CombinedContext.java index 47b171c9746..6b73872ce90 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/CombinedContext.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/CombinedContext.java @@ -60,7 +60,7 @@ /** * Wrapper class that takes an existing DTFJ context and augments * it with a DDR interactive context if one exists. - * + * * @author adam */ public class CombinedContext extends DTFJContext implements ICombinedContext { @@ -193,7 +193,7 @@ private static boolean isDDRCommand(String cmdline) { /** * Starts a DDR interactive session using the loaded image. If the core file is not DDR enabled * this is recorded and future pling commands will not be available. In order to get access to the - * DDR classes it uses the Image classloader which, if the core file is DDR enabled, can see the + * DDR classes it uses the Image classloader which, if the core file is DDR enabled, can see the * required classes. * @param image Image created from the core file */ diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/ConsoleOutputChannel.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/ConsoleOutputChannel.java index 897ab6e9559..414aaf8dd14 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/ConsoleOutputChannel.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/ConsoleOutputChannel.java @@ -29,7 +29,7 @@ public class ConsoleOutputChannel implements IOutputChannel { private PrintStream out = System.out; //grab the print stream in case it gets redirected later on - + private boolean noPrint = false; public void print(String outputString) { @@ -50,7 +50,7 @@ public void error(String outputString) { System.err.print("\n"); System.err.print("ERROR: " + outputString + "\n"); } - + //logs an error to the specified output channel public void error(String msg, Exception e) { System.err.println(Utils.toString(msg)); @@ -61,11 +61,11 @@ public void printInput(long timestamp, String prompt, String outputString) { // we don't need to output anything, but we could output the time the command was started //System.out.println(""); } - + public void close() { // do nothing, because we don't need to close System.out or System.err } - + public void setNoPrint(boolean b) { noPrint = b; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/DTFJView.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/DTFJView.java index 6257a5213ac..c281a265d28 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/DTFJView.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/DTFJView.java @@ -46,13 +46,13 @@ public static void main(String[] args) { DTFJView dtfjView = new DTFJView(); dtfjView.launch(args); } - + public void launch(String[] args) { setPluginsPath(); session = Session.getInstance(args); ((Session)session).run(); } - + /* * There is no longer a hard coded list of in-built jdmpview commands, instead the dynamic discovery mechanism * introduced by the introduction of support for DTFJ plugins is used. In order to do this the current class path @@ -61,7 +61,7 @@ public void launch(String[] args) { * set of commands. Prepending this path ensures that in the event of a namespace clash with a subsequently developed * plugin, the in-built command will take precedence. */ - + private void setPluginsPath() { ClassLoader loader = getClass().getClassLoader(); if(loader instanceof URLClassLoader) { @@ -80,7 +80,7 @@ private void setPluginsPath() { } } } - + private void addSelfToPath(File jar) throws IOException { String prop = System.getProperty(PluginConstants.PLUGIN_SYSTEM_PROPERTY); if(prop == null) { diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/ExitCodes.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/ExitCodes.java index de1f6dd33f9..94c3ea0fb57 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/ExitCodes.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/ExitCodes.java @@ -25,7 +25,7 @@ /** * Exit codes which can be returned by jdmpview. * see Jazz Design 46749 - * + * * @author adam * */ @@ -34,33 +34,32 @@ public interface ExitCodes { * Processing completed normally without error */ public static final int JDMPVIEW_SUCCESS = 0; - + /** * One of the supplied commands could not be executed, or had a syntax error, processing continued afterwards. */ public static final int JDMPVIEW_SYNTAX_ERROR = 1; - + /** * The core file could not be found */ public static final int JDMPVIEW_FILE_ERROR = 2; - + /** * There were no jvm's found in the core file */ public static final int JDMPVIEW_NOJVM_ERROR = 3; - - + /** - * An internal error occurred and processing was aborted + * An internal error occurred and processing was aborted */ public static final int JDMPVIEW_INTERNAL_ERROR = 4; - + /** * An output file already exists and the overwrite option was not set */ public static final int JDMPVIEW_OUTFILE_EXISTS = 5; - + /** * Option -append and Option -overwrite can not co-exist. */ diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/FileOutputChannel.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/FileOutputChannel.java index a841bf7a2ad..33835ccb99b 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/FileOutputChannel.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/FileOutputChannel.java @@ -47,7 +47,7 @@ public void print(String outputString) { fw.write(Utils.toString(outputString)); fw.flush(); } catch (IOException e) { - + } } @@ -60,7 +60,7 @@ public void println(String outputString) { fw.write(Utils.toString(outputString) + "\n"); fw.flush(); } catch (IOException e) { - + } } @@ -71,10 +71,10 @@ public void error(String outputString) { fw.write("\n"); fw.flush(); } catch (IOException e) { - + } } - + //logs an error to the specified output channel public void error(String msg, Exception e) { try { @@ -85,7 +85,7 @@ public void error(String msg, Exception e) { e.printStackTrace(writer); fw.flush(); } catch (IOException ioe) { - + } } @@ -95,15 +95,15 @@ public void printInput(long timestamp, String prompt, String outputString) { prompt + Utils.toString(outputString) + "\n"); fw.flush(); } catch (IOException e) { - + } } - + public void close() { try { fw.close(); } catch (IOException e) { - + } } @@ -111,7 +111,7 @@ public void flush() { try { fw.flush(); } catch (IOException e) { - + } } @@ -132,6 +132,5 @@ private Object getFile() { public int hashCode() { return file.hashCode(); } - - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewContextManager.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewContextManager.java index c15bbb1940c..be5525e18df 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewContextManager.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewContextManager.java @@ -38,7 +38,7 @@ /** * Class for managing jdmpview contexts as it is possible to add and remove contexts * without exiting the application. - * + * * @author adam * */ @@ -46,10 +46,10 @@ public class JdmpviewContextManager implements ISessionContextManager { private Map> contextTracker = new LinkedHashMap>(); private int maxContextID = 0; private boolean hasChanged = false; - + /** * Create a new context from DTFJ. - * + * * @param image the DTFJ Image * @param major the DTFJ API major number * @param minor the DTFJ API minor number @@ -72,14 +72,14 @@ public ICombinedContext createContext(final Image image, final int major, final hasChanged = true; return combinedctx; } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISessionContextManager#removeContexts(com.ibm.dtfj.image.Image) */ public void removeContexts(Image image) { removeContexts(image.getSource()); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISessionContextManager#removeContexts(java.net.URI) */ @@ -92,7 +92,7 @@ public void removeContexts(URI source) { hasChanged = true; } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISessionContextManager#removeAllContexts() */ @@ -106,14 +106,14 @@ public void removeAllContexts() { removeContexts(source); } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISessionContextManager#getContexts() */ public Map> getContexts() { return Collections.unmodifiableMap(contextTracker); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISessionContextManager#hasMultipleContexts() */ @@ -123,12 +123,12 @@ public boolean hasMultipleContexts() { return false; case 1: //only one source, so need to look at contexts return contextTracker.values().size() > 1; - + default : //two or more sources exist = multiple contexts return true; } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISessionContextManager#getContext(int) */ @@ -145,7 +145,7 @@ public ICombinedContext getContext(int id) { } return null; //couldn't find the context } - + //indicates if the context list has changed since the last time this method was called /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISessionContextManager#hasChanged() diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewInitException.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewInitException.java index 104737aa52e..5a992859f5d 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewInitException.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewInitException.java @@ -24,14 +24,14 @@ /** * Indicates that jdmpview failed to initialize - * + * * @author adam * */ public class JdmpviewInitException extends RuntimeException { private static final long serialVersionUID = -5317431018607771062L; private final int exitCode; - + public JdmpviewInitException(int exitCode) { super(); this.exitCode = exitCode; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewPrintStream.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewPrintStream.java index d002ecb516f..e9968fbeed3 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewPrintStream.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/JdmpviewPrintStream.java @@ -31,13 +31,13 @@ /** * Jdmpview specific print stream which allows access to the underlying * Output class which controls an arbitrary number of write destinations - * + * * @author adam * */ public class JdmpviewPrintStream extends PrintStream { private OutputStream os = null; - + public JdmpviewPrintStream(OutputStream out) { super(out); os = out; @@ -68,10 +68,10 @@ public JdmpviewPrintStream(OutputStream out, boolean autoFlush, String encoding) super(out, autoFlush, encoding); os = out; } - + /** * Returns the output stream that was used in the constructor. - * + * * @return the stream or null if one wasn't used by the constructor */ public OutputStream getOutputStream() { diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Output.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Output.java index 37c52470a0e..4dd12e23bc7 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Output.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Output.java @@ -36,7 +36,7 @@ public class Output extends OutputStream implements IOutputManager { private ByteArrayOutputStream bos = new ByteArrayOutputStream(); //used to internally buffer data private PrintStream internalStream = new PrintStream(bos); private boolean isBufferingEnabled = false; //default of no buffering - + Vector outputChannels; long lastTimestamp = 0; String lastPrompt = ""; @@ -45,28 +45,28 @@ public class Output extends OutputStream implements IOutputManager { public Output(){ outputChannels = new Vector(); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#clearBuffer() */ public void clearBuffer() { bos.reset(); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#setBuffering(boolean) */ public void setBuffering(boolean enabled) { isBufferingEnabled = enabled; } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#getBuffer() */ public String getBuffer() { return bos.toString(); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#print(java.lang.String) */ @@ -79,7 +79,7 @@ public void print(String outputString){ } } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#printPrompt(java.lang.String) */ @@ -92,7 +92,7 @@ public void printPrompt(String prompt){ } } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#println(java.lang.String) */ @@ -105,22 +105,21 @@ public void println(String outputString){ } } } - - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#addChannel(com.ibm.jvm.dtfjview.spi.OutputChannel) */ public void addChannel(IOutputChannel channel){ addChannel(channel, false); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#addChannel(com.ibm.jvm.dtfjview.spi.OutputChannel, boolean) */ public void addChannel(IOutputChannel channel, boolean printLastInput){ outputChannels.add(channel); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#removeChannel(java.lang.Class) */ @@ -148,7 +147,7 @@ public void removeChannel(IOutputChannel channel) { public void removeAllChannels() { outputChannels.clear(); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#removeFileChannel() */ @@ -161,7 +160,7 @@ public void removeFileChannel(){ } } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#setConsoleNoPrint(boolean) */ @@ -173,7 +172,7 @@ public void setConsoleNoPrint(boolean noPrint){ } } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#close() */ @@ -207,7 +206,7 @@ public void write(int b) throws IOException { String msg = new String (chars); print(msg); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutput#flush() */ diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/OutputChannelRedirector.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/OutputChannelRedirector.java index f47addfefdf..c728b48b385 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/OutputChannelRedirector.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/OutputChannelRedirector.java @@ -33,7 +33,7 @@ public class OutputChannelRedirector implements IOutputChannel { private PrintStream redirector; - + public OutputChannelRedirector(PrintStream redirector) { if (null == redirector) { this.redirector = System.out; @@ -41,7 +41,7 @@ public OutputChannelRedirector(PrintStream redirector) { this.redirector = redirector; } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.IOutputChannel#print(java.lang.String) */ diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Session.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Session.java index d856304e2e7..cd5bd6f9ddd 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Session.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Session.java @@ -81,13 +81,13 @@ public class Session implements ISession { public static final String LOGGER_PROPERTY = "com.ibm.jvm.dtfjview.logger"; private String factoryName; - + private IOutputManager out; - + private static final String PROMPT_FORMAT_DEFAULT = "> "; private static final String PROMPT_FORMAT_MULTICONTEXT = "CTX:%d> "; public static String prompt = "> "; - + private static final String ARG_CORE = "-core"; private static final String ARG_ZIP = "-zip"; private static final String ARG_VERSION = "-version"; @@ -99,7 +99,7 @@ public class Session implements ISession { private static final String ARG_APPEND = "-append"; private static final String ARG_NOEXTRACT = "-notemp"; private static final String ARG_LEGACYZIP = "-legacyzip"; - + private static enum CmdLineParseStateEnum { //controls the parsing of the command line args PARSE_SCAN, //parsing is scanning the entries PARSE_PAIR, //parsing a name / value pair @@ -107,20 +107,20 @@ private static enum CmdLineParseStateEnum { //controls the parsing of the co PARSE_CMDS, //parsing any commands at the end of the line PARSE_COMPLETE //parsing is complete }; - + private CmdLineParseStateEnum parseState = CmdLineParseStateEnum.PARSE_SCAN; //default parse state - + private final Map args = new HashMap(); //map for name/value pair args private final Set singleargs = new HashSet(); //commands that are single args only e.g. -verbose private final Set pairedargs = new HashSet(); - private final Queue commands = new LinkedList(); //commands that could be specified on the command line - private final Set sessioncommands = new HashSet(); // commands which should execute against the session context + private final Queue commands = new LinkedList(); //commands that could be specified on the command line + private final Set sessioncommands = new HashSet(); // commands which should execute against the session context private boolean isInteractiveSession = false; //flag to indicated if running in batch or interactive mode private boolean isVerboseEnabled = false; //flag for verbose logging private IOutputChannel defaultOutputChannel = null; private FileOutputChannel foc = null; - private String charsetName = null; - + private String charsetName = null; + // private final ArrayList contexts = new ArrayList(); //the contexts related to the runtimes from core files private CombinedContext ctxroot = null; //root context for console access @@ -131,14 +131,14 @@ private static enum CmdLineParseStateEnum { //controls the parsing of the co private static final String CMD_CLOSE = "close"; private static final String CMD_CD = "cd"; private static final String CMD_PWD = "pwd"; - private boolean isZOS = false; //flag to control some formatting aspects - + private boolean isZOS = false; //flag to control some formatting aspects + private final HashMap variables = new HashMap(); //variables to propagate into contexts - + private final Logger logger = Logger.getLogger(LOGGER_PROPERTY); //logger for verbose messages - + private final ISessionContextManager ctxmgr = new JdmpviewContextManager(); - + { //define the list of supported command line args singleargs.add(ARG_VERBOSE); @@ -152,7 +152,7 @@ private static enum CmdLineParseStateEnum { //controls the parsing of the co pairedargs.add(ARG_OUTFILE); pairedargs.add(ARG_CHARSET); pairedargs.add(ARG_ZIP); - + // define the list of session commands - ones which run against the session context, not the per-image context // set logging and show logging are also session commands but are dealt with separately sessioncommands.add(CMD_CLOSE); @@ -161,17 +161,17 @@ private static enum CmdLineParseStateEnum { //controls the parsing of the co sessioncommands.add(CMD_PWD); } - + /** * Factory method for creating new sessions. - * + * * @param args any session arguments * @return the session */ public static ISession getInstance(String[] args) { return new Session(args); } - + private Session(String[] args) { sessionInit(args); } @@ -182,7 +182,7 @@ private Session(String[] args) { public IOutputManager getOutputManager() { return out; } - + public String getCharset() { return charsetName; } @@ -216,10 +216,10 @@ private void sessionInit(String[] cmdlineargs) { ctxroot = new CombinedContext(0, 0, null, null, null, null, -1); initializeContext(ctxroot); currentContext = ctxroot; //default to the root context at startup - + // Set system property to switch off additional DDR processing for Node.JS System.setProperty("com.ibm.j9ddr.noextrasearchfornode","true"); - + if(args.containsKey(ARG_CORE) || args.containsKey(ARG_ZIP) || args.containsKey(ARG_VERSION)) { //file to open has been specified on the command line // Note that although -version is not really an "open" action we pass it to the "open" action because @@ -227,7 +227,7 @@ private void sessionInit(String[] cmdlineargs) { imageFromCommandLine(); } } - + //initializes the supplied context with its starting parameters and property values private void initializeContext(IDTFJContext ctx) { ctx.refresh(); @@ -236,7 +236,7 @@ private void initializeContext(IDTFJContext ctx) { ctx.getProperties().put(key, variables.get(key)); //populate the context properties } } - + private void setPrompt() { if(ctxmgr.hasMultipleContexts()) { prompt = String.format(PROMPT_FORMAT_MULTICONTEXT, ctxid); @@ -244,21 +244,21 @@ private void setPrompt() { prompt = String.format(PROMPT_FORMAT_DEFAULT); } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISession#getCurrentContext() */ public ICombinedContext getCurrentContext() { return currentContext; } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISession#getCtxManager() */ public ISessionContextManager getContextManager() { return ctxmgr; } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISession#setContext(int) */ @@ -269,7 +269,7 @@ public void setContext(int id) throws CommandException { } setContext(switchTo); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISession#setContext(com.ibm.jvm.dtfjview.CombinedContext) */ @@ -281,7 +281,7 @@ public void setContext(ICombinedContext switchTo) throws CommandException { setPrompt(); //the prompt may reflect the currently selected context } } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISession#showContexts(boolean) */ @@ -300,7 +300,7 @@ public void showContexts(boolean shortFormat) { } for(ICombinedContext context : contexts.get(source)) { if(context == currentContext) { - out.print("\t*"); + out.print("\t*"); } else { out.print("\t "); } @@ -309,7 +309,7 @@ public void showContexts(boolean shortFormat) { } out.print("\n"); } - + //stops the current processing and exits with and optional code private void exit(String msg, int exitCode) { if(System.getProperty(SYSPROP_NOSYSTEMEXIT) == null) { @@ -326,7 +326,7 @@ private void exit(String msg, int exitCode) { throw new JdmpviewInitException(exitCode, msg); } } - + //checks to see if the specified flag has been set, this will be a single arg command line parameter private boolean hasFlagBeenSet(String name) { if(singleargs.contains(name)) { @@ -341,15 +341,15 @@ private boolean hasFlagBeenSet(String name) { return false; } } - - //state machine which parses all the command line arguments. It validates the correct use of single and + + //state machine which parses all the command line arguments. It validates the correct use of single and //paired arguments. It will regard the first item without a - as the start of any jdmpview cmds to run private void parseCommandLineArgs(String[] cmdargs) { if(cmdargs.length == 0) { //check at least one argument was supplied exit("No parameters were supplied", JDMPVIEW_SYNTAX_ERROR); } - + // Quotation marks are removed by the shell and that can cause filenames containing spaces to be split into several arguments. // This is rather crude, but if there is a quotation mark or an apostrophe in the parameter, quote it with the other (apostrophe or quotation mark) // If there isn't any, just surround it with "s. @@ -371,7 +371,7 @@ private void parseCommandLineArgs(String[] cmdargs) { cmdargs[i] = "\"" + cmdargs[i] + "\""; } } - + StringBuilder line = new StringBuilder(); int index = 0; while((index < cmdargs.length) && (parseState != CmdLineParseStateEnum.PARSE_COMPLETE)) { @@ -434,7 +434,7 @@ private void parseCommandLineArgs(String[] cmdargs) { exit("Internal error occurred whilst processing the command line args", JDMPVIEW_INTERNAL_ERROR); } } - + //checks that a specified command line arg is recognised private void checkArgIsRecognised(String cmdarg) { if(pairedargs.contains(cmdarg) || singleargs.contains(cmdarg)){ @@ -442,7 +442,7 @@ private void checkArgIsRecognised(String cmdarg) { } exit("The command " + cmdarg + " was not recognised", JDMPVIEW_SYNTAX_ERROR); } - + //if verbose is specified write out how the command line args have been interpreted private void logCommandLineArgs() { if(!isVerboseEnabled) { @@ -459,19 +459,19 @@ private void logCommandLineArgs() { } out.println("Batch mode commands: " + commands.toString()); } - + //print some help for the user private void printHelp() { String launcher = System.getProperty(SYSPROP_LAUNCHER, "jdmpview"); - + out.print( "Usage: \"" + launcher + " -core [-verbose]\" or \n" + " \"" + launcher + " -zip [-verbose]\" or \n" + " \"" + launcher + " -version\"\n\n" + - "To analyze dumps from DDR-enabled JVMs, " + launcher + " only requires a core file.\n\n" + + "To analyze dumps from DDR-enabled JVMs, " + launcher + " only requires a core file.\n\n" + "The default ImageFactory is " + factoryName + ". To change the ImageFactory use: \n" + - "\t -J-D" + SYSPROP_FACTORY + "= \n\n"); - + "\t -J-D" + SYSPROP_FACTORY + "= \n\n"); + out.print(launcher + " can also be used in 'batch mode' whereby commands can be issued without entering an interactive prompt.\n" + "This processing is controlled via the following command line options :\n"+ " -cmdfile : will read and sequentially execute\n" + @@ -484,11 +484,11 @@ private void printHelp() { "of the command line which executes " + launcher + "\n" + "e.g. " + launcher + " -core mycore.dmp info class\n\n" + "Finally, some commands which take the * parameter will need to have that specified on the command line as ALL\n" + - "This is to ensure correct processing by the OS " + + "This is to ensure correct processing by the OS " + "e.g. " + launcher + " -core mycore.dmp info thread ALL\n" ); } - + //if the -outfile param has been specified do some checking on the supplied file private void processOutfile() { if(!args.containsKey(ARG_OUTFILE)) { @@ -520,13 +520,13 @@ private void processOutfile() { } try { FileWriter writer = null; - + if(file.exists() && append) { writer = new FileWriter(file, true); } else { writer = new FileWriter(file); } - + foc = new FileOutputChannel(writer, file); out.addChannel(foc); ToolsRegistryOutputChannels.addChannel(foc); @@ -535,7 +535,7 @@ private void processOutfile() { exit("Unexpected error creating the output file " + file.getAbsolutePath(), JDMPVIEW_INTERNAL_ERROR); } } - + private String stripQuotesFromFilename(String name) { if((name.length() > 0) && (name.charAt(0) == '"')) { //strip out any initial quote @@ -547,7 +547,7 @@ private String stripQuotesFromFilename(String name) { } return name; } - + //if the -cmdfile option has been specified then process it and place them on the internal queue private void processCommandFile() { if (!args.containsKey(ARG_CMDFILE)) { @@ -558,7 +558,7 @@ private void processCommandFile() { commands.addAll(cmds); } } - + //read any commands from the specified file, there is no validation of the commands at this point private List parseCommandsFromFile() { String name = stripQuotesFromFilename(args.get(ARG_CMDFILE)); @@ -642,7 +642,7 @@ public void findAndSetContextWithJVM() { if(context.getRuntime() != null) { setContext(context); return; - } + } } } setContext(defaultContext); @@ -650,7 +650,7 @@ public void findAndSetContextWithJVM() { out.print("ERROR : Unable to set current context"); } } - + //start point for running the session /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISession#run() @@ -681,7 +681,7 @@ public void run() { out.println("Error closing contexts: " + e.getMessage()); } } - + //run in batch and exit after the last command is executed private void runBatch() { findAndSetContextWithJVM(); @@ -695,16 +695,16 @@ private void runBatch() { } catch (com.ibm.jvm.dtfjview.tools.CommandException e) { out.println(e.getMessage()); } - } + } out.close(); } - + //run in interactive mode with a prompt etc. private void runInteractive(){ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); String input = ""; String quit = ""; - + out.println("For a list of commands, type \"help\"; " + "for how to use \"help\", type \"help help\""); @@ -725,14 +725,14 @@ private void runInteractive(){ setPrompt(); } out.printPrompt(prompt); - + try { input = stdin.readLine(); } catch (IOException e) { out.print("IOException encountered while reading input; exiting program..."); break; } - + if (null == input) { out.print("End of input stream has been reached; exiting program..."); @@ -745,13 +745,13 @@ private void runInteractive(){ } quit = (String)currentContext.getProperties().get("quit"); } - + // "out" MUST be closed here, otherwise the file deletions in the below // code block will not work out.close(); - + } - + /** * Execute a command line. *

        @@ -772,13 +772,13 @@ public void execute(String line, PrintStream redirector) { } out.addChannel(defaultOutputChannel); } - + /* (non-Javadoc) * @see com.ibm.jvm.dtfjview.spi.ISession#execute(java.lang.String) */ public void execute(String line) { String trimmedInput = line.trim(); - + if (!trimmedInput.equals("")) { try { @@ -788,11 +788,11 @@ public void execute(String line) { // There is special processing in what follows for "set logging" and "show logging" // We cannot just pass the logic through to a secondary handler like we can with "info" // because when we see "set" or "show" we need to distinguish here and now which context to pass - // - "set logging" requires the session context + // - "set logging" requires the session context // - "set heapdump" requires the per-image context. - // For both "set logging" and "show logging" remove the word "logging" from the arguments and make it + // For both "set logging" and "show logging" remove the word "logging" from the arguments and make it // part of the command. - + if(cmd.equals(CMD_CONTEXT)) { switchContext(trimmedInput.toLowerCase()); } else if (cmd.equals("set") && parser.getArguments().length > 0 && parser.getArguments()[0].equals("logging")) { @@ -805,11 +805,11 @@ public void execute(String line) { String[] newargs = new String[oldargs.length-1]; // remove the first argument "logging" System.arraycopy(oldargs, 1, newargs, 0, newargs.length); ctxroot.execute("show logging", newargs, out.getPrintStream()); - } else if(sessioncommands.contains(cmd)) { + } else if(sessioncommands.contains(cmd)) { // if command is in the remaining list of session commands - // at the time of writing this is quit, help, open, close, pwd, cd - ctxroot.execute(parser, out.getPrintStream()); - } else { + // at the time of writing this is quit, help, open, close, pwd, cd + ctxroot.execute(parser, out.getPrintStream()); + } else { // not a session command, execute against the per-image context currentContext.execute(parser, out.getPrintStream()); } @@ -820,7 +820,7 @@ public void execute(String line) { } } } - + //switch contexts either by sequential ID or by ASID for z/OS cores private void switchContext(String input) { String[] args = input.trim().split(" "); @@ -837,7 +837,7 @@ private void switchContext(String input) { if(radix == 16) { id = Integer.parseInt(args[1].substring(2), radix); } else { - id = Integer.parseInt(args[1], radix); + id = Integer.parseInt(args[1], radix); } if((radix == 16) && isZOS) { //if context is in hex and on z/OS then see if this matches an ASID if(switchContextByASID(args[1])) { @@ -854,7 +854,7 @@ private void switchContext(String input) { if(isZOS) { if(!switchContextByASID(args[2])) { out.println("The specified context ASID : " + args[2] + " is not a valid ASID"); - } + } } else { out.println("Switching context by ASID is not supported for this core file"); } @@ -871,8 +871,8 @@ private void switchContext(String input) { } catch (Exception e) { out.println(e.getMessage()); } - } - + } + private boolean switchContextByASID(String asid) throws Exception { int radix = asid.startsWith("0x") ? 16 : 10; if((radix == 16) && isZOS) { @@ -888,11 +888,11 @@ private boolean switchContextByASID(String asid) throws Exception { } return false; } - + /** * Enables console logger for the supplied logger. Typically used to surface * log commands generated by internal components - * + * * @param log the logger to enable */ private void enableConsoleLogging(Logger log) { @@ -906,7 +906,7 @@ private void enableConsoleLogging(Logger log) { out.println("Console logging is now enabled for " + log.getName()); } } - + /** * Logs an exception to the DTFJView logger or creates an anonymous logger if this * one is not available. diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/SessionProperties.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/SessionProperties.java index 60ff3c00efb..86cb18c3aa9 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/SessionProperties.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/SessionProperties.java @@ -24,7 +24,7 @@ /** * Interface which lists all of the property names which are part of the DTFJ context property bag. - * + * * @author adam * */ @@ -33,41 +33,40 @@ public interface SessionProperties { * If jdmpview was started with -verbose then this property is present and has the value "true". */ public static final String VERBOSE_MODE_PROPERTY = "verbose.mode"; - + /** * Controls if files are extracted from archives or not */ public static final String EXTRACT_PROPERTY = "extract.mode"; - + /** * The path to the core file which is providing the current context */ public static final String CORE_FILE_PATH_PROPERTY = "core_file_path"; - + /** * Contains the DTFJ image factory */ public static final String IMAGE_FACTORY_PROPERTY = "image.factory"; - + /** * Name of the logger to use */ public static final String LOGGER_PROPERTY = "com.ibm.jvm.dtfjview.logger"; - + /** * Holds the value of the users current working directory */ public static final String PWD_PROPERTY = "pwd"; - + /** * A reference to the jdmpview session which is currently being executed */ public static final String SESSION_PROPERTY = "session"; - + /** - * Set if zip files are to be treated as in legacy implementations + * Set if zip files are to be treated as in legacy implementations * which will call ImageFactory.getImage(File) */ public static final String LEGACY_ZIP_MODE_PROPERTY = "zip.mode.legacy"; } - diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/SystemProperties.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/SystemProperties.java index ea4b8669c62..a66179eeb3e 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/SystemProperties.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/SystemProperties.java @@ -24,7 +24,7 @@ /** * Interface which lists all the system properties which are recognised by jdmpview. - * + * * @author adam * */ @@ -33,16 +33,16 @@ public interface SystemProperties { * The DTFJ factory used to create an Image from */ public static final String SYSPROP_FACTORY = "com.ibm.dtfj.image.factoryclass"; - + /** - * Launcher to use + * Launcher to use */ public static final String SYSPROP_LAUNCHER = "com.ibm.jvm.dtfjview.launcher"; - + /** * Normally jdmpview will terminate with System.exit if an error is encountered when starting up. * This allows batch / scripts to detect abnormal terminations. However for interactive sessions - * setting this property changes this behaviour so that a runtime exception can be raised and + * setting this property changes this behaviour so that a runtime exception can be raised and * handled by the invoking process. */ public static final String SYSPROP_NOSYSTEMEXIT = "com.ibm.jvm.dtfjview.nosystemexit"; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Version.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Version.java index b6f03a9b9e7..1cd9b75e0db 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Version.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/Version.java @@ -36,21 +36,21 @@ public class Version { private static int majorVersion = 4; private static int minorVersion = 29; // minor version is the VM stream private static int buildVersion = 5; // build version - historically the tag from RAS_Auto-Build/projects.psf - now just a number - + private static String name = "DTFJView"; - + public static String getVersion() { return Integer.toString(majorVersion) + "." + Integer.toString(minorVersion) + "." + Integer.toString(buildVersion); } - + public static String getName() { return name; } - + public static String getAllVersionInfo(ImageFactory factory) { String DTFJViewVersion = getName() + " version " + getVersion(); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/BaseJdmpviewCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/BaseJdmpviewCommand.java index b7fee15737c..2b52ca2916c 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/BaseJdmpviewCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/BaseJdmpviewCommand.java @@ -32,16 +32,16 @@ import com.ibm.java.diagnostics.utils.commands.CommandException; /** - * This the base command for all jdmpview commands. It ensures consistent + * This the base command for all jdmpview commands. It ensures consistent * behaviour with the legacy commands without breaking the generic command * encapsulation. - * + * * There are a number of methods which allow DTFJ objects to be consistently * displayed across different plugins e.g. getClassInfo(). Where the method - * name starts with getXYZ the output will be returned for further processing, - * however where the method starts with writeXYZ then the output is written + * name starts with getXYZ the output will be returned for further processing, + * however where the method starts with writeXYZ then the output is written * immediately to the command's print stream. - * + * * @author adam * */ @@ -53,18 +53,18 @@ public abstract class BaseJdmpviewCommand extends BaseCommand { protected IDTFJContext ctx = null; //the context within which to run protected Logger logger = Logger.getLogger("com.ibm.jvm.dtfjview.logger.command"); protected String hexfmt = "0x%016x"; //default 64bit format for hex strings - + /** * Print detailed help for a given command - * + * * @param out stream to write the output to */ public abstract void printDetailedHelp(PrintStream out); /** - * Common processing to initialize the command and make the porting of + * Common processing to initialize the command and make the porting of * existing jdmpview commands easier. - * + * * @param command the command being executed * @param args the supplied arguments * @param context the context within which it is operating @@ -87,12 +87,12 @@ public final boolean initCommand(String command, String[] args, IContext context } return false; } - + /** * Typically used when an extension takes a numeric argument, and wants to * accept a variety of formats. Currently it will support decimal or * hexadecimal formats. - * + * * @param number * String representation of the number to parse * @return the numeric value @@ -104,23 +104,23 @@ public long toLong(String number) { return Long.parseLong(number); } } - + /** * Enum for identifying the type of artifact that is currently being analyzed. - * + * * @author adam * */ protected enum ArtifactType { core, phd, javacore, unknown } - + /* * This will be changed internally when the DTFJ Image.getType() call is implemented */ /** * Determine the type of artifact currently being operated on. - * + * * @return artifact type */ protected ArtifactType getArtifactType() { @@ -146,7 +146,7 @@ protected ArtifactType getArtifactType() { /** * Format an address as hex padded with zeros according to the size of the process. - * e.g. 17 would be formatted as 0x00000011 for 32 bit and 0x0000000000000011 for 64 bit + * e.g. 17 would be formatted as 0x00000011 for 32 bit and 0x0000000000000011 for 64 bit * @param num the number to format * @return formatted number */ @@ -157,21 +157,21 @@ public String toHexStringAddr(long num) { /** * Lots of DTFJ methods will throw a standard set of exceptions such as corrupt data * or data unavailable. This method provides a central point for handling these exceptions - * and attempts to provide more context as to whether or not this is an expected occurrence + * and attempts to provide more context as to whether or not this is an expected occurrence * for the artifact type under analysis. - * + * * @param cause the exception returned from a call to the DTFJ API * @return formatted string for displaying to the user */ public String handleException(Throwable cause) { return ExceptionHandler.handleException(this, cause); } - + /** * Textual description of a thread state. - * + * * @param state state to convert - * @return cumulative description of the states + * @return cumulative description of the states */ public String decodeThreadState(int state) { int[] states = { JavaThread.STATE_ALIVE, @@ -202,11 +202,11 @@ public String decodeThreadState(int state) { } return sb.toString(); } - + /** * Enumeration for the various formats that can be applied to the * output strings. - * + * * @author adam * */ @@ -217,20 +217,20 @@ private enum FormatEnum { HEX_INT("0x%08x"), DEC_FLOAT("%e"), DEC_DOUBLE("%e"); - + FormatEnum(String format) { this.format = format; } - + private final String format; - + public String getFormat() { return format; } } - + /** - * Format a number with the correct number of zeros as padding according + * Format a number with the correct number of zeros as padding according * to the data type passed in. * @param num the number to format * @return formatted number @@ -238,9 +238,9 @@ public String getFormat() { public String toHexString(long num) { return String.format(FormatEnum.HEX_LONG.getFormat(), num); } - + /** - * Format a number with the correct number of zeros as padding according + * Format a number with the correct number of zeros as padding according * to the data type passed in. * @param num the number to format * @return formatted number @@ -250,7 +250,7 @@ public String toHexString(short num) { } /** - * Format a number with the correct number of zeros as padding according + * Format a number with the correct number of zeros as padding according * to the data type passed in. * @param num the number to format * @return formatted number @@ -258,9 +258,9 @@ public String toHexString(short num) { public String toHexString(int num) { return String.format(FormatEnum.HEX_INT.getFormat(), num); } - + /** - * Format a number with the correct number of zeros as padding according + * Format a number with the correct number of zeros as padding according * to the data type passed in. * @param num the number to format * @return formatted number diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/CdCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/CdCommand.java index df9fb61af37..2b38d0e2770 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/CdCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/CdCommand.java @@ -33,9 +33,9 @@ @DTFJPlugin(version="1.*", runtime=false) public class CdCommand extends BaseJdmpviewCommand { { - addCommand("cd", "", "changes the current working directory, used for log files"); + addCommand("cd", "", "changes the current working directory, used for log files"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -50,9 +50,9 @@ public void run(String command, String[] args, IContext context, PrintStream out path += arg + " "; } path = path.substring(0, path.length() - 1); - + File newPwd = Utils.absPath(ctx.getProperties(), path); - + if (!newPwd.isDirectory()) { if (newPwd.isFile()) { out.println("cannot change to specified path because it specifies a file, not a directory"); @@ -76,6 +76,6 @@ public void printDetailedHelp(PrintStream out) { "absolute path when set. Note: to see what the current working " + "directory is set to, use the \"pwd\" command.\n" ); - + } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/CloseCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/CloseCommand.java index f4ea0aa87cb..983227c8ded 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/CloseCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/CloseCommand.java @@ -34,7 +34,7 @@ public class CloseCommand extends BaseJdmpviewCommand { private static final String CMD_NAME = "close"; - + { addCommand(CMD_NAME, "[context id]","closes the connection to a core file"); } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/DeadlockCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/DeadlockCommand.java index a1ea18c63bf..1c9625f7d02 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/DeadlockCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/DeadlockCommand.java @@ -47,9 +47,9 @@ @DTFJPlugin(version="1.*",runtime=false) public class DeadlockCommand extends BaseJdmpviewCommand { { - addCommand("deadlock", "", "displays information about deadlocks if there are any"); + addCommand("deadlock", "", "displays information about deadlocks if there are any"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -60,18 +60,18 @@ public void run(String command, String[] args, IContext context, PrintStream out } doCommand(); } - + public void doCommand() { SortedMap monitorNodes = new TreeMap<>(); JavaRuntime jr = ctx.getRuntime(); Iterator itMonitor = jr.getMonitors(); int nodeListNum = 0; - + out.print("\n deadlocks for runtime \n"); - - // Step 1. iterate over all monitors, creating a MonitorNode for each monitor that - // contains the monitor (JavaMonitor) and some parameters and adding that MonitorNode + + // Step 1. iterate over all monitors, creating a MonitorNode for each monitor that + // contains the monitor (JavaMonitor) and some parameters and adding that MonitorNode // to a Hashtable, indexed by owner (JavaThread object address) // Note: defect 133638, this code used to use the ImageThread address as index, but // JVM dumps on Linux don't have all the image threads, so we now use JavaThreads @@ -80,7 +80,7 @@ public void doCommand() MonitorNode node = new MonitorNode(monitor); JavaThread owner = null; Long id = null; - + try { owner = monitor.getOwner(); } catch (CorruptDataException e) { @@ -90,10 +90,10 @@ public void doCommand() } if (null == owner) { - // A monitor with no owner cannot be involved in a deadlock, according to the + // A monitor with no owner cannot be involved in a deadlock, according to the // algorithm used here anyway, because in order for a monitor to be in a deadlock, - // its owner must be in a deadlock or an owner somewhere down the chain of - // ownership must own the given monitor. Since there is no owner, we can't get + // its owner must be in a deadlock or an owner somewhere down the chain of + // ownership must own the given monitor. Since there is no owner, we can't get // the monitor's owner or the next monitor in a potential deadlock chain. continue; } else { @@ -107,7 +107,7 @@ public void doCommand() } id = Long.valueOf(threadObject.getID().getAddress()); } - + // Note: defect 133638, we used to give up here with an error if there was already // a monitor node in the table with the same key (thread). This is very common (a // thread owning multiple monitors). Longer term the intention is to replace this @@ -115,7 +115,7 @@ public void doCommand() // still find a deadlock, with some node(s) discarded. monitorNodes.put(id, node); } - + // Step 1.b // Add the JUC locks, technically to find all of them you need to walk the whole // heap. But the active ones can be found by walking the thread list and looking @@ -163,13 +163,13 @@ public void doCommand() } Iterator values = monitorNodes.values().iterator(); - + // Step 2. iterate over Hashtable and for every MonitorNode, iterate over monitor m1's - // enter waiters (JavaMonitor.getEnterWaiters()), which are JavaThreads, and for each + // enter waiters (JavaMonitor.getEnterWaiters()), which are JavaThreads, and for each // enter waiter, set that waiter's MonitorNode's waitingOn to m1. while (values.hasNext()) { MonitorNode currNode = (MonitorNode)values.next(); - + Iterator itWaiters = currNode.getEnterWaiters(); while (itWaiters.hasNext()) { Object o = itWaiters.next(); @@ -179,17 +179,17 @@ public void doCommand() JavaThread waiter = (JavaThread)o; JavaObject threadObject; Long id = null; - + try { threadObject = waiter.getObject(); } catch (CorruptDataException e) { out.println("exception encountered while getting waiter's ImageThread: " + Exceptions.getCorruptDataExceptionString()); return; - } - - id = Long.valueOf(threadObject.getID().getAddress()); - + } + + id = Long.valueOf(threadObject.getID().getAddress()); + MonitorNode waiterNode = (MonitorNode)monitorNodes.get(id); if (null != waiterNode) { waiterNode.waitingOn = currNode; @@ -200,7 +200,7 @@ public void doCommand() values = monitorNodes.values().iterator(); int visit = 1; Vector lists = new Vector<>(); - + // Step 3. iterate over Hashtable and for every MonitorNode m1: // Step 3a. set a unique visit number, visit > 0 (visit++ would work) // Step 3b. iterate over waitingOns, setting visit number, until a null @@ -213,7 +213,7 @@ public void doCommand() // note: Step 4* are not laid out precisely as specified; the instructions // listed for Step 4* are integrated into Step 3 - + // Step 4. for each MonitorNode m1 where inList == false and m1 is part // of a deadlock loop *, create a new list and push it on the list // stack right away: @@ -226,34 +226,34 @@ public void doCommand() // Step 4d. if there is more than one enter waiter, continue creating // current list and start a new list, pushing it on the list stack // right away - + while (values.hasNext()) { MonitorNode startNode = (MonitorNode)values.next(); MonitorNode currNode = startNode; MonitorNode endNode; - + if (0 != startNode.visit) { continue; } - + while (true) { currNode.visit = visit; - + if (null == currNode.waitingOn) { currNode.deadlock = MonitorNode.NO_DEADLOCK; break; } - + if (isDeadlocked(currNode.waitingOn)) { // we've encountered a deadlocked node in the chain; // set branch deadlock for all nodes between startNode // and currNode - + endNode = currNode.waitingOn; currNode = startNode; NodeList branchList = null; @@ -269,7 +269,7 @@ public void doCommand() if (currNode != endNode) currNode.inList = branchList; } - + if (endNode.inList.isLoop()) { lists.insertElementAt(branchList, lists.indexOf(endNode.inList)); @@ -277,7 +277,7 @@ public void doCommand() else { NodeList oldList = endNode.inList; - + // FIXME: the below line will cause problems with at least // one case that was not considered when attachOrSplit was // coded: if a NodeList n1 has already been split and another @@ -293,19 +293,19 @@ public void doCommand() } break; } - + if (currNode.waitingOn.visit == visit) { // we've encountered a node in the same visit as the current // visit, ie. we've found a loop; first flag the whole loop // with a loop deadlock flag, then flag the rest of the nodes // in the chain with a branch deadlock - + endNode = currNode.waitingOn; currNode = endNode; NodeList loopList = new NodeList(currNode, nodeListNum++); lists.insertElementAt(loopList, 0); - + do { currNode.deadlock = MonitorNode.LOOP_DEADLOCK; @@ -313,7 +313,7 @@ public void doCommand() loopList.add(currNode); currNode.inList = loopList; } while (currNode != endNode); - + currNode = startNode; NodeList branchList = null; while (currNode != endNode) @@ -331,10 +331,10 @@ public void doCommand() } break; } - + currNode = currNode.waitingOn; } - + visit++; } @@ -345,7 +345,7 @@ public void doCommand() out.print("\n"); return; } - + boolean lastListWasLoop = true; Iterator itList = lists.iterator(); @@ -353,7 +353,7 @@ public void doCommand() while (itList.hasNext()) { NodeList list = (NodeList)itList.next(); - + if (list.isLoop()) { out.print("\n deadlock loop:\n"); lastListWasLoop = true; @@ -361,14 +361,14 @@ public void doCommand() out.print("\n\n deadlock branch(es):\n"); lastListWasLoop = false; } - + out.print("\t " + list.toString()); out.print("\n"); } out.print("\n"); } - + private boolean isDeadlocked(MonitorNode node) { return MonitorNode.LOOP_DEADLOCK == node.deadlock || diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/ExceptionHandler.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/ExceptionHandler.java index ea7f09451b5..c3e2bb7b58a 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/ExceptionHandler.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/ExceptionHandler.java @@ -38,9 +38,9 @@ /** * Class which attempts to handle exceptions thrown by the DTFJ API in a consistent manner. - * It is context aware and knows which DTFJ calls will not be possible when analyzing certain + * It is context aware and knows which DTFJ calls will not be possible when analyzing certain * artifacts. e.g. it understands that thread information is not available from a PHD file. - * + * * @author adam * */ @@ -49,19 +49,18 @@ public class ExceptionHandler { private static final int WORKS = 1; private static final int CAN_FAIL = 2; private static final int FAILS = 3; - + private static HashMap methodTable = new HashMap(); - private static IDTFJContext ctx; //current DTFJ context + private static IDTFJContext ctx; //current DTFJ context private static final Logger logger = Logger.getLogger("com.ibm.jvm.dtfjview.logger.command"); - + static { init(); } - - + /** * Handle an exception thrown by the DTFJ API. - * + * * @param cmd the command current executing the API. This is required to provide access to context information. * @param cause exception to be handled * @return textual data to be written out @@ -167,11 +166,11 @@ public static String handleException(BaseJdmpviewCommand cmd, Throwable cause) { } return sb.toString(); } - + /** * Get the DTFJ method which caused the exception by examining the call stack for the * exception. - * + * * @param myStack stack from an exception * @return the DTFJ method which caused the exception or null if it could not determined */ @@ -206,7 +205,7 @@ private static DTFJMethod getDTFJMethod(StackTraceElement[] myStack, BaseJdmpvie /** * Find the DTFJ interface for a specified class - * + * * @param c class to check * @param methodName method name to find in the DTFJ interface * @return the located method or null if no match is found diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/FindCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/FindCommand.java index 45bc73f10a0..b2cc993d5f1 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/FindCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/FindCommand.java @@ -99,7 +99,7 @@ public void doCommand(String[] params) { printLastMatchContent(); } - // prepend "0x" back to pattern for findnext command + // prepend "0x" back to pattern for findnext command restoreHexPrefix(); } @@ -111,7 +111,7 @@ private void restoreHexPrefix() { private void printLastMatchContent() { // forward onto the hexdump command - ctx.execute("hexdump" + " 0x" + ctx.execute("hexdump" + " 0x" + Long.toHexString(findAtt.lastMatch) + " " + findAtt.numBytesToPrint, out); } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/FindNextCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/FindNextCommand.java index 83d855973bd..77012ff35da 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/FindNextCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/FindNextCommand.java @@ -32,9 +32,8 @@ @DTFJPlugin(version="1.*", runtime=false) public class FindNextCommand extends BaseJdmpviewCommand{ { - addCommand("findnext", "", "finds the next instance of the last string passed to \"find\""); + addCommand("findnext", "", "finds the next instance of the last string passed to \"find\""); } - public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { @@ -45,11 +44,11 @@ public void run(String command, String[] args, IContext context, PrintStream out out.println("No find command has been executed."); return; } - + String startAddress = Long.toHexString((findAtt.lastMatch + 1)); String endAddress = Long.toHexString(findAtt.endAddress); - - ctx.execute("find" + " " + + ctx.execute("find" + " " + findAtt.pattern + "," + startAddress + "," + endAddress + "," + findAtt.boundary + "," + findAtt.numBytesToPrint + "," + findAtt.numMatchesToDisplay, out); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HeapdumpCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HeapdumpCommand.java index a435d7fca19..d67c3fe7e7b 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HeapdumpCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HeapdumpCommand.java @@ -66,7 +66,7 @@ /** * Command for dumping heapdumps from DTFJ. - * + * * Contains the heap-walking logic for building the reference tree. The code for writing the heapdumps * (both PHD and classic) is in the com.ibm.jvm.heapdump package. * @author andhall @@ -82,7 +82,7 @@ public class HeapdumpCommand extends BaseJdmpviewCommand + "Writes a heapdump from the memory image.\n" + "The file name and format are controlled using the \"set heapdump\" command; the current settings " + "can be displayed using \"show heapdump\".\n"; - + private static final String PROTECTION_DOMAIN_FIELD_NAME = "protectionDomain"; /** * Regexp pattern used to extract a subset of the versions string @@ -98,9 +98,9 @@ public class HeapdumpCommand extends BaseJdmpviewCommand private boolean _is32BitHash; { - addCommand(COMMAND_NAME, "", DESCRIPTION); + addCommand(COMMAND_NAME, "", DESCRIPTION); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -111,17 +111,17 @@ public void run(String command, String[] args, IContext context, PrintStream out public void doCommand(String[] args) { Set heapsToDump = new HashSet(); - + _numberOfObjects = 0; _numberOfErrors = 0; _numberOfClasses = 0; - + if (ctx.hasPropertyBeenSet(VERBOSE_MODE_PROPERTY)) { _verbose = true; } - + JavaRuntime runtime = ctx.getRuntime(); - + while( runtime != null ) { ImageAddressSpace addressSpace = null; try { @@ -141,11 +141,11 @@ public void doCommand(String[] args) String version = getVersionString(runtime); if (version.contains("IBM J9 2.3") || version.contains("IBM J9 2.4") || version.contains("IBM J9 2.5")) { // J9 JVMs versions prior to 2.6 have 16-bit hashcodes, later JVMs have 32-bit hashcodes - _is32BitHash = false; + _is32BitHash = false; } else { _is32BitHash = true; } - + boolean is64Bit = addressSpace.getCurrentProcess().getPointerSize() == 64; String filename = HeapDumpSettings.getFileName(ctx.getProperties()); @@ -161,12 +161,12 @@ public void doCommand(String[] args) if(_numberOfErrors == 0) { out.print("\nSuccessfully wrote " + _numberOfObjects + " objects and " + _numberOfClasses + " classes\n"); } else { - out.print("\nWrote " - + _numberOfObjects - + " objects and " - + _numberOfClasses - + " classes and encountered " - + _numberOfErrors + out.print("\nWrote " + + _numberOfObjects + + " objects and " + + _numberOfClasses + + " classes and encountered " + + _numberOfErrors + " errors." + "\n"); } @@ -177,11 +177,11 @@ public void doCommand(String[] args) ex.printStackTrace(new PrintWriter(writer)); out.println(writer.toString()); } - + runtime = null; } } - + /** * Checks the list of heaps to dump as specified by the user. * @param runtime Current java runtime @@ -193,18 +193,18 @@ private boolean heapArgumentsAreValid(JavaRuntime runtime, Set heapsToDump) if(heapsToDump.size() == 0) { return true; } - + Set workingSet = new HashSet(); workingSet.addAll(heapsToDump); - + Iterator heapIt = runtime.getHeaps(); - + while(heapIt.hasNext()) { Object potential = heapIt.next(); - + if(potential instanceof JavaHeap) { JavaHeap thisHeap = (JavaHeap)potential; - + workingSet.remove(thisHeap.getName()); } else if (potential instanceof CorruptData) { reportError("Corrupt heap found. Address = " + ((CorruptData)potential).getAddress(),null); @@ -214,23 +214,23 @@ private boolean heapArgumentsAreValid(JavaRuntime runtime, Set heapsToDump) reportError("Unexpected type " + potential.getClass().getName() + " found in heap iterator",null); } } - + if(workingSet.isEmpty()) { return true; } else { StringBuffer buffer = new StringBuffer(); buffer.append("These specified heaps do not exist:\n"); - + Iterator nameIterator = workingSet.iterator(); - + while(nameIterator.hasNext()) { buffer.append("\t\t" + nameIterator.next() + "\n"); } - + buffer.append("\tUse \"info heap\" to see list of heap names"); - + out.println(buffer.toString()); - + return false; } } @@ -245,10 +245,10 @@ private String getVersionString(JavaRuntime runtime) { try { String rawVersion = runtime.getVersion(); - + Matcher matcher = J9_VERSION_PATTERN.matcher(rawVersion); - - if(matcher.find()) { // dump prior to JVM 2.6, extract single line version string + + if(matcher.find()) { // dump prior to JVM 2.6, extract single line version string String minimalVersion = matcher.group(1); return minimalVersion; } else { // dump from JVM 2.6 or later, return unchanged version string @@ -262,48 +262,46 @@ private String getVersionString(JavaRuntime runtime) return "*Corrupt*"; } } - + private void dumpMultipleHeapsInOneFile(JavaRuntime runtime, String version, boolean is64Bit, boolean phdFormat, String filename, Set heapsToDump) throws IOException { Iterator heapIterator = runtime.getHeaps(); - + HeapDumpFormatter formatter = getFormatter(filename, version, is64Bit, phdFormat); - + out.println("Writing " + ( phdFormat ? "PHD" : "Classic") + " format heapdump into " + filename); - - while (heapIterator.hasNext()) { Object thisHeapObj = heapIterator.next(); if (thisHeapObj instanceof CorruptData) { - out.println("Corrupt heap data found at: " + out.println("Corrupt heap data found at: " + ((CorruptData) thisHeapObj).getAddress()); _numberOfErrors++; continue; } JavaHeap thisHeap = (JavaHeap) thisHeapObj; - + if(heapsToDump.size() > 0 && ! heapsToDump.contains(thisHeap.getName())) { continue; } - + dumpHeap(formatter, thisHeap); } - + dumpClasses(formatter,runtime); - + formatter.close(); } private void dumpMultipleHeapsInSeparateFiles(JavaRuntime runtime,String version, boolean is64Bit, boolean phdFormat,String baseFileName, Set heapsToDump) throws IOException { Iterator heapIterator = runtime.getHeaps(); - + HeapDumpFormatter formatter = null; - + while (heapIterator.hasNext()) { Object thisHeapObj = heapIterator.next(); @@ -324,24 +322,24 @@ private void dumpMultipleHeapsInSeparateFiles(JavaRuntime runtime,String version if(heapsToDump.size() > 0 && ! heapsToDump.contains(thisHeap.getName())) { continue; } - + String fileName = getFileNameForHeap(thisHeap,baseFileName); - out.print("Writing " - + ( phdFormat ? "PHD" : "Classic") - + " format heapdump for heap " - + thisHeap.getName() - + " into " + out.print("Writing " + + ( phdFormat ? "PHD" : "Classic") + + " format heapdump for heap " + + thisHeap.getName() + + " into " + fileName + "\n"); - + formatter = getFormatter(fileName, version, is64Bit, phdFormat); - + //We have to dump classes in every heapdump dumpClasses(formatter,runtime); - + dumpHeap(formatter, thisHeap); } - + if(formatter != null) { formatter.close(); } @@ -353,52 +351,52 @@ private void dumpMultipleHeapsInSeparateFiles(JavaRuntime runtime,String version private void dumpClasses(HeapDumpFormatter formatter, JavaRuntime runtime) throws IOException { Iterator classLoaderIt = runtime.getJavaClassLoaders(); - + int numberOfClasses = 0; - + ITERATING_LOADERS:while(classLoaderIt.hasNext()) { Object potential = classLoaderIt.next(); - + if(potential instanceof CorruptData) { _numberOfErrors++; reportError("CorruptData found in classloader list at address: " + ((CorruptData)potential).getAddress(), null); continue ITERATING_LOADERS; } - + JavaClassLoader thisClassLoader = (JavaClassLoader)potential; - + Iterator classesIt = thisClassLoader.getDefinedClasses(); - + ITERATING_CLASSES:while(classesIt.hasNext()) { potential = classesIt.next(); - + numberOfClasses++; - + try { - + if(potential instanceof CorruptData) { _numberOfErrors++; reportError("CorruptData found in class list for classloader " - + Long.toHexString(thisClassLoader.getObject().getID().getAddress()) + + Long.toHexString(thisClassLoader.getObject().getID().getAddress()) + " at address: " + ((CorruptData)potential).getAddress(), null); continue ITERATING_CLASSES; } JavaClass thisJavaClass = (JavaClass)potential; - + JavaClass superClass = thisJavaClass.getSuperclass(); - + JavaObject classObject = thisJavaClass.getObject(); - + long instanceSize; if(thisJavaClass.isArray()) { instanceSize = 0; } else { instanceSize = thisJavaClass.getInstanceSize(); } - + int hashcode = 0; - if (_is32BitHash) { // JVMs from 2.6 on, optional 32-bit hashcodes, if object was hashed + if (_is32BitHash) { // JVMs from 2.6 on, optional 32-bit hashcodes, if object was hashed try { hashcode = classObject != null ? (int)classObject.getPersistentHashcode() : 0; } catch (DataUnavailable ex) { @@ -407,9 +405,9 @@ private void dumpClasses(HeapDumpFormatter formatter, JavaRuntime runtime) throw } else { // JVMs prior to 2.6, all objects should have a 16-bit hashcode hashcode = classObject != null ? (int)classObject.getHashcode() : 0; } - + formatter.addClass(classObject.getID().getAddress(), - thisJavaClass.getName(), + thisJavaClass.getName(), superClass != null ? superClass.getID().getAddress() : 0, classObject != null ? (int)classObject.getSize() : 0, instanceSize, @@ -423,11 +421,11 @@ private void dumpClasses(HeapDumpFormatter formatter, JavaRuntime runtime) throw } } } - - _numberOfClasses = numberOfClasses; - if((pdSkipCount > 0) && _verbose) { - out.println("Warning : The protection domain information was not available for " + pdSkipCount + " classes"); - } + + _numberOfClasses = numberOfClasses; + if ((pdSkipCount > 0) && _verbose) { + out.println("Warning : The protection domain information was not available for " + pdSkipCount + " classes"); + } } /** @@ -453,12 +451,12 @@ private void dumpHeap(HeapDumpFormatter formatter, JavaHeap thisHeap) if (thisObject.getJavaClass().getName().equals("java/lang/Class")) { // heap classes are handled separately, in dumpClasses() continue; - } + } JavaClass thisClass = thisObject.getJavaClass(); JavaObject thisClassObject = thisClass.getObject(); int hashcode = 0; - if (_is32BitHash) { // JVMs from 2.6 on, optional 32-bit hashcodes, if object was hashed + if (_is32BitHash) { // JVMs from 2.6 on, optional 32-bit hashcodes, if object was hashed try { hashcode = (int) thisObject.getPersistentHashcode(); } catch (DataUnavailable ex) { @@ -475,30 +473,30 @@ private void dumpHeap(HeapDumpFormatter formatter, JavaHeap thisHeap) if (thisObject.isArray()) { if (isPrimitive(thisClass.getComponentType())) { - formatter.addPrimitiveArray(thisObject.getID().getAddress(), + formatter.addPrimitiveArray(thisObject.getID().getAddress(), thisClassObject.getID().getAddress(), getPrimitiveTypeCode(thisClass.getComponentType()), - thisObject.getSize(), + thisObject.getSize(), hashcode, thisObject.getArraySize()); } else { - formatter.addObjectArray(thisObject.getID().getAddress(), - thisClassObject.getID().getAddress(), - thisClass.getName(), + formatter.addObjectArray(thisObject.getID().getAddress(), + thisClassObject.getID().getAddress(), + thisClass.getName(), thisClass.getComponentType().getObject().getID().getAddress(), - thisClass.getComponentType().getName(), + thisClass.getComponentType().getName(), thisObject.getSize(), thisObject.getArraySize(), - hashcode, + hashcode, getObjectReferences(thisObject)); } } else { - formatter.addObject(thisObject.getID().getAddress(), - thisClassObject.getID().getAddress(), - thisClass.getName(), + formatter.addObject(thisObject.getID().getAddress(), + thisClassObject.getID().getAddress(), + thisClass.getName(), (int)thisObject.getSize(), - hashcode, + hashcode, getObjectReferences(thisObject)); } } @@ -517,21 +515,21 @@ private void dumpHeap(HeapDumpFormatter formatter, JavaHeap thisHeap) /** * Gets the references for the supplied class - * - * @param thisJavaClass Class being examined + * + * @param thisJavaClass Class being examined */ private ReferenceIterator getClassReferences(JavaClass thisJavaClass) { List references = new LinkedList(); - + try { // Class object instance references addReferences(thisJavaClass.getObject(), references); - //Statics + //Statics addStaticReferences(thisJavaClass, references); - + addProtectionDomainReference(thisJavaClass,references); - + // Constant pool class references Iterator constantPoolIt = thisJavaClass.getConstantPoolReferences(); while (constantPoolIt.hasNext()) { @@ -542,17 +540,17 @@ private ReferenceIterator getClassReferences(JavaClass thisJavaClass) references.add(Long.valueOf(cpJavaClass.getObject().getID().getAddress())); } } - + // Superclass references JavaClass superClass = thisJavaClass.getSuperclass(); while (null != superClass){ references.add(Long.valueOf(superClass.getObject().getID().getAddress())); superClass = superClass.getSuperclass(); } - + //Classloader JavaClassLoader loader = thisJavaClass.getClassLoader(); - + if(loader != null) { JavaObject loaderObject = loader.getObject(); if(loaderObject != null) { @@ -565,20 +563,20 @@ private ReferenceIterator getClassReferences(JavaClass thisJavaClass) reportError("Null classloader returned for class: " + thisJavaClass.getName() + "(" + thisJavaClass.getID() + ")",null); _numberOfErrors++; } - + } catch(DTFJException ex) { reportError(null,ex); _numberOfErrors++; } - + return new LongListReferenceIterator(references); } - + private long pdSkipCount = 0; - + private void addProtectionDomainReference(JavaClass thisJavaClass, List references) throws CorruptDataException, MemoryAccessException - + { try { JavaObject protectionDomain = thisJavaClass.getProtectionDomain(); @@ -600,10 +598,10 @@ private void addStaticReferences(JavaClass thisClass, List references) throws CorruptDataException, MemoryAccessException { Iterator fieldsIt = thisClass.getDeclaredFields(); - + while(fieldsIt.hasNext()) { Object potential = fieldsIt.next(); - + if(potential instanceof CorruptData) { reportError("Corrupt field found in class " + thisClass.getName() @@ -613,15 +611,15 @@ private void addStaticReferences(JavaClass thisClass, List references) _numberOfErrors++; continue; } - + JavaField field = (JavaField) potential; - + if(! Modifier.isStatic(field.getModifiers())) { continue; } - + Object referent = field.get(thisClass.getObject()); - + if(referent instanceof CorruptData) { _numberOfErrors++; reportError("Corrupt referent found in class " @@ -633,17 +631,17 @@ private void addStaticReferences(JavaClass thisClass, List references) ,null); } else if (referent instanceof JavaObject) { JavaObject referredObject = (JavaObject) referent; - + references.add(Long.valueOf(referredObject.getID().getAddress())); } else if (referent == null) { references.add(Long.valueOf(0)); } else if (referent instanceof Number || referent instanceof Boolean || referent instanceof Character) { //Ignore } else { - reportError("Unexpected type: " - + referent.getClass().getName() - + " returned from field " - + field.getName() + reportError("Unexpected type: " + + referent.getClass().getName() + + " returned from field " + + field.getName() + " from class " + thisClass.getName() + "(" + thisClass.getID()+ ")" @@ -652,7 +650,7 @@ private void addStaticReferences(JavaClass thisClass, List references) } } } - + /** * Gets instance references for objects * @param thisObject Object being examined @@ -668,12 +666,12 @@ private ReferenceIterator getObjectReferences(JavaObject thisObject) /** * Reverse the order of the elements for an object array. * - * In a classic heapdump or portable heapdump from the vm, the array elements are always + * In a classic heapdump or portable heapdump from the vm, the array elements are always * in reverse order (i.e. the opposite of index order) because for historical reasons - * that is the order in which the gc iterator returns them. + * that is the order in which the gc iterator returns them. * Therefore reverse the order before writing them out so that the heapdump * that we generate looks as close as possible to one from the vm. - *

        + *

        * See CMVC 193691 */ Long[] refsAsArray = references.toArray(new Long[0]); // Java idiom to dump a list to an array @@ -681,7 +679,7 @@ private ReferenceIterator getObjectReferences(JavaObject thisObject) for (int i = refsAsArray.length - 1; i >= 0; i--) { references.add(refsAsArray[i]); - } + } } } catch(DTFJException ex) { _numberOfErrors++; @@ -703,23 +701,23 @@ private void addReferences(JavaObject object, { Iterator it = object.getReferences(); Object ref = null; - + // discard the first reference which is always to the class if (it.hasNext()) { // test hasNext() to be on the safe side. ref = it.next(); } - - while (it.hasNext()) { + + while (it.hasNext()) { ref = it.next(); if(ref instanceof CorruptData) { // can sometimes get a nasty surprise in the list - e.g. a J9DDRCorruptData _numberOfErrors++; - reportError("Corrupt data found at address " - + ((CorruptData)ref).getAddress() + reportError("Corrupt data found at address " + + ((CorruptData)ref).getAddress() + " getting references from object at address: " + Long.toHexString(object.getID().getAddress()) + " of class " - + object.getJavaClass().getName() + + object.getJavaClass().getName() + "(" + object.getJavaClass().getID() + ")" ,null); continue; @@ -727,11 +725,11 @@ private void addReferences(JavaObject object, if ( ! (ref instanceof JavaReference)) { _numberOfErrors++; reportError("Object of unexpected type " - + ref.getClass() + + ref.getClass() + " found within references from object at address: " + object.getID().getAddress() + " of class " - + object.getJavaClass().getName() + + object.getJavaClass().getName() + "(" + object.getJavaClass().getID() + ")" ,null); continue; @@ -748,13 +746,13 @@ private void addReferences(JavaObject object, } // the following ugliness is necessary as JavaObject and JavaClass both support getID() but do not inherit from a common parent if (target instanceof JavaObject) { - references.add(Long.valueOf(((JavaObject) target).getID().getAddress())); + references.add(Long.valueOf(((JavaObject) target).getID().getAddress())); } else if (target instanceof JavaClass) { references.add(Long.valueOf(((JavaClass) target).getID().getAddress())); } else { _numberOfErrors++; reportError("Object of unexpected type " - + target.getClass() + + target.getClass() + " returned from call to getTarget() on reference " + ref ,null); @@ -765,7 +763,7 @@ private void addReferences(JavaObject object, /** * Checks if class is primitive - * + * * @param clazz * Class under test * @return True if clazz represents a primitive type, false otherwise @@ -790,7 +788,7 @@ private static boolean isPrimitive(JavaClass clazz) } /** - * Converts a class into a primitive type code (as used by the HeapdumpFormatter interface). + * Converts a class into a primitive type code (as used by the HeapdumpFormatter interface). * @param clazz * @return */ @@ -834,7 +832,7 @@ private HeapDumpFormatter getFormatter(String fileName, String version, private String getFileNameForHeap(JavaHeap thisHeap, String baseFileName) { int pointIndex = baseFileName.lastIndexOf("."); - + if(pointIndex != -1) { return baseFileName.substring(0,pointIndex) + "." + thisHeap.getName() + baseFileName.substring(pointIndex); } else { @@ -845,27 +843,27 @@ private String getFileNameForHeap(JavaHeap thisHeap, String baseFileName) /** * Internal error handling routine that only reports the supplied message if verbose was supplied on the command line. */ - private void reportError(String msg,Throwable t) + private void reportError(String msg,Throwable t) { if(!_verbose) { return; } - + if(msg != null) { out.println(msg); } - + if(t != null) { StringWriter writer = new StringWriter(); - + t.printStackTrace(new PrintWriter(writer)); - + out.println(writer.toString()); } } - + @Override public void printDetailedHelp(PrintStream out) { - out.println(LONG_DESCRIPTION); + out.println(LONG_DESCRIPTION); } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HelpCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HelpCommand.java index 43b8744f7f9..b08695a236c 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HelpCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HelpCommand.java @@ -37,14 +37,14 @@ * command is a 'pseudo-command' in that it is what controls switching contexts and so * is never actually in the list of commands available for the current context. The help * entries for the context command are therefore added manually. - * + * * @author adam * */ @DTFJPlugin(version=".*", runtime=false, image=false) public class HelpCommand extends BaseJdmpviewCommand { private static final String CMD_NAME = "help"; - + { addCommand(CMD_NAME, "[command name]","displays list of commands or help for a specific command"); } @@ -58,14 +58,14 @@ public void run(String command, String[] args, IContext context, PrintStream out } else { StringBuilder cmdline = new StringBuilder(); if(args[0].equalsIgnoreCase("context")) { - out.println("switches to another context when more than one context is available. For z/OS the ASID can be specified with" + + out.println("switches to another context when more than one context is available. For z/OS the ASID can be specified with" + " the 'asid' flag e.g. context asid . Execute 'context' to see the list of currently available contexts"); } else { for(String arg : args) { cmdline.append(arg); cmdline.append(" "); } - + if (!ctx.isCommandRecognised(cmdline.toString().trim())) { out.println("Unrecognised command: " + cmdline.toString().trim()); } else { @@ -75,7 +75,7 @@ public void run(String command, String[] args, IContext context, PrintStream out } } } - + private void printHelpSummary() { SortedSet helpTable = new TreeSet(); @@ -105,6 +105,6 @@ public void printDetailedHelp(PrintStream out) { "otherwise, the command's complete description will be displayed.\n\n" + "To view help on a command's sub-command, specify both the command " + "name and the sub-command name. For example, \"help info thread\" " + - "will display \"info thread\"'s description."); + "will display \"info thread\"'s description."); } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HexdumpCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HexdumpCommand.java index 86a0aa2f767..64abaa29224 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HexdumpCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/HexdumpCommand.java @@ -39,7 +39,7 @@ public class HexdumpCommand extends BaseJdmpviewCommand { { - addCommand("hexdump", " []", "outputs a section of memory in hexadecimal, ASCII and EBCDIC"); + addCommand("hexdump", " []", "outputs a section of memory in hexadecimal, ASCII and EBCDIC"); } @Override @@ -182,8 +182,8 @@ public void doCommand(String[] args) { @Override public void printDetailedHelp(PrintStream out) { out.format("outputs a section of memory in hexadecimal, ASCII and EBCDIC%n" - + "%n" - + "parameters: []%n" + + "%n" + + "parameters: []%n" + "%n" + "outputs (default 256) bytes of memory contents starting from %n" + "EBCDIC output is also provided for z/OS dumps%n"); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/PwdCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/PwdCommand.java index b927d6bbb9f..54abcde45d2 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/PwdCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/PwdCommand.java @@ -33,9 +33,9 @@ @DTFJPlugin(version=".*", runtime=false) public class PwdCommand extends BaseJdmpviewCommand { { - addCommand("pwd", "", "displays the current working directory"); + addCommand("pwd", "", "displays the current working directory"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -45,7 +45,7 @@ public void run(String command, String[] args, IContext context, PrintStream out return; } File pwd = (File)ctx.getProperties().get(SessionProperties.PWD_PROPERTY); - + out.print("\n"); out.print("\t" + pwd.getPath()); out.print("\n\n"); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/ScrollCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/ScrollCommand.java index 44630824404..ad226b1d652 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/ScrollCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/ScrollCommand.java @@ -30,12 +30,12 @@ import com.ibm.jvm.dtfjview.commands.helpers.Utils; @DTFJPlugin(version="1.*", runtime=false) -public class ScrollCommand extends BaseJdmpviewCommand{ +public class ScrollCommand extends BaseJdmpviewCommand { { - addCommand("+", "", "displays the next section of memory in hexdump-like format"); + addCommand("+", "", "displays the next section of memory in hexdump-like format"); addCommand("-", "", "displays the previous section of memory in hexdump-like format"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -47,7 +47,7 @@ public void run(String command, String[] args, IContext context, PrintStream out "by running hexdump command"); return; } - + long newMemAddress = 0; if(command.equals("+")) { newMemAddress = currentMemAddress.longValue() + currentNumBytesToPrint.intValue(); @@ -61,7 +61,7 @@ public void run(String command, String[] args, IContext context, PrintStream out @Override public void printDetailedHelp(PrintStream out) { - out.println("displays the next section of memory in hexdump-like format\n\n" + + out.println("displays the next section of memory in hexdump-like format\n\n" + "parameters: none\n\n" + "The + command is used in conjunction with the hexdump command \n" + "to allow easy scrolling forwards through memory. It repeats the \n" + @@ -72,5 +72,5 @@ public void printDetailedHelp(PrintStream out) { "before the previous one." ); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/SimpleRedirectorCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/SimpleRedirectorCommand.java index 6902c2d2c09..d50f708842c 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/SimpleRedirectorCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/SimpleRedirectorCommand.java @@ -29,22 +29,22 @@ /** * There are a number of jdmpview commands which just act as routing - * commands onto other more specific commands. This class provides an + * commands onto other more specific commands. This class provides an * abstract superclass for these commands to inherit from. - * + * * @author adam * */ public abstract class SimpleRedirectorCommand extends BaseJdmpviewCommand { protected static final String SUB_CMD_FORMAT = "%s %s"; - + /** * Get the base command name which triggers this routing - * + * * @return */ protected abstract String getCmdName(); - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -56,7 +56,7 @@ public void run(String command, String[] args, IContext context, PrintStream out break; case 1 : String subcmd = String.format(SUB_CMD_FORMAT, getCmdName(), args[0]); - context.execute(subcmd, new String[0], out); + context.execute(subcmd, new String[0], out); break; default : String[] arguments = new String[args.length - 1]; @@ -66,7 +66,7 @@ public void run(String command, String[] args, IContext context, PrintStream out subcmd = String.format(SUB_CMD_FORMAT, getCmdName(), args[0]); context.execute(subcmd, arguments, out); break; - + } } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/WhatisCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/WhatisCommand.java index 41174b693e5..abfa16031ab 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/WhatisCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/WhatisCommand.java @@ -42,9 +42,9 @@ public class WhatisCommand extends BaseJdmpviewCommand { { - addCommand("whatis", "[hex address]", "gives information about what is stored at the given memory address"); + addCommand("whatis", "[hex address]", "gives information about what is stored at the given memory address"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -55,37 +55,37 @@ public void run(String command, String[] args, IContext context, PrintStream out } Long lAddressInDecimal = Utils.longFromString(args[0]); if (null == lAddressInDecimal){ - out.println("cannot convert \"" + args[0] + "\" to numeric value"); + out.println("cannot convert \"" + args[0] + "\" to numeric value"); return; } long addressInDecimal = lAddressInDecimal.longValue(); - + findInRuntime(addressInDecimal); - + out.print("\n"); } - + private void findInRuntime(long address) { JavaHeap jh; Iterator itHeap = ctx.getRuntime().getHeaps(); int count = 1; - + while (itHeap.hasNext()) { jh = (JavaHeap)itHeap.next(); - + out.print("\theap #" + count + " - name: "); out.print(jh.getName() + "\n"); - + findInHeap(jh, address); count++; } } - + private void findInHeap(JavaHeap jh, long address) { //TODO: checkWithinValidMemRange(sb, ...); - + if (isWithinImageSections(jh.getSections(), null, false, address)){ //if it's start or within the range of an object if (!isStartOfObj(jh.getObjects(), address)){ @@ -95,14 +95,13 @@ private void findInHeap(JavaHeap jh, long address) } } else { out.print("\t\t0x" + Long.toHexString(address) + " is not within this heap.\n"); - //TODO : function to indicate 16 or 32 bit + //TODO : function to indicate 16 or 32 bit long bound = 12; //bounds default to 16 for 32 bit system. checkClassInRange(jh.getObjects(), bound, address); checkMethodInRange(jh.getObjects(), address); } } - - + private void checkMethodInRange(Iterator objects, long address){ while(objects.hasNext()){ JavaObject jObject = (JavaObject)objects.next(); @@ -137,7 +136,7 @@ private void checkMonitorInRange(Iterator monitors){ } } */ - + private void checkClassInRange(Iterator objects, long bound, long address){ long startAddress, endAddress ; while(objects.hasNext()){ @@ -159,13 +158,13 @@ private void checkClassInRange(Iterator objects, long bound, long address){ return; } if (isWithinRange(startAddress, endAddress, address)){ - out.print("0x" + Long.toHexString(address) + out.print("0x" + Long.toHexString(address) + " is within the java/lang/Class object for " + className); return; } } } - + private boolean isWithinObjectRange(Iterator objects, long address){ long startAddress, endAddress ; String className; @@ -180,7 +179,7 @@ private boolean isWithinObjectRange(Iterator objects, long address){ continue; } if (isWithinRange(startAddress, endAddress, address)){ - out.print("\t\t0x" + Long.toHexString(address) + " is within an object on the heap:\n" + + out.print("\t\t0x" + Long.toHexString(address) + " is within an object on the heap:\n" + "\t\t\toffset " + (address - startAddress) + " within "+ className + " instance @ 0x" + Long.toHexString(startAddress) + "\n"); return true; @@ -188,15 +187,15 @@ private boolean isWithinObjectRange(Iterator objects, long address){ } return false; } - + private boolean isWithinRange(long startAddress, long endAddress, long address){ return (address <= endAddress && address > startAddress); } - + private boolean isStartOfObj(Iterator objects, long address){ String className; long corruptObjectCount = 0; - + while(objects.hasNext()){ Object obj = objects.next(); if (obj instanceof CorruptData) { @@ -219,7 +218,7 @@ private boolean isStartOfObj(Iterator objects, long address){ } return false; } - + private boolean isWithinImageSections(Iterator heapImageSections, Object memType, boolean isMethodCompiled, long address) { @@ -228,10 +227,10 @@ private boolean isWithinImageSections(Iterator heapImageSections, Object memType long baseAddress = imageSection.getBaseAddress().getAddress(); long size = imageSection.getSize(); long endAddress = baseAddress + size; - + if (address <= endAddress && address >= baseAddress) { if (null == memType) { - out.print("\t\t0x" + Long.toHexString(address) + " is within heap segment: " + + out.print("\t\t0x" + Long.toHexString(address) + " is within heap segment: " + Long.toHexString(baseAddress) + " -- " + Long.toHexString(endAddress) + "\n"); return true; } @@ -241,13 +240,13 @@ private boolean isWithinImageSections(Iterator heapImageSections, Object memType methodName = ((JavaMethod)memType).getName(); methodSig = ((JavaMethod)memType).getSignature(); className = ((JavaMethod)memType).getDeclaringClass().getName(); - }catch(CorruptDataException cde){ + }catch(CorruptDataException cde){ }catch(DataUnavailable du){ } String codeType = isMethodCompiled ? "compiled code" : "byte code"; - out.print("\t0x" + Long.toHexString(address) + " is within the " + codeType + " range: " + + out.print("\t0x" + Long.toHexString(address) + " is within the " + codeType + " range: " + Long.toHexString(baseAddress) + " -- " + Long.toHexString(endAddress) + "\n\t" + "...of method " + - methodName + " with signature " + methodSig + "\n\t" + + methodName + " with signature " + methodSig + "\n\t" + "...in class " + className + "\n"); return true; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/ClassOutput.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/ClassOutput.java index 0044b6d058b..f001a36be28 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/ClassOutput.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/ClassOutput.java @@ -50,14 +50,14 @@ public static void printStaticFields(JavaClass jc, PrintStream out) } catch (CorruptDataException cde) { out.print("\t \n\n"); } - + String className; try { className = jc.getName(); } catch (CorruptDataException cde) { className = null; } - + // we've found a class, so we'll print out its static fields boolean found = false; Iterator itField = jc.getDeclaredFields(); @@ -65,7 +65,7 @@ public static void printStaticFields(JavaClass jc, PrintStream out) { JavaField jf = (JavaField)itField.next(); boolean isStatic; - + try { isStatic = Modifier.isStatic(jf.getModifiers()); } catch (CorruptDataException e) { @@ -78,7 +78,7 @@ public static void printStaticFields(JavaClass jc, PrintStream out) out.print("\", " + Exceptions.getCorruptDataExceptionString() + ">"); isStatic = false; } - + if (isStatic) { if (!found) @@ -105,14 +105,14 @@ public static void printNonStaticFields(JavaClass jc, PrintStream out) } catch (CorruptDataException cde) { out.print("\t \n\n"); } - + String className; try { className = jc.getName(); } catch (CorruptDataException cde) { className = null; } - + // we've found a class, so we'll print out its static fields boolean found = false; Iterator itField = jc.getDeclaredFields(); @@ -120,7 +120,7 @@ public static void printNonStaticFields(JavaClass jc, PrintStream out) { JavaField jf = (JavaField)itField.next(); boolean isStatic; - + try { isStatic = Modifier.isStatic(jf.getModifiers()); } catch (CorruptDataException e) { @@ -133,7 +133,7 @@ public static void printNonStaticFields(JavaClass jc, PrintStream out) out.print("\", " + Exceptions.getCorruptDataExceptionString() + ">"); isStatic = false; } - + if (!isStatic) { if (!found) @@ -149,11 +149,11 @@ public static void printNonStaticFields(JavaClass jc, PrintStream out) else out.print("\t \"" + className + "\" has no non-static fields\n\n"); } - + public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, PrintStream out) { boolean array; - + try { array = jo.isArray(); } catch (CorruptDataException e) { @@ -167,7 +167,7 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin { String componentType; int arraySize; - + try { componentType = jc.getComponentType().getName(); } catch (CorruptDataException e) { @@ -183,9 +183,7 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin Exceptions.getCorruptDataExceptionString() + ")>\n"); return; } - - - + Object dst = null; if (componentType.equals("boolean")) { @@ -207,7 +205,7 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin } else { dst = new JavaObject[arraySize]; } - + try { jo.arraycopy(0, dst, 0, arraySize); } catch (CorruptDataException e) { @@ -218,12 +216,12 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin out.print("\t \n"); return; - } catch (UnsupportedOperationException e) { + } catch (UnsupportedOperationException e) { // Some artefacts e.g. phd do not support arraycopy so just put out what we can out.print("\t This is an array of size " + arraySize + " elements\n"); return; } - + for (int i = 0; i < arraySize; i++) { out.print("\t " + i + ":\t"); @@ -250,12 +248,12 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin } } else - { - + { + JavaClass initialJC = jc; - List classList = new ArrayList(); + List classList = new ArrayList(); while (jc != null){ - + classList.add(jc); try { jc = jc.getSuperclass(); @@ -264,10 +262,10 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin } } for (int i = (classList.size()-1); i >=0 ; i--){ - + jc = classList.get(i); Iterator itField = jc.getDeclaredFields(); - + if (itField.hasNext()){ if (jc.equals(initialJC)){ out.print("\t declared fields:\n"); @@ -280,12 +278,12 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin } } } - + while (itField.hasNext()) { JavaField jf = (JavaField)itField.next(); boolean isStatic; - + try { isStatic = Modifier.isStatic(jf.getModifiers()); } catch (CorruptDataException e) { @@ -298,7 +296,7 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin out.print("\", " + Exceptions.getCorruptDataExceptionString() + ">"); isStatic = true; } - + if (!isStatic) { printNonStaticFieldData(jo, jf, out); @@ -308,21 +306,21 @@ public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Prin } out.print("\n"); } - + private static void printStaticFieldData(JavaField jf, PrintStream out) { printFieldData(null, jf, out, true); } - + private static void printNonStaticFieldData(JavaObject jo, JavaField jf, PrintStream out) { printFieldData(jo, jf, out, false); } - + private static void printFieldData(JavaObject jo, JavaField jf, PrintStream out, boolean isStatic) { String signature; - + out.print("\t "); try { @@ -347,22 +345,22 @@ private static void printFieldData(JavaObject jo, JavaField jf, PrintStream out, out.print(name); } } - + out.print(" "); - + try { out.print(jf.getName()); } catch (CorruptDataException e) { out.print(Exceptions.getCorruptDataExceptionString()); } - + if (isStatic || null != jo) { out.print(" = "); out.print(Utils.getVal(jo, jf)); } out.print("\n"); } - + public static void printMethods(Iterator methods, PrintStream out) { while(methods.hasNext()) { @@ -383,10 +381,9 @@ public static void printMethods(Iterator methods, PrintStream out) firstSectionPassed = true; } out.print(": "); - - + String signature; - + try { out.print(Utils.getMethodModifierString(jMethod)); } catch (CorruptDataException e) { @@ -408,7 +405,7 @@ public static void printMethods(Iterator methods, PrintStream out) out.print(name); } } - + out.print(" "); out.print(jMethod.getName()); @@ -421,7 +418,7 @@ public static void printMethods(Iterator methods, PrintStream out) out.print(name); } } - + out.print("\n"); }catch (CorruptDataException cde){ out.print("N/A (CorruptDataException occurred)"); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/Exceptions.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/Exceptions.java index ac7bf68a932..b3f8b0d613f 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/Exceptions.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/Exceptions.java @@ -38,7 +38,7 @@ public static String getDataUnavailableDoubleByte() { return "--"; } - + public static String getCorruptDataExceptionString() { return ""; @@ -53,7 +53,7 @@ public static String getCorruptDataExceptionDoubleByte() { return "--"; } - + public static String getMemoryAccessExceptionString() { return ""; @@ -68,7 +68,7 @@ public static String getMemoryAccessExceptionDoubleByte() { return "--"; } - + public static String getIOExceptionString() { return ""; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/JUCMonitorNode.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/JUCMonitorNode.java index b689e196fb9..7808a5ba7d6 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/JUCMonitorNode.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/JUCMonitorNode.java @@ -37,12 +37,12 @@ public class JUCMonitorNode extends MonitorNode { private JavaObject lock; private JavaRuntime jr; - + public JUCMonitorNode(JavaObject jucLock, JavaRuntime rt) { this.lock = jucLock; this.jr = rt; } - + public Iterator getEnterWaiters() { List waiters = new LinkedList(); Iterator itThread = jr.getThreads(); @@ -75,7 +75,7 @@ public JavaThread getOwner() throws CorruptDataException, MemoryAccessException public JavaObject getObject() { return lock; } - + public String getType() { try { return lock.getJavaClass().getName(); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/MonitorNode.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/MonitorNode.java index 982629be230..ad4da06c3b8 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/MonitorNode.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/MonitorNode.java @@ -36,13 +36,13 @@ public class MonitorNode { public static final int NO_DEADLOCK = 1; public static final int LOOP_DEADLOCK = 2; public static final int BRANCH_DEADLOCK = 3; - + private JavaMonitor monitor; public int visit; public MonitorNode waitingOn; public int deadlock; public NodeList inList; - + // For subclasses to call. protected MonitorNode() { visit = 0; @@ -50,7 +50,7 @@ protected MonitorNode() { deadlock = UNKNOWN; inList = null; } - + public MonitorNode(JavaMonitor _monitor) { monitor = _monitor; @@ -88,9 +88,9 @@ public String getType() { return "monitor"; } } - + public long getMonitorAddress() { return monitor.getID().getAddress(); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/MonitorState.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/MonitorState.java index ad81511dd29..7063890b664 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/MonitorState.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/MonitorState.java @@ -25,29 +25,29 @@ import com.ibm.dtfj.java.JavaMonitor; public class MonitorState { - + public static int WAITING_TO_ENTER = 1; public static int WAITING_TO_BE_NOTIFIED_ON = 2; private JavaMonitor jm; private int status; - + public MonitorState(JavaMonitor _jm, int _status) { jm = _jm; status = _status; } - + public JavaMonitor getMonitor() { return jm; } - + public int getStatus() { return status; } - + public String getStatusString() { if (status == WAITING_TO_ENTER) { @@ -58,7 +58,7 @@ public String getStatusString() return ""; } } - + public static String getStatusString(int statusToGet) { if (statusToGet == WAITING_TO_ENTER) { diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/NodeList.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/NodeList.java index 4f5a366f596..7e2f10f5a72 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/NodeList.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/NodeList.java @@ -29,13 +29,12 @@ import com.ibm.dtfj.image.DataUnavailable; import com.ibm.dtfj.image.MemoryAccessException; - public class NodeList { private MonitorNode head; private MonitorNode tail; private int id; - + public NodeList(MonitorNode node, int _id) { head = node; @@ -43,12 +42,12 @@ public NodeList(MonitorNode node, int _id) node.inList = this; id = _id; } - + public int getID() { return id; } - + public boolean equals(Object other) { return ((NodeList)other).getID() == id; @@ -92,27 +91,27 @@ public NodeList attachOrSplit(NodeList other, int nodeListNum) return null; } } - + public void add(MonitorNode node) { head = node; } - + public MonitorNode getHead() { return head; } - + public MonitorNode getTail() { return tail; } - + public boolean isLoop() { return tail == head; } - + // Print this list of monitor nodes (ie the owning threads and there object addresses) public String toString() { @@ -121,13 +120,13 @@ public String toString() MonitorNode lastNode = null; boolean firstTime = true; boolean done = false; - + do { String name = ""; String objAddr = ""; JavaObject object = null; JavaThread owner = null; - + try { owner = currNode.getOwner(); name = owner.getName(); @@ -142,18 +141,18 @@ public String toString() } catch (MemoryAccessException e) { name = Exceptions.getMemoryAccessExceptionString(); } - + object = currNode.getObject(); if (null == object) { objAddr = " at : " + Utils.toHex(currNode.getMonitorAddress()); } else { objAddr = " object : " + Utils.toHex(object.getID().getAddress()); } - + String lockName = currNode.getType(); - + retval += "thread: " + name + " (owns " + lockName + objAddr + ") waiting for =>\n\t "; - + lastNode = currNode; currNode = currNode.waitingOn; @@ -165,9 +164,9 @@ public String toString() done = true; } firstTime = false; - + } while (!done); - + retval = retval.substring(0, retval.length() - 18); // removes the tail of the last entry return retval; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/StateToString.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/StateToString.java index 596609be35a..bb0bd31388b 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/StateToString.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/StateToString.java @@ -23,7 +23,7 @@ package com.ibm.jvm.dtfjview.commands.helpers; public class StateToString { - + private static int JVMTI_THREAD_STATE_ALIVE = 0x0001; private static int JVMTI_THREAD_STATE_TERMINATED = 0x0002; private static int JVMTI_THREAD_STATE_RUNNABLE = 0x0004; @@ -40,7 +40,7 @@ public class StateToString { private static int JVMTI_THREAD_STATE_VENDOR_1 = 0x10000000; private static int JVMTI_THREAD_STATE_VENDOR_2 = 0x20000000; private static int JVMTI_THREAD_STATE_VENDOR_3 = 0x40000000; - + private static int JVMTI_JAVA_LANG_THREAD_STATE_MASK = JVMTI_THREAD_STATE_TERMINATED | JVMTI_THREAD_STATE_ALIVE | @@ -71,11 +71,11 @@ public class StateToString { public static String getJVMTIStateString(int state) { String retval = ""; - + if (0 == state) { return " "; } - + if ((state & JVMTI_THREAD_STATE_ALIVE) == JVMTI_THREAD_STATE_ALIVE) { retval += "ALIVE "; } @@ -124,20 +124,20 @@ public static String getJVMTIStateString(int state) if ((state & JVMTI_THREAD_STATE_VENDOR_3) == JVMTI_THREAD_STATE_VENDOR_3) { retval += "VENDOR_3 "; } - + if (retval.equals("")) { retval = " "; } - + return retval; } - + public static String getThreadStateString(int state) { String retval = ""; - + state &= JVMTI_JAVA_LANG_THREAD_STATE_MASK; - + if (state == JVMTI_JAVA_LANG_THREAD_STATE_NEW) { return "NEW "; } @@ -156,11 +156,11 @@ public static String getThreadStateString(int state) if ((state & JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING) == JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING) { retval += "TIMED_WAITING "; } - + if (retval.equals("")) { retval = " "; } - + return retval; } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/ThreadData.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/ThreadData.java index 74e6abb9919..09b63efc3a4 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/ThreadData.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/ThreadData.java @@ -26,7 +26,7 @@ import com.ibm.dtfj.java.JavaThread; public class ThreadData { - + private JavaThread jt; private JavaRuntime jr; @@ -34,11 +34,11 @@ public ThreadData(JavaThread _jt, JavaRuntime _jr) { jt = _jt; jr = _jr; } - + public JavaThread getThread() { return jt; } - + public JavaRuntime getRuntime() { return jr; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/Utils.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/Utils.java index 40ea70da4bf..71b4cdbafa0 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/Utils.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/helpers/Utils.java @@ -73,7 +73,7 @@ public class Utils { "................" + "................" ; - + public static final String byteToEbcdic = "................" + "................" + @@ -92,13 +92,13 @@ public class Utils { "\\.STUVWXYZ......"+ "0123456789......" ; - - //List of keys used by HashMap object associated with each session + + //List of keys used by HashMap object associated with each session public static final String CURRENT_MEM_ADDRESS = "currentMemPtrAddress"; public static final String CURRENT_NUM_BYTES_TO_PRINT = "currentNumBytes"; public static final String RootCommand_OBJECT = "RootCommandObject"; public static final String FIND_ATTRIBUTES = "FindAttributes"; - + private static final int CLASS_MODIFIERS_MASK = 0xc1f; private static final int INTERFACE_MODIFIERS_MASK = 0xe0f; private static final int CONSTRUCTOR_MODIFIERS_MASK = 0x7; @@ -111,7 +111,7 @@ public class Utils { public static final String SORT_BY_COUNT_FLAG = "-sort:count"; public static final String REVERSE_SORT_FLAG = "-sort:reverse"; public static final String VERBOSE_FLAG = "-verbose"; - + public static Iterator getRuntimes(Image loadedImage) { Vector runtimes = new Vector(); @@ -121,7 +121,7 @@ public static Iterator getRuntimes(Image loadedImage) ManagedRuntime mr; ImageAddressSpace ias; ImageProcess ip; - + itAddressSpace = loadedImage.getAddressSpaces(); while (itAddressSpace.hasNext()) { ias = (ImageAddressSpace)itAddressSpace.next(); @@ -144,12 +144,12 @@ public static Iterator getRuntimes(Image loadedImage) } } return runtimes.iterator(); - } + } /** * Format an ImagePointer for printing. * Get the address and format it as a hex string with 0x at the front - * + * * @param p the ImagePointer * @return p.getAddress() as a hex string */ @@ -157,17 +157,17 @@ public static String toHex(ImagePointer p) { return toHex(p.getAddress()); } - + public static String toHex(long l) { return "0x" + Long.toHexString(l); } - + public static String toHex(int i) { return "0x" + Integer.toHexString(i); } - + public static String toHex(short s) { // bit-wise AND is done to cancel the sign-extension that int casting does; @@ -176,7 +176,7 @@ public static String toHex(short s) // representation before the short is cast to an int, which the bit-wise AND does return "0x" + Integer.toHexString(s & 0x0000ffff); } - + public static String toHex(byte b) { // bit-wise AND is done to cancel the sign-extension that int casting does; @@ -185,17 +185,17 @@ public static String toHex(byte b) // representation before the byte is cast to an int, which the bit-wise AND does return "0x" + Integer.toHexString(b & 0x000000ff); } - + public static String toFixedWidthHex(long l) { return Utils.padWithZeroes(Long.toHexString(l), 16); } - + public static String toFixedWidthHex(int i) { return Utils.padWithZeroes(Integer.toHexString(i), 8); } - + public static String toFixedWidthHex(short s) { // bit-wise AND is done to cancel the sign-extension that int casting does; @@ -204,7 +204,7 @@ public static String toFixedWidthHex(short s) // representation before the short is cast to an int, which the bit-wise AND does return Utils.padWithZeroes(Integer.toHexString(s & 0x0000ffff), 4); } - + public static String toFixedWidthHex(byte b) { // bit-wise AND is done to cancel the sign-extension that int casting does; @@ -213,13 +213,13 @@ public static String toFixedWidthHex(byte b) // representation before the byte is cast to an int, which the bit-wise AND does return Utils.padWithZeroes(Integer.toHexString(b & 0x000000ff), 2); } - + public static Stack constructStackFromString(String args) { String[] argsArray = args.split("\\s+"); return constructStackFromStringArray(argsArray); } - + public static Stack constructStackFromStringArray(String[] argsArray){ Stack s = new Stack(); for (int i = argsArray.length - 1; i >= 0; i--){ @@ -227,7 +227,7 @@ public static Stack constructStackFromStringArray(String[] argsArray){ } return s; } - + public static String concatArgsFromStack(Stack args){ String s = ""; while(!args.empty()){ @@ -235,14 +235,14 @@ public static String concatArgsFromStack(Stack args){ } return s; } - + //CMVC 175488 : fixed so that this function returns an address space which contains a process //rather than the first address space it finds. public static ImageAddressSpace _extractAddressSpace(Image loadedImage) { ImageAddressSpace space = null; Iterator spaces = loadedImage.getAddressSpaces(); - + Object obj = null; //object returned through DTFJ iterators while (spaces.hasNext()) { obj = spaces.next(); @@ -260,11 +260,11 @@ public static ImageAddressSpace _extractAddressSpace(Image loadedImage) //failed to find an address space which contains a process. return null; } - + public static Long longFromString(String value) { Long translated = null; - + if (null != value) { if (value.startsWith("0x")) { value = value.substring(2); @@ -285,24 +285,24 @@ public static Long longFromString(String value) } return translated; } - + public static Long longFromStringWithPrefix(String value) { Long translated = null; - + if (value.startsWith("0x")) { translated = longFromString(value); } - + return translated; } - + public static String getSignatureName(String signature) { Hashtable table = new Hashtable(); String retval = null; - + table.put("Z", "boolean"); table.put("B", "byte"); table.put("C", "char"); @@ -312,7 +312,7 @@ public static String getSignatureName(String signature) table.put("F", "float"); table.put("D", "double"); table.put("V", "void"); - + if (signature.startsWith("L")) { StringTokenizer st = new StringTokenizer(signature.substring(1), ";"); @@ -333,28 +333,28 @@ else if (signature.startsWith("[")) { String currSig = new String(signature); String arraySuffix = ""; - + while (currSig.startsWith("[")) { arraySuffix += "[]"; currSig = currSig.substring(1); } - + retval = Utils.getSignatureName(currSig) + arraySuffix; } else { retval = (String)table.get(signature.substring(0,1)); } - + return retval; } - + public static String getMethodSignatureName(String signature) { Hashtable table = new Hashtable(); String retval = ""; - + table.put("Z", "boolean"); table.put("B", "byte"); table.put("C", "char"); @@ -363,7 +363,7 @@ public static String getMethodSignatureName(String signature) table.put("J", "long"); table.put("F", "float"); table.put("D", "double"); - + if (signature.startsWith("(")) { StringTokenizer st = new StringTokenizer(signature.substring(1), ")"); @@ -405,13 +405,13 @@ else if (signature.startsWith("[")) { String currSig = new String(signature); String arraySuffix = ""; - + while (currSig.startsWith("[")) { arraySuffix += "[]"; currSig = currSig.substring(1); } - + if (currSig.startsWith("L")) { if (currSig.indexOf(';') + 1 == currSig.length()) { retval = Utils.getSignatureName(currSig) + arraySuffix; @@ -441,10 +441,10 @@ else if (signature.startsWith("[")) retval += ", " + Utils.getMethodSignatureName(signature.substring(1)); } } - + return retval; } - + public static String getReturnValueName(String signature) { if (signature.startsWith("(")) @@ -475,7 +475,7 @@ public static String getReturnValueName(String signature) return null; } } - + public static String toString(String s) { if (null == s) @@ -483,7 +483,7 @@ public static String toString(String s) else return s; } - + public static File absPath(Properties properties, String path) { File oldPwd = (File)properties.get("pwd"); @@ -495,17 +495,17 @@ public static File absPath(Properties properties, String path) try { newPwd = newPwd.getCanonicalFile(); } catch (IOException e) { - + } - + return newPwd; } - + public static String getVal(Object o) { return Utils.getVal(o, null, null); } - + // note: this method lets you pass in a null JavaObject, but it _will_ throw a // NullPointerException if the JavaField is not a static field when you pass it // a null JavaObject; this is the behavior of jf.get() and jf.getString() @@ -513,7 +513,7 @@ public static String getVal(JavaObject jo, JavaField jf) { Object o; String s; - + if (null == jf) { o = jo; @@ -529,7 +529,7 @@ public static String getVal(JavaObject jo, JavaField jf) } catch (NumberFormatException nfe) { return ""; } - + try { s = jf.getString(jo); } catch (CorruptDataException e) { @@ -540,10 +540,10 @@ public static String getVal(JavaObject jo, JavaField jf) s = null; } } - + return getVal(o, s, jf); } - + public static String getVal(Object o, String str, JavaField jf) { String val = ""; @@ -597,7 +597,7 @@ public static String getVal(Object o, String str, JavaField jf) } else { // FIXME } - + // why are we processing objects here? // because we want control over the exceptions that are thrown if (object) @@ -605,13 +605,13 @@ public static String getVal(Object o, String str, JavaField jf) JavaObject joField = (JavaObject)o; JavaClass jcField; String jcName; - + try { jcField = joField.getJavaClass(); } catch (CorruptDataException e) { jcField = null; } - + try { if (null != jcField) { jcName = jcField.getName(); @@ -621,7 +621,7 @@ public static String getVal(Object o, String str, JavaField jf) } catch (CorruptDataException e) { jcName = null; } - + if (null != jcName && jcName.equals("java/lang/String")) { if (null == str) { @@ -643,21 +643,21 @@ public static String getVal(Object o, String str, JavaField jf) val += Utils.toHex(value.longValue()); val += ")"; } - + return val; } - + private static String getStringVal(JavaObject jo) { JavaClass jc; - + try { jc = jo.getJavaClass(); } catch (CorruptDataException e) { return ""; } - + Iterator itJavaField = jc.getDeclaredFields(); JavaField jf = null; while (itJavaField.hasNext()) @@ -667,14 +667,14 @@ private static String getStringVal(JavaObject jo) if (jf.getSignature().equals("[C") && !Modifier.isStatic(jf.getModifiers())) break; } catch (CorruptDataException e) { - // if we have an exception, do nothing and go onto the next field + // if we have an exception, do nothing and go onto the next field } } if (jf == null) { // empty field iterator (occurs e.g. when reading PHD heapdumps), can't get the char array return ""; } - + JavaObject charArray = null; try { charArray = (JavaObject)jf.get(jo); @@ -685,7 +685,7 @@ private static String getStringVal(JavaObject jo) return ""; } - + int arraySize; try { arraySize = charArray.getArraySize(); @@ -693,9 +693,9 @@ private static String getStringVal(JavaObject jo) return ""; } - + char[] dst = new char[arraySize]; - + try { charArray.arraycopy(0, dst, 0, arraySize); } catch (CorruptDataException e) { @@ -705,10 +705,9 @@ private static String getStringVal(JavaObject jo) return ""; } - + return "\"" + Utils.getPrintable(new String(dst)) + "\""; } - public static String getPrintable(char c) { @@ -716,7 +715,7 @@ public static String getPrintable(char c) // static char arrays of the String class; the memory addresses of these arrays // can be found by using the command "x/j java/lang/String" and looking at the // static fields printed at the top of the output - + switch (c) { // the following 8 cases were taken from Section 3.10.6 of the @@ -762,24 +761,24 @@ public static String getPrintable(char c) } } } - + public static String getPrintableWithQuotes(char c) { return "\'" + Utils.getPrintable(c) + "\'"; } - + public static String getPrintable(String s) { String retval = ""; - + for (int i = 0; i < s.length(); i++) { retval += Utils.getPrintable(s.charAt(i)); } - + return retval; } - + public static String padWithZeroes(String unpadded, int desiredLength) { String output = new String(unpadded); @@ -802,25 +801,25 @@ public static Iterator getAddressSpaceSectionInfo(Image loadedImage) { } return vSections.iterator(); } - + public static String getFieldModifierString(JavaField jf) throws CorruptDataException{ int modifiers = jf.getModifiers(); int typeMask = FIELD_MODIFIERS_MASK; return getModifierString(modifiers, typeMask); } - + public static String getMethodModifierString(JavaMethod jm) throws CorruptDataException{ int modifiers = jm.getModifiers(); int typeMask = ("".equals(jm.getName()))?CONSTRUCTOR_MODIFIERS_MASK:METHOD_MODIFIERS_MASK; return getModifierString(modifiers, typeMask); } - + public static String getClassModifierString(JavaClass jc) throws CorruptDataException{ int modifiers = jc.getModifiers(); int typeMask = Modifier.isInterface(modifiers)?INTERFACE_MODIFIERS_MASK|Modifier.INTERFACE:CLASS_MODIFIERS_MASK; return getModifierString(modifiers, typeMask); } - + private static String getModifierString(int modifiers, int typeMask){ if (modifiers == JavaClass.MODIFIERS_UNAVAILABLE) { return "No modifiers available"; @@ -841,12 +840,12 @@ private static String getModifierString(int modifiers, int typeMask){ if(Modifier.isStrict(modifiers)) retval += "strict "; return retval; } - + public static boolean isNull(JavaObject jo) { return jo.getID().getAddress() == 0; } - + public static String padWithSpaces(String unpadded, int desiredLength) { String output = new String(unpadded); @@ -856,7 +855,7 @@ public static String padWithSpaces(String unpadded, int desiredLength) } return output; } - + public static String prePadWithSpaces(String unpadded, int desiredLength) { String output = ""; @@ -867,12 +866,12 @@ public static String prePadWithSpaces(String unpadded, int desiredLength) output += unpadded; return output; } - + public static JavaClass[] getClassGivenName(String className, JavaRuntime jr, PrintStream out) { Iterator itJavaClassLoader = jr.getJavaClassLoaders(); List classes = new ArrayList(); - + while (itJavaClassLoader.hasNext() ) { Object nextCl = itJavaClassLoader.next(); @@ -911,11 +910,11 @@ public static JavaClass[] getClassGivenName(String className, JavaRuntime jr, Pr return null; } } - + public static JavaClass getClassGivenAddress(long address, JavaRuntime jr) { Iterator itJavaClassLoader = jr.getJavaClassLoaders(); - + while (itJavaClassLoader.hasNext() ) { Object nextCl = itJavaClassLoader.next(); @@ -926,7 +925,7 @@ public static JavaClass getClassGivenAddress(long address, JavaRuntime jr) Iterator itJavaClass = jcl.getDefinedClasses(); while (itJavaClass.hasNext() ) { - + Object next = itJavaClass.next(); if( !(next instanceof JavaClass) ) { continue; @@ -945,10 +944,10 @@ public static JavaClass getClassGivenAddress(long address, JavaRuntime jr) return null; } - + /* Find the JavaThread that owns a blocking object by finding the java/lang/Thread * JavaObject of the owner and then looking through the list of JavaThreads to - * see who that belongs to. + * see who that belongs to. */ public static JavaThread getParkBlockerOwner(JavaObject blocker, JavaRuntime r) throws CorruptDataException, MemoryAccessException { JavaObject ownerObj = getParkBlockerOwnerObject(blocker, r); @@ -964,10 +963,10 @@ public static JavaThread getParkBlockerOwner(JavaObject blocker, JavaRuntime r) return thread; } } - } + } return null; } - + /* Given an object that a parked thread has as it's blocker find the java/lang/Thread * object for it's owner. (Not the dtfj JavaThread!) */ @@ -994,7 +993,7 @@ public static JavaObject getParkBlockerOwnerObject(JavaObject blocker, JavaRunti } return null; } - + public static String getThreadNameFromObject(JavaObject lockOwnerObj, JavaRuntime rt, PrintStream out) throws CorruptDataException, MemoryAccessException { if( lockOwnerObj == null ) { return null; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoClassCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoClassCommand.java index 4479dcf9de6..3e3cb505c7c 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoClassCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoClassCommand.java @@ -54,15 +54,15 @@ public class InfoClassCommand extends BaseJdmpviewCommand { * Cache of all classes and their respective ClassStatistics, organized by JavaRuntime. */ private static Map> classInstanceCounts; - + { - addCommand("info class", "[Java class name] [-sort:]", "Provides information about the specified Java class"); + addCommand("info class", "[Java class name] [-sort:]", "Provides information about the specified Java class"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { String className = null; Comparator sortOrder = new ClassNameComparator(); - + if(initCommand(command, args, context, out)) { return; //processing already handled by super class } @@ -81,7 +81,7 @@ public void run(String command, String[] args, IContext context, PrintStream out className = arg; } } - + if( className == null ) { printAllRuntimeClasses(sortOrder); } else { @@ -89,7 +89,7 @@ public void run(String command, String[] args, IContext context, PrintStream out } } - + private void printSingleRuntimeClassInfo(String className) { JavaRuntime jr = ctx.getRuntime(); @@ -104,7 +104,7 @@ private void printSingleRuntimeClassInfo(String className) } else { classes = Utils.getClassGivenName(className, jr, out); } - + // if we couldn't find a class of that name, return; the passed in class name could // still be an array type or it might not exist if (null == classes || classes.length == 0 ) { @@ -195,7 +195,7 @@ private void printClassHierarchy(JavaClass jClass) { while (null != jClass){ try{ stack.add(jClass.getName()); - jClass = jClass.getSuperclass(); + jClass = jClass.getSuperclass(); }catch(CorruptDataException cde){ stack.add("N/A (CorruptDataException occurred)"); break; @@ -203,7 +203,7 @@ private void printClassHierarchy(JavaClass jClass) { } printStack(stack); } - + private void printStack(Stack stack){ out.print("Inheritance chain....\n\n"); String tab = "\t"; @@ -213,20 +213,19 @@ private void printStack(Stack stack){ spaces += " "; } } - + private void printFields(JavaClass jClass) { out.print("Fields......\n\n"); ClassOutput.printStaticFields(jClass, out); ClassOutput.printNonStaticFields(jClass, out); } - + private void printMethods(JavaClass jClass){ out.print("Methods......\n\n"); ClassOutput.printMethods(jClass.getDeclaredMethods(), out); out.print("\n"); } - /** * Pre-populates the classInstanceCounts map with just classes, and empty ClassStatistics objects. * The key-set of classInstanceCounts.get(someRuntime) can be then treated as a cache of all classes for that runtime, @@ -238,7 +237,7 @@ private void cacheRuntimeClasses() { classInstanceCounts = new HashMap>(); long corruptClassCount = 0; - + Map classesOfThisRuntime = new HashMap(); JavaRuntime runtime = ctx.getRuntime(); classInstanceCounts.put(runtime, classesOfThisRuntime); @@ -247,7 +246,7 @@ private void cacheRuntimeClasses() { while (itClassLoader.hasNext()) { JavaClassLoader jcl = (JavaClassLoader)itClassLoader.next(); - + Iterator itClass = jcl.getDefinedClasses(); while (itClass.hasNext()) { Object obj = itClass.next(); @@ -263,11 +262,11 @@ private void cacheRuntimeClasses() { out.print("Warning, found " + corruptClassCount + " corrupt classes during classloader walk\n"); } } - + private void printAllRuntimeClasses(Comparator sortOrder) { JavaRuntime jr = ctx.getRuntime(); Collection javaClasses = getRuntimeClasses(jr); - + long objCount = 0; long totalSize = 0; Iterator itClass; @@ -289,18 +288,18 @@ private void printAllRuntimeClasses(Comparator sortOrder) { } while (itClass.hasNext()) { JavaClass jc = itClass.next(); - + ClassStatistics d = getClassStatisticsFor(jr, jc); totalSize += d.getSize(); objCount += d.getCount(); printOneClass(jc, d); } - + out.print("\n"); out.print("\t Total number of objects: " + objCount + "\n"); out.print("\t Total size of objects: " + totalSize + "\n"); } - + private static Collection getRuntimeClasses(JavaRuntime jr) { return classInstanceCounts.get(jr).keySet(); } @@ -316,7 +315,7 @@ private void countClassInstances() { long corruptObjectCount = 0; long corruptClassCount = 0; long corruptClassNameCount = 0; - + Iterator itHeap = runtime.getHeaps(); while (itHeap.hasNext()) { Object heap = itHeap.next(); @@ -326,16 +325,16 @@ private void countClassInstances() { } JavaHeap jh = (JavaHeap)heap; Iterator itObject = jh.getObjects(); - + // Walk through all objects in this heap, accumulating counts and total memory size by class while (itObject.hasNext()) { Object next = itObject.next(); - // Check that this is a JavaObject (there may be CorruptData objects in the - // JavaHeap, we don't attempt to count these as instances of known classes). + // Check that this is a JavaObject (there may be CorruptData objects in the + // JavaHeap, we don't attempt to count these as instances of known classes). if (next instanceof JavaObject) { JavaObject jo = (JavaObject)next; ClassStatistics stats = null; - + try { // Check whether we found this class in the classloaders walk earlier JavaClass jc = jo.getJavaClass(); @@ -353,7 +352,7 @@ private void countClassInstances() { corruptClassNameCount++; } } - + // Increment the statistic for objects of this class (accumulated count and size) stats.incrementCount(); try { @@ -379,7 +378,7 @@ private void countClassInstances() { out.println("Warning, found " + corruptClassNameCount + " corrupt class names during heap walk"); } } - + private void printClassListHeader() { out.print("\n" + Utils.prePadWithSpaces("instances", 16)); out.print(Utils.prePadWithSpaces("total size on heap", 20)); @@ -400,28 +399,28 @@ private void printOneClass(JavaClass jc, ClassStatistics datum){ out.print(" " + className); out.print("\n"); } - + public static class ClassStatistics { private int count; private long totalSize; - + public ClassStatistics(){ this.count = 0; this.totalSize = 0; } - + public int getCount(){ return this.count; } - + public long getSize(){ return this.totalSize; } - + public void incrementCount(){ this.count++; } - + public void addToSize(long sizeToAdd){ this.totalSize += sizeToAdd; } @@ -436,7 +435,7 @@ private static int cmp(long n1, long n2) { return -1; } } - + private class TotalSizeComparator implements Comparator { public int compare(JavaClass o1, JavaClass o2) { @@ -445,7 +444,7 @@ public int compare(JavaClass o1, JavaClass o2) { return cmp(s1, s2); } } - + private class InstanceCountComparator implements Comparator { public int compare(JavaClass o1, JavaClass o2) { @@ -454,7 +453,7 @@ public int compare(JavaClass o1, JavaClass o2) { return cmp(s1, s2); } } - + private class ClassNameComparator implements Comparator { public int compare(JavaClass o1, JavaClass o2) { @@ -471,10 +470,10 @@ public int compare(JavaClass o1, JavaClass o2) { return s1.compareTo(s2); } } - + @Override public void printDetailedHelp(PrintStream out) { - out.println("Prints inheritance chain and other data for a given class\n\n" + + out.println("Prints inheritance chain and other data for a given class\n\n" + "Parameters: none, class name or ID, sort flags\n\n" + "If name or id parameters are omitted then \"info class\", prints the " + "number of instances of each class and the total size of all " + @@ -496,6 +495,6 @@ public void printDetailedHelp(PrintStream out) { "If multiple classes with the same name (on different class loaders) are found " + "then the class ID and class loader are printed for each class. Use info class " + "with the class ID to print out information on a specific class."); - + } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoHeapCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoHeapCommand.java index 041cdb153d0..a780af7b4f3 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoHeapCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoHeapCommand.java @@ -40,15 +40,15 @@ @DTFJPlugin(version="1.*", runtime=false) public class InfoHeapCommand extends BaseJdmpviewCommand { { - addCommand("info heap", "[*|heap name]", "Displays information about Java heaps"); + addCommand("info heap", "[*|heap name]", "Displays information about Java heaps"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class } out.print("\n"); - + if (args.length == 0){ printHeapInfo(null,ctx.getRuntime(), out); out.print("\nUse \"info heap *\" or \"info heap \" " + @@ -60,7 +60,7 @@ public void run(String command, String[] args, IContext context, PrintStream out return; } else { boolean foundHeap = searchForHeap(args[0], ctx.getRuntime(), out); - + if (!foundHeap){ out.print("Unable to locate heap: \"" + args[0] +"\"."); out.print("\tAvailable heaps: \n"); @@ -68,13 +68,11 @@ public void run(String command, String[] args, IContext context, PrintStream out } } } - - private void printHeapInfo(String param, JavaRuntime runtime, PrintStream out){ Iterator itHeaps = runtime.getHeaps(); int countheaps = 1; - + while (itHeaps.hasNext()) { Object heap = itHeaps.next(); @@ -93,13 +91,13 @@ private void printHeapInfo(String param, JavaRuntime runtime, PrintStream out){ private void printSectionInfo(JavaHeap theHeap, PrintStream out){ Iterator itSections = theHeap.getSections(); int countSections = 1; - + while (itSections.hasNext()){ - + ImageSection theSection = (ImageSection)itSections.next(); out.print("\t Section #"+ countSections + ": " + theSection.getName() + "\n"); out.print("\t Size: " + theSection.getSize() + " bytes\n"); - try + try { out.print("\t Shared: " + theSection.isShared() + "\n"); out.print("\t Executable: " + theSection.isExecutable() +"\n"); @@ -114,11 +112,11 @@ private void printSectionInfo(JavaHeap theHeap, PrintStream out){ } } private boolean searchForHeap(String param, JavaRuntime jr, PrintStream out){ - + boolean foundHeap = false; Iterator itHeaps = jr.getHeaps(); int countheaps = 1; - + while (itHeaps.hasNext()) { JavaHeap theHeap = (JavaHeap)itHeaps.next(); @@ -130,21 +128,21 @@ private boolean searchForHeap(String param, JavaRuntime jr, PrintStream out){ } countheaps++; } - + return foundHeap; } private void printOccupancyInfo(JavaHeap theHeap, PrintStream out){ /* - * This method takes a lot of time and hence this information is only included - * when using "info heap ". If this method was run for every heap + * This method takes a lot of time and hence this information is only included + * when using "info heap ". If this method was run for every heap * when using "info heap *" the amount of time it would take would be astronomical. */ long size = 0; long totalObjectSize = 0; long totalObjects = 0; //total number of objects on the heap - long totalCorruptObjects = 0; //total number of corrupt objects - + long totalCorruptObjects = 0; //total number of corrupt objects + Iterator itSections = theHeap.getSections(); Object obj = null; //object returned from various iterators CorruptData cdata = null; //corrupt data @@ -163,7 +161,7 @@ private void printOccupancyInfo(JavaHeap theHeap, PrintStream out){ } } out.print("\t Size of heap: "+ size + " bytes\n"); - + Iterator itObjects = theHeap.getObjects(); try{ while (itObjects.hasNext()){ @@ -182,19 +180,18 @@ private void printOccupancyInfo(JavaHeap theHeap, PrintStream out){ totalObjectSize = totalObjectSize + theObject.getSize(); } } - - float percentage = ((float)totalObjectSize/(float)size)*10000; + + float percentage = ((float)totalObjectSize/(float)size)*10000; int trimmedPercent = ((int)percentage); // Sending this float through an int gets it down to 2 decimal places. percentage = ((float)trimmedPercent)/100; - + out.print("\t Occupancy : "+ totalObjectSize + " bytes (" + percentage + "%)\n"); out.print("\t Total objects : "+ totalObjects + "\n"); out.print("\t Total corrupted objects : "+ totalCorruptObjects + "\n"); - + } catch (CorruptDataException e){ out.print("\t Occupancy : \n"); } - } @Override @@ -216,5 +213,5 @@ public void printDetailedHelp(PrintStream out) { " - whether the section is read only\n" ); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoJitmCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoJitmCommand.java index dcb151d2d50..1149c315d16 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoJitmCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoJitmCommand.java @@ -40,11 +40,11 @@ @DTFJPlugin(version="1.*", runtime=false) public class InfoJitmCommand extends BaseJdmpviewCommand { - + { - addCommand("info jitm", "", "Displays JIT'ed methods and their addresses"); + addCommand("info jitm", "", "Displays JIT'ed methods and their addresses"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -55,7 +55,7 @@ public void run(String command, String[] args, IContext context, PrintStream out } showJITdMethods(); } - + private void showJITdMethods() { JavaRuntime jr = ctx.getRuntime(); Iterator itJavaClassLoader = jr.getJavaClassLoaders(); @@ -63,31 +63,31 @@ private void showJITdMethods() { { JavaClassLoader jcl = (JavaClassLoader)itJavaClassLoader.next(); Iterator itJavaClass = jcl.getDefinedClasses(); - + while (itJavaClass.hasNext()) { JavaClass jc = (JavaClass)itJavaClass.next(); Iterator itJavaMethod = jc.getDeclaredMethods(); - + String jcName; try { jcName = jc.getName(); } catch (CorruptDataException e) { jcName = Exceptions.getCorruptDataExceptionString(); } - + while (itJavaMethod.hasNext()) { JavaMethod jm = (JavaMethod)itJavaMethod.next(); String name; String sig; - + try { name = jm.getName(); } catch (CorruptDataException e) { name = Exceptions.getCorruptDataExceptionString(); } - + try { sig = jm.getSignature(); } catch (CorruptDataException e) { @@ -103,7 +103,7 @@ private void showJITdMethods() { long startAddr = is.getBaseAddress().getAddress(); long size = is.getSize(); long endAddr = startAddr + size; - + out.print("\n\t" + "start=" + Utils.toHex(startAddr) + " " + "end=" + Utils.toHex(endAddr) + " " + jcName + "::" + name + sig); @@ -118,12 +118,11 @@ private void showJITdMethods() { @Override public void printDetailedHelp(PrintStream out) { out.println("displays JIT'ed methods and their addresses\n\n" + - "parameters: none\n\n" + - "prints the following information about each JIT'ed method\n\n" + - " - method name and signature\n" + - " - method start address\n" + - " - method end address\n" -); - + "parameters: none\n\n" + + "prints the following information about each JIT'ed method\n\n" + + " - method name and signature\n" + + " - method start address\n" + + " - method end address\n" + ); } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoLockCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoLockCommand.java index 636042aee6b..fe67d44bdc6 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoLockCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoLockCommand.java @@ -50,9 +50,9 @@ @DTFJPlugin(version="1.*",runtime=false) public class InfoLockCommand extends BaseJdmpviewCommand{ { - addCommand("info lock", "", "outputs a list of system monitors and locked objects"); + addCommand("info lock", "", "outputs a list of system monitors and locked objects"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -64,12 +64,12 @@ public void run(String command, String[] args, IContext context, PrintStream out showSystemLocks(); showJavaUtilConcurrentLocks(); } - + private void showSystemLocks() { Vector vMonitorsWithLockedObjects = new Vector<>(); JavaRuntime jRuntime = ctx.getRuntime(); Iterator monitors = jRuntime.getMonitors(); - + out.println("\nSystem locks..."); while (monitors.hasNext()){ JavaMonitor jMonitor = (JavaMonitor)monitors.next(); @@ -91,9 +91,9 @@ private void showSystemLocks() { logger.log(Level.FINE, Exceptions.getDataUnavailableString(), e); } } - + showWaiters(jMonitor); - + } catch(CorruptDataException cde) { out.println("\nwarning, corrupt data encountered during scan for system locks..."); } @@ -116,7 +116,7 @@ private void showWaiters(JavaMonitor jMonitor) } JavaThread jThread = (JavaThread)t; try { - out.println("\twaiting thread id: " + jThread.getImageThread().getID() + out.println("\twaiting thread id: " + jThread.getImageThread().getID() + " name: " + jThread.getName()); } catch (DataUnavailable dae) { out.println("\twaiting thread id: "); @@ -131,7 +131,7 @@ private void showWaiters(JavaMonitor jMonitor) } JavaThread jThread = (JavaThread)t; try { - out.println("\twaiting thread id: " + jThread.getImageThread().getID() + out.println("\twaiting thread id: " + jThread.getImageThread().getID() + " name: " + jThread.getName()); } catch (DataUnavailable dae) { out.println("\twaiting thread id: "); @@ -139,7 +139,7 @@ private void showWaiters(JavaMonitor jMonitor) } } } - + private void showLockedObjects(Vector vMonitorsWithLockedObjects) { out.println("\nObject Locks in use..."); if (0 == vMonitorsWithLockedObjects.size()){ @@ -153,9 +153,9 @@ private void showLockedObjects(Vector vMonitorsWithLockedObjects) { try{ JavaThread owner = jMonitor.getOwner(); String className = ""; - JavaClass jClass = jObject.getJavaClass(); + JavaClass jClass = jObject.getJavaClass(); if (null != jClass) { - className = jClass.getName(); + className = jClass.getName(); } String jObjectID = Long.toHexString(jObject.getID().getAddress()); if (null == owner) { @@ -177,7 +177,7 @@ private void showLockedObjects(Vector vMonitorsWithLockedObjects) { } } } - + private void showJavaUtilConcurrentLocks() { // A map of lock objects and their waiting threads. Map> locksToThreads = new HashMap<>(); @@ -234,15 +234,15 @@ private void showJavaUtilConcurrentLocks() { } if( threads != null && threads.size() > 0) { String lockID = Long.toHexString(lock.getID().getAddress()); - + ImageThread imageThread = (lockOwnerThread!=null?lockOwnerThread.getImageThread():null); - + out.println(lock.getJavaClass().getName() + "@0x" + lockID + "\n\tlocked by java thread id: " + ((imageThread!=null)?imageThread.getID():"") + " name: " + (threadName)); - + for( Object t: threads) { JavaThread waiter = (JavaThread) t; - out.println("\twaiting thread id: " + waiter.getImageThread().getID() + out.println("\twaiting thread id: " + waiter.getImageThread().getID() + " name: " + waiter.getName()); } } @@ -258,12 +258,11 @@ private void showJavaUtilConcurrentLocks() { } } } - + @Override public void printDetailedHelp(PrintStream out) { out.println("outputs a list of system monitors and locked objects\n\n" + "parameters: none\n\n" + "The info lock command outputs a list of system monitors and locked objects."); - } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoMemoryCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoMemoryCommand.java index a72ac7fe19f..88b5b91b8ec 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoMemoryCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoMemoryCommand.java @@ -42,13 +42,13 @@ @DTFJPlugin(version="1.*", runtime=false) public class InfoMemoryCommand extends BaseJdmpviewCommand { - + private static final String COM_IBM_DBGMALLOC_PROPERTY = "-Dcom.ibm.dbgmalloc=true"; { - addCommand("info memory", "", "Provides information about the native memory usage in the Java Virtual Machine"); + addCommand("info memory", "", "Provides information about the native memory usage in the Java Virtual Machine"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if (initCommand(command, args, context, out)) { return; // processing already handled by super class @@ -123,7 +123,7 @@ private void printAllMemoryCategories(PrintStream out, Iterator memoryCategor * Print a category and any of it's children. The stack argument is a list of how many children * each parent category has so we can work out how to print the ascii art lines from parents * to children. - * + * * @param category * @param stack * @param out @@ -142,14 +142,14 @@ private void printCategory(JavaRuntimeMemoryCategory category, LinkedList category.getShallowBytes() ) { - + Iterator memoryCategories = category.getChildren(); JavaRuntimeMemoryCategory other = getOtherCategory(category); - + while (memoryCategories.hasNext()) { int parentCount = stack.get(depth); parentCount--; @@ -176,10 +176,10 @@ private void printCategory(JavaRuntimeMemoryCategory category, LinkedList stack, PrintStream out, int depth) { for (int i = 0; i < depth; i++) { diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoMmapCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoMmapCommand.java index 05ec81c83ad..65ffca283e1 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoMmapCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoMmapCommand.java @@ -42,21 +42,21 @@ @DTFJPlugin(version="1.*", runtime=false) public class InfoMmapCommand extends BaseJdmpviewCommand{ - + { - addCommand("info mmap", "[address] [-verbose] [-sort:]", "Outputs a list of all memory segments in the address space"); + addCommand("info mmap", "[address] [-verbose] [-sort:]", "Outputs a list of all memory segments in the address space"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { - + boolean verbose = false; ImagePointer addressPointer = null; Comparator sortOrder = null; - + if(initCommand(command, args, context, out)) { return; //processing already handled by super class } - + for( String arg: args) { if (Utils.SORT_BY_SIZE_FLAG.equals(arg)) { sortOrder = new SizeComparator(); @@ -85,7 +85,7 @@ public void run(String command, String[] args, IContext context, PrintStream out if( sortOrder != null ) { Collections.sort(sortedSections, sortOrder); } - + int addrSize = ctx.getProcess().getPointerSize() == 64 ? 16 : 8; // Width for decimals can vary as we use the locales format (via %,d) int decWidth = 0; @@ -155,13 +155,13 @@ public void run(String command, String[] args, IContext context, PrintStream out String tableFormatString = "\t%-"+maxLen+"s\t%-"+maxLen+"s\n"; while( tableIterator.hasNext() ) { out.printf(tableFormatString, tableIterator.next(), tableIterator.hasNext()?tableIterator.next():""); - + } out.println(); } else { out.println(); } - + } if( addressPointer == null ) { if( totalSizeRwx > 0 && totalSize != totalSizeRwx) { @@ -169,7 +169,7 @@ public void run(String command, String[] args, IContext context, PrintStream out } out.printf("Total size: 0x%1$x (%1$,d) bytes\n", totalSize); } - + } private static int cmp(long n1, long n2) { @@ -181,7 +181,7 @@ private static int cmp(long n1, long n2) { return -1; } } - + private class SizeComparator implements Comparator { public int compare(ImageSection o1, ImageSection o2) { @@ -190,7 +190,7 @@ public int compare(ImageSection o1, ImageSection o2) { return cmp(s1,s2); } } - + private class AddressComparator implements Comparator { public int compare(ImageSection o1, ImageSection o2) { @@ -202,7 +202,7 @@ public int compare(ImageSection o1, ImageSection o2) { @Override public void printDetailedHelp(PrintStream out) { - out.println("outputs a list of all memory segments in the address space\n\n" + + out.println("outputs a list of all memory segments in the address space\n\n" + "parameters: none, an address in memory, sort flags, verbose output\n\n" + "If no address is specified outputs a list all memory segments (ImageSections) " + "in the address space with start address, size and properties\n" + @@ -210,7 +210,6 @@ public void printDetailedHelp(PrintStream out) { " or " + Utils.SORT_BY_SIZE_FLAG + " flags.\n" + "If " + Utils.VERBOSE_FLAG + " is specified then each memory segment is followed by any further detailed information." + "If an address is specified then just the memory segment containing that address is output.\n" - ); - + ); } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoProcCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoProcCommand.java index fbf82a3f55c..425b5ea5eda 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoProcCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoProcCommand.java @@ -45,10 +45,10 @@ @DTFJPlugin(version="1.*", runtime=false) public class InfoProcCommand extends BaseJdmpviewCommand { { - addCommand("info process", "", "displays threads, command line arguments, environment"); + addCommand("info process", "", "displays threads, command line arguments, environment"); addCommand("info proc", "", "shortened form of info process"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -59,7 +59,7 @@ public void run(String command, String[] args, IContext context, PrintStream out } printAddressSpaceInfo(); } - + private void printAddressSpaceInfo() { ImageAddressSpace ias = ctx.getAddressSpace(); @@ -72,7 +72,7 @@ private void printAddressSpaceInfo() } out.print("\n"); } - + private void printProcessInfo() { out.print("\n"); @@ -98,11 +98,11 @@ private void printProcessID() { out.print(Exceptions.getDataUnavailableString()); } catch (CorruptDataException e) { out.print(Exceptions.getCorruptDataExceptionString()); - + } out.print("\n"); } - + private void printJITOptions() { try { if(ctx.getRuntime().isJITEnabled()) { @@ -122,7 +122,7 @@ private void printJITOptions() { out.println("\t JIT options not supported by this implementation of DTFJ"); } } - + private void printThreads() { ImageProcess ip = ctx.getProcess(); @@ -137,9 +137,9 @@ private void printThreads() { Object next = itThread.next(); if (next instanceof CorruptData) { - out.print("\n\t "); - continue; - } + out.print("\n\t "); + continue; + } ImageThread it = (ImageThread)next; try { @@ -163,7 +163,7 @@ private void printCommandLine() { ImageProcess ip = ctx.getProcess(); out.print("\t Command line:\n\t "); - + try { String commandLine = ip.getCommandLine(); if (null == commandLine) @@ -203,13 +203,13 @@ private void printCommandLine() } out.print("\n"); } - + private void printEnvironmentVariables() { ImageProcess ip = ctx.getProcess(); out.print("\t Environment variables:"); out.print("\n"); - + Properties variables; try { variables = ip.getEnvironment(); @@ -220,7 +220,7 @@ private void printEnvironmentVariables() out.print("\t " + Exceptions.getDataUnavailableString() + "\n"); return; } - + Enumeration keys = variables.propertyNames(); while (keys.hasMoreElements()) { @@ -228,24 +228,23 @@ private void printEnvironmentVariables() printVariableInfo(key, variables.getProperty(key)); } } - + private void printVariableInfo(String key, String value) { out.print("\t " + key + "=" + value + "\n"); } - + @Override public void printDetailedHelp(PrintStream out) { out.println("displays process ID, threads, command line arguments and environment " + - "variables for the current process\n\n" + - - "parameters: none\n\n" + - "prints the following information about the current process\n\n" + - " - process ID for the process and thread IDs for all its threads\n" + - " - the command line arguments and JVM init arguments it's using\n" + - " - its environment variables\n\n" + - "note: to view the shared libraries used by a process, use the " + - "\"info mod\" command\n" -); + "variables for the current process\n\n" + + "parameters: none\n\n" + + "prints the following information about the current process\n\n" + + " - process ID for the process and thread IDs for all its threads\n" + + " - the command line arguments and JVM init arguments it's using\n" + + " - its environment variables\n\n" + + "note: to view the shared libraries used by a process, use the " + + "\"info mod\" command\n" + ); } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoSymCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoSymCommand.java index 4bbb4e5fa05..bbc8f5c5700 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoSymCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoSymCommand.java @@ -56,7 +56,7 @@ public class InfoSymCommand extends BaseJdmpviewCommand { addCommand("info sym", "", "an alias for 'mod'"); //this is kept for backwards compatibility addCommand("info mod", "", "outputs module information"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -109,7 +109,7 @@ private void listModules(String moduleName) { iLibs = null; out.println(Exceptions.getCorruptDataExceptionString()); } - + // iterate through the libraries while (null != iLibs && iLibs.hasNext()) { Object next = iLibs.next(); @@ -147,7 +147,7 @@ private void printModule(ImageModule imageModule, boolean printSymbols) { } catch (CorruptDataException cde) { out.print("\t " + Exceptions.getCorruptDataExceptionString()); } - + try { String addressInHex = String.format("0x%x",imageModule.getLoadAddress()); out.print(" @ " + addressInHex); @@ -158,9 +158,9 @@ private void printModule(ImageModule imageModule, boolean printSymbols) { } Iterator itSection = imageModule.getSections(); - + if (itSection.hasNext()) { - out.print(", sections:\n"); + out.print(", sections:\n"); } else { out.print(", \n"); } @@ -217,7 +217,7 @@ private boolean checkModuleName(final String name, String moduleName) { boolean wildCardStart = false; boolean wildCardEnd = false; - + moduleName = moduleName.trim(); if (moduleName.startsWith("*")) { wildCardStart = true; @@ -245,10 +245,9 @@ private boolean checkModuleName(final String name, } return false; } - + @Override public void printDetailedHelp(PrintStream out) { out.println(longDesc); - } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoSystemCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoSystemCommand.java index e615db906a6..71fa1148309 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoSystemCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/infocommands/InfoSystemCommand.java @@ -43,9 +43,9 @@ public class InfoSystemCommand extends BaseJdmpviewCommand { { addCommand("info sys", "", "shortened form of info system"); - addCommand("info system", "", "displays information about the system the core dump is from"); + addCommand("info system", "", "displays information about the system the core dump is from"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -56,7 +56,7 @@ public void run(String command, String[] args, IContext context, PrintStream out } doCommand(); } - + public void doCommand(){ try { out.println("\nMachine OS:\t" + ctx.getImage().getSystemType()); @@ -81,18 +81,18 @@ public void doCommand(){ out.println("Machine IP address(es):"); try { - Iterator itIPAddresses = ctx.getImage().getIPAddresses(); + Iterator itIPAddresses = ctx.getImage().getIPAddresses(); while (itIPAddresses.hasNext()) { - Object addr = itIPAddresses.next(); + Object addr = itIPAddresses.next(); if (addr instanceof InetAddress) { out.println("\t\t" + ((InetAddress)addr).getHostAddress()); } else if (addr instanceof CorruptData) { out.println("\t\tdata corrupted"); - } + } } } catch (DataUnavailable du) { out.println("\t\tdata unavailable"); - } + } try { out.println("System memory:\t" + ctx.getImage().getInstalledMemory()); } catch (DataUnavailable exc) { @@ -111,7 +111,7 @@ public void doCommand(){ } catch (DataUnavailable d) { out.println("\nDump creation time: data unavailable"); } - + // Dump creation time - nanotime - added in DTFJ 1.12 try { long createTimeNanos = ctx.getImage().getCreationTimeNanos(); @@ -178,7 +178,7 @@ public void doCommand(){ kernelSettingPrinted = true; } } - + out.println(); } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetCommand.java index 20b97728c4a..fef86c60263 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetCommand.java @@ -29,7 +29,7 @@ @DTFJPlugin(version="1.*", runtime=false) public class SetCommand extends SimpleRedirectorCommand { - private static final String CMD_NAME = "set"; + private static final String CMD_NAME = "set"; { addCommand(CMD_NAME, "[logging|heapdump]", "Sets options for the specified command"); @@ -44,5 +44,5 @@ public void printDetailedHelp(PrintStream out) { protected String getCmdName() { return CMD_NAME; } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetHeapdumpCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetHeapdumpCommand.java index 8c700eea1c1..b0986806a01 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetHeapdumpCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetHeapdumpCommand.java @@ -35,7 +35,7 @@ public class SetHeapdumpCommand extends BaseJdmpviewCommand { private static final String SHORT_DESCRIPTION = "configures heapdump format, filename and multiple heap support"; private static final String COMMAND_NAME = "set heapdump"; - private static final String LONG_DESCRIPTION = "parameters: [phd|txt], [file ], [multiplefiles on|off]\n\n" + private static final String LONG_DESCRIPTION = "parameters: [phd|txt], [file ], [multiplefiles on|off]\n\n" + "[phd|txt] - the format for the heapdump. Default: phd.\n" + "[file ] - the file to write the heapdump to. Default: .phd or .txt.\n\n" + "[multiplefiles on|off] - if set to on, multiple heaps are written to separate heapdumps. If set to off, multiple heaps are written " + @@ -43,9 +43,9 @@ public class SetHeapdumpCommand extends BaseJdmpviewCommand + "Use \"show heapdump\" to see current settings.\n"; { - addCommand(COMMAND_NAME, "", SHORT_DESCRIPTION); + addCommand(COMMAND_NAME, "", SHORT_DESCRIPTION); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -54,48 +54,48 @@ public void run(String command, String[] args, IContext context, PrintStream out out.println("\"set heapdump\" requires at least one parameter\n"); return; } - + String arg1 = args[0]; - + if(arg1.equalsIgnoreCase("phd")) { HeapDumpSettings.setPHDHeapDumps(ctx.getProperties()); - + out.print("Heapdump format set to PHD\n"); } else if (arg1.equalsIgnoreCase("txt")){ HeapDumpSettings.setClassicHeapDumps(ctx.getProperties()); - + out.print("Heapdump format set to classic (TXT)\n"); } else if (arg1.equalsIgnoreCase("file")) { if(args.length == 1) { out.println("\"set heapdump file\" requires at least one parameter\n"); return; } - + if(args.length > 2) { out.println("\"set heapdump file\" accepts 1 parameter. You supplied " + (args.length - 1) + ".\n"); return; } - + String filename = args[1]; - + String originalFileName = HeapDumpSettings.getFileName(ctx.getProperties()); - + HeapDumpSettings.setFileName(filename, ctx.getProperties()); - + out.print("Heapdump file changed from " + originalFileName + " to " + filename + "\n"); } else if (arg1.equalsIgnoreCase("multiplefiles")) { if(args.length == 1) { out.println("\"set heapdump multiplefiles\" requires one parameter: on or off\n"); return; } - + if(args.length > 2) { out.println("\"set heapdump multiplefiles\" requires one parameter: on or off. You suppled " + (args.length - 1) + " parameters\n"); return; } - + String setting = args[1]; - + if(setting.equalsIgnoreCase("on")) { out.println("Multiple heaps will be dumped into multiple heapdumps"); HeapDumpSettings.setMultipleHeapsMultipleFiles(ctx.getProperties()); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetLoggingCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetLoggingCommand.java index dfa1e93c9da..7be8dd43f6c 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetLoggingCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/setcommands/SetLoggingCommand.java @@ -43,13 +43,13 @@ public class SetLoggingCommand extends BaseJdmpviewCommand { public static final String LOG_STATE_OVERWRITE = "set_logging_overwrite"; //indicates the current setting for overwriting log files public static final String LOG_STATE_LOGGING = "set_logging"; //indicates if logging is on or off public static final String LOG_STATE_FILE = "current_logging_file"; //file logging is being or will be written to - + private static final String CMD = "set logging"; private static final String SUBCMD_ON = "on"; private static final String SUBCMD_OFF = "off"; private static final String SUBCMD_FILE = "file"; private static final String SUBCMD_OVERWRITE = "overwrite"; - + private boolean isOverwriteEnabled = false; private boolean isLoggingEnabled = false; private File logFile = null; @@ -60,7 +60,7 @@ private enum SubCommand { off(SUBCMD_OFF, "", "turn off logging"), file(SUBCMD_FILE, "", "turn on logging"), overwrite(SUBCMD_OVERWRITE, "", "controls the overwriting of log files"); - + private final String name; private final String params; private final String help; @@ -70,11 +70,11 @@ private SubCommand(String name, String params, String help) { this.help = help; } } - + { addCommand(CMD, "", "configures several logging-related parameters, starts/stops logging"); for(SubCommand sub : SubCommand.values()) { - addSubCommand(CMD, sub.name, sub.params, sub.help); + addSubCommand(CMD, sub.name, sub.params, sub.help); } } @@ -133,7 +133,7 @@ public void run(String command, String[] args, IContext context, PrintStream out out.println("\"" + args[0] + "\" is not a valid parameter for the \"set logging\" command"); } } - + //restores the state of the logging command from the context property bag private void restoreState() { isOverwriteEnabled = parseBoolean(ctx.getProperties().get(LOG_STATE_OVERWRITE)); @@ -143,7 +143,7 @@ private void restoreState() { logFile = Utils.absPath(ctx.getProperties(), file); } } - + //allows boolean 'true' to be either 'true' or 'on' private boolean parseBoolean(Object obj) { if(obj == null) { @@ -167,7 +167,7 @@ private void setOverwrite(boolean enabled) { ctx.getProperties().put(LOG_STATE_OVERWRITE, state); out.println("overwriting of log file option changed to \"" + state + "\""); } - + private void setLogging(boolean enabled) { if (!(isLoggingEnabled ^ enabled)) { out.println("Command ignored : logging already has this setting"); @@ -188,7 +188,7 @@ private void setLogging(boolean enabled) { } isLoggingEnabled = enabled; } - + private boolean isLogFileValid() { if(logFile.exists()) { if(logFile.isDirectory()) { @@ -209,7 +209,7 @@ private boolean isLogFileValid() { } return true; } - + private void setDefaultLogFile() { Calendar cal = Calendar.getInstance(); String filename = String.format("jdmpview.%1$tY%1$tm%1$td.%1$tH%1$tM%1$tS.txt", cal); @@ -217,8 +217,8 @@ private void setDefaultLogFile() { out.println("to change this type 'set logging off' then specify a file with 'set logging file '"); setLogFile(filename); } - - private void setLogFile(String filename) { + + private void setLogFile(String filename) { if (null != logFile) { if(isLoggingEnabled) { setLogging(false); @@ -230,15 +230,15 @@ private void setLogFile(String filename) { // test whether the file name is an absolute path File test = new File(filename); if (test.isAbsolute()) { - logFile = new File(filename); + logFile = new File(filename); } else { - File pwd = (File)ctx.getProperties().get(SessionProperties.PWD_PROPERTY); - logFile = new File(pwd.getPath() + File.separator + filename); + File pwd = (File)ctx.getProperties().get(SessionProperties.PWD_PROPERTY); + logFile = new File(pwd.getPath() + File.separator + filename); } ctx.getProperties().put(LOG_STATE_FILE, logFile.getAbsolutePath()); } } - + private void openLogFile() { FileWriter f; try { @@ -253,7 +253,7 @@ private void openLogFile() { ToolsRegistryOutputChannels.addChannel(fileChannel); out.println("logging turned on; outputting to \"" + logFile.getAbsolutePath() + "\""); } - + private void closeLogFile() { ToolsRegistryOutputChannels.removeChannel(fileChannel); out.println("logging turned off; was logging to \"" + logFile + "\""); @@ -264,7 +264,7 @@ private void closeLogFile() { public void printDetailedHelp(PrintStream out) { out.println("configures several logging-related parameters, " + "starts/stops logging\n\n" + - + "parameters: [on|off], file , overwrite [on|off]\n" + "- [on|off] - turns logging on or off (default: off)\n" + "- file - sets the file to log to; this will be relative " + @@ -277,7 +277,7 @@ public void printDetailedHelp(PrintStream out) { "this is on, the log file will be cleared every time \"set logging " + "on\" is run (default: off)\n" ); - + } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowCommand.java index d62acfc15d2..2e120972afa 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowCommand.java @@ -29,12 +29,12 @@ @DTFJPlugin(version="1.*", runtime=false) public class ShowCommand extends SimpleRedirectorCommand { - private static final String CMD_NAME = "show"; + private static final String CMD_NAME = "show"; { addCommand(CMD_NAME, "[logging|heapdump]", "Displays the current set options for a command"); } - + @Override public void printDetailedHelp(PrintStream out) { out.println("Show the options for the specified command"); @@ -44,5 +44,5 @@ public void printDetailedHelp(PrintStream out) { protected String getCmdName() { return CMD_NAME; } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowHeapdumpCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowHeapdumpCommand.java index c6179d0a8f1..600545f319e 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowHeapdumpCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowHeapdumpCommand.java @@ -40,9 +40,9 @@ public class ShowHeapdumpCommand extends BaseJdmpviewCommand + "Use \"set heapdump\" to change settings\n"; { - addCommand(COMMAND_NAME, "", COMMAND_DESCRIPTION); + addCommand(COMMAND_NAME, "", COMMAND_DESCRIPTION); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -51,20 +51,19 @@ public void run(String command, String[] args, IContext context, PrintStream out out.println("\"show heapdump\" does not take any parameters."); return; } - + out.print("Heapdump Settings:\n\n"); - + out.print("\tFormat: " + (HeapDumpSettings.areHeapDumpsPHD(ctx.getProperties()) ? "PHD" : "Classic (TXT)") + "\n"); out.print("\tFile Name: " + HeapDumpSettings.getFileName(ctx.getProperties()) + "\n"); - out.print("\tMultiple heaps will be written to " - + (HeapDumpSettings.multipleHeapsInMultipleFiles(ctx.getProperties()) ? "multiple files":"a single file") + out.print("\tMultiple heaps will be written to " + + (HeapDumpSettings.multipleHeapsInMultipleFiles(ctx.getProperties()) ? "multiple files":"a single file") + "\n"); } - @Override public void printDetailedHelp(PrintStream out) { out.println(LONG_DESCRIPTION); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowLoggingCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowLoggingCommand.java index 949563642bd..513a3a1ef25 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowLoggingCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/showcommands/ShowLoggingCommand.java @@ -34,9 +34,9 @@ public class ShowLoggingCommand extends BaseJdmpviewCommand { { - addCommand("show logging", "", "shows the current logging options"); + addCommand("show logging", "", "shows the current logging options"); } - + public void run(String command, String[] args, IContext context, PrintStream out) throws CommandException { if(initCommand(command, args, context, out)) { return; //processing already handled by super class @@ -50,7 +50,7 @@ public void run(String command, String[] args, IContext context, PrintStream out } doCommand(); } - + public void doCommand(){ out.print("Logging is currently turned "); String value = (String)ctx.getProperties().get(SetLoggingCommand.LOG_STATE_LOGGING); @@ -73,7 +73,7 @@ public void doCommand(){ out.println(value); } } - + @Override public void printDetailedHelp(PrintStream out) { out.println("displays the current values of logging settings\n\n" + diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XCommand.java index 8a0b7646f90..faa2d97ad95 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XCommand.java @@ -30,26 +30,26 @@ import com.ibm.jvm.dtfjview.commands.BaseJdmpviewCommand; /** - * Abstract superclass for all x/ commands + * Abstract superclass for all x/ commands */ public abstract class XCommand extends BaseJdmpviewCommand { protected int argUnitSize = 1; protected int argUnitNumber = 1; protected String argDisplayFormat = ""; - + // note: do NOT add any of the following: // - XBCommand // - XHCommand // - XWCommand // - XGCommand - + // why not? because 'b', 'h', 'w', and 'g' represent unit sizes and // the parser won't know whether you mean a unit size or a display format // if you use any of the above characters for a display format /* (non-Javadoc) * @see com.ibm.java.diagnostics.commands.BaseCommand#recognises(java.lang.String, com.ibm.java.diagnostics.IContext) - * + * * Override this because this command needs to implement wild card matching of any command that starts x/ */ @Override @@ -71,16 +71,16 @@ public void run(String command, String[] args, IContext context, PrintStream out } doCommand(args); } - + protected abstract void doCommand(String[] args); - + protected void parseArgs(String arg) { - + int n; Character unitSize; Character displayFormat; - + if (null == arg || arg.equals("")) { // user didn't specify any parameters; use the defaults @@ -95,15 +95,15 @@ protected void parseArgs(String arg) for (i = 0; i < arg.length() && Character.isDigit(arg.charAt(i)); i++) { n *= 10; - n += Character.getNumericValue(arg.charAt(i)); + n += Character.getNumericValue(arg.charAt(i)); } - + if (0 == n) n = 1; - + displayFormat = null; unitSize = null; - + if (i < arg.length()) { char currChar = arg.charAt(i); @@ -121,7 +121,7 @@ protected void parseArgs(String arg) } i++; } - + if (i < arg.length()) { char currChar = arg.charAt(i); @@ -159,7 +159,7 @@ protected void parseArgs(String arg) } i++; } - + if (arg.length() != i) { out.println("too many letters after \"x/\"; the \"x/\" command accepts at " + @@ -167,28 +167,28 @@ protected void parseArgs(String arg) "size character"); return; } - + // we now have all the necessary information to put on the stack (except // for the unspecified parameters that assume use of defaults) so let's // get the required default values and push some parameters back on to // the argument stack - + if (null == unitSize) { unitSize = getDefaultUnitSize(ctx.getProperties()); } else { setDefaultUnitSize(ctx.getProperties(), unitSize); } - + if (null == displayFormat) { displayFormat = getDefaultDisplayFormat(ctx.getProperties()); } else { setDefaultDisplayFormat(ctx.getProperties(), displayFormat); } } - + int nUnitSize = 1; char cUnitSize = unitSize.charValue(); - + switch (cUnitSize) { case 'b': @@ -208,8 +208,8 @@ protected void parseArgs(String arg) argUnitSize = nUnitSize; // add the unit size to the stack argUnitNumber = n; // add the number of units to print to the stack - argDisplayFormat = displayFormat.toString(); // add the display format as a String - + argDisplayFormat = displayFormat.toString(); // add the display format as a String + } private Character getDefaultUnitSize(Properties properties) @@ -220,7 +220,7 @@ private Character getDefaultUnitSize(Properties properties) else return defaultUnitSize; } - + private Character getDefaultDisplayFormat(Properties properties) { Character defaultDisplayFormat = (Character)properties.get("x_default_display_format"); @@ -229,12 +229,12 @@ private Character getDefaultDisplayFormat(Properties properties) else return defaultDisplayFormat; } - + private void setDefaultUnitSize(Properties properties, Character defaultUnitSize) { properties.put("x_default_unit_size", defaultUnitSize); } - + private void setDefaultDisplayFormat(Properties properties, Character defaultDisplayFormat) { properties.put("x_default_display_format", defaultDisplayFormat); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XDCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XDCommand.java index 08f74af9e86..ec371ed4eb0 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XDCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XDCommand.java @@ -34,9 +34,9 @@ @DTFJPlugin(version="1.*", runtime=false) public class XDCommand extends XCommand { { - addCommand("x/d", "", "displays the integer at the specified address"); + addCommand("x/d", "", "displays the integer at the specified address"); } - + @Override public boolean recognises(String command, IContext context) { if(super.recognises(command, context)) { @@ -49,7 +49,7 @@ public void doCommand(String[] args) { String param = args[0]; Long address; - + address = Utils.longFromStringWithPrefix(param); if (null == address) { @@ -60,19 +60,19 @@ public void doCommand(String[] args) out.print("\n"); boolean found = false; - + for (int index = 0; index < argUnitNumber; index++) { - + long currAddr = address.longValue() + (index * argUnitSize); - + out.print("\t"); out.print(Utils.toHex(currAddr)); out.print(": "); - + ImageAddressSpace ias = ctx.getAddressSpace(); ImagePointer ip = ias.getPointer(currAddr); - + byte b = 0; short s = 0; int i = 0; @@ -93,7 +93,7 @@ public void doCommand(String[] args) l = ip.getLongAt(0); break; } - + found = true; } catch (CorruptDataException e) { found = false; @@ -121,7 +121,7 @@ public void doCommand(String[] args) } out.print("\n"); } - + if (!found) { out.print("

        "); @@ -140,5 +140,5 @@ public void printDetailedHelp(PrintStream out) { "it by the \"x/\" command.\n" ); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XJCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XJCommand.java index 9152a20c49a..ddd230a07fb 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XJCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XJCommand.java @@ -42,7 +42,7 @@ @DTFJPlugin(version="1.*", runtime=false) public class XJCommand extends XCommand { { - addCommand("x/j", " | ", "displays information about a particular object or all objects of a class"); + addCommand("x/j", " | ", "displays information about a particular object or all objects of a class"); } @Override @@ -52,7 +52,7 @@ public boolean recognises(String command, IContext context) { } return false; } - + public void doCommand(String[] args) { boolean supers = false; @@ -88,26 +88,26 @@ else if (option.equals("nosuper")) } printHeapObjects(objAddress, objName, out, supers); - + } - + private void printHeapObjects(Long objAddress, String objName, PrintStream out, boolean supers) { - JavaRuntime jr = ctx.getRuntime(); + JavaRuntime jr = ctx.getRuntime(); JavaHeap jh; Iterator itHeap = jr.getHeaps(); int count = 1; - + while (itHeap.hasNext()) { Object obj = itHeap.next(); if(obj instanceof JavaHeap) { jh = (JavaHeap)obj; - + out.print("\t heap #" + count + " - name: "); out.print(jh.getName()); out.print("\n\n"); - + printObjects(jh, objAddress, objName, out, supers, jr); count++; } else { @@ -115,7 +115,7 @@ private void printHeapObjects(Long objAddress, String objName, } } } - + private void printObjects(JavaHeap jh, Long objAddress, String objName, PrintStream out, boolean supers, JavaRuntime jr) { if( objName != null ) { @@ -124,7 +124,7 @@ private void printObjects(JavaHeap jh, Long objAddress, String objName, PrintStr printObjectsFromAddress(jh, objAddress, out, jr); } } - + private void printObjectsFromName(JavaHeap jh, String objName, PrintStream out, boolean supers, JavaRuntime jr) { @@ -132,10 +132,10 @@ private void printObjectsFromName(JavaHeap jh, String objName, PrintStream out, if (objName != null) { JavaClass[] classes = Utils.getClassGivenName(objName, jr, out); - + // if we couldn't find a class of that name, return; the passed in class name could // still be an array type or it might not exist - if( classes == null || classes.length == 0 ) { + if( classes == null || classes.length == 0 ) { out.print("\t could not find class with name \"" + objName + "\"\n\n"); return; } @@ -154,7 +154,7 @@ private void printObjectsFromName(JavaHeap jh, String objName, PrintStream out, if(obj instanceof CorruptData) { //skip the corrupt object corruptObjectCount++; - continue; + continue; } JavaObject jo = (JavaObject)obj; String hierarchy = ""; @@ -196,7 +196,7 @@ private void printObjectsFromName(JavaHeap jh, String objName, PrintStream out, out.print(" @ "); out.print(Utils.toHex(jo.getID().getAddress())); out.print("\n"); - + ClassOutput.printFields(jo, jc, jr, out); printReferences(jo, out); } else { @@ -233,9 +233,9 @@ private void printObjectsFromAddress(JavaHeap jh, Long objAddress, PrintStream o JavaObject jo; Iterator itObject = jh.getObjects(); boolean found = false; - + boolean done = false; - + int corruptObjectCount = 0; while (itObject.hasNext() && !done) { @@ -243,11 +243,10 @@ private void printObjectsFromAddress(JavaHeap jh, Long objAddress, PrintStream o if(obj instanceof CorruptData) { //skip the corrupt object corruptObjectCount++; - continue; + continue; } - - jo = (JavaObject)obj; + jo = (JavaObject)obj; if (jo.getID().getAddress() == objAddress.longValue()) { @@ -276,7 +275,7 @@ private void printObjectsFromAddress(JavaHeap jh, Long objAddress, PrintStream o out.print(" @ "); out.print(Utils.toHex(objAddress.longValue())); out.print("\n"); - + ClassOutput.printFields(jo, jc, jr, out); printReferences(jo, out); @@ -295,14 +294,13 @@ private void printObjectsFromAddress(JavaHeap jh, Long objAddress, PrintStream o out.println("\t Warning : " + corruptObjectCount + " corrupt objects were skipped\n"); } } - - + @Override public void printDetailedHelp(PrintStream out) { super.printDetailedHelp(out); out.println("displays information about a particular object or all " + "objects of a class\n\n" + - + "parameters: 0x | [super | nosuper]\n\n" + "If given class name, all static fields with their values will be " + "printed, followed by all objects of that class with their fields " + @@ -316,26 +314,26 @@ public void printDetailedHelp(PrintStream out) { "to it by the \"x/\" command.\n\n" ); } - + /** - * Print the references from the given object. Omit the first reference: this is always a reference to the - * object's class. + * Print the references from the given object. Omit the first reference: this is always a reference to the + * object's class. */ public static void printReferences(JavaObject jo, PrintStream out) { Iterator references = jo.getReferences(); - if (references.hasNext()) { + if (references.hasNext()) { references.next(); // reference to the class, ignore this one } if ( ! references.hasNext()) { out.print("\t references: \n "); - out.print("\t "); + out.print("\t "); } else { out.print("\t references:\n "); out.print("\t "); while (references.hasNext()) { Object potential_reference = references.next(); if (potential_reference instanceof JavaReference) { - JavaReference reference = (JavaReference) potential_reference; + JavaReference reference = (JavaReference) potential_reference; try { Object target = reference.getTarget(); if (target instanceof JavaObject) { diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XKCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XKCommand.java index 93bdc17344f..a74b26e6c49 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XKCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XKCommand.java @@ -43,9 +43,9 @@ @DTFJPlugin(version="1.*", runtime=false) public class XKCommand extends XCommand { { - addCommand("x/k", "", "displays the specified memory section as if it were a stack frame parameters"); + addCommand("x/k", "", "displays the specified memory section as if it were a stack frame parameters"); } - + @Override public boolean recognises(String command, IContext context) { if(super.recognises(command, context)) { @@ -53,37 +53,37 @@ public boolean recognises(String command, IContext context) { } return false; } - + public void doCommand(String[] args) { String param = args[0]; - + Long address = Utils.longFromStringWithPrefix(param); - + if (null == address) { out.println("invalid hex address specified; address must be specified as " + "\"0x\""); return; } - + ImageAddressSpace ias = ctx.getAddressSpace(); int pointerSize = getIASPointerSize(ias); int unitSize; - + if (pointerSize > 32) unitSize = 8; else unitSize = 4; - + out.print("\n"); - + for (int index = 0; index < argUnitNumber; index++) { boolean found = false; long currAddr = address.longValue() + (index * unitSize); ImagePointer ip = ias.getPointer(currAddr); - + out.print("\t"); out.print(Utils.toHex(currAddr)); out.print(" "); @@ -100,14 +100,14 @@ public void doCommand(String[] args) if (found) { long pointer = l; - + out.print(toAdjustedHex(l, pointerSize)); out.print(" "); if (31 == pointerSize) { pointer = (int)(pointer & (((long)1) << pointerSize) - 1); } - + if (printSymbol(pointer, l - currAddr, pointerSize)) { } else if (printStackPointer(pointer, l - currAddr, pointerSize, ias)) { } @@ -116,10 +116,10 @@ public void doCommand(String[] args) out.print("
        \n"); } } - + out.print("\n"); } - + private boolean printSymbol(long pointer, long diff, int pointerSize) { ImageProcess ip = ctx.getProcess(); @@ -140,7 +140,7 @@ private boolean printSymbol(long pointer, long diff, int pointerSize) ImageSection is = (ImageSection)itImageSection.next(); long startAddr = is.getBaseAddress().getAddress(); long endAddr = startAddr + is.getSize(); - + if (pointer >= startAddr && pointer < endAddr) { /* can we find a matching symbol? */ long maxDifference = pointer - startAddr; @@ -156,7 +156,7 @@ private boolean printSymbol(long pointer, long diff, int pointerSize) bestSymbol = symbol; } } - + try { out.print(im.getName()); } catch (CorruptDataException e) { @@ -170,7 +170,7 @@ private boolean printSymbol(long pointer, long diff, int pointerSize) } out.print("+"); out.print(Long.toString(maxDifference)); - + // if we find the address in the symbols, there's no need to continue // trying to find it elsewhere in the address space return true; @@ -180,10 +180,10 @@ private boolean printSymbol(long pointer, long diff, int pointerSize) } return false; } - + private boolean printStackPointer(long pointer, long diff, int pointerSize, ImageAddressSpace ias) { - if (Math.abs(diff) <= 4096) { + if (Math.abs(diff) <= 4096) { if (diff < 0) { out.print(" ."); out.print(Long.toString(diff)); @@ -195,7 +195,7 @@ private boolean printStackPointer(long pointer, long diff, int pointerSize, Imag } return false; } - + private int getIASPointerSize(ImageAddressSpace ias) { return ((ImageProcess)ias.getProcesses().next()).getPointerSize(); @@ -234,5 +234,4 @@ public void printDetailedHelp(PrintStream out) { "it by the \"x/\" command, but ignores the unit size.\n"); } - } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XXCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XXCommand.java index d442c0f3dd1..e838d475422 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XXCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/commands/xcommands/XXCommand.java @@ -35,9 +35,9 @@ @DTFJPlugin(version="1.*", runtime=false) public class XXCommand extends XCommand { { - addCommand("x/x", "", "displays the hex value of the bytes at the specified address"); + addCommand("x/x", "", "displays the hex value of the bytes at the specified address"); } - + @Override public boolean recognises(String command, IContext context) { if(super.recognises(command, context)) { @@ -45,7 +45,7 @@ public boolean recognises(String command, IContext context) { } return false; } - + public void doCommand(String[] args) { Long address; @@ -59,19 +59,19 @@ public void doCommand(String[] args) } out.print("\n"); - + boolean found = false; for (int index = 0; index < argUnitNumber; index++) { long currAddr = address.longValue() + (index * argUnitSize); - + out.print("\t"); out.print(Utils.toHex(currAddr)); out.print(": "); ImageAddressSpace ias = ctx.getAddressSpace(); ImagePointer ip = ias.getPointer(currAddr); - + byte b = 0; short s = 0; int i = 0; @@ -92,7 +92,7 @@ public void doCommand(String[] args) l = ip.getLongAt(0); break; } - + found = true; } catch (CorruptDataException e) { found = false; @@ -120,13 +120,13 @@ public void doCommand(String[] args) } out.print("\n"); } - + if (!found) { out.print("
        "); } out.print("\n"); - + } @Override @@ -141,5 +141,5 @@ public void printDetailedHelp(PrintStream out) { "it by the \"x/\" command.\n" ); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/HeapDumpFormatter.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/HeapDumpFormatter.java index 0e38196c60c..892e402d6de 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/HeapDumpFormatter.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/HeapDumpFormatter.java @@ -27,18 +27,18 @@ /** * Abstract class to decouple the formatting of heapdumps from the walking of * the internal data structures that hold the source data. - * + * * @author andhall - * + * */ public abstract class HeapDumpFormatter { - protected final String _version; + protected final String _version; protected final boolean _is64Bit; /** * Constructor - * + * * @param version JVM version information to be included in heapdump header * @param is64Bit True if we are dumping a 64 bit image, false otherwise */ @@ -50,7 +50,7 @@ protected HeapDumpFormatter(String version,boolean is64Bit) /** * Adds a class to the heapdump. - * + * * @param address * Address of class * @param name @@ -73,7 +73,7 @@ public abstract void addClass(long address, String name, /** * Adds an object to the heapdump. - * + * * @param address * Address of object * @param classAddress @@ -94,10 +94,10 @@ public abstract void addObject(long address, long classAddress, /** * Adds a primitive array object to the heapdump - * + * * Type code is: 0 - bool, 1 - char, 2 - float, 3 - double, 4 - byte, 5 - short, 6 - * int, 7 - long - * + * * @param address * Address of object * @param arrayClassAddress @@ -121,7 +121,7 @@ public abstract void addPrimitiveArray(long address, long arrayClassAddress, int /** * Adds an object array to the heapdump. - * + * * @param address * Address of object * @param arrayClassAddress @@ -147,10 +147,10 @@ public abstract void addObjectArray(long address, long arrayClassAddress, String arrayClassName, long elementClassAddress, String elementClassName, long size, int numberOfElements, int hashCode, ReferenceIterator references) throws IOException; - + /** * Closes the heapdump - * + * * @throws IOException */ public abstract void close() throws IOException; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/HeapDumpSettings.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/HeapDumpSettings.java index 5b9838d9fb1..05180569d98 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/HeapDumpSettings.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/HeapDumpSettings.java @@ -30,42 +30,42 @@ /** * Encapsulates the marshalling and unmarshalling of heapdump * settings through the properties map. - * + * * @author andhall * */ public class HeapDumpSettings { public static final String HEAP_DUMP_FILE_PROPERTY = "heap_dump_file"; - public static final String HEAP_DUMP_FORMAT_PROPERTY = "heap_dump_format"; + public static final String HEAP_DUMP_FORMAT_PROPERTY = "heap_dump_format"; public static final String MULTIPLE_HEAPS_MULTIPLE_FILES_PROPERTY = "heap_dump_multiple_heaps_multiple_files"; public static final String HEAP_DUMP_RUNTIME_ID = "heap_dump_runtime_id"; - - public static void setFileName(String fileName,Map properties) + + public static void setFileName(String fileName,Map properties) { properties.put(HEAP_DUMP_FILE_PROPERTY, fileName); } - + /** * Returns the filename to use for writing out a heap dump, either based - * on what the user has set or by generating the default name based on the + * on what the user has set or by generating the default name based on the * image name */ public static String getFileName(Map properties) { String propertyFileName = (String) properties.get(HEAP_DUMP_FILE_PROPERTY); - + if(propertyFileName != null) { return propertyFileName; } else { return getDefaultHeapDumpFileName(properties); } } - + public static boolean heapDumpFileNameSet(Map properties) { return properties.containsKey(HEAP_DUMP_FILE_PROPERTY); } - + private static String getDefaultHeapDumpFileName(Map properties) { String baseFileName = (String) properties.get(SessionProperties.CORE_FILE_PATH_PROPERTY); @@ -73,30 +73,30 @@ private static String getDefaultHeapDumpFileName(Map properties) if( runtimeID == null ) { runtimeID = ""; } - + if(areHeapDumpsPHD(properties)) { return baseFileName + runtimeID +".phd"; } else { return baseFileName + runtimeID +".txt"; } } - + public static void setClassicHeapDumps(Map properties) { properties.put(HEAP_DUMP_FORMAT_PROPERTY, "classic"); } - - public static boolean areHeapDumpsPHD(Map properties) + + public static boolean areHeapDumpsPHD(Map properties) { Object formatValue = properties.get(HEAP_DUMP_FORMAT_PROPERTY); - + if(formatValue != null && formatValue.equals("classic")) { return false; } else { return true; } } - + public static void setPHDHeapDumps(Map properties) { properties.put(HEAP_DUMP_FORMAT_PROPERTY, "phd"); @@ -106,20 +106,20 @@ public static void setMultipleHeapsMultipleFiles(Map properties) { properties.put(MULTIPLE_HEAPS_MULTIPLE_FILES_PROPERTY, "true"); } - + public static void setMultipleHeapsSingleFile(Map properties) { properties.put(MULTIPLE_HEAPS_MULTIPLE_FILES_PROPERTY, "false"); } - + public static void setRuntimeID(Map properties, int id) { properties.put(HEAP_DUMP_RUNTIME_ID, "." + id); } - + public static boolean multipleHeapsInMultipleFiles(Map properties) { Object multipleFilesValue = properties.get(MULTIPLE_HEAPS_MULTIPLE_FILES_PROPERTY); - + if(multipleFilesValue == null) { return false; } else { diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/LongArrayReferenceIterator.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/LongArrayReferenceIterator.java index 55b969303e3..e22221cc425 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/LongArrayReferenceIterator.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/LongArrayReferenceIterator.java @@ -22,11 +22,11 @@ */ package com.ibm.jvm.dtfjview.heapdump; -public class LongArrayReferenceIterator implements ReferenceIterator +public class LongArrayReferenceIterator implements ReferenceIterator { private final long _fields[]; private int _index = 0; - + public LongArrayReferenceIterator(long[] fields) { if(fields != null) { _fields = fields; @@ -34,7 +34,7 @@ public LongArrayReferenceIterator(long[] fields) { _fields = new long[0]; } } - + public boolean hasNext() { return _index < (_fields.length); @@ -43,9 +43,9 @@ public boolean hasNext() public Long next() { Long toReturn = Long.valueOf(_fields[_index]); - + _index++; - + return toReturn; } @@ -53,5 +53,5 @@ public void reset() { _index = 0; } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/LongListReferenceIterator.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/LongListReferenceIterator.java index 93999b3e201..c4410faa583 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/LongListReferenceIterator.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/LongListReferenceIterator.java @@ -25,23 +25,22 @@ import java.util.Iterator; import java.util.List; - /** * Reference iterator based on a list of Longs. - * + * * @author andhall */ public class LongListReferenceIterator implements ReferenceIterator { private final List _data; private Iterator _currentIterator; - - public LongListReferenceIterator(List data) + + public LongListReferenceIterator(List data) { _data = data; reset(); } - + public boolean hasNext() { return _currentIterator.hasNext(); @@ -56,5 +55,5 @@ public void reset() { _currentIterator = _data.iterator(); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/ReferenceIterator.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/ReferenceIterator.java index be3ccca1688..38707667eeb 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/ReferenceIterator.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/ReferenceIterator.java @@ -24,7 +24,7 @@ /** * Type-safe, resettable iterator for references. - * + * * @author andhall * */ @@ -32,20 +32,20 @@ public interface ReferenceIterator { /** - * + * * @return True if next() will return non-null, * false otherwise. */ public boolean hasNext(); - + /** - * + * * @return Next reference */ public Long next(); - + /** - * Resets the iterator back to the start of the + * Resets the iterator back to the start of the * structure it is iterating. Iterator will behave * as if it has just been constructed */ diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/classic/ClassicHeapDumpFormatter.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/classic/ClassicHeapDumpFormatter.java index 68758cec7cc..c21036efb33 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/classic/ClassicHeapDumpFormatter.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/classic/ClassicHeapDumpFormatter.java @@ -32,9 +32,9 @@ /** * A formatter for classic heap dumps. - * + * * Format specification is in the diagnostic guide. - * + * * @author andhall * */ @@ -43,7 +43,7 @@ public class ClassicHeapDumpFormatter extends HeapDumpFormatter private static final String EOF_HEADER = "// EOF: Total 'Objects',Refs(null) :"; private static final String BREAKDOWN_HEADER = "// Breakdown - Classes:"; private static final String VERSION_HEADER = "// Version: "; - + // Using a BufferedWriter rather than a PrintWriter because a BufferedWriter preserves IOExceptions while providing newLine(). private final BufferedWriter _out; private int _classCount = 0; @@ -54,18 +54,18 @@ public class ClassicHeapDumpFormatter extends HeapDumpFormatter private int _referenceCount = 0; private int _nullReferenceCount = 0; private boolean _closed = false; - + private boolean is64bit = false; - + public ClassicHeapDumpFormatter(Writer out,String version,boolean is64bit) throws IOException { super(version,is64bit); _out = new BufferedWriter(out); this.is64bit = is64bit; - + writeHeader(); } - + private void writeHeader() throws IOException { _out.write(VERSION_HEADER + _version); @@ -83,59 +83,59 @@ private void writeReferences(ReferenceIterator references) throws IOException _out.newLine(); return; } - + StringBuffer referenceString = new StringBuffer(); referenceString.append("\t"); - + boolean first = true; - + while(references.hasNext()) { Long thisRef = references.next(); - + if(first) { first = false; } else { referenceString.append(" "); } - + referenceString.append(toHexString(thisRef.longValue())); - + _referenceCount++; if(thisRef.longValue() == 0) { _nullReferenceCount++; } } - - referenceString.append(" "); // the classic heapdump from the JVM has a blank on the end of each line + + referenceString.append(" "); // the classic heapdump from the JVM has a blank on the end of each line _out.write(referenceString.toString()); _out.newLine(); } - + private String toHexString(long value) { //Fast-path for 0 if(value == 0) { return "0x0"; } - - if (is64bit) { + + if (is64bit) { return "0x" + String.format("%016X",value); - } else { + } else { return "0x" + String.format("%08X",value); } } - + public void addClass(long address, String name, long superClassAddress, int size, long instanceSize, int hashCode, ReferenceIterator references) throws IOException { checkClosed(); - + _out.write(toHexString(address) + " [" + size + "] CLS " + name); _out.newLine(); - + writeReferences(references); - + _classCount++; _allObjectCount++; } @@ -153,16 +153,16 @@ private void writeEntry(long address, long size,String className,ReferenceIterat _out.newLine(); writeReferences(references); - + _allObjectCount++; } - + public void addObject(long address, long classAddress, String className, int size, int hashCode, ReferenceIterator references) throws IOException { checkClosed(); - + writeEntry(address,size,className,references); } @@ -171,11 +171,11 @@ public void addObject(long address, long classAddress, String className, */ private static ReferenceIterator addReference(final ReferenceIterator original, final long extra) - { - return new ReferenceIterator(){ + { + return new ReferenceIterator() { private boolean _returnedExtra = false; - + public boolean hasNext() { if(_returnedExtra) { @@ -208,9 +208,9 @@ public void addObjectArray(long address, long arrayClassAddress, int hashCode, ReferenceIterator references) throws IOException { checkClosed(); - + writeEntry(address,size,arrayClassName,references); - + _objectArraysCount++; } @@ -219,11 +219,11 @@ public void addPrimitiveArray(long address, long arrayClassAddress, int type, lo IllegalArgumentException { checkClosed(); - + ReferenceIterator references = new LongArrayReferenceIterator(new long[]{}); - + writeEntry(address,size,getPrimitiveArrayName(type),references); - + _primitiveArraysCount++; } @@ -252,27 +252,27 @@ private String getPrimitiveArrayName(int type) } public void close() throws IOException - { + { printBreakdown(); - + printEOFSummary(); - + _out.close(); - + _closed = true; } private void printEOFSummary() throws IOException { StringBuffer buffer = new StringBuffer(EOF_HEADER); - + buffer.append(_allObjectCount); buffer.append(","); buffer.append(_referenceCount); buffer.append("("); buffer.append(_nullReferenceCount); buffer.append(")"); - + _out.write(buffer.toString()); _out.newLine(); } @@ -280,19 +280,19 @@ private void printEOFSummary() throws IOException private void printBreakdown() throws IOException { int objectsCount = ((_allObjectCount - _primitiveArraysCount) - _objectArraysCount) - _classCount; - + StringBuffer buffer = new StringBuffer(BREAKDOWN_HEADER); buffer.append(_classCount); - + buffer.append(", Objects:"); buffer.append(objectsCount); - + buffer.append(", ObjectArrays:"); buffer.append(_objectArraysCount); - + buffer.append(", PrimitiveArrays:"); buffer.append(_primitiveArraysCount); - + _out.write(buffer.toString()); _out.newLine(); } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ClassRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ClassRecord.java index 56609f0836e..062c0c35843 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ClassRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ClassRecord.java @@ -29,7 +29,7 @@ /** * Object representing a PHD ClassRecord - * + * * @author andhall * */ @@ -37,19 +37,19 @@ public class ClassRecord extends PortableHeapDumpRecord { private final String _className; private final long _superClassAddress; - private final long _instanceSize; + private final long _instanceSize; private final int _hashCode; private final boolean _is64Bit; private final boolean _is32BitHash; - + protected ClassRecord(long address, long previousAddress, String className, long superClassAddress, long instanceSize, int hashCode, boolean is64Bit, ReferenceIterator references, boolean is32BitHash) { super(address, previousAddress, references); - + this._className = className; this._superClassAddress = superClassAddress; - + this._instanceSize = instanceSize; this._is64Bit = is64Bit; this._hashCode = hashCode; @@ -59,38 +59,38 @@ protected ClassRecord(long address, long previousAddress, String className, long protected void writeHeapDump(DataOutput out) throws IOException { out.writeByte(PortableHeapDumpFormatter.CLASS_RECORD_TAG); - + byte flag = 0; flag |= _gapSize << 6; flag |= _referenceFieldSize << 4; if (_is32BitHash && _hashCode != 0) { // JVM 2.6 and later, 32-bit optional hashcodes flag |= (byte) 0x08; // set 0x08 flag if the class record includes a hashcode } - + out.writeByte(flag); - + writeReference(out,_gapSize,_gapPreceding); out.writeInt((int)_instanceSize); // instance size became a long for defect 176753, when DTFJ interface changed to 1.6 - + if (_is32BitHash) { // JVM 2.6 and later, write optional 32-bit hashcode if (_hashCode != 0) { out.writeInt(_hashCode); } - } else { // JVM prior to 2.6, all objects have a 16-bit hashcode + } else { // JVM prior to 2.6, all objects have a 16-bit hashcode out.writeShort(_hashCode); } - + if(_is64Bit) { out.writeLong(_superClassAddress); } else { out.writeInt((int)_superClassAddress); } - + out.writeUTF(_className); - + out.writeInt(_numberOfReferences); - + writeReferences(out); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/LongObjectRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/LongObjectRecord.java index 53bef4e3eca..19a5de7a52c 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/LongObjectRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/LongObjectRecord.java @@ -28,36 +28,36 @@ import com.ibm.jvm.dtfjview.heapdump.ReferenceIterator; public class LongObjectRecord extends ObjectRecord -{ +{ private final byte _tag; private final boolean _is64Bit; - + public LongObjectRecord(long address, long previousAddress, long classAddress, int hashCode, ReferenceIterator references, boolean is64Bit, boolean is32BitHash) { this(PortableHeapDumpFormatter.LONG_OBJECT_RECORD_TAG,address,previousAddress,classAddress,hashCode,references,is64Bit,is32BitHash); } - + /** * Alternative constructor for use by object array record - the structure of that record is - * essentially identical with a different tag. + * essentially identical with a different tag. */ protected LongObjectRecord(byte tag,long address, long previousAddress, long classAddress, int hashCode, ReferenceIterator references, boolean is64Bit, boolean is32BitHash) { super(address,previousAddress,classAddress,hashCode,references,is32BitHash); - + _tag = tag; - + _is64Bit = is64Bit; } protected void writeHeapDump(DataOutput out) throws IOException { out.writeByte(_tag); - + byte flag = 0; flag |= _gapSize << 6; flag |= _referenceFieldSize << 4; @@ -68,17 +68,17 @@ protected void writeHeapDump(DataOutput out) throws IOException } else { // JVM prior to 2.6, all objects have a 16-bit hashcode flag |= (byte) 0x01; } - + out.writeByte(flag); - + writeReference(out,_gapSize,_gapPreceding); - + if(_is64Bit){ out.writeLong(_classAddress); } else { out.writeInt((int)_classAddress); } - + if (_is32BitHash) { // JVM 2.6 and later, optional 32-bit hashcode if (_hashCode != 0) { out.writeInt(_hashCode); @@ -86,10 +86,10 @@ protected void writeHeapDump(DataOutput out) throws IOException } else { // JVM prior to 2.6 VM, all objects have a 16-bit hashcode out.writeShort(_hashCode); } - + out.writeInt(_numberOfReferences); - + writeReferences(out); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/LongPrimitiveArrayRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/LongPrimitiveArrayRecord.java index 1d81d981705..558cf51aed1 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/LongPrimitiveArrayRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/LongPrimitiveArrayRecord.java @@ -26,26 +26,26 @@ import java.io.IOException; public class LongPrimitiveArrayRecord extends PortableHeapDumpRecord -{ +{ private final int _type; private final int _numberOfElements; private final int _hashCode; private final boolean _is64Bit; private final long _instanceSize; private final boolean _is32BitHash; - + public LongPrimitiveArrayRecord(long address, long previousAddress, int type, int numberOfElements, int hashCode, boolean is64Bit, long instanceSize, boolean is32BitHash) { super(address,previousAddress,null); - + this._type = type; this._numberOfElements = numberOfElements; this._hashCode = hashCode; this._is64Bit = is64Bit; this._instanceSize = instanceSize; this._is32BitHash = is32BitHash; - + if(type < 0 || type > 7) { throw new IllegalArgumentException("Unrecognised type code: " + type); } @@ -54,31 +54,31 @@ public LongPrimitiveArrayRecord(long address, long previousAddress, int type, in protected void writeHeapDump(DataOutput out) throws IOException { out.writeByte(PortableHeapDumpFormatter.LONG_PRIMITIVE_ARRAY_RECORD_TAG); - + byte flag = 0; flag |= _type << 5; - + byte arrayLengthSize = PortableHeapDumpRecord.sizeofReference(_numberOfElements); - + if(arrayLengthSize < _gapSize) { arrayLengthSize = _gapSize; } - + if(arrayLengthSize != ONE_BYTE_REF) { flag |= 1 << 4; } - + //Set flag for moved & hashed - flag |= 1 << 1; - + flag |= 1 << 1; + out.writeByte(flag); - + if(arrayLengthSize > ONE_BYTE_REF) { - if(_is64Bit){ + if(_is64Bit){ out.writeLong(_gapPreceding); out.writeLong(_numberOfElements); } - else { + else { out.writeInt((int)_gapPreceding); out.writeInt(_numberOfElements); } @@ -86,15 +86,15 @@ protected void writeHeapDump(DataOutput out) throws IOException out.writeByte((byte)_gapPreceding); out.writeByte(_numberOfElements); } - + if (_is32BitHash) { // JVM 2.6 and later, 32-bit hashcode out.writeInt(_hashCode); } else { // JVM prior to 2.6, 16-bit hashcode out.writeShort(_hashCode); } - - // instance size is held in the PHD since PHD version 6 - // divide the size by 4 and write into the datastream as an + + // instance size is held in the PHD since PHD version 6 + // divide the size by 4 and write into the datastream as an // unsigned int to make it possible to encode up to 16GB out.writeInt((int)(_instanceSize / 4)); } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/MediumObjectRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/MediumObjectRecord.java index 08df74586e6..7330054244e 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/MediumObjectRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/MediumObjectRecord.java @@ -28,40 +28,40 @@ import com.ibm.jvm.dtfjview.heapdump.ReferenceIterator; public class MediumObjectRecord extends ObjectRecord -{ +{ private final boolean _is64Bit; - + public MediumObjectRecord(long address, long previousAddress, long classAddress, int hashCode, ReferenceIterator references, boolean is64Bit, boolean is32BitHash) { super(address,previousAddress,classAddress,hashCode,references,is32BitHash); - + _is64Bit = is64Bit; } - + protected void writeHeapDump(DataOutput out) throws IOException { byte tagAndFlag = PortableHeapDumpFormatter.MEDIUM_OBJECT_RECORD_TAG; tagAndFlag |= _numberOfReferences << 3; tagAndFlag |= _gapSize << 2; tagAndFlag |= _referenceFieldSize; - + out.writeByte(tagAndFlag); writeReference(out,_gapSize,_gapPreceding); - + if(_is64Bit) { out.writeLong(_classAddress); - } else { - out.writeInt((int)_classAddress); + } else { + out.writeInt((int)_classAddress); } - - // JVMs prior to 2.6 have a 16-bit hashcode for all objects, which is added to all PHD records. - if (!_is32BitHash) { + + // JVMs prior to 2.6 have a 16-bit hashcode for all objects, which is added to all PHD records. + if (!_is32BitHash) { out.writeShort(_hashCode); } // Note: JVM 2.6 and later have optional 32-bit hashcodes. We use a LongObjectRecord if the hashcode was set. - + writeReferences(out); } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ObjectArrayRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ObjectArrayRecord.java index 04aea86556b..469ff1cb960 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ObjectArrayRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ObjectArrayRecord.java @@ -29,14 +29,14 @@ /** * Record representing an object array. - * + * * As of PHD v5 this contains a number of elements record on the * end of the LongObjectRecord structure * @author andhall * */ public class ObjectArrayRecord extends LongObjectRecord -{ +{ private final int _numberOfElements; private final long _instanceSize; @@ -55,8 +55,8 @@ protected void writeHeapDump(DataOutput out) throws IOException super.writeHeapDump(out); out.writeInt(_numberOfElements); - // instance size is held in the PHD since PHD version 6 - // divide the size by 4 and write into the datastream as an + // instance size is held in the PHD since PHD version 6 + // divide the size by 4 and write into the datastream as an // unsigned int to make it possible to encode up to 16GB out.writeInt((int)(_instanceSize / 4)); } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ObjectRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ObjectRecord.java index ba75cfc682d..dc61c5c9355 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ObjectRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ObjectRecord.java @@ -26,10 +26,10 @@ /** * Object record. - * + * * Base class for anything that looks like an object (has a classAddress, a size and a hashcode * in addition to the address, previousAddress and references required to be a PortableHeapDumpRecord). - * + * * @author andhall * */ @@ -38,13 +38,13 @@ public abstract class ObjectRecord extends PortableHeapDumpRecord protected final int _hashCode; protected final long _classAddress; protected final boolean _is32BitHash; - + protected ObjectRecord(long address, long previousAddress, long classAddress, int hashCode, ReferenceIterator references, boolean is32BitHash) { super(address, previousAddress, references); - + this._hashCode = hashCode; this._classAddress = classAddress; this._is32BitHash = is32BitHash; @@ -54,7 +54,7 @@ protected static boolean isShortObjectEligible(long current, long previous) { long addressDifference = PortableHeapDumpRecord.getAddressDifference(current, previous); return ( addressDifference < Short.MAX_VALUE && addressDifference > Short.MIN_VALUE ); } - + /** * Static factory method to pick the appropriate * factory method @@ -64,7 +64,7 @@ public static ObjectRecord getObjectRecord(long address, long previousAddress, l ReferenceIterator references, PortableHeapDumpClassCache cache, boolean is64Bit, boolean is32BitHash) { byte classCacheIndex = cache.getClassCacheIndex(classAddress); - + if (classCacheIndex == -1 || previousAddress == 0) { cache.setClassCacheIndex(classAddress); return new LongObjectRecord(address,previousAddress,classAddress,hashCode,references,is64Bit,is32BitHash); @@ -74,8 +74,8 @@ public static ObjectRecord getObjectRecord(long address, long previousAddress, l return new LongObjectRecord(address,previousAddress,classAddress,hashCode,references,is64Bit,is32BitHash); } else if (isShortObjectEligible(address,previousAddress)) { int numberOfReferences = countReferences(references); - - if (numberOfReferences <= 3) { + + if (numberOfReferences <= 3) { //this is a short object return new ShortObjectRecord(address,previousAddress,classAddress,hashCode,references,classCacheIndex,is32BitHash); } else if (numberOfReferences < 8) { @@ -86,7 +86,7 @@ public static ObjectRecord getObjectRecord(long address, long previousAddress, l cache.setClassCacheIndex(classAddress); return new LongObjectRecord(address,previousAddress,classAddress,hashCode,references,is64Bit,is32BitHash); } - } else { + } else { //address difference is bigger than Short.MAX_VALUE doublewords. cache.setClassCacheIndex(classAddress); return new LongObjectRecord(address,previousAddress,classAddress,hashCode,references,is64Bit,is32BitHash); @@ -96,14 +96,14 @@ public static ObjectRecord getObjectRecord(long address, long previousAddress, l private static int countReferences(ReferenceIterator references) { int count = 0; - + references.reset(); - + while(references.hasNext()) { references.next(); count++; } - + return count; } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpClassCache.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpClassCache.java index 3e7d8a1bf44..38137ca68bf 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpClassCache.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpClassCache.java @@ -24,7 +24,7 @@ /** * @author schan - * + * * Object representing the PHD class cache. A compression mechanism * based around assigning numbers to the last 4 class addresses * written out in full. @@ -32,7 +32,7 @@ public class PortableHeapDumpClassCache { public static final int CLASSCACHE_SIZE = 4; - + private final long _classCache[] = new long[CLASSCACHE_SIZE]; private byte _classIndex = 0; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpFormatter.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpFormatter.java index dcb0febebcc..f54758369f6 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpFormatter.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpFormatter.java @@ -30,9 +30,9 @@ /** * A formatter for Portable heap dumps (PHDs). - * + * * Format documented here: http://w3.hursley.ibm.com/~dgriff/newphd.html - * + * * @author andhall * */ @@ -61,7 +61,7 @@ public class PortableHeapDumpFormatter extends HeapDumpFormatter public static final byte OBJECT_ARRAY_RECORD_TAG = 8; public static final byte PRIMITIVE_ARRAY_RECORD_TAG = (byte) 0x20; public static final byte LONG_PRIMITIVE_ARRAY_RECORD_TAG = 7; - + private final DataOutputStream _out; private final PortableHeapDumpClassCache _classCache = new PortableHeapDumpClassCache(); private final boolean _is32BitHash; @@ -70,26 +70,26 @@ public class PortableHeapDumpFormatter extends HeapDumpFormatter */ private long _lastAddress = 0; private boolean _closed = false; - + public PortableHeapDumpFormatter(DataOutputStream output,String version,boolean is64Bit, boolean is32BitHash) throws IOException { super(version,is64Bit); - + _out = output; _is32BitHash = is32BitHash; - + writeHeader(); } private void writeHeader() throws IOException { PortableHeapDumpHeader header = new PortableHeapDumpHeader(_version,_is64Bit,_is32BitHash); - + header.writeHeapDump(_out); } - + private void checkClosed() - { + { if(_closed) { throw new UnsupportedOperationException("Dump is closed"); } @@ -99,11 +99,11 @@ public void addClass(long address, String name, long superClassAddress, int size, long instanceSize, int hashCode, ReferenceIterator references) throws IOException { checkClosed(); - + ClassRecord record = new ClassRecord(address,_lastAddress, name,superClassAddress,instanceSize, hashCode, _is64Bit, filterNullReferences(references),_is32BitHash); - + record.writeHeapDump(_out); - + _lastAddress = address; } @@ -113,7 +113,7 @@ public void addObject(long address, long classAddress, String className, ObjectRecord record = ObjectRecord.getObjectRecord(address, _lastAddress, classAddress, hashCode, filterNullReferences(references), _classCache, _is64Bit,_is32BitHash); record.writeHeapDump(_out); - + _lastAddress = address; } @@ -123,9 +123,9 @@ public void addObjectArray(long address, long arrayClassAddress, int hashCode, ReferenceIterator references) throws IOException { ObjectArrayRecord record = new ObjectArrayRecord(address,_lastAddress,elementClassAddress,hashCode,numberOfElements,filterNullReferences(references),_is64Bit,size,_is32BitHash); - + record.writeHeapDump(_out); - + _lastAddress = address; } @@ -145,53 +145,53 @@ record = new PrimitiveArrayRecord(address,_lastAddress,type,numberOfElements,has record = new PrimitiveArrayRecord(address,_lastAddress,type,numberOfElements,hashCode,_is64Bit, size, _is32BitHash); } record.writeHeapDump(_out); - + _lastAddress = address; } public void close() throws IOException { _closed = true; - + _out.writeByte(END_OF_DUMP_TAG); - + _out.close(); } - + /** * Removes null references from the reference iterator - as required by PHD spec. - * + * * Returned value wraps input, so operations on the returned value affect the state of input. */ - private static ReferenceIterator filterNullReferences(final ReferenceIterator input) + private static ReferenceIterator filterNullReferences(final ReferenceIterator input) { return new ReferenceIterator() { private Long next; - + public boolean hasNext() { while(next == null && input.hasNext()) { Long potential = input.next(); - + if(potential.longValue() != 0) { next = potential; } } - + return next != null; } - + public Long next() { if(! hasNext()) { return null; } - + Long toReturn = next; next = null; - + return toReturn; } @@ -200,7 +200,7 @@ public void reset() input.reset(); next = null; } - + }; } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpHeader.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpHeader.java index 39a4c54d9b7..4c7f387ede7 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpHeader.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpHeader.java @@ -25,7 +25,6 @@ import java.io.DataOutput; import java.io.IOException; - /** * @author andhall * @@ -35,22 +34,22 @@ public class PortableHeapDumpHeader { private final String _version; private final boolean _is64Bit; private final boolean _is32BitHash; - - public PortableHeapDumpHeader(String version, boolean is64Bit, boolean is32BitHash) + + public PortableHeapDumpHeader(String version, boolean is64Bit, boolean is32BitHash) { _version = version; _is64Bit = is64Bit; _is32BitHash = is32BitHash; } - public int writeHeapDump(DataOutput dos) throws IOException + public int writeHeapDump(DataOutput dos) throws IOException { - dos.writeUTF(PortableHeapDumpFormatter.MAGIC_STRING); + dos.writeUTF(PortableHeapDumpFormatter.MAGIC_STRING); dos.writeInt(PortableHeapDumpFormatter.PHD_VERSION_NUMBER); //Flags about dump int headerFlag = 0; - + if (_is64Bit) { headerFlag = PortableHeapDumpFormatter.IS_64_BIT_HEADER_FLAG; } @@ -66,10 +65,10 @@ public int writeHeapDump(DataOutput dos) throws IOException dos.writeByte(PortableHeapDumpFormatter.START_OF_HEADER_TAG); dos.writeByte(PortableHeapDumpFormatter.FULL_VERSION_TAG); dos.writeUTF(_version); - + dos.writeByte(PortableHeapDumpFormatter.END_OF_HEADER_TAG); dos.writeByte(PortableHeapDumpFormatter.START_OF_DUMP_TAG); return 0; } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpRecord.java index adbe1486cab..eab0296e74b 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PortableHeapDumpRecord.java @@ -29,11 +29,11 @@ /** * Base class for all PHD records. - * + * * Contains logic common to relative-addressed entities with references - * + * * @author andhall - * + * */ public abstract class PortableHeapDumpRecord { @@ -58,7 +58,7 @@ public abstract class PortableHeapDumpRecord /** * Constructor - * + * * @param baseAddress * The address to base the relative reference addresses from * @param references @@ -68,7 +68,7 @@ protected PortableHeapDumpRecord(long address, long previousAddress, ReferenceIterator references) { _baseAddress = address; - + if(references != null) { _references = getDifferenceReferences(references, address); _referenceFieldSize = calculateReferenceFieldSize(references); @@ -76,7 +76,7 @@ protected PortableHeapDumpRecord(long address, long previousAddress, _references = null; _referenceFieldSize = 0; } - + _gapPreceding = getAddressDifference(address,previousAddress); _gapSize = sizeofReference(_gapPreceding); } @@ -84,11 +84,11 @@ protected PortableHeapDumpRecord(long address, long previousAddress, private byte calculateReferenceFieldSize(ReferenceIterator references) { byte toReturn = ONE_BYTE_REF; - + references.reset(); - + _numberOfReferences = 0; - + while (references.hasNext()) { Long thisRef = references.next(); @@ -97,7 +97,7 @@ private byte calculateReferenceFieldSize(ReferenceIterator references) if (thisSize > toReturn) { toReturn = thisSize; } - + _numberOfReferences++; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PrimitiveArrayRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PrimitiveArrayRecord.java index 1647d10075e..709ff4d1154 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PrimitiveArrayRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/PrimitiveArrayRecord.java @@ -33,19 +33,19 @@ public class PrimitiveArrayRecord extends PortableHeapDumpRecord private final boolean _is64Bit; private final long _instanceSize; private final boolean _is32BitHash; - + public PrimitiveArrayRecord(long address, long previousAddress, int type, int numberOfElements, int hashCode, boolean is64Bit, long instanceSize, boolean is32BitHash) { super(address,previousAddress,null); - + this._type = type; this._numberOfElements = numberOfElements; this._hashCode = hashCode; this._is64Bit = is64Bit; this._instanceSize = instanceSize; this._is32BitHash = is32BitHash; - + if(type < 0 || type > 7) { throw new IllegalArgumentException("Unrecognised type code: " + type); } @@ -55,27 +55,27 @@ protected void writeHeapDump(DataOutput out) throws IOException { byte tagAndFlag = PortableHeapDumpFormatter.PRIMITIVE_ARRAY_RECORD_TAG; tagAndFlag |= _type << 2; - + byte arrayLengthSize = PortableHeapDumpRecord.sizeofReference(_numberOfElements); // Array length size and gap size in this record have to be the same, so use the larger byte fieldSize = arrayLengthSize > _gapSize ? arrayLengthSize : _gapSize; tagAndFlag |= fieldSize; - + out.writeByte(tagAndFlag); - + // Write the address delta (gap) writeReference(out, fieldSize,_gapPreceding); // Write the array length writeReference(out, fieldSize, arrayLengthSize); - + // JVMs prior to 2.6 have a 16-bit hashcode for all objects, which is added to all PHD records if (!_is32BitHash) { out.writeShort(_hashCode); } // Note: JVM 2.6 and later have optional 32-bit hashcodes. We use a LongPrimitiveArrayRecord if the hashcode was set - - // Instance size is held in the PHD since PHD version 6 - // divide the size by 4 and write into the datastream as an + + // Instance size is held in the PHD since PHD version 6 + // divide the size by 4 and write into the datastream as an // unsigned int to make it possible to encode up to 16GB out.writeInt((int)(_instanceSize / 4)); } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ShortObjectRecord.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ShortObjectRecord.java index 27a9f8bc3e6..50884e05a27 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ShortObjectRecord.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/heapdump/portable/ShortObjectRecord.java @@ -28,15 +28,15 @@ import com.ibm.jvm.dtfjview.heapdump.ReferenceIterator; public class ShortObjectRecord extends ObjectRecord -{ +{ private final byte _classCacheIndex; - + public ShortObjectRecord(long address, long previousAddress, long classAddress, int hashCode, ReferenceIterator references, byte classCacheIndex, boolean is32BitHash) { super(address,previousAddress,classAddress,hashCode,references,is32BitHash); - + _classCacheIndex = classCacheIndex; } @@ -47,17 +47,17 @@ protected void writeHeapDump(DataOutput out) throws IOException tagAndFlag |= _numberOfReferences << 3; tagAndFlag |= _gapSize << 2; tagAndFlag |= _referenceFieldSize; - + out.writeByte(tagAndFlag); writeReference(out,_gapSize,_gapPreceding); - + // JVMs prior to 2.6 have a 16-bit hashcode for all objects, which is added to all PHD records. if (!_is32BitHash) { out.writeShort(_hashCode); } // Note: JVM 2.6 and later have optional 32-bit hashcodes. We use a LongObjectRecord if the hashcode was set. - + writeReferences(out); } - + } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ICombinedContext.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ICombinedContext.java index 31419547e20..ace1d0582b3 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ICombinedContext.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ICombinedContext.java @@ -26,9 +26,9 @@ /** * A combined context is an extended DTFJ context which also contains a DDR context. - * This is to allow commands to be passed down the stack starting with DTFJ and then + * This is to allow commands to be passed down the stack starting with DTFJ and then * moving to DDR if necessary. - * + * * @author adam * */ @@ -38,7 +38,7 @@ public interface ICombinedContext extends IDTFJContext { * Contexts have a unique positive numeric identifier within a session. This number always * increases if new contexts are created via the open command rather than attempting to re-use * any already used IDs. - * + * * @return the ID for this context */ public int getID(); @@ -47,38 +47,38 @@ public interface ICombinedContext extends IDTFJContext { * Sets the numeric ID for this context. This setter is provided so as to allow context creation * before assigning the ID. However once set it should not be changed. Later implementations may * enforce this. - * + * * @param id the context ID */ public void setID(int id); /** * A handle to the underlying DDR interactive session - * + * * @return a valid session or null if the core file is not DDR enabled */ public Object getDDRIObject(); /** * Get the exception which was thrown when trying to start a DDR interactive session. - * + * * @return the exception or null if the session started without error. */ public Throwable getDDRStartupException(); /** * Display the contexts which are present in the core file currently being analysed. - * + * * @param shortFormat true for short format which just displays the first line of the java -version string */ public void displayContext(IOutputManager out, boolean shortFormat); /** * Called when this context becomes the current context to allow - * any initialisation to take place. + * any initialisation to take place. */ public void setAsCurrent(); - + /** * Flag to indicate if an associated DDR context is available as well as the DTFJ one. * @return true if DDR is available diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/IOutputChannel.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/IOutputChannel.java index 89a77ae1bd0..58ea1dd2a32 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/IOutputChannel.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/IOutputChannel.java @@ -25,7 +25,7 @@ /** * An output channel provides a mechanism by which text will be displayed * to the user. - * + * * @author adam * */ @@ -33,7 +33,7 @@ public interface IOutputChannel { /** * Sends text to channel - * + * * @param outputString text to send */ public void print(String outputString); @@ -42,18 +42,18 @@ public interface IOutputChannel { * Sets the prompt which should be displayed when an interactive session * is running. Typically this will display the context number in a * multi-context environment. - * + * * @param prompt prompt to display. */ public void printPrompt(String prompt); /** * Sends text to the channel with an appended \n - * + * * @param outputString text to send */ public void println(String outputString); - + /** * Instructs this channel to close and free any resources. Once closed a channel * cannot be re-opened. @@ -61,7 +61,7 @@ public interface IOutputChannel { public void close(); /** - * Causes the channel to flush any buffered text. Depending upon the channel + * Causes the channel to flush any buffered text. Depending upon the channel * implementation this may not have any effect. */ public void flush(); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/IOutputManager.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/IOutputManager.java index a55a6a37301..af3a812a12f 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/IOutputManager.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/IOutputManager.java @@ -24,18 +24,17 @@ import java.io.PrintStream; - /** * The output manager is responsible for managing a collection of registered * output channels. It provides methods to register and remove channels as * well as control buffering. When text is written to the manager then it * is sent to all registered output channels. - * + * * This interface is an extension of IOutputChannel so as to enforce consistency - * between the declarations for printing text to an output channel. The manager - * is in effect acting as a single proxy channel for all of it's individually + * between the declarations for printing text to an output channel. The manager + * is in effect acting as a single proxy channel for all of it's individually * registered channels. - * + * * @author adam * */ @@ -46,13 +45,13 @@ public interface IOutputManager extends IOutputChannel { * to an internal buffer rather than immediately to the underlying output * channels. This is typically used by clients to inspect or intercept the results from * a command before carrying out further processing. - * + * * By default buffering is not enabled. - * + * * @param enabled true turns on buffering */ public void setBuffering(boolean enabled); - + /** * Clears the current buffer contents. */ @@ -60,14 +59,14 @@ public interface IOutputManager extends IOutputChannel { /** * Gets the current buffer contents. - * + * * @return buffer contents */ public String getBuffer(); /** * Adds a channel to the list of registered channels. - * + * * @param channel channel to add. */ public void addChannel(IOutputChannel channel); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ISession.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ISession.java index 65cc4ef2a1a..54f40cf55c1 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ISession.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ISession.java @@ -26,7 +26,7 @@ /** * Represents a single jdmpview session which may contain multiple contexts. - * + * * @author adam * */ @@ -34,28 +34,28 @@ public interface ISession { /** * The instance which is managing all registered output channels. - * + * * @return the manager */ public IOutputManager getOutputManager(); /** * The currently selected context against which commands will be executed. - * + * * @return the current context, it may or may not have DDR interactive support */ public ICombinedContext getCurrentContext(); /** * Get the manager which is managing this context within this session. - * + * * @return the context manager */ public ISessionContextManager getContextManager(); /** * Set the context within which subsequent commands will be executed. - * + * * @param id context ID * @throws CommandException thrown if an invalid context ID is specified */ @@ -63,7 +63,7 @@ public interface ISession { /** * Set the context within which subsequent commands will be executed. - * + * * @param switchTo the context to switch to * @throws CommandException thrown if the switch fails. The underlying reason will be in the logs. */ @@ -71,7 +71,7 @@ public interface ISession { /** * Display the contexts which are present in the core file currently being analysed. - * + * * @param shortFormat true for short format which just displays the first line of the java -version string */ public void showContexts(boolean shortFormat); @@ -82,11 +82,11 @@ public interface ISession { * one it finds with a non-corrupt DTFJ JavaRuntime in it. */ public void findAndSetContextWithJVM(); - + /** - * Executes the supplied command. Output will be written via the IOutputManager to + * Executes the supplied command. Output will be written via the IOutputManager to * all registered channels. - * + * * @param command the command and any parameters to execute. */ public void execute(String command); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ISessionContextManager.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ISessionContextManager.java index 6a6d033905a..27dcff9cf11 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ISessionContextManager.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/spi/ISessionContextManager.java @@ -30,7 +30,7 @@ /** * Controls the creation and deletion of contexts within a session. - * + * * @author adam * */ @@ -40,7 +40,7 @@ public interface ISessionContextManager { * Remove all contexts which have been derived from an image source. * e.g. if there are multiple JVMs in a single core then closing the core * file would result in all images derived from that file also being closed. - * + * * @param image the source image from which derived contexts should be closed. */ public void removeContexts(Image image); @@ -48,7 +48,7 @@ public interface ISessionContextManager { /** * Remove all contexts which have been defined as coming from a specified URI * (note that the URI may or may not be a file URI). - * + * * @param URI the source URI from which derived contexts should be closed. */ public void removeContexts(URI source); @@ -60,7 +60,7 @@ public interface ISessionContextManager { /** * Lists all contexts keyed by the URI from which they were derived. - * + * * @return map of URI's to contexts */ public Map> getContexts(); @@ -68,14 +68,14 @@ public interface ISessionContextManager { /** * Convenience method for determining if more than one context is currently open. It * is a less expensive call than getContexts() - * + * * @return true if more than one context is currently open and available */ public boolean hasMultipleContexts(); /** * Gets the context with the specified ID. - * + * * @param id the context ID * @return the located context or null if it was not found */ diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/CommandException.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/CommandException.java index dbb0ebd890a..b7a7f2736ff 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/CommandException.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/CommandException.java @@ -36,13 +36,16 @@ public class CommandException extends Exception { public CommandException() { super(); } - public CommandException(Throwable cause) { - super(cause); - } - public CommandException(String message) { - super(message); - } - public CommandException(String message, Throwable cause) { - super(message, cause); - } + + public CommandException(Throwable cause) { + super(cause); + } + + public CommandException(String message) { + super(message); + } + + public CommandException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ITool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ITool.java index 00c16d47054..6a80175cf0a 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ITool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ITool.java @@ -35,23 +35,23 @@ public interface ITool { * @throws CommandException */ public boolean start(String [] args, PrintStream out) throws CommandException; - + /** * Closes the tool. */ public void close(); - + /** * Determines if a command is accepted by current tool. *

        * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String [] args); - + /** * Processes the command. *

        @@ -62,26 +62,26 @@ public interface ITool { * @throws CommandException */ public void process(String command, String [] args, PrintStream out) throws CommandException; - + /** * To print the detailed help message. */ - public void printDetailedHelp(PrintStream out); - + public void printDetailedHelp(PrintStream out); + /** * To gets the tool's command name. *

        * @return The tool's command name. */ public String getCommandName(); - + /** * To gets the tool's argument description. *

        * @return The tool's argument description. */ public String getArgumentDescription(); - + /** * To gets the tool's help description. *

        diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ParsedCommand.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ParsedCommand.java index 0fcad7e2ce5..9c13f478cf9 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ParsedCommand.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ParsedCommand.java @@ -33,7 +33,7 @@ * @author Manqing Li, IBM. * */ -public class ParsedCommand +public class ParsedCommand { /** * This is a convenient method to parse a command line. @@ -115,7 +115,7 @@ public String getCombinedCommandLine() { } return sb.toString(); } - + private static String [] separateAndReorganizeTokens(final String line) { ArrayList alTokens = new ArrayList(); StringBuffer sb = new StringBuffer(); @@ -124,14 +124,14 @@ public String getCombinedCommandLine() { while (i < length) { char c = line.charAt(i++); if ('"' == c || '\'' == c) { - // if the next char matches the quotation, we have an empty String here. + // if the next char matches the quotation, we have an empty String here. // We need add the empty String back. if(i < line.length() && c == line.charAt(i)) { sb.append(c).append(c); i++; continue; } - + char quotation = c; while(i < line.length()) { c = line.charAt(i++); @@ -147,7 +147,7 @@ public String getCombinedCommandLine() { } } else if ( '|' == c) { if(sb.length() > 0) { - alTokens.add(sb.toString()); + alTokens.add(sb.toString()); sb = new StringBuffer(); } alTokens.add("|"); @@ -185,7 +185,7 @@ private static ArrayList reorganize(final ArrayList al, int star } break; } - + if (piped) { if (ToolsRegistry.isPipeLineEnabled(token, null) == false) { alNew.add("run"); @@ -199,12 +199,12 @@ private static ArrayList reorganize(final ArrayList al, int star } piped = false; } - + alNew.add(token); } return alNew; } - + private String command; private String [] arguments; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/Tool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/Tool.java index 544fed18d53..afed7f6cb12 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/Tool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/Tool.java @@ -25,7 +25,7 @@ import java.io.PrintStream; public abstract class Tool implements ITool { - + public Tool() { ToolsRegistry.registerTool(this); } @@ -39,8 +39,8 @@ public Tool() { *

        * @throws CommandException */ - public boolean start(String[] args, PrintStream out) - throws CommandException + public boolean start(String[] args, PrintStream out) + throws CommandException { return true; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ToolsRegistry.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ToolsRegistry.java index dcb99f4aec9..a49a1590548 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ToolsRegistry.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/ToolsRegistry.java @@ -46,15 +46,15 @@ */ public class ToolsRegistry { public static void initialize(Session session) { - + ToolsRegistryOutputChannels.initialize(session.getCharset()); - + if (null == registry) { registry = new ToolsRegistry(session); registry.initializeTools(); } } - + /** * To record the command in the history and then execute it. * This method is called only right after the command is typed in from the console. @@ -88,7 +88,7 @@ public static void execute(String command) throws CommandException ParsedCommand parsedCommand = ParsedCommand.parse(command); execute(parsedCommand.getCommand(), parsedCommand.getArguments()); } - + /** * To execute a command with its arguments. * Note: Default print stream will be used. @@ -107,7 +107,7 @@ public static void execute(String command, String [] args) throws CommandExcepti } executeJdmpviewCommand(new ParsedCommand(command, args).getCombinedCommandLine(), out); } - + /** * To execute a command. * Note: this method should not be called directly by any DDR/Jdmpview commands; @@ -122,7 +122,7 @@ public static void process(String command, PrintStream out) throws CommandExcept ParsedCommand parsedCommand = ParsedCommand.parse(command); process(parsedCommand.getCommand(), parsedCommand.getArguments(), out); } - + /** * To execute a command. *

        @@ -134,7 +134,7 @@ public static String process(String command) throws CommandException ParsedCommand parsedCommand = ParsedCommand.parse(command); return process(parsedCommand.getCommand(), parsedCommand.getArguments()); } - + /** * To execute a command. * Note: this method should not be called directly by any DDR/Jdmpview commands; @@ -155,7 +155,7 @@ public static void process(String command, String [] args, PrintStream out) thro } executeJdmpviewCommand(new ParsedCommand(command, args).getCombinedCommandLine(), out); } - + /** * To execute a command. *

        @@ -173,7 +173,7 @@ public static String process(String command, String [] args) throws CommandExcep throw new CommandException(e); } } - + /** * To execute a Jdmpview command. *

        @@ -183,7 +183,7 @@ public static String process(String command, String [] args) throws CommandExcep public static void executeJdmpviewCommand(String jdmpviewCommand, PrintStream out) { registry.session.execute(jdmpviewCommand, out); } - + /** * To check if a command is pipeline enabled. *

        @@ -201,7 +201,7 @@ public static boolean isPipeLineEnabled(String command, String [] args) } return false; } - + /** * To register a tool. *

        @@ -210,7 +210,7 @@ public static boolean isPipeLineEnabled(String command, String [] args) public static void registerTool(ITool tool) { registry.toolList.add(tool); } - + /** * To get all the registered tools. *

        @@ -219,7 +219,7 @@ public static void registerTool(ITool tool) { public static List getAllTools() { return registry.toolList; } - + /** * To initialize the Store object. */ @@ -228,10 +228,10 @@ private ToolsRegistry(Session session) { this.toolList = new ArrayList(); this.charsetName = session.getCharset(); } - + /** * This method is to instantiate all the tools (except the Jdmpview/DDR tool). - * Note: + * Note: * (1) Individual tools have to call ToolsRegistry.registerTool() to register themselves * to the ToolsRegistry. * (2) If a tool such as the Grep tool extends com.ibm.jvm.dtfjview.tools.Tool, the tool @@ -248,7 +248,7 @@ private void initializeTools() { new CmdFileTool(this.charsetName); new TokensTool(); } - + private List toolList; private HistoryTool history; private Session session; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CharsFromTool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CharsFromTool.java index a5cb79309d9..8c5c2ca0446 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CharsFromTool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CharsFromTool.java @@ -48,7 +48,7 @@ public class CharsFromTool extends Tool implements IPipe { * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String[] args) { @@ -126,7 +126,7 @@ private static Arguments processArguments(String[] args) { boolean includeToken = true; boolean keepMismatchedLines = false; boolean ignoreCase = false; - + int x = 0; for (;x < args.length; ++x) { if(args[x].equalsIgnoreCase("-e") || args[x].equalsIgnoreCase("-exclude")) { @@ -139,26 +139,26 @@ private static Arguments processArguments(String[] args) { break; } } - + if (x >= args.length) { return null; } String searchToken = args[x]; ++x; - + if (x >= args.length) { return null; } - + String command = args[x]; ++x; - + String [] commandArgs = new String[args.length - x]; System.arraycopy(args, x, commandArgs, 0, args.length - x); return new Arguments(searchToken, includeToken, keepMismatchedLines, ignoreCase, command, commandArgs); } - + private static final class Arguments { Arguments(String searchToken, boolean includeToken, boolean keepMismatchedLines, boolean ignoreCase, String command, String [] commandArgs) { this.searchToken = ignoreCase ? searchToken.toLowerCase() : searchToken; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CharsToTool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CharsToTool.java index ef03b6bef34..b115fe39f87 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CharsToTool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CharsToTool.java @@ -32,7 +32,7 @@ import com.ibm.jvm.dtfjview.tools.utils.OutputStreamModifier; public class CharsToTool extends Tool implements IPipe { - private static final String COMMAND = "charsTo"; + private static final String COMMAND = "charsTo"; private static final String ARGUMENT_DESCRIPTION = "[options] "; private static final String HELP_DESCRIPTION = "To be used after a pipeline to keep the characters from a line until a specific pattern is found."; private static final String USAGE = COMMAND + "\t" + ARGUMENT_DESCRIPTION + "\t" + HELP_DESCRIPTION + "\n" + @@ -47,7 +47,7 @@ public class CharsToTool extends Tool implements IPipe { * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String[] args) { @@ -127,7 +127,7 @@ private static Arguments processArguments(String[] args) { boolean ignoreCase = false; int x = 0; - + for (; x < args.length; ++x) { if(args[x].equalsIgnoreCase("-include")) { includeToken = true; @@ -149,16 +149,16 @@ private static Arguments processArguments(String[] args) { if (x >= args.length) { return null; } - + String command = args[x]; ++x; - + String [] commandArgs = new String[args.length - x]; System.arraycopy(args, x, commandArgs, 0, args.length - x); return new Arguments(searchToken, includeToken, keepMismatchedLines, ignoreCase, command, commandArgs); } - + private static final class Arguments { Arguments(String searchToken, boolean includeToken, boolean keepMismatchedLines, boolean ignoreCase, String command, String [] commandArgs) { this.searchToken = ignoreCase ? searchToken.toLowerCase() : searchToken; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CmdFileTool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CmdFileTool.java index d74a440edee..698e3d7c213 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CmdFileTool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/CmdFileTool.java @@ -50,7 +50,7 @@ public class CmdFileTool extends Tool { " Empty lines or lines starting with \"//\" or \"#\" will be ignored.\n" + " [charset] : the character set for the commands specified in the command file.\n" + " The character set name must be a supported charset as defined in java.nio.charset.Charset. For example, US-ASCII."; - + public CmdFileTool(String charset) { this.defaultCharset = charset; } @@ -62,7 +62,7 @@ public CmdFileTool(String charset) { *

        * @return The list of commands. *

        - * @throws UnsupportedEncodingException + * @throws UnsupportedEncodingException * @throws IOException */ public static List parseCmdFile(File cmdFile, String charset) throws UnsupportedEncodingException, IOException { @@ -73,21 +73,21 @@ public static List parseCmdFile(File cmdFile, String charset) throws Uns cmd = cmd.trim(); if (cmd.length() > 0 && cmd.startsWith("//") == false - && cmd.startsWith("#") == false) + && cmd.startsWith("#") == false) { commands.add(cmd); } } return commands; } - + /** * Determines if a command is accepted by the current tool. *

        * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String[] args) { @@ -117,7 +117,7 @@ public void process(String command, String[] args, PrintStream out) throws Comma out.println("The specified command file " + file.getAbsolutePath() + " is too large to be read"); return; } - + String charset = defaultCharset; if (args.length == 2) { charset = args[1]; @@ -125,7 +125,7 @@ public void process(String command, String[] args, PrintStream out) throws Comma out.println(USAGE); return; } - + try { List commands = parseCmdFile(file, charset); for (String cmd : commands) { @@ -151,7 +151,7 @@ public void process(String command, String[] args, PrintStream out) throws Comma public String getCommandName() { return COMMAND; } - + /** * To gets the tool's argument description. *

        @@ -176,6 +176,6 @@ public String getHelpDescription() { public void printDetailedHelp(PrintStream out) { out.println(USAGE); } - + private String defaultCharset = null; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/GrepTool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/GrepTool.java index 94cc1f7d2f9..883a0e3157e 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/GrepTool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/GrepTool.java @@ -53,7 +53,7 @@ public class GrepTool extends Tool implements IPipe { public static final String ARGUMENT_DESCRIPTION = "[options] "; public static final String HELP_DESCRIPTION = "to be used after the pipeline to show lines which match a pattern."; - public static final String USAGE = COMMAND + "\t" + ARGUMENT_DESCRIPTION + "\t" + HELP_DESCRIPTION + "\n" + + public static final String USAGE = COMMAND + "\t" + ARGUMENT_DESCRIPTION + "\t" + HELP_DESCRIPTION + "\n" + " Options :\n" + " -i : Ignore case.\n" + " -r, -G, --regex : Use regular expression as defined in the Java documentation of class java.utils.regex.Pattern.\n" + @@ -65,15 +65,15 @@ public class GrepTool extends Tool implements IPipe { " -F, --fixed-strings : to treat character '*' not as a wide card. This option can not be used together with -r, -G or --regex.\n" + " Pattern : \n" + " Character '*' in a pattern will be treated as a wild card unless option -F or --fixed-strings is used.\n" + - " If a pattern contains any spaces, enclose the pattern in a pair of double quotation marks.\n" + - " If a pattern contains any double quotation marks, enclose the pattern in a pair of single quotation marks.\n" + - " The pattern can be in the following format to show lines which match any of the sub-patterns:\n" + - " \"[||...|]\"\n" + - " This format has to start with \"[ and ends with ]\" and use character '|' as the sub-pattern separator.\n" + - " No quotation marks and character '|' are allowed in any sub-patterns.\n" + - " Spaces are allowed in the middle of a sub-patterns, but leading and trailing spaces will be trimmed.\n" + - " This format only works when option -r, -G, and --regex are not used.\n" + - " Use command " + COMMAND_NEGATE + " to show lines which do not match the pattern."; + " If a pattern contains any spaces, enclose the pattern in a pair of double quotation marks.\n" + + " If a pattern contains any double quotation marks, enclose the pattern in a pair of single quotation marks.\n" + + " The pattern can be in the following format to show lines which match any of the sub-patterns:\n" + + " \"[||...|]\"\n" + + " This format has to start with \"[ and ends with ]\" and use character '|' as the sub-pattern separator.\n" + + " No quotation marks and character '|' are allowed in any sub-patterns.\n" + + " Spaces are allowed in the middle of a sub-patterns, but leading and trailing spaces will be trimmed.\n" + + " This format only works when option -r, -G, and --regex are not used.\n" + + " Use command " + COMMAND_NEGATE + " to show lines which do not match the pattern."; /** * Determines if a command is accepted by the current tool. @@ -81,13 +81,13 @@ public class GrepTool extends Tool implements IPipe { * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String[] args) { return command.equalsIgnoreCase(COMMAND) || command.equalsIgnoreCase(COMMAND_NEGATE); } - + /** * Processes the command. *

        @@ -97,8 +97,8 @@ public boolean accept(String command, String[] args) { *

        * @throws CommandException */ - public void process(String command, String[] args, PrintStream out) throws CommandException - { + public void process(String command, String[] args, PrintStream out) throws CommandException + { Attributes attributes = null; try { attributes = readAttributes(command, args, command.equalsIgnoreCase(COMMAND_NEGATE), out); @@ -109,7 +109,7 @@ public void process(String command, String[] args, PrintStream out) throws Comma out.println(USAGE); return; } - + IPrematchHandle prematchHandle = null; if (attributes.matchBlock) { prematchHandle = new BlockPrematchHandle(); @@ -123,29 +123,28 @@ public void process(String command, String[] args, PrintStream out) throws Comma } else { matchHandle = new MatchHandle(attributes.normalStringsToGrep, attributes.caseInsensitive, attributes.negate, attributes.isFixedString); } - + IPostmatchHandle postmatchHandle = null; if (attributes.matchBlock) { postmatchHandle = new BlockPostmatchHandle(); } else { postmatchHandle = new MaxLinesPostmatchHandle(attributes.maxNextLines); } - - ToolsRegistry.process(attributes.nextCommand, attributes.nextCommandArgs, + + ToolsRegistry.process(attributes.nextCommand, attributes.nextCommandArgs, new PrintStream( - new OutputStreamModifier(out, + new OutputStreamModifier(out, new StringModifier(prematchHandle, matchHandle, postmatchHandle)))); - + } - /** * To print the detailed help message. */ public void printDetailedHelp(PrintStream out) { out.println(USAGE); } - + /** * To gets the tool's command name. *

        @@ -154,7 +153,7 @@ public void printDetailedHelp(PrintStream out) { public String getCommandName() { return COMMAND; } - + /** * To gets the tool's argument description. *

        @@ -172,7 +171,7 @@ public String getArgumentDescription() { public String getHelpDescription() { return HELP_DESCRIPTION; } - + private Attributes readAttributes(String command, String [] args, boolean negate, PrintStream out) { if (2 > args.length) { return null; @@ -193,15 +192,15 @@ private Attributes readAttributes(String command, String [] args, boolean negate if (false == grepOptionsEnded && args[i].equals("-i")) { caseInsensitive = true; continue; - } + } if (false == grepOptionsEnded && (args[i].equals("-b") || args[i].equals("--block"))) { matchBlock = true; continue; - } + } if (false == grepOptionsEnded && (args[i].equals("-r") || args[i].equals("-G") || args[i].equals("--regex"))) { useRegularExpression = true; continue; - } + } if (false == grepOptionsEnded && (args[i].equals("-F") || args[i].equals("--fixed-strings"))) { isFixedString = true; continue; @@ -253,12 +252,12 @@ private Attributes readAttributes(String command, String [] args, boolean negate // This means the search string starts with "+" ! } } - + if (false == grepOptionsEnded && (args[i].equals("-v") || args[i].equalsIgnoreCase("--invert-match"))) { dashVUsed = true; continue; } - + if (false == grepOptionsEnded && args[i].equals("-B")) { if (i < args.length - 1) { i++; @@ -273,7 +272,7 @@ private Attributes readAttributes(String command, String [] args, boolean negate out.println("Option -B is not followed by a number."); return null; } - + if (false == grepOptionsEnded && args[i].startsWith("-")) { try { maxPreviousLines = Integer.parseInt(args[i].substring(1)); @@ -282,7 +281,7 @@ private Attributes readAttributes(String command, String [] args, boolean negate // This means the search string starts with "-" ! } } - + grepOptionsEnded = true; if (stringToGrep == null) { stringToGrep = args[i]; @@ -308,16 +307,16 @@ private Attributes readAttributes(String command, String [] args, boolean negate out.println("Option -F and --fixed-strings can not be used with option -r, -G, or --regex."); return null; } - return new Attributes(negate, useRegularExpression, + return new Attributes(negate, useRegularExpression, caseInsensitive, stringToGrep, nextCommand, nextCommandArgs.toArray(new String [nextCommandArgs.size()]), maxPreviousLines, maxNextLines, matchBlock, isFixedString); } - - private class Attributes + + private class Attributes { - public Attributes(boolean negate, boolean useRegularExpression, boolean caseInsensitive, - String stringToGrep, String nextCommand, String [] nextCommandArgs, - int maxPreviousLines, int maxNextLines, boolean matchBlock, boolean isFixedString) + public Attributes(boolean negate, boolean useRegularExpression, boolean caseInsensitive, + String stringToGrep, String nextCommand, String [] nextCommandArgs, + int maxPreviousLines, int maxNextLines, boolean matchBlock, boolean isFixedString) { this.negate = negate; this.useRegularExpression = useRegularExpression; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/HelpTool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/HelpTool.java index 7c85d42f709..e55bb86c85e 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/HelpTool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/HelpTool.java @@ -38,7 +38,7 @@ public class HelpTool extends Tool public static final String COMMAND = "help"; public static final String HELP_DESCRIPTION = "to display command help messages"; public static final String USAGE = COMMAND + ":\t" + HELP_DESCRIPTION; - public static final String JDMPVIEW_HELP_COMMAND = COMMAND; + public static final String JDMPVIEW_HELP_COMMAND = COMMAND; public static final String COMMAND_FORMAT = "%-25s %-20s %s"; /** @@ -47,13 +47,13 @@ public class HelpTool extends Tool * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String[] args) { return command.equalsIgnoreCase(COMMAND); } - + /** * Processes the command. *

        @@ -75,7 +75,7 @@ public void process(String command, String[] args, PrintStream redirector) throw printHelpMessages(commandToBeHelped, newArgs, redirector); } } - + /** * To print the detailed help message. */ @@ -91,7 +91,7 @@ public void printDetailedHelp(PrintStream out) { public String getCommandName() { return COMMAND; } - + /** * To gets the tool's argument description. *

        @@ -100,7 +100,7 @@ public String getCommandName() { public String getArgumentDescription() { return ""; } - + /** * To gets the tool's help description. *

        @@ -109,7 +109,7 @@ public String getArgumentDescription() { public String getHelpDescription() { return null; } - + /** * To print help messages for all commands. *

        @@ -123,7 +123,7 @@ private void printAllHelpMessages(PrintStream out) { } } } - + /** * To print the help message for a specific command. *

        @@ -131,16 +131,16 @@ private void printAllHelpMessages(PrintStream out) { * @param arguments The arguments. * @param out The PrintStream to print the messages. */ - private void printHelpMessages(String commandToBeHelped, String[] arguments, PrintStream out) + private void printHelpMessages(String commandToBeHelped, String[] arguments, PrintStream out) { for (ITool aTool : ToolsRegistry.getAllTools()) { - if ((aTool instanceof HelpTool == false) && aTool.accept(commandToBeHelped, arguments)) + if ((aTool instanceof HelpTool == false) && aTool.accept(commandToBeHelped, arguments)) { aTool.printDetailedHelp(out); return; } } - + StringBuffer sb = new StringBuffer(JDMPVIEW_HELP_COMMAND); sb.append(" ").append(commandToBeHelped); for (String arg : arguments) { diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/HistoryTool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/HistoryTool.java index febffad9a04..512c246a52f 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/HistoryTool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/HistoryTool.java @@ -34,28 +34,28 @@ public class HistoryTool extends Tool { public static final String COMMAND_SHORT = "his"; public static final int DEFAULT_DISPLAY_N = 20; public static final String ARGUMENT_DESCRIPTION = "[-r] [N]"; - public static final String HELP_DESCRIPTION = + public static final String HELP_DESCRIPTION = " If option -r is used, the Nth history command (default to the last one) will be run;\n" + " otherwise, at most N (default " + DEFAULT_DISPLAY_N + ") history commands will be displayed."; public static final String USAGE = COMMAND + "|" + COMMAND_SHORT + "\t" + ARGUMENT_DESCRIPTION + "\n" + HELP_DESCRIPTION; - + public HistoryTool() { super(); history = new LinkedList(); defaultExecutingIndex = -1; } - + /** * To record a history command. *

        * @param cmd The command to be recorded. */ - public void record(String cmd) + public void record(String cmd) { history.add(cmd); defaultExecutingIndex = history.size() - 1; } - + /** * Processes the command. *

        @@ -65,7 +65,7 @@ public void record(String cmd) *

        * @throws CommandException */ - public void process(String command, String[] args, PrintStream out) throws CommandException + public void process(String command, String[] args, PrintStream out) throws CommandException { int n = DEFAULT_DISPLAY_N; boolean executeCommand = false; @@ -74,7 +74,7 @@ public void process(String command, String[] args, PrintStream out) throws Comma showHistoryCommands(DEFAULT_DISPLAY_N, out); return; } - + if (args.length > 0) { if (args[0].startsWith("-r")) { executeCommand = true; @@ -111,27 +111,27 @@ public void process(String command, String[] args, PrintStream out) throws Comma showHistoryCommands(n, out); } } - + /** * Determines if a command is accepted by the current tool. *

        * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String[] args) { return command.equalsIgnoreCase(COMMAND_SHORT) || command.equalsIgnoreCase(COMMAND); } - + /** * To print the detailed help message. */ public void printDetailedHelp(PrintStream out) { out.println(USAGE); } - + /** * To gets the tool's command name. *

        @@ -140,7 +140,7 @@ public void printDetailedHelp(PrintStream out) { public String getCommandName() { return COMMAND; } - + /** * To gets the tool's argument description. *

        @@ -158,7 +158,7 @@ public String getArgumentDescription() { public String getHelpDescription() { return HELP_DESCRIPTION; } - + private void executeHistoryCommand(int n, PrintStream out) throws CommandException { if (history.size() == 0) { out.println("The history repository is empty."); @@ -170,8 +170,8 @@ private void executeHistoryCommand(int n, PrintStream out) throws CommandExcepti } ToolsRegistry.process(history.get(n), out); } - - private void showHistoryCommands(int counter, PrintStream out) { + + private void showHistoryCommands(int counter, PrintStream out) { if (counter <= 0) { out.println("The number " + counter + " is not a valid counter."); return; @@ -180,7 +180,7 @@ private void showHistoryCommands(int counter, PrintStream out) { out.println("The history repository is empty."); return; } - counter = Math.min(counter, history.size()); + counter = Math.min(counter, history.size()); for (int index = history.size() - counter; index < history.size(); index++) { out.println(index + " : " + history.get(index)); } @@ -189,4 +189,3 @@ private void showHistoryCommands(int counter, PrintStream out) { private LinkedList history; private int defaultExecutingIndex; } - diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/OutFileTool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/OutFileTool.java index bf1f64831e2..3d0f798c8d4 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/OutFileTool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/OutFileTool.java @@ -45,21 +45,21 @@ public class OutFileTool extends Tool implements IPipe public static final String ARGUMENT_DESCRIPTION = ""; public static final String HELP_DESCRIPTION = "to be used at the end of a command to redirect messages to a file (overwrite|append)."; public static final String USAGE = COMMAND_OVERWRITE + "|" + COMMAND_APPEND + "\t" + ARGUMENT_DESCRIPTION + "\t" + HELP_DESCRIPTION; - + /** * Determines if a command is accepted by current tool. *

        * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String[] args) { - return command.equalsIgnoreCase(COMMAND_OVERWRITE) + return command.equalsIgnoreCase(COMMAND_OVERWRITE) || command.equalsIgnoreCase(COMMAND_APPEND); } - + /** * Processes the command. *

        @@ -115,7 +115,7 @@ public void printDetailedHelp(PrintStream out) { public String getCommandName() { return COMMAND_OVERWRITE + "|" + COMMAND_APPEND; } - + /** * To gets the tool's argument description. *

        @@ -124,7 +124,7 @@ public String getCommandName() { public String getArgumentDescription() { return ARGUMENT_DESCRIPTION; } - + /** * To gets the tool's help description. *

        @@ -153,7 +153,7 @@ private PrintStream getOutputFile(final Attributes attributes) throws IOExceptio throw new IOException("Could not create some of the requested directories: " + parentDirectories); } } - + if (attributes.append && outFile.exists()) { // in this case do not create a new file, but use the existing one outStream = new PrintStream(new FileOutputStream(outFile, true)); @@ -161,7 +161,7 @@ private PrintStream getOutputFile(final Attributes attributes) throws IOExceptio outStream = new PrintStream(outFile); // this will create a new file } - return outStream; + return outStream; } private Attributes readAttributes(String command, String[] args) { @@ -182,10 +182,10 @@ private Attributes readAttributes(String command, String[] args) { } return new Attributes(filePath, ddrCommand, ddrCommandArgs, command.equalsIgnoreCase(COMMAND_APPEND)); } - - private class Attributes + + private class Attributes { - public Attributes(String filePath,String ddrCommand,String [] ddrCommandArgs, boolean append) + public Attributes(String filePath,String ddrCommand,String [] ddrCommandArgs, boolean append) { this.filePath = filePath; this.nextCommand = ddrCommand; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/TokensTool.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/TokensTool.java index 41e503dd2ad..2576cc96cd7 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/TokensTool.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/impl/TokensTool.java @@ -86,7 +86,7 @@ public void process(String command, String[] args, PrintStream out) throws Comma * @param command The command * @param args The arguments taken by the command. *

        - * @return true if this is the correct tool for this command; + * @return true if this is the correct tool for this command; * false otherwise. */ public boolean accept(String command, String[] args) { @@ -144,7 +144,7 @@ private static Arguments processArguments(String[] args, PrintStream out) { keep = true; currentIndex++; } - + StringTokenizer st = new StringTokenizer(args[currentIndex], ","); while(st.hasMoreTokens()) { Range range = TokensTool.parseRange(st.nextToken(), out); @@ -155,7 +155,7 @@ private static Arguments processArguments(String[] args, PrintStream out) { } } currentIndex++; - + if (args[currentIndex].equalsIgnoreCase(OPTION_KEEP)) { keep = true; currentIndex++; @@ -169,7 +169,7 @@ private static Arguments processArguments(String[] args, PrintStream out) { } return new Arguments(keep, rangeList, ddrCommand, ddrCommandArgs); } - + /** * To parse a range. * Note, a NULL object will be returned if the specified range is found to have any errors. @@ -177,7 +177,7 @@ private static Arguments processArguments(String[] args, PrintStream out) { private static Range parseRange(String range, PrintStream out) { int start = 1; int end = -1; - + int index = range.indexOf(RANGE_INDICATOR); try { if (index < 0) { @@ -197,7 +197,7 @@ private static Range parseRange(String range, PrintStream out) { out.println("Range must be numeric : " + range); return null; } - + // do some basic verification here. // (1) start and end of the range can not be 0 because we start counting from 1 or -1. // (2) if start and end are both positive or both negative, we need ensure start is not greater than end; @@ -210,11 +210,11 @@ private static Range parseRange(String range, PrintStream out) { } return new Range (start, end); } - + private static final class Range { final int start; final int end; - + public Range(int start, int end) { this.start = start; this.end = end; @@ -222,12 +222,12 @@ public Range(int start, int end) { public int getStartIndex(int tokenSize) { return Math.max(0, start < 0 ? tokenSize + start : start - 1); } - + public int getEndIndex(int tokenSize) { return Math.min(tokenSize - 1, end < 0 ? tokenSize + end : end - 1); } } - + private static final class Arguments { public Arguments(boolean keep, List rangeList, String nextCommand, String [] nextCommandArgs) { this.keep = keep; @@ -238,14 +238,14 @@ public Arguments(boolean keep, List rangeList, String nextCommand, String public final String nextCommand; public final String [] nextCommandArgs; public final boolean keep; - public final List rangeList; + public final List rangeList; } - + private static final class StringModifier implements IStringModifier { public StringModifier(Arguments arguments) { this.arguments = arguments; } - + public String modify(String s) { StringBuilder sb = null; List tokenList = tokenize(s); @@ -261,7 +261,7 @@ public String modify(String s) { sb.append(tokenList.get(index)); } } - + if(sb == null || sb.length() == 0) { if (arguments.keep) { return s.endsWith("\n") ? s : s + "\n"; @@ -271,7 +271,7 @@ public String modify(String s) { } return sb.toString() + "\n"; } - + private static List tokenize(String s) { List tokenList = new ArrayList(); StringTokenizer st = new StringTokenizer(s); @@ -280,7 +280,7 @@ private static List tokenize(String s) { } return tokenList; } - + private final Arguments arguments; } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/BlockPostmatchHandle.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/BlockPostmatchHandle.java index 0e587435304..6874b3b713f 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/BlockPostmatchHandle.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/BlockPostmatchHandle.java @@ -23,7 +23,7 @@ package com.ibm.jvm.dtfjview.tools.utils; /** - * This class will start cache lines once any match is found. It will + * This class will start cache lines once any match is found. It will * release the cached lines once it encounters an empty line. *

        * @author Manqing Li @@ -48,6 +48,6 @@ public String process(String s) { return ""; } } - + private boolean ended = false; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/BlockPrematchHandle.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/BlockPrematchHandle.java index 1180c9bd6b1..4ff1aed576b 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/BlockPrematchHandle.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/BlockPrematchHandle.java @@ -26,8 +26,8 @@ import java.util.List; /** - * This class first caches all the lines. The cache will be cleaned - * if it encounters an empty line and cache will be restarted. The + * This class first caches all the lines. The cache will be cleaned + * if it encounters an empty line and cache will be restarted. The * cached lines will be released once it is asked to do so. *

        * @author Manqing Li, IBM. @@ -38,7 +38,7 @@ public class BlockPrematchHandle implements IPrematchHandle { public BlockPrematchHandle() { this.cached = new LinkedList(); } - + public void process(String s) { if (null == s || 0 == s.trim().length()) { cached = new LinkedList(); diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/FileUtils.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/FileUtils.java index 543dc3b3a4c..ac3b5e8aaca 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/FileUtils.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/FileUtils.java @@ -37,13 +37,13 @@ public class FileUtils { *

        * @return content of the file. *

        - * @throws UnsupportedEncodingException + * @throws UnsupportedEncodingException * @throws IOException */ public static String [] read(File file) throws IOException, UnsupportedEncodingException { return read(file, null); } - + /** * To read a file. *

        @@ -52,7 +52,7 @@ public class FileUtils { *

        * @return content of the file. *

        - * @throws UnsupportedEncodingException + * @throws UnsupportedEncodingException * @throws IOException */ public static String [] read(File file, String charset) throws IOException, UnsupportedEncodingException { @@ -72,7 +72,7 @@ public class FileUtils { in.close(); } } - return (charset == null ? new String(buffer) : new String(buffer, charset)).split("\n"); + return (charset == null ? new String(buffer) : new String(buffer, charset)).split("\n"); // TODO needs to test "\n" if this works on zOS. } } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IMatchHandle.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IMatchHandle.java index ab5467ad19d..7a1606504cd 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IMatchHandle.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IMatchHandle.java @@ -23,7 +23,7 @@ package com.ibm.jvm.dtfjview.tools.utils; public interface IMatchHandle { - + /** * To check if the string is matched. *

        @@ -33,7 +33,7 @@ public interface IMatchHandle { * false otherwise. */ public boolean matches(String s); - + /** * To process the string. *

        diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IPostmatchHandle.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IPostmatchHandle.java index 4dc1d25a5cf..6e04d3665ff 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IPostmatchHandle.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IPostmatchHandle.java @@ -35,7 +35,7 @@ public interface IPostmatchHandle { * when a match was just found (by a match handle). */ public void justMatched(); - + /** * This is for the post match handle to perform actions on the string *

        diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IPrematchHandle.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IPrematchHandle.java index fe1c7e552da..0873eb25d73 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IPrematchHandle.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IPrematchHandle.java @@ -34,13 +34,13 @@ public interface IPrematchHandle { * This is for the prematch handle to process the incoming string (such * as cache it, trim it, etc). *

        - * @param s + * @param s */ public void process(String s); - + /** - * This is to release the string. Note, depending on the actual - * implementation of the pre-match handle, the released string + * This is to release the string. Note, depending on the actual + * implementation of the pre-match handle, the released string * can have multiple lines. *

        * @return a String object. diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IStringModifier.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IStringModifier.java index b6d112b6eff..e2593d43cb4 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IStringModifier.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/IStringModifier.java @@ -23,9 +23,9 @@ package com.ibm.jvm.dtfjview.tools.utils; public interface IStringModifier { - + /** - * This method is to be called by an OutputStreamModifier object + * This method is to be called by an OutputStreamModifier object * before the string is sent to the OutputStream. *

        * @param s The string to be modified. diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/MatchHandle.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/MatchHandle.java index 7a28f000250..9043f0bb652 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/MatchHandle.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/MatchHandle.java @@ -37,7 +37,7 @@ public class MatchHandle implements IMatchHandle { public MatchHandle(String [] matchStringList, boolean ignoreCase) { this(matchStringList, ignoreCase, false, false); } - + public MatchHandle(String [] matchStringList, boolean ignoreCase, boolean negated, boolean isFixedString) { this.matchStringList = matchStringList; this.ignoreCase = ignoreCase; @@ -61,7 +61,7 @@ public boolean matches(String s) { } return false; } - + /** * To process the string. *

        @@ -81,7 +81,7 @@ private boolean match(String s, String match) { if (isFixedString) { return matchFixedStrings(s, new String[] {match}); } - + StringTokenizer st = new StringTokenizer(match, "*"); List ls = new ArrayList(); while (st.hasMoreTokens()) { @@ -110,8 +110,8 @@ private boolean matchFixedStrings(String s, String [] matches) { } return true; } - - private final String [] matchStringList; + + private final String[] matchStringList; private final boolean ignoreCase; private final boolean negated; private final boolean isFixedString; diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/MaxLinesPrematchHandle.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/MaxLinesPrematchHandle.java index a825dea798f..c1e8505f7d7 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/MaxLinesPrematchHandle.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/MaxLinesPrematchHandle.java @@ -36,14 +36,14 @@ public MaxLinesPrematchHandle(int maxPrematchLines) { this.maxPrematchLines = maxPrematchLines > 0 ? maxPrematchLines : 0; cached = new LinkedList(); } - + public void process(String s) { cached.addLast(s); if (maxPrematchLines < cached.size()) { cached.removeFirst(); } } - + public String release() { StringBuffer sb = new StringBuffer(); for (String line : cached) { diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/OutputStreamModifier.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/OutputStreamModifier.java index 805c7a515a6..1290d0f02e9 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/OutputStreamModifier.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/OutputStreamModifier.java @@ -29,7 +29,7 @@ /** * This class works with the class OutputStream and class IStringModifier. * It first caches the bytes from the OutputStream. If a new line char is - * encountered or if the output stream is closed, it will ask the string + * encountered or if the output stream is closed, it will ask the string * modifier to modify it first before it sends the line to the output stream. *

        * @author Manqing Li diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/RegExprMatchHandle.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/RegExprMatchHandle.java index e8cb7ab433e..a2ad4341a51 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/RegExprMatchHandle.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/RegExprMatchHandle.java @@ -66,7 +66,7 @@ public boolean matches(String s) { public String process(String s) { return s; } - + private final Pattern [] patternList; private final boolean negated; } diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/StringModifier.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/StringModifier.java index c9ebb8611ce..9d30b12b36b 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/StringModifier.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/StringModifier.java @@ -22,10 +22,9 @@ */ package com.ibm.jvm.dtfjview.tools.utils; - /** - * This class is to be used together with pre-match handler, match handler - * and post-match handler. It receives strings from the OutputStreamModifier + * This class is to be used together with pre-match handler, match handler + * and post-match handler. It receives strings from the OutputStreamModifier * and delegates them to the above handlers according to the matching status. *

        * @author Manqing Li, IBM. @@ -48,7 +47,7 @@ public String modify(String s) { } else if (false == matched && true == becomeMatched) { matched = true; postmatchHandle.justMatched(); - return prematchHandle.release() + matchHandle.process(s); + return prematchHandle.release() + matchHandle.process(s); } else if (true == matched && false == becomeMatched) { return postmatchHandle.process(s); } else { // matched == true && becomeMatched == true diff --git a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/StringReceiver.java b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/StringReceiver.java index cb1d331a9d6..e96062f4bb6 100644 --- a/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/StringReceiver.java +++ b/jcl/src/openj9.dtfjview/share/classes/com/ibm/jvm/dtfjview/tools/utils/StringReceiver.java @@ -28,7 +28,7 @@ import java.io.UnsupportedEncodingException; /** - * This is a kind of OutputStream which caches the incoming bytes (instead if printing them out) + * This is a kind of OutputStream which caches the incoming bytes (instead if printing them out) * and releases them as a string whenever it is asked to. *

        * @author Manqing Li, IBM. From 3be484bbf7daf95f0f2827268e8d1f2e76d5f72c Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 16:20:57 -0400 Subject: [PATCH 12/16] Tidy up whitespace in openj9.gpu * remove trailing whitespace Signed-off-by: Keith W. Campbell --- .../share/classes/com/ibm/gpu/GPUSortException.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jcl/src/openj9.gpu/share/classes/com/ibm/gpu/GPUSortException.java b/jcl/src/openj9.gpu/share/classes/com/ibm/gpu/GPUSortException.java index 88cf853efa6..b5432a98eba 100644 --- a/jcl/src/openj9.gpu/share/classes/com/ibm/gpu/GPUSortException.java +++ b/jcl/src/openj9.gpu/share/classes/com/ibm/gpu/GPUSortException.java @@ -32,7 +32,7 @@ public final class GPUSortException extends Exception { /** * Creates a new GPUSortException with a provided message. - * + * * @param message The message to be provided. */ public GPUSortException(String message) { @@ -41,7 +41,7 @@ public GPUSortException(String message) { /** * Creates a new GPUSortException with a provided message and cause. - * + * * @param message The message to be provided. * @param cause The cause of this exception. */ From 16fb05fed5a7927243ba471329955465acf275b4 Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 16:22:23 -0400 Subject: [PATCH 13/16] Tidy up whitespace in openj9.jvm * remove trailing whitespace Signed-off-by: Keith W. Campbell --- .../share/classes/com/ibm/jvm/Debuggable.java | 3 +-- .../share/classes/com/ibm/jvm/DumpPermission.java | 4 ++-- .../openj9.jvm/share/classes/com/ibm/jvm/Log.java | 12 ++++++------ .../share/classes/com/ibm/jvm/TracePermission.java | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/Debuggable.java b/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/Debuggable.java index 1e829cebd62..6fec523b03d 100644 --- a/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/Debuggable.java +++ b/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/Debuggable.java @@ -29,8 +29,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - -/** +/** * The Debuggable annotation applies to either classes or methods and provides * a hint to the VM that decorated entities must remain debuggable. This facility * is intended for use by languages implemented in Java where portions of the program diff --git a/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/DumpPermission.java b/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/DumpPermission.java index 7a007a94120..adbc0f94ef3 100644 --- a/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/DumpPermission.java +++ b/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/DumpPermission.java @@ -30,13 +30,13 @@ * Allowing code access to this permission will allow changes to be made * to system wide dump settings controlling which events cause dumps to be * and allow dumps to be triggered directly. - * + * * Triggering dumps may pause the application while the dump is taken. This pause * can potentially be minutes depending on the size of the application. * A dump file may be a complete image of the applications memory. Code with read * access to dump files produced by com.ibm.jvm.Dump should be considered as having * access to any information that was within the application at the time the dump - * was taken. + * was taken. */ public class DumpPermission extends BasicPermission { diff --git a/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/Log.java b/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/Log.java index 2ce57959f78..24fb0d0f43a 100644 --- a/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/Log.java +++ b/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/Log.java @@ -25,16 +25,16 @@ import java.util.Objects; /** - * + * * The Log class contains methods for controlling system log options * This class cannot be instantiated. */ public class Log { private static final String LEGACY_LOG_PERMISSION_PROPERTY = "com.ibm.jvm.enableLegacyLogSecurity"; //$NON-NLS-1$ - + private static final LogPermission LOG_PERMISSION = new LogPermission(); - + /** * Query the log options. Returns a String representation of the log options. * @return The current log options @@ -48,10 +48,10 @@ public static String QueryOptions() { /** * Set the log options. * Use the same syntax as the -Xsyslog command-line option, with the initial -Xsyslog: omitted. - * + * * @param options The command line log flags. * @return status 0 on success otherwise a RuntimeException is thrown - * + * * @throws RuntimeException if there is a problem setting the log options * @throws SecurityException if there is a security manager and it doesn't allow the checks required to change the log settings */ @@ -87,7 +87,7 @@ private static void checkLogSecurityPermssion() throws SecurityException { /* * Log should not be instantiated. */ - private Log() { + private Log() { } private static native String QueryOptionsImpl(); diff --git a/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/TracePermission.java b/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/TracePermission.java index 599f7e28b4f..3b089418c54 100644 --- a/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/TracePermission.java +++ b/jcl/src/openj9.jvm/share/classes/com/ibm/jvm/TracePermission.java @@ -28,7 +28,7 @@ /** * The permission class for operations on the com.ibm.jvm.Trace class. * Allowing code access to this permission will allow changes to be made - * to system wide trace settings + * to system wide trace settings */ public class TracePermission extends BasicPermission { From cbe04f9f77e54daa7ded7a289c8c96ba091c836e Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 16:25:38 -0400 Subject: [PATCH 14/16] Tidy up whitespace in openj9.sharedclasses * remove trailing whitespace * indent with tabs consistently Signed-off-by: Keith W. Campbell --- .../com/ibm/oti/shared/SharedClassFilter.java | 2 +- .../shared/SharedClassTokenHelperImpl.java | 4 +- .../shared/SharedClassURLClasspathHelper.java | 74 +++++++++---------- .../SharedClassURLClasspathHelperImpl.java | 41 +++++----- .../ibm/oti/shared/SharedClassURLHelper.java | 16 ++-- .../oti/shared/SharedClassURLHelperImpl.java | 28 +++---- .../shared/SharedClassesNamedPermission.java | 4 +- .../ibm/oti/shared/SharedDataHelperImpl.java | 2 +- .../com/ibm/oti/shared/package-info.java | 2 +- .../provider/SharedClassProviderImpl.java | 2 +- 10 files changed, 87 insertions(+), 88 deletions(-) diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassFilter.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassFilter.java index a73e016d5b5..b3421bdc0cd 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassFilter.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassFilter.java @@ -23,7 +23,7 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 */ -/** +/** * SharedClassFilter allows users of a Helper API to filter which classes are found and stored in the cache. * The user should provide a class that implements the interface in which the functions return true or false, * and then pass an instance of this class to setSharingFilter() in a shared class helper. diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassTokenHelperImpl.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassTokenHelperImpl.java index 17414a67830..1b0953aa2a4 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassTokenHelperImpl.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassTokenHelperImpl.java @@ -38,7 +38,7 @@ final class SharedClassTokenHelperImpl extends SharedClassAbstractHelper impleme initializeShareableClassloader(loader); } - private native boolean findSharedClassImpl2(int loaderId, String className, ClassLoader loader, String token, + private native boolean findSharedClassImpl2(int loaderId, String className, ClassLoader loader, String token, boolean doFind, boolean doStore, byte[] romClassCookie); private native boolean storeSharedClassImpl2(int loaderId, ClassLoader loader, String token, Class clazz, byte[] flags); @@ -110,7 +110,7 @@ public boolean storeSharedClass(String token, Class clazz) { } return storeSharedClassImpl2(this.id, actualLoader, token, clazz, nativeFlags); } - + @Override String getHelperType() { return "SharedClassTokenHelper"; //$NON-NLS-1$ diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLClasspathHelper.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLClasspathHelper.java index b2c394a36e4..aebaa21a4a0 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLClasspathHelper.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLClasspathHelper.java @@ -41,7 +41,7 @@ *

        Classes can be stored only by using URLs that have file or jar protocols, and that refer to existing resources. * The presence of any other protocol in a URL prevents SharedClassURLClasspathHelper from locating and storing classes in the shared cache.

        *

        Using classpaths

        - *

        When a findSharedClass request is made from a SharedClassURLClasspathHelper, the shared cache determines whether to return a class + *

        When a findSharedClass request is made from a SharedClassURLClasspathHelper, the shared cache determines whether to return a class * by comparing the caller's classpath to the classpath or URL that the class was stored against. Classpaths do not have to explicitly match.

        *

        * For example, a class c1 loaded from c.jar and stored using classpath a.jar;b.jar;c.jar;d.jar may be found by using the following classpaths:

        @@ -59,10 +59,10 @@ * confirmed entry. The definition of a confirmed entry is that it has been opened and read by the ClassLoader. Entries are confirmed by calling * storeSharedClass (every entry up to and including the index used is confirmed) or by calling confirmAllEntries(). The latter should only be used if * the classpath is guaranteed not to change (but can still be appended to).

        - *

        Note that if findSharedClass returns null for whatever reason (even though the cache has the required class), calling storeSharedClass(...) + *

        Note that if findSharedClass returns null for whatever reason (even though the cache has the required class), calling storeSharedClass(...) * on the class loaded from disk is the correct thing to do. This confirms the classpath entry, and the cache does not store a duplicate class.

        *

        In this way, classes can be shared as effectively as possible between class loaders using different classpaths or URL helper types.

        - *

        Note that two identical classes are never stored twice in the class cache, but many entries may exist for the same class. + *

        Note that two identical classes are never stored twice in the class cache, but many entries may exist for the same class. * For example, if class X is stored from a.jar and also from b.jar, the class will exist once in the cache, but will have two entries.

        *

        Modifying classpaths

        *

        It is possible that the classpath of a ClassLoader may change after it is initially set. There is a jar extension mechanism, for example, @@ -74,7 +74,7 @@ *

        After classpath entries are confirmed, they cannot be changed, so setClasspath may only make changes to parts of the classpath that are not yet confirmed. * For example in the given example, a.jar;b.jar;x.jar;c.jar is acceptable, whereas a.jar;x.jar;b.jar;c.jar;d.jar is not. If an attempt is made to make * changes to confirmed classpath entries, a CannotSetClasspathException is thrown.

        - *

        Dynamic cache updates

        + *

        Dynamic cache updates

        *

        Because the shared cache persists beyond the lifetime of a JVM, classes in the shared cache can become out of date (stale). * Classes in the cache are automatically kept up to date by default.

        *

        If findSharedClass is called for a class that exists in the cache but which has been updated on the filesystem since it was stored, @@ -89,33 +89,33 @@ *

        It is essential that findSharedClass does not then return the version of c1 in c.jar. * It will detect the change, return null and c1 from a.jar should then be stored.

        *

        (This behaviour can be disabled by using the correct command-line option, but this is not recommended. See -Xshareclasses:help.)

        - *

        It is also assumed that after a jar/zip has been opened, the ClassLoader maintains a read lock on that file during its lifetime, + *

        It is also assumed that after a jar/zip has been opened, the ClassLoader maintains a read lock on that file during its lifetime, * preventing its modification. This prevents the cache from having to constantly check for updates. * However, it is understood that non-existent jars/zips on a classpath can only be locked if/when they exist.

        *

        Partitions

        - *

        A partition can be used when finding or storing a class, which allows modified versions of the same class + *

        A partition can be used when finding or storing a class, which allows modified versions of the same class * to be stored in the cache, effectively creating partitions in the cache.

        - *

        Partitions are designed for bytecode modification such as the use of Aspects. It is the responsibility of the ClassLoader + *

        Partitions are designed for bytecode modification such as the use of Aspects. It is the responsibility of the ClassLoader * to create partitions that describe the type of modification performed on the class bytes.

        - *

        If a class is updated on the filesystem and automatic dynamic updates are enabled, then all versions of the class across + *

        If a class is updated on the filesystem and automatic dynamic updates are enabled, then all versions of the class across * all partitions will be marked stale.

        *

        Class metadata

        *

        A ClassLoader can create metadata when loading and defining classes, such as a jar manifest or security data. - * None of this metadata can be stored in the cache, so if a ClassLoader is finding classes in the shared cache, it must load + * None of this metadata can be stored in the cache, so if a ClassLoader is finding classes in the shared cache, it must load * any metadata that it needs from disk before defining the classes.

        *

        * Example:
        * For static metadata specific to URL classpath entries (such as Manifest/CodeSource information), a suggested solution is to create * a local array to cache the metadata when it is loaded from disk. When findSharedClass is called and an index is returned, look to see * if metadata is already cached in the local array for that index. If it is, define the class. If not, load the class from disk to obtain - * the metadata, cache it in the local array, define the class, and then call storeSharedClass on it (it doesn't matter if it is already in the cache). + * the metadata, cache it in the local array, define the class, and then call storeSharedClass on it (it doesn't matter if it is already in the cache). * All future results from findSharedClass for that classpath entry can then use the cached metadata.

        *

        If findSharedClass returns null, then load the class from disk, cache the metadata from the entry anyway, define the class, and store it.

        *

        Security

        *

        A SharedClassHelper will only allow classes that were defined by the ClassLoader that owns the SharedClassHelper to be stored in the cache.

        *

        If a SecurityManager is installed, SharedClassPermissions must be used to permit read/write access to the shared class cache. * Permissions are granted by ClassLoader classname in the java.policy file and are fixed when the SharedClassHelper is created.

        - *

        Note also that if the createClassLoader RuntimePermission is not granted, ClassLoaders cannot be created, + *

        Note also that if the createClassLoader RuntimePermission is not granted, ClassLoaders cannot be created, * which in turn means that SharedClassHelpers cannot be created.

        *

        Efficient use of the SharedClassURLClasspathHelper

        * Here are some recommendations on using the SharedClassURLClasspathHelper:
        @@ -141,7 +141,7 @@ public interface SharedClassURLClasspathHelper extends SharedClassHelper { public interface IndexHolder { /** * Sets the index in the caller ClassLoader's classpath at which the class was found. - * + * * @param index The index. */ public void setIndex(int index); @@ -149,18 +149,18 @@ public interface IndexHolder { /** *

        Finds a class in the shared cache by using the class name given (implicitly using the caller's classpath).

        - * + * *

        See Using classpaths for rules on when a class will be found.
        - * Null is returned if the class cannot be found, if it is stale (see Dynamic cache updates) + * Null is returned if the class cannot be found, if it is stale (see Dynamic cache updates) * or if it is found for an unconfirmed entry (see Using classpaths).

        - * + * * @param className String. * The name of the class to be found - * + * * @param indexFoundAt IndexHolder. * The index in the caller ClassLoader's classpath at which the class was found. * This parameter can be null if this data is not needed. - * + * * @return byte[]. * A byte array describing the class found, or null. */ @@ -169,25 +169,25 @@ public interface IndexHolder { /** *

        Finds a class in the shared cache by using the class name and partition given (implicitly using the caller's classpath).

        *

        See Using classpaths for rules on when a class will be found.
        - * Null is returned if the class cannot be found, if it is stale (see Dynamic cache updates) + * Null is returned if the class cannot be found, if it is stale (see Dynamic cache updates) * or if it is found for an unconfirmed entry (see Using classpaths).

        - * + * * @param partition String. - * User-defined partition if finding modified bytecode (see Partitions). + * User-defined partition if finding modified bytecode (see Partitions). * Passing null is equivalent of calling non-partition findSharedClass call. - * + * * @param className String. * The name of the class to be found - * + * * @param indexFoundAt IndexHolder. * The index in the caller ClassLoader's classpath at which the class was found. * This parameter can be null if this data is not needed. - * + * * @return byte[]. * A byte array describing the class found, or null. */ public byte[] findSharedClass(String partition, String className, IndexHolder indexFoundAt); - + /** *

        Stores a class in the shared cache by using the caller's URL classpath.

        *

        The class being stored must have been defined by the caller ClassLoader and must exist in the URL location specified.

        @@ -208,12 +208,12 @@ public interface IndexHolder { /** *

        Stores a class in the shared cache by using the caller's URL classpath and with a user-defined partition.

        - * + * *

        The class that is being stored must have been defined by the caller ClassLoader and must exist in the URL location specified.

        *

        Returns true if the class is stored successfully or false otherwise.

        *

        Will return false if the class that is being stored was not defined by the caller ClassLoader.

        *

        Also returns false if the URL at foundAtIndex is not a file URL or if the resource it refers to does not exist.

        - * + * * @param partition String. * User-defined partition if storing modified bytecode (see Partitions). * Passing null is equivalent of calling non-partition storeSharedClass call. @@ -231,40 +231,40 @@ public interface IndexHolder { /** *

        Updates the helper's classpath by appending a URL (see Usage).

        - * + * *

        Note: It is essential that the helper's classpath is kept up-to-date with the classloader.

        - * + * * @param cpe URL. * The classpath entry to append to the classpath */ public void addClasspathEntry(URL cpe); - + /** *

        Updates the helper's classpath with a new classpath.

        - * + * *

        This function is useful for ClassLoaders that compute their classpath lazily. The initial classpath * is passed to the constructor optimistically, but if the classloader discovers a change while reading * an entry, it can update the classpath by using this function.

        *

        Note: It is essential that the helper's classpath is kept up-to-date with the classloader.

        - * + * *

        The classpath that is passed to this function must be exactly the same as the original * classpath up to and including the right-most entry that classes have been loaded from (the right-most confirmed entry).

        *

        Throws a CannotSetClasspathException if this is not the case (see Modifying classpaths).

        - * + * *

        After the classpath has been updated, any indexes passed to storeSharedClass and returned from * findSharedClass correspond to the new classpath.

        - * + * * @param newClasspath * The new URL classpath array - * + * * @throws CannotSetClasspathException when the class path cannot be set. */ public void setClasspath(URL[] newClasspath) throws CannotSetClasspathException; - + /** - *

        Confirms all entries in the current classpath. + *

        Confirms all entries in the current classpath. * Any new entries added will not automatically be confirmed.

        - * + * *

        Note that if all entries are confirmed, setClasspath cannot be used to modify the classpath, only to append new entries. * (see Efficient use of the SharedClassURLClasspathHelper).

        */ diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLClasspathHelperImpl.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLClasspathHelperImpl.java index e3f3cf8a17a..c48862aa475 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLClasspathHelperImpl.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLClasspathHelperImpl.java @@ -28,7 +28,6 @@ import com.ibm.oti.util.Msg; - /** *

        Implementation of SharedClassURLClasspathHelper.

        * @see SharedClassURLClasspathHelper @@ -42,9 +41,9 @@ final class SharedClassURLClasspathHelperImpl extends SharedClassAbstractHelper private int urlCount, confirmedCount; private boolean invalidURLExists; private ReentrantReadWriteLock urlcpReadWriteLock; - + private static native void init(); - + static { init(); } @@ -75,7 +74,7 @@ private void initializeURLs() { } } - private native int findSharedClassImpl2(int loaderId, String partition, String className, ClassLoader loader, URL[] loaderURLs, + private native int findSharedClassImpl2(int loaderId, String partition, String className, ClassLoader loader, URL[] loaderURLs, boolean doFind, boolean doStore, int loaderURLCount, int confirmedURLCount, byte[] romClassCookie); private native boolean storeSharedClassImpl2(int loaderid, String partition, ClassLoader loader, URL[] loaderURLs, int loaderURLCount, int cpLoadIndex, Class clazz, byte[] flags); @@ -86,7 +85,7 @@ private native int findSharedClassImpl2(int loaderId, String partition, String c * essentially flushes the classpath caches and forces them to rebuild. */ private native void notifyClasspathChange2(ClassLoader classloader); - + /* Notify the open state to all the jar/zip files on the URL classpath to force a timestamp check once */ private native void notifyClasspathChange3(int loaderId, ClassLoader classloader, URL[] loaderURLs, int urlIndex, int loaderURLCount, boolean isOpen); @@ -94,7 +93,7 @@ private native int findSharedClassImpl2(int loaderId, String partition, String c public byte[] findSharedClass(String className, IndexHolder indexFoundAtHolder) { return findSharedClass(null, className, indexFoundAtHolder); } - + @Override public byte[] findSharedClass(String partition, String className, IndexHolder indexFoundAtHolder) { ClassLoader loader = getClassLoader(); @@ -135,7 +134,7 @@ public byte[] findSharedClass(String partition, String className, IndexHolder in /* Any URL which has its protocol other than 'jar:' or 'file:' is not supported by * shared class cache and is considered invalid. * invalidURLExists = true indicates classpath contains an invalid URL, - * As such there is no point in calling native method findSharedClassImpl2() + * As such there is no point in calling native method findSharedClassImpl2() * since it is bound to fail when creating classpath entries. */ /*[MSG "K05a4", "Classpath contains an invalid URL. Returning null."]*/ @@ -161,7 +160,7 @@ public byte[] findSharedClass(String partition, String className, IndexHolder in } return romClassCookie; } - + @Override public boolean storeSharedClass(Class clazz, int foundAtIndex) { return storeSharedClass(null, clazz, foundAtIndex); @@ -177,7 +176,7 @@ public boolean storeSharedClass(String partition, Class clazz, int foundAtInd printVerboseError(Msg.getString("K05a3")); //$NON-NLS-1$ return false; } - + if (foundAtIndex<0) { /*[MSG "K05a7", "foundAtIndex cannot be <0 for storeSharedClass. Returning false."]*/ printVerboseError(Msg.getString("K05a7")); //$NON-NLS-1$ @@ -206,9 +205,9 @@ public boolean storeSharedClass(String partition, Class clazz, int foundAtInd /* Any URL which has its protocol other than 'jar:' or 'file:' is not supported by * shared class cache and is considered invalid. * invalidURLExists = true indicates classpath contains an invalid URL, - * As such there is no point in calling native method storeSharedClassImpl2() + * As such there is no point in calling native method storeSharedClassImpl2() * since it is bound to fail when creating classpath entries. - */ + */ /*[MSG "K05a9", "Classpath contains an invalid URL. Returning false."]*/ printVerboseInfo(Msg.getString("K05a9")); //$NON-NLS-1$ return false; @@ -296,7 +295,7 @@ URL[] getClasspath() { } return correctLengthArray; } - + private void increaseConfirmedCount(int newCount) { urlcpReadWriteLock.writeLock().lock(); try { @@ -330,7 +329,7 @@ public void setClasspath(URL[] newClasspath) throws CannotSetClasspathException /*[MSG "K059a", "ClassLoader has been garbage collected. Cannot set sharing filter."]*/ throw new CannotSetClasspathException(Msg.getString("K059a")); //$NON-NLS-1$ } - + urlcpReadWriteLock.writeLock().lock(); try { int commonURLsLength = (origurls.length < newClasspath.length) ? origurls.length : newClasspath.length; @@ -344,17 +343,17 @@ public void setClasspath(URL[] newClasspath) throws CannotSetClasspathException throw new CannotSetClasspathException(Msg.getString("K05ae", i)); //$NON-NLS-1$ } } - + /* Grow urls if necessary */ if (newClasspath.length > origurls.length) { growURLs(newClasspath.length); } - + /* Having ensured that confirmed URLs are the same, validate the others if required, and copy them if they have been modified */ for (int i = confirmedCount; i < commonURLsLength; i++) { boolean urlUpdated = !newClasspath[i].equals(origurls[i]); - - /* If the original classpath had any invalid URL then unconfirmed URLs in original classpath + + /* If the original classpath had any invalid URL then unconfirmed URLs in original classpath * should be validated again in case invalid URL has been corrected now. */ if (invalidURLExists || urlUpdated) { @@ -383,21 +382,21 @@ public void setClasspath(URL[] newClasspath) throws CannotSetClasspathException } else { invalidURLExists = false; } - + for (int i = commonURLsLength; i < newClasspath.length; i++) { origurls[i] = newClasspath[i]; urls[i] = convertJarURL(newClasspath[i]); - + /* if 'invalidURLExists' is already set to true, no need to validate any more URLs */ if (!invalidURLExists && !validateURL(urls[i], false)) { /*[MSG "K05b0", "setClasspath() added new invalid URL {0} at index {1}"]*/ printVerboseInfo(Msg.getString("K05b0", newClasspath[i], Integer.valueOf(i))); //$NON-NLS-1$ - + invalidURLExists = true; } changeMade = true; } - + /* If new classpath is shorter, remaining entries will be ignored as they are > urlCount */ if (urlCount != newClasspath.length) { urlCount = newClasspath.length; diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLHelper.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLHelper.java index 77d2a87c89b..6000a5923e6 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLHelper.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLHelper.java @@ -38,7 +38,7 @@ *

        If partitions are required, the ClassLoader is responsible for coordinating the creation and use of partition Strings.

        *

        Classes can be stored only by using URLs that have file or jar protocols, and that refer to existing resources. * The presence of any other protocol in a URL prevents SharedClassURLHelper from locating and storing classes in the shared cache.

        - *

        Dynamic Cache Updates

        + *

        Dynamic Cache Updates

        *

        Because the shared cache persists beyond the lifetime of a JVM, classes in the shared cache can become out of date (stale).

        * Classes in the cache are automatically kept up to date by default:
        *

        If findSharedClass is called for a class that exists in the cache but which has been updated on the filesystem since it was stored, @@ -63,12 +63,12 @@ *

        A SharedClassHelper will only allow classes that were defined by the ClassLoader that owns the SharedClassHelper to be stored in the cache.

        *

        If a SecurityManager is installed, SharedClassPermissions must be used to permit read/write access to the shared class cache. * Permissions are granted by ClassLoader classname in the java.policy file and are fixed when the SharedClassHelper is created.

        - *

        Note also that if the createClassLoader RuntimePermission is not granted, ClassLoaders cannot be created, + *

        Note also that if the createClassLoader RuntimePermission is not granted, ClassLoaders cannot be created, * which in turn means that SharedClassHelpers cannot be created.

        *

        Compatibility with other SharedClassHelpers

        *

        Classes stored by using the SharedClassURLHelper can be retrieved by using the SharedClassURLClasspathHelper and vice versa. * This is also true for partitions that can be used across these two helpers.

        - * + * * @see SharedClassURLHelper * @see SharedClassHelperFactory * @see SharedClassPermission @@ -139,7 +139,7 @@ public interface SharedClassURLHelper extends SharedClassHelper { * Returns true if the class is stored successfully or false otherwise.

        *

        Will return false if the class being stored was not defined by the caller ClassLoader.

        *

        Also returns false if the URL at foundAtIndex is not a file URL or if the resource it refers to does not exist.

        - * + * * @param partition String. * User-defined partition if storing modified bytecode (see Partitions). * Passing null is equivalent of calling non-partition storeSharedClass call. @@ -152,17 +152,17 @@ public interface SharedClassURLHelper extends SharedClassHelper { * * @return boolean. * True if the class was stored successfully, false otherwise. - */ + */ public boolean storeSharedClass(String partition, URL path, Class clazz); - + /** *

        Minimizes update checking on jar files for optimal performance.

        *

        By default, when a class is loaded from the shared class cache, the timestamp of the container it was originally loaded from is * compared with the timestamp of the actual container on the filesystem. If the two do not match, the original class is marked stale * and is not returned by findSharedClass(). These checks are not performed if the container is held open by the ClassLoader.

        - *

        If the ClassLoader does not want to open the container, but doesn't want the timestamp to be constantly checked when + *

        If the ClassLoader does not want to open the container, but doesn't want the timestamp to be constantly checked when * classes are loaded, it should call this function immediately after the SharedClassURLHelper object has been created. - * After this function has been called, each container timestamp is checked once and then is only checked again if the + * After this function has been called, each container timestamp is checked once and then is only checked again if the * container jar file is opened.
        *

        This feature cannot be unset.

        * diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLHelperImpl.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLHelperImpl.java index e648ef678cc..2e35c2a914c 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLHelperImpl.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassURLHelperImpl.java @@ -39,10 +39,10 @@ final class SharedClassURLHelperImpl extends SharedClassAbstractHelper implements SharedClassURLHelper { /* Not public - should only be created by factory */ private boolean minimizeUpdateChecks; - + /* Used to keep track of new jar files */ private Set jarFileNameCache = null; - + /*[PR VMDESIGN 1080] set to "true" in builds in which VMDESIGN 1080 is finished. */ // This field is examined using the CDS adaptor public static final boolean MINIMIZE_ENABLED = true; @@ -51,15 +51,15 @@ final class SharedClassURLHelperImpl extends SharedClassAbstractHelper implement initialize(loader, id, canFind, canStore); initializeShareableClassloader(loader); } - + private static native void init(); - + /* The passed-in URL path contains a jar file */ private boolean newJarFileCheck(URL convertedJarPath) { String protocol = convertedJarPath.getProtocol(); String jarFile = convertedJarPath.getFile(); boolean isJarType = false; - + if (protocol.equalsIgnoreCase("jar")) { //$NON-NLS-1$ isJarType = true; } else if (protocol.equalsIgnoreCase("file")) { //$NON-NLS-1$ @@ -69,33 +69,33 @@ private boolean newJarFileCheck(URL convertedJarPath) { isJarType = true; } } - + if (null == jarFileNameCache) { jarFileNameCache = ConcurrentHashMap.newKeySet(); } - + if (isJarType) { return jarFileNameCache.add(jarFile); } - + return false; } - private native boolean findSharedClassImpl3(int loaderId, String partition, String className, ClassLoader loader, URL url, + private native boolean findSharedClassImpl3(int loaderId, String partition, String className, ClassLoader loader, URL url, boolean doFind, boolean doStore, byte[] romClassCookie, boolean newJarFile, boolean minUpdateChecks); private native boolean storeSharedClassImpl3(int idloaderId, String partition, ClassLoader loader, URL url, Class clazz, boolean newJarFile, boolean minUpdateChecks, byte[] flags); - + static { init(); } - + @Override public boolean setMinimizeUpdateChecks() { minimizeUpdateChecks = true; return true; } - + @Override public byte[] findSharedClass(URL path, String className) { return findSharedClass(null, path, className); @@ -143,7 +143,7 @@ public byte[] findSharedClass(String partition, URL path, String className) { if (!validateURL(convertedPath, false)) { return null; } - + byte[] romClassCookie = new byte[ROMCLASS_COOKIE_SIZE]; boolean newJarFile = minimizeUpdateChecks ? false : newJarFileCheck(convertedPath); boolean found = findSharedClassImpl3(this.id, partition, className, loader, convertedPath, doFind, doStore, romClassCookie, newJarFile, minimizeUpdateChecks); @@ -178,7 +178,7 @@ public boolean storeSharedClass(String partition, URL path, Class clazz) { if (!validateURL(convertedPath, false)) { return false; } - + ClassLoader actualLoader = getClassLoader(); if (!validateClassLoader(actualLoader, clazz)) { /* Attempt to call storeSharedClass with class defined by a different classloader */ diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassesNamedPermission.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassesNamedPermission.java index 7cc27bb2e15..635b2035e39 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassesNamedPermission.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedClassesNamedPermission.java @@ -47,7 +47,7 @@ *
    */ public final class SharedClassesNamedPermission extends BasicPermission { - + private static final long serialVersionUID = -4800623387760880313L; /* @@ -57,7 +57,7 @@ static final class SharedPermissions { public static final SharedClassesNamedPermission getSharedCacheInfo = new SharedClassesNamedPermission("getSharedCacheInfo"); //$NON-NLS-1$ public static final SharedClassesNamedPermission destroySharedCache = new SharedClassesNamedPermission("destroySharedCache"); //$NON-NLS-1$ } - + /** * Create a representation of the named permissions. * diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedDataHelperImpl.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedDataHelperImpl.java index a8babed0ce2..d7b4b5c68c1 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedDataHelperImpl.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/SharedDataHelperImpl.java @@ -28,7 +28,7 @@ import com.ibm.oti.util.Msg; /** - * Implementation of SharedDataHelper. + * Implementation of SharedDataHelper. *

    * @see SharedDataHelper * @see SharedAbstractHelper diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/package-info.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/package-info.java index b6f3af2d00e..84c881b9f00 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/package-info.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/package-info.java @@ -23,6 +23,6 @@ /** * The OpenJ9 shared classes API, a persistent share which can contain classes, precompiled code (AOT), - * JIT data, and other data used to improve start up performance and reduce memory footprint. + * JIT data, and other data used to improve start up performance and reduce memory footprint. */ package com.ibm.oti.shared; diff --git a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/provider/SharedClassProviderImpl.java b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/provider/SharedClassProviderImpl.java index c60a0e56b54..e5bd52cedfe 100644 --- a/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/provider/SharedClassProviderImpl.java +++ b/jcl/src/openj9.sharedclasses/share/classes/com/ibm/oti/shared/provider/SharedClassProviderImpl.java @@ -82,7 +82,7 @@ public SharedClassProvider initializeProvider(ClassLoader loader, URL[] classpat return null; } } - } catch (HelperAlreadyDefinedException ex) { + } catch (HelperAlreadyDefinedException ex) { return null; } return this; From fc7dee893deab9f4f1086a9ef074b9d0cf59fec6 Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 17:07:25 -0400 Subject: [PATCH 15/16] Tidy up whitespace in openj9.traceformat * remove trailing whitespace * indent with tabs consistently * collapse sequences of two or more blank lines * remove extra trailing blank lines Signed-off-by: Keith W. Campbell --- .../com/ibm/jvm/format/ActiveSection.java | 96 +- .../com/ibm/jvm/format/Format2Tprof.java | 250 +-- .../ibm/jvm/format/IncompleteTracePoint.java | 10 +- .../format/InvalidSpannedRecordException.java | 14 +- .../classes/com/ibm/jvm/format/Merge.java | 218 +-- .../classes/com/ibm/jvm/format/Message.java | 1073 ++++++------ .../com/ibm/jvm/format/MessageFile.java | 26 +- .../com/ibm/jvm/format/ProcessorSection.java | 132 +- .../com/ibm/jvm/format/ServiceSection.java | 222 +-- .../com/ibm/jvm/format/StartupSection.java | 140 +- .../classes/com/ibm/jvm/format/TraceArgs.java | 442 +++-- .../classes/com/ibm/jvm/format/TraceFile.java | 269 ++- .../com/ibm/jvm/format/TraceFileHeader.java | 389 ++--- .../com/ibm/jvm/format/TraceFormat.java | 96 +- .../com/ibm/jvm/format/TracePoint.java | 38 +- .../com/ibm/jvm/format/TraceRecord.java | 1041 ++++++------ .../com/ibm/jvm/format/TraceRecord50.java | 68 +- .../ibm/jvm/format/TraceRecordExternal.java | 425 +++-- .../ibm/jvm/format/TraceRecordInternal.java | 370 +++-- .../com/ibm/jvm/format/TraceSection.java | 132 +- .../com/ibm/jvm/format/TraceThread.java | 322 ++-- .../classes/com/ibm/jvm/format/Util.java | 1444 ++++++++--------- .../classes/com/ibm/jvm/trace/TraceFile.java | 27 +- .../com/ibm/jvm/trace/TraceFileHeader.java | 7 +- .../classes/com/ibm/jvm/trace/TracePoint.java | 12 +- ...TracePointGlobalChronologicalIterator.java | 10 +- ...TracePointThreadChronologicalIterator.java | 6 +- .../com/ibm/jvm/trace/TraceThread.java | 2 +- .../jvm/trace/format/api/ActiveSection.java | 16 +- .../ibm/jvm/trace/format/api/ByteStream.java | 31 +- .../ibm/jvm/trace/format/api/Component.java | 2 +- .../ibm/jvm/trace/format/api/DataHeader.java | 4 +- .../com/ibm/jvm/trace/format/api/Message.java | 54 +- .../ibm/jvm/trace/format/api/MessageFile.java | 16 +- .../trace/format/api/ProcessorSection.java | 11 +- .../jvm/trace/format/api/ServiceSection.java | 8 +- .../jvm/trace/format/api/StartupSection.java | 10 +- .../jvm/trace/format/api/TraceContext.java | 97 +- .../jvm/trace/format/api/TraceFileHeader.java | 26 +- .../ibm/jvm/trace/format/api/TracePoint.java | 4 +- .../trace/format/api/TracePointDebugInfo.java | 6 +- .../jvm/trace/format/api/TracePointImpl.java | 14 +- .../ibm/jvm/trace/format/api/TraceRecord.java | 140 +- .../jvm/trace/format/api/TraceSection.java | 6 +- .../ibm/jvm/trace/format/api/TraceThread.java | 24 +- .../jvm/trace/format/api/package-info.java | 1 - .../com/ibm/jvm/traceformat/TraceFormat.java | 14 +- 47 files changed, 3870 insertions(+), 3895 deletions(-) diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ActiveSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ActiveSection.java index 08a5443c070..0adc2464ca6 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ActiveSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ActiveSection.java @@ -25,64 +25,64 @@ import java.io.BufferedWriter; import java.io.IOException; -/** +/** * Active section of a file header. * * @author Tim Preece */ public class ActiveSection { - private String eyecatcher_string; - private int length; - private int version; - private int modification; - private long active_offset; - private long active_end; + private String eyecatcher_string; + private int length; + private int version; + private int modification; + private long active_offset; + private long active_end; - private TraceFile traceFile; + private TraceFile traceFile; - public ActiveSection (TraceFile traceFile, int start ) throws IOException - { - // Version 1.1 - this.traceFile = traceFile; - traceFile.seek((long)start); - eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); - length = traceFile.readI(); - version = traceFile.readI(); - modification = traceFile.readI(); - active_offset = traceFile.getFilePointer(); - active_end = start + length; + public ActiveSection (TraceFile traceFile, int start ) throws IOException + { + // Version 1.1 + this.traceFile = traceFile; + traceFile.seek((long)start); + eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); + length = traceFile.readI(); + version = traceFile.readI(); + modification = traceFile.readI(); + active_offset = traceFile.getFilePointer(); + active_end = start + length; - Util.Debug.println("ActiveSection: eyecatcher: " + eyecatcher_string); - Util.Debug.println("ActiveSection: length: " + length); - Util.Debug.println("ActiveSection: version: " + version); - Util.Debug.println("ActiveSection: modification: " + modification); + Util.Debug.println("ActiveSection: eyecatcher: " + eyecatcher_string); + Util.Debug.println("ActiveSection: length: " + length); + Util.Debug.println("ActiveSection: version: " + version); + Util.Debug.println("ActiveSection: modification: " + modification); - } + } - protected void summary(BufferedWriter out) throws IOException - { - traceFile.seek(active_offset); - byte[] activeBuffer = new byte[(int)(active_end - active_offset)]; - Util.Debug.println("ActiveSection: active_offset: " + active_offset); - Util.Debug.println("ActiveSection: active_end: " + active_end); + protected void summary(BufferedWriter out) throws IOException + { + traceFile.seek(active_offset); + byte[] activeBuffer = new byte[(int)(active_end - active_offset)]; + Util.Debug.println("ActiveSection: active_offset: " + active_offset); + Util.Debug.println("ActiveSection: active_end: " + active_end); - out.write("Activation Info :"); - out.newLine(); + out.write("Activation Info :"); + out.newLine(); - StringBuffer buf; - traceFile.read(activeBuffer); - // Util.printDump(activeBuffer,activeBuffer.length); - for (int i=0, j=0; (i 2) { - System.err.println("Format2Tprof [tprof output]"); - return; - } - LinkedList sampleMethodTable = new LinkedList(); - if (!readAndFormat(args, sampleMethodTable)) { - System.err.println("No method sampling event found in the trace. No output will be written."); - return; - } - Collections.sort(sampleMethodTable); - // System.err.println(sampleMethodTable); - totalCount = sampleMethodTable.size(); - countSampleMethod(sampleMethodTable); // dup method names will be removed - Collections.sort(sampleMethodTable, new Comparator() - { - public int compare(Object o1, Object o2) { - MethodEntry m1 = (MethodEntry) o1; - MethodEntry m2 = (MethodEntry) o2; - return m2.count - m1.count; // in descending order - } - } - ); - try { - PrintStream ps = System.out; // default - if (args.length == 2) - ps = new PrintStream(new FileOutputStream(args[1])); - generateTprofOutput(ps, sampleMethodTable); - if (args.length == 2) - ps.close(); - } - catch (FileNotFoundException e) { - System.err.println("Error opening output file"); - e.printStackTrace(); - } - } - - public static void main(String args[]) { - Format2Tprof pf = new Format2Tprof(); - pf.run(args); - } - - public void countSampleMethod(Collection s) { - Iterator iter = s.iterator(); - MethodEntry pe = (MethodEntry) iter.next(); - pe.count++; - while (iter.hasNext()) - { - MethodEntry e = (MethodEntry) iter.next(); - if (pe.equals(e)) - iter.remove(); - else - pe = e; - pe.count++; - } - } + public class MethodEntry implements Comparable { + public String name = null; + public String offset = null; + public int count = 0; + public MethodEntry(String n, String o) { name = n; offset = o; } + public MethodEntry(String n) { name = n; } + /* offset won't be compared */ + public boolean equals(Object o) { MethodEntry e = (MethodEntry) o; return name.equals(e.name); } + public int compareTo(Object o) { MethodEntry e = (MethodEntry) o; return name.compareTo(e.name); } + } - public void generateTprofOutput(PrintStream out, Collection s) { - Iterator iter = s.iterator(); - while (iter.hasNext()) - { - MethodEntry e = (MethodEntry) iter.next(); - float percent = (float) (e.count * 100) / totalCount; - String percentStr = Float.toString(percent).substring(0, 4) + "%"; - out.println(percentStr + " " + e.count + " " + e.name); - } - } + public void run(String args[]) { + if (args.length < 1 || args.length > 2) { + System.err.println("Format2Tprof [tprof output]"); + return; + } + LinkedList sampleMethodTable = new LinkedList(); + if (!readAndFormat(args, sampleMethodTable)) { + System.err.println("No method sampling event found in the trace. No output will be written."); + return; + } + Collections.sort(sampleMethodTable); + // System.err.println(sampleMethodTable); + totalCount = sampleMethodTable.size(); + countSampleMethod(sampleMethodTable); // dup method names will be removed + Collections.sort(sampleMethodTable, new Comparator() + { + public int compare(Object o1, Object o2) { + MethodEntry m1 = (MethodEntry) o1; + MethodEntry m2 = (MethodEntry) o2; + return m2.count - m1.count; // in descending order + } + } + ); + try { + PrintStream ps = System.out; // default + if (args.length == 2) + ps = new PrintStream(new FileOutputStream(args[1])); + generateTprofOutput(ps, sampleMethodTable); + if (args.length == 2) + ps.close(); + } + catch (FileNotFoundException e) { + System.err.println("Error opening output file"); + e.printStackTrace(); + } + } - public MethodEntry getJittedMethod(String msg) { - int firstTabPos = msg.indexOf(FS); - int secondTabPos = (firstTabPos != -1) ? msg.indexOf(FS, firstTabPos+1) : -1; - if (firstTabPos == -1 || secondTabPos == -1) - return null; - String name = msg.substring(firstTabPos+1,secondTabPos-1); - int thirdTabPos = msg.indexOf(FS, secondTabPos+1); - if (thirdTabPos == -1) - return new MethodEntry(name); - int fourthTabPos = msg.indexOf(FS, thirdTabPos+1); - if (fourthTabPos == -1) - return new MethodEntry(name, msg.substring(thirdTabPos+1)); - return new MethodEntry(name, msg.substring(thirdTabPos+1,fourthTabPos-1)); - } + public static void main(String args[]) { + Format2Tprof pf = new Format2Tprof(); + pf.run(args); + } - public boolean readAndFormat(String args[], List methodTable) { - boolean rc = false; - try { - BufferedReader in = new BufferedReader(new FileReader(args[0])); - String line = null; - while ((line = in.readLine()) != null) { - int pos; - if ((pos = line.indexOf(TraceEntryPrefix)) != -1) { - String formattedData = line.substring(pos); - MethodEntry me = getJittedMethod(formattedData); - if (me != null) { - rc = true; - methodTable.add(me); - } - } - } - in.close(); - } - catch (FileNotFoundException e) { - System.err.println("Error opening trace file"); - e.printStackTrace(); - } - catch (IOException e) { - System.err.println("Error processing trace file"); - e.printStackTrace(); - } - return rc; - } + public void countSampleMethod(Collection s) { + Iterator iter = s.iterator(); + MethodEntry pe = (MethodEntry) iter.next(); + pe.count++; + while (iter.hasNext()) + { + MethodEntry e = (MethodEntry) iter.next(); + if (pe.equals(e)) + iter.remove(); + else + pe = e; + pe.count++; + } + } + + public void generateTprofOutput(PrintStream out, Collection s) { + Iterator iter = s.iterator(); + while (iter.hasNext()) + { + MethodEntry e = (MethodEntry) iter.next(); + float percent = (float) (e.count * 100) / totalCount; + String percentStr = Float.toString(percent).substring(0, 4) + "%"; + out.println(percentStr + " " + e.count + " " + e.name); + } + } + + public MethodEntry getJittedMethod(String msg) { + int firstTabPos = msg.indexOf(FS); + int secondTabPos = (firstTabPos != -1) ? msg.indexOf(FS, firstTabPos+1) : -1; + if (firstTabPos == -1 || secondTabPos == -1) + return null; + String name = msg.substring(firstTabPos+1,secondTabPos-1); + int thirdTabPos = msg.indexOf(FS, secondTabPos+1); + if (thirdTabPos == -1) + return new MethodEntry(name); + int fourthTabPos = msg.indexOf(FS, thirdTabPos+1); + if (fourthTabPos == -1) + return new MethodEntry(name, msg.substring(thirdTabPos+1)); + return new MethodEntry(name, msg.substring(thirdTabPos+1,fourthTabPos-1)); + } + + public boolean readAndFormat(String args[], List methodTable) { + boolean rc = false; + try { + BufferedReader in = new BufferedReader(new FileReader(args[0])); + String line = null; + while ((line = in.readLine()) != null) { + int pos; + if ((pos = line.indexOf(TraceEntryPrefix)) != -1) { + String formattedData = line.substring(pos); + MethodEntry me = getJittedMethod(formattedData); + if (me != null) { + rc = true; + methodTable.add(me); + } + } + } + in.close(); + } + catch (FileNotFoundException e) { + System.err.println("Error opening trace file"); + e.printStackTrace(); + } + catch (IOException e) { + System.err.println("Error processing trace file"); + e.printStackTrace(); + } + return rc; + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/IncompleteTracePoint.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/IncompleteTracePoint.java index c34e8d95481..c3a3409d1a5 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/IncompleteTracePoint.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/IncompleteTracePoint.java @@ -29,17 +29,17 @@ public class IncompleteTracePoint{ public static final int INVALID_TYPE = -1; public static final int START_TYPE = 1; public static final int END_TYPE = 2; - + private int type = INVALID_TYPE; private int bytesMissing = 0; - + public IncompleteTracePoint( byte[] data, int length, int type, long threadId ){ this.type = type; - this.threadId = threadId; + this.threadId = threadId; this.data = new byte[ length ]; System.arraycopy(data, 0, this.data, 0, length); } - + public int setBytesRequired(int bytes){ this.bytesMissing = bytes; return bytes; @@ -56,7 +56,7 @@ public byte[] getData(){ public long getThreadID(){ return threadId; } - + public int getType(){ return type; } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/InvalidSpannedRecordException.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/InvalidSpannedRecordException.java index 451885bc549..46fc72f0718 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/InvalidSpannedRecordException.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/InvalidSpannedRecordException.java @@ -24,7 +24,7 @@ import java.io.IOException; -/** +/** * This exception is thrown when the beginning of a buffer (including spanned * record if any) is not the start of a record. *

    An InvalidSpannedRecordException is thrown whenever an invalid spanned @@ -35,11 +35,11 @@ */ public class InvalidSpannedRecordException extends IOException { - public InvalidSpannedRecordException() { - super(); - } + public InvalidSpannedRecordException() { + super(); + } - public InvalidSpannedRecordException(String s) { - super(s); - } + public InvalidSpannedRecordException(String s) { + super(s); + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Merge.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Merge.java index daf9281917e..0d3264d35a6 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Merge.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Merge.java @@ -26,119 +26,119 @@ import java.math.BigInteger; import java.util.*; -/** +/** * Merges the trace entries * * @author Tim Preece */ final public class Merge { - private Vector threads; - private TraceRecord currentTraceRecord=null; - private BigInteger nextOldest; - private LinkedList traceRecordList = new LinkedList(); - private boolean oneThreadLeft = false; - private int numberOfRecordsProcessed = 0; - - /** construct the Merge object - * - * @param List of threads with trace records to merge - */ - protected Merge(Vector threads) throws IOException - { - this.threads = threads; - - // prime the oldest Trace Record in each thread - TraceThread traceThread; - TraceRecord traceRecord; - for (Iterator t=threads.iterator(); t.hasNext();) { - traceThread = (TraceThread)t.next(); - traceRecord = (TraceRecord)traceThread.firstElement(); - traceRecord.prime(); - traceRecordList.add(traceRecord); - } - TraceFormat.outStream.println("Number of Trace Buffers Processed:"); - TraceFormat.outStream.print(" 0 "); - - getCurrentTraceRecordAndUpdateNextOldest(); - Util.Debug.println("Merge: nextOldest after constructor " + nextOldest); - } - - /** get the current Trace Record and update the nextOldest. - * - * @param void - * @return void - */ - final protected void getCurrentTraceRecordAndUpdateNextOldest() - { - Collections.sort(traceRecordList); - currentTraceRecord = (TraceRecord)traceRecordList.get(0); - if (traceRecordList.size() > 1) { - nextOldest = ((TraceRecord)traceRecordList.get(1)).getCurrentTimeStamp(); - } - else { - nextOldest = BigInteger.ZERO; - oneThreadLeft = true; - } - return ; - } - - /** get the next trace entry ( the oldest ) - * - * @param void - * @return the formatted trace entry ( null means we are finished ) - */ - final protected String getNextEntry() throws IOException - { - BigInteger timeStamp; // timeStamp of the next entry - TraceRecord traceRecord; - - while (currentTraceRecord.getNextEntry() == 0) { // 0 means we have no more entries on this record - Util.Debug.println("Merge: no more entries in this Record"); - - numberOfRecordsProcessed++; - if (numberOfRecordsProcessed%10 == 0 || - numberOfRecordsProcessed == TraceFormat.expectedRecords) - { - StringBuffer tempBuffer = new StringBuffer(Integer.toString(numberOfRecordsProcessed)); - Util.padBuffer(tempBuffer, 6, ' ', false); // right justify - field width 6 (at least) - TraceFormat.outStream.print(tempBuffer+" "); - } - - if ((numberOfRecordsProcessed+10)%100 == 0) { // throw new line BEFORE the 100 multiples - TraceFormat.outStream.println(""); - } - - currentTraceRecord.release(); // release the large buffer for GC - traceRecordList.remove(currentTraceRecord); // remove Record from list of current Records - traceRecord = currentTraceRecord.getNextRecord(); // get this threads next record - if (traceRecord != null ) { // if we have one .... - Util.Debug.println("Merge: priming next Record on this thread"); - traceRecord.prime(); // prime it .... - traceRecordList.add(traceRecord); // and add to list of current Records - } - - if (traceRecordList.size() == 0 ) { // if current record list is empty ..... - Util.Debug.println("Merge: Finished"); - TraceFormat.outStream.println(" "); - return null; // we have finished - } - getCurrentTraceRecordAndUpdateNextOldest(); // update currentTraceRecord and nextOldest - } - timeStamp = currentTraceRecord.getCurrentTimeStamp(); - - //Util.Debug.println("Merge: timeStamp = " + timeStamp); - //Util.Debug.println("Merge: nextOldest = " + nextOldest); - //Util.Debug.println("Merge: compareTo = " + timeStamp.compareTo(nextOldest)); - - // is current TimeStamp older than cached ( nextOldest ) - if (timeStamp.compareTo(nextOldest) != -1 && oneThreadLeft == false ) { - //Util.Debug.println("Merge: swapping records " ); - getCurrentTraceRecordAndUpdateNextOldest(); - //Util.Debug.println("Merge: nextOldest after swap " + nextOldest); - currentTraceRecord.getNextEntry(); - } - - return currentTraceRecord.formatCurrentEntry(); - } + private Vector threads; + private TraceRecord currentTraceRecord=null; + private BigInteger nextOldest; + private LinkedList traceRecordList = new LinkedList(); + private boolean oneThreadLeft = false; + private int numberOfRecordsProcessed = 0; + + /** construct the Merge object + * + * @param List of threads with trace records to merge + */ + protected Merge(Vector threads) throws IOException + { + this.threads = threads; + + // prime the oldest Trace Record in each thread + TraceThread traceThread; + TraceRecord traceRecord; + for (Iterator t=threads.iterator(); t.hasNext();) { + traceThread = (TraceThread)t.next(); + traceRecord = (TraceRecord)traceThread.firstElement(); + traceRecord.prime(); + traceRecordList.add(traceRecord); + } + TraceFormat.outStream.println("Number of Trace Buffers Processed:"); + TraceFormat.outStream.print(" 0 "); + + getCurrentTraceRecordAndUpdateNextOldest(); + Util.Debug.println("Merge: nextOldest after constructor " + nextOldest); + } + + /** get the current Trace Record and update the nextOldest. + * + * @param void + * @return void + */ + final protected void getCurrentTraceRecordAndUpdateNextOldest() + { + Collections.sort(traceRecordList); + currentTraceRecord = (TraceRecord)traceRecordList.get(0); + if (traceRecordList.size() > 1) { + nextOldest = ((TraceRecord)traceRecordList.get(1)).getCurrentTimeStamp(); + } + else { + nextOldest = BigInteger.ZERO; + oneThreadLeft = true; + } + return ; + } + + /** get the next trace entry ( the oldest ) + * + * @param void + * @return the formatted trace entry ( null means we are finished ) + */ + final protected String getNextEntry() throws IOException + { + BigInteger timeStamp; // timeStamp of the next entry + TraceRecord traceRecord; + + while (currentTraceRecord.getNextEntry() == 0) { // 0 means we have no more entries on this record + Util.Debug.println("Merge: no more entries in this Record"); + + numberOfRecordsProcessed++; + if (numberOfRecordsProcessed%10 == 0 || + numberOfRecordsProcessed == TraceFormat.expectedRecords) + { + StringBuffer tempBuffer = new StringBuffer(Integer.toString(numberOfRecordsProcessed)); + Util.padBuffer(tempBuffer, 6, ' ', false); // right justify - field width 6 (at least) + TraceFormat.outStream.print(tempBuffer+" "); + } + + if ((numberOfRecordsProcessed+10)%100 == 0) { // throw new line BEFORE the 100 multiples + TraceFormat.outStream.println(""); + } + + currentTraceRecord.release(); // release the large buffer for GC + traceRecordList.remove(currentTraceRecord); // remove Record from list of current Records + traceRecord = currentTraceRecord.getNextRecord(); // get this threads next record + if (traceRecord != null ) { // if we have one .... + Util.Debug.println("Merge: priming next Record on this thread"); + traceRecord.prime(); // prime it .... + traceRecordList.add(traceRecord); // and add to list of current Records + } + + if (traceRecordList.size() == 0 ) { // if current record list is empty ..... + Util.Debug.println("Merge: Finished"); + TraceFormat.outStream.println(" "); + return null; // we have finished + } + getCurrentTraceRecordAndUpdateNextOldest(); // update currentTraceRecord and nextOldest + } + timeStamp = currentTraceRecord.getCurrentTimeStamp(); + + //Util.Debug.println("Merge: timeStamp = " + timeStamp); + //Util.Debug.println("Merge: nextOldest = " + nextOldest); + //Util.Debug.println("Merge: compareTo = " + timeStamp.compareTo(nextOldest)); + + // is current TimeStamp older than cached ( nextOldest ) + if (timeStamp.compareTo(nextOldest) != -1 && oneThreadLeft == false ) { + //Util.Debug.println("Merge: swapping records " ); + getCurrentTraceRecordAndUpdateNextOldest(); + //Util.Debug.println("Merge: nextOldest after swap " + nextOldest); + currentTraceRecord.getNextEntry(); + } + + return currentTraceRecord.formatCurrentEntry(); + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Message.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Message.java index e82a5d9ca70..383c510c7b9 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Message.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Message.java @@ -26,542 +26,541 @@ final public class Message { - private static int ptrSize; - - private int type; - private String message; - private String component; - private boolean zero = false; - private String symbol; - - public Message(int type, String message, String component, String symbol) - { - this.type = type; - this.message = message; - this.component = component; - this.symbol = symbol; - } - - /** processs all the percent sign directives in a string, much like a call to printf - * - * @param str a string - * @return the string with percent directive replaces by their associated values - * - */ - protected StringBuffer processPercents(String str, byte[] buffer, int offset) - { - - FormatSpec fspec = null; - StringBuffer result = new StringBuffer(); - int index = str.indexOf("%"); - zero = false; - int dataSize; - long l; - int i; - String s; - boolean prefix0x; - boolean utf8; - - while ( (index != -1) && (offset < buffer.length)) - { - utf8 = false; - dataSize = 4; // Default to an integer - prefix0x = (index > 1) ? // Check for "0x" prefix - "0x".equalsIgnoreCase(str.substring(index - 2, index)): - false; - result.append(str.substring(0, index)); - str = str.substring(index+1, str.length()); - /* - * Check for "-" prefix - */ - if ( str.charAt(0) == '-' ) - { - fspec = new FormatSpec(true); - str = str.substring(1, str.length()); - } - - /* - * Zero padding ? - */ - if (str.charAt(0) == '0') - { - zero = true; - str = str.substring(1, str.length()); - } - /* - * Handle width... - */ - if ( Character.isDigit(str.charAt(0)) ) - { - if ( fspec == null ) - { - fspec = new FormatSpec(); - } - String val = readDigits(str); - fspec.width = Integer.valueOf(val); - str = str.substring(val.length(), str.length()); - } - - /* - * ...and precision - */ - if ( str.charAt(0) == '.' ) - { - str = str.substring(1, str.length()); - if (str.charAt(0) == '*') { - utf8 = true; - str = str.substring(1, str.length()); - } else { - - if ( fspec == null ) - { - fspec = new FormatSpec(); - } - - String prec = readDigits(str); - fspec.precision = Integer.valueOf(prec); - str = str.substring(prec.length(), str.length()); - } - } - - /* - * Check for a size modifier - */ - char first = str.charAt(0); - - if (first == 'l') - { - if (str.charAt(1) == 'l') - { - dataSize = Util.LONG; - str = str.substring(2, str.length()); - } else { - // Default size is INT - str = str.substring(1, str.length()); - } - } - else if (first == 'I' && str.charAt(1) == '6' && str.charAt(2) == '4') - { - dataSize = Util.LONG; - str = str.substring(3, str.length()); - } - else if (first == 'h') - { - dataSize = 2; - str = str.substring(1, str.length()); - } - else if (first == 'z') - { - if (ptrSize == 8) { - dataSize = Util.LONG; - } - str = str.substring(1, str.length()); - } - - /* - * Finally check for a type - */ - first = str.charAt(0); - switch (first) { - - case 'p': - l = ptrSize == 4 ? Util.constructUnsignedInt(buffer, offset) : - Util.constructUnsignedLong(buffer, offset).longValue(); - offset += ptrSize; - if (!prefix0x) { - result.append("0x"); - } - result.append(format(l, fspec, 16)); - str = str.substring(1, str.length()); - break; - - case 's': - if (utf8) { - int utf8Length = Util.constructUnsignedLong(buffer, offset, 2).intValue(); - offset += 2; - s = Util.constructString(buffer, offset, utf8Length); - offset += utf8Length; - } else { - s = Util.constructString(buffer, offset); - offset += (s.length() + 1); - } - s = Util.escapeControlCharacters(s); - result.append(format(s, fspec)); - str = str.substring(1, str.length()); - break; - - case 'd': - case 'i': - l = dataSize == 4 ? Util.constructUnsignedInt(buffer, offset) : - Util.constructUnsignedLong(buffer, offset).longValue(); - offset += dataSize; - result.append(format(l, fspec)); - str = str.substring(1, str.length()); - break; - - case 'u': - if (dataSize == 4) { - l = Util.constructUnsignedInt(buffer, offset); - l = l & 0xffffffffL; - } else { - l = Util.constructUnsignedLong(buffer, offset).longValue(); - } - offset += dataSize; - result.append(format(l, fspec)); - str = str.substring(1, str.length()); - break; - - case 'f': - /* CMVC 164940 All %f tracepoints were promoted to double in runtime trace code. - * Affects: - * TraceFormat com/ibm/jvm/format/Message.java - * TraceFormat com/ibm/jvm/trace/format/api/Message.java - * runtime ute/ut_trace.c - * TraceGen OldTrace.java - * Intentional fall through to next case. - */ - case 'g': - l = Util.constructUnsignedLong(buffer, offset).longValue(); - offset += Util.LONG; - result.append(format(Double.longBitsToDouble(l), fspec)); - str = str.substring(1, str.length()); - break; - - case 'X': - case 'x': - if (dataSize == 4) { - l = Util.constructUnsignedInt(buffer, offset); - l = l & 0xffffffffL; - } else { - l = Util.constructUnsignedLong(buffer, offset).longValue(); - } - offset += dataSize; - if (!prefix0x) { - result.append("0x"); - } - result.append(format(l, fspec, 16)); - str = str.substring(1, str.length()); - break; - - case 'c': - s = Util.constructString(buffer, offset, 1); - offset += 1; - s = Util.escapeControlCharacters(s); - result.append(format(s, fspec)); - str = str.substring(1, str.length()); - break; - - case '%': - result.append("%"); - str = str.substring(1, str.length()); - break; - - case '+': - case ' ': - case '#': - TraceFormat.outStream.println("Used a printf flag not supported " + first); - str = str.substring(1, str.length()); - break; - - default: - TraceFormat.outStream.println("error percent directive looked like => " + str); - str = str.substring(1, str.length()); - } - - fspec = null; - zero = false; - index = str.indexOf("%"); - } - result.append(str); - return result; - } - - /** process all the percent sign directives in a string, making them "???" - * - * @param str a string - * @return the string with percent directives replaced by "???" - * - */ - protected StringBuffer skipPercents(String str, byte[] buffer, int offset) - { - - StringBuffer result = new StringBuffer(); - int index = str.indexOf("%"); - - while ( (index != -1) && (offset < buffer.length)) - { - result.append(str.substring(0, index)); - str = str.substring(index+1, str.length()); - if ( str.charAt(0) == '-' || - str.charAt(0) == '0') - { - str = str.substring(1, str.length()); - } - - if ( Character.isDigit(str.charAt(0)) ) - { - String val = readDigits(str); - str = str.substring(val.length(), str.length()); - } - - if ( str.charAt(0) == '.' ) - { - str = str.substring(1, str.length()); - if (str.charAt(0) == '*') { - str = str.substring(1, str.length()); - } else { - String prec = readDigits(str); - str = str.substring(prec.length(), str.length()); - } - } - /* - * Check for a size modifier - */ - - char first = str.charAt(0); - - if (first == 'l') - { - str = str.substring((str.charAt(1) == 'l' ? 2 : 1), str.length()); - } - else if (first == 'I' && str.charAt(1) == '6' && str.charAt(2) == '4') - { - str = str.substring(3, str.length()); - } - else if (first == 'h') - { - str = str.substring(1, str.length()); - } - else if (first == 'z') - { - str = str.substring(1, str.length()); - } - - /* - * Now look for a type - */ - first = str.charAt(0); - switch (first) { - - case 'd': - case 'i': - case 'u': - case 'f': - case 'X': - case 'x': - case 'p': - case 's': - case 'c': - str = str.substring(1, str.length()); - result.append("???"); - break; - case '%': - result.append("%"); - str = str.substring(1, str.length()); - break; - case '+': - case ' ': - case '#': - TraceFormat.outStream.println("Used a printf flag not supported " + first); - str = str.substring(1, str.length()); - break; - default: - TraceFormat.outStream.println("Error: percent directive looked like => " + str); - str = str.substring(1, str.length()); - } - index = str.indexOf("%"); - } - result.append(str); - return result; - } - - protected static void setPointerSize() - { - ptrSize = Integer.valueOf(Util.getProperty("POINTER_SIZE")).intValue(); - } - - private String readDigits(String str) - { - - char[] digits = new char[10]; - int index = 0; - - while ( Character.isDigit(str.charAt(index)) ) - { - - if ( index < digits.length ) - { - digits[index] = str.charAt(index); - index++; - } - } - return new String(digits, 0, index); - } - - - private StringBuffer format(BigInteger val, FormatSpec spec) - { - StringBuffer str = new StringBuffer(val.toString()); - if ( spec != null ) - { - if ( spec.precision != null ) - { - Util.padBuffer(str, spec.precision.intValue(), '0'); - } - if ( spec.width != null ) - { - Util.padBuffer(str, spec.width.intValue(), ' ', spec.leftJustified); - } - } - return str; - } - - private StringBuffer format(long val, FormatSpec spec) - { - return format(val, spec, 10); - } - - private StringBuffer format(long val, FormatSpec spec, int radix) - { - StringBuffer str = new StringBuffer(Long.toString(val, radix)); - if ( spec != null ) - { - if ( spec.precision != null ) - { - Util.padBuffer(str, spec.precision.intValue(), '0'); - } - if ( spec.width != null ) - { - Util.padBuffer(str, - spec.width.intValue(), - (zero && !spec.leftJustified) ? '0' : ' ', - spec.leftJustified); - } - } - return str; - } - - private StringBuffer format(float val, FormatSpec spec) - { - StringBuffer str = new StringBuffer(Float.toString(val)); - if ( spec != null ) - { - if ( spec.width != null ) - { - Util.padBuffer(str, spec.width.intValue(), ' ', spec.leftJustified); - } - } - return str; - } - - private StringBuffer format(double val, FormatSpec spec) - { - StringBuffer str = new StringBuffer(Double.toString(val)); - if ( spec != null ) - { - if ( spec.width != null ) - { - Util.padBuffer(str, spec.width.intValue(), ' ', spec.leftJustified); - } - } - return str; - } - private StringBuffer format(String str, FormatSpec spec) - { - StringBuffer result = new StringBuffer(); - if ( spec != null ) - { - if ( spec.precision != null ) - { - int x = spec.precision.intValue(); - - if ( x < str.length() ) - { - - str = str.substring(0, x); - } - } - result.append(str); - if ( spec.width != null ) - { - Util.padBuffer(result, spec.width.intValue(), ' ', spec.leftJustified); - } - } - else - { - result.append(str); - } - return result; - } - - - /** retrieve the text of the message, parsing any percent directives and replacing them with data from the buffer - * - * @param buffer an array of bytes - * @param offset an int - * @return a string that is the message from the file with any percent directives replaces by data from the buffer - */ - public String getMessage(byte[] buffer, int offset, int end) - { - String prefix = ( TraceArgs.symbolic ) ? symbol+" " : ""; - - if ( offset < end ) - { - // If this is preformatted application trace, skip the first 4 bytes - if (component == "ApplicationTrace") { - offset += 4; - } - return prefix + processPercents(message, buffer, offset).toString(); - } else { - return prefix + skipPercents(message, buffer, offset).toString(); - } - } - - /** returns the component this message corresponds to, as - * determined by the message file - * - * @return an String that is component from which this message came from - */ - protected String getComponent() - { - return component; - } - - /** returns the type of entry this message corresponds - * to, as determined by the message file and TraceRecord - * - * @return an int that is one of the types defined in TraceRecord - * @see TraceRecord - */ - protected int getType() - { - return type; - } - - protected String getFormattingTemplate(){ - return message; - } - - class FormatSpec - { - protected Integer width; // this are object types to have - protected Integer precision; // a null value mean not set. - protected boolean leftJustified = false; - - public FormatSpec(boolean left) - { - this.leftJustified = left; - } - - public FormatSpec() - { - this(false); - } - - public String toString() - { - return "FormatSpec w: "+ width +" p:"+ precision + " just: "+ leftJustified; - } - } + private static int ptrSize; + + private int type; + private String message; + private String component; + private boolean zero = false; + private String symbol; + + public Message(int type, String message, String component, String symbol) + { + this.type = type; + this.message = message; + this.component = component; + this.symbol = symbol; + } + + /** processs all the percent sign directives in a string, much like a call to printf + * + * @param str a string + * @return the string with percent directive replaces by their associated values + * + */ + protected StringBuffer processPercents(String str, byte[] buffer, int offset) + { + + FormatSpec fspec = null; + StringBuffer result = new StringBuffer(); + int index = str.indexOf("%"); + zero = false; + int dataSize; + long l; + int i; + String s; + boolean prefix0x; + boolean utf8; + + while ( (index != -1) && (offset < buffer.length)) + { + utf8 = false; + dataSize = 4; // Default to an integer + prefix0x = (index > 1) ? // Check for "0x" prefix + "0x".equalsIgnoreCase(str.substring(index - 2, index)) : + false; + result.append(str.substring(0, index)); + str = str.substring(index+1, str.length()); + /* + * Check for "-" prefix + */ + if ( str.charAt(0) == '-' ) + { + fspec = new FormatSpec(true); + str = str.substring(1, str.length()); + } + + /* + * Zero padding ? + */ + if (str.charAt(0) == '0') + { + zero = true; + str = str.substring(1, str.length()); + } + /* + * Handle width... + */ + if ( Character.isDigit(str.charAt(0)) ) + { + if ( fspec == null ) + { + fspec = new FormatSpec(); + } + String val = readDigits(str); + fspec.width = Integer.valueOf(val); + str = str.substring(val.length(), str.length()); + } + + /* + * ...and precision + */ + if ( str.charAt(0) == '.' ) + { + str = str.substring(1, str.length()); + if (str.charAt(0) == '*') { + utf8 = true; + str = str.substring(1, str.length()); + } else { + + if ( fspec == null ) + { + fspec = new FormatSpec(); + } + + String prec = readDigits(str); + fspec.precision = Integer.valueOf(prec); + str = str.substring(prec.length(), str.length()); + } + } + + /* + * Check for a size modifier + */ + char first = str.charAt(0); + + if (first == 'l') + { + if (str.charAt(1) == 'l') + { + dataSize = Util.LONG; + str = str.substring(2, str.length()); + } else { + // Default size is INT + str = str.substring(1, str.length()); + } + } + else if (first == 'I' && str.charAt(1) == '6' && str.charAt(2) == '4') + { + dataSize = Util.LONG; + str = str.substring(3, str.length()); + } + else if (first == 'h') + { + dataSize = 2; + str = str.substring(1, str.length()); + } + else if (first == 'z') + { + if (ptrSize == 8) { + dataSize = Util.LONG; + } + str = str.substring(1, str.length()); + } + + /* + * Finally check for a type + */ + first = str.charAt(0); + switch (first) { + + case 'p': + l = ptrSize == 4 ? Util.constructUnsignedInt(buffer, offset) : + Util.constructUnsignedLong(buffer, offset).longValue(); + offset += ptrSize; + if (!prefix0x) { + result.append("0x"); + } + result.append(format(l, fspec, 16)); + str = str.substring(1, str.length()); + break; + + case 's': + if (utf8) { + int utf8Length = Util.constructUnsignedLong(buffer, offset, 2).intValue(); + offset += 2; + s = Util.constructString(buffer, offset, utf8Length); + offset += utf8Length; + } else { + s = Util.constructString(buffer, offset); + offset += (s.length() + 1); + } + s = Util.escapeControlCharacters(s); + result.append(format(s, fspec)); + str = str.substring(1, str.length()); + break; + + case 'd': + case 'i': + l = dataSize == 4 ? Util.constructUnsignedInt(buffer, offset) : + Util.constructUnsignedLong(buffer, offset).longValue(); + offset += dataSize; + result.append(format(l, fspec)); + str = str.substring(1, str.length()); + break; + + case 'u': + if (dataSize == 4) { + l = Util.constructUnsignedInt(buffer, offset); + l = l & 0xffffffffL; + } else { + l = Util.constructUnsignedLong(buffer, offset).longValue(); + } + offset += dataSize; + result.append(format(l, fspec)); + str = str.substring(1, str.length()); + break; + + case 'f': + /* CMVC 164940 All %f tracepoints were promoted to double in runtime trace code. + * Affects: + * TraceFormat com/ibm/jvm/format/Message.java + * TraceFormat com/ibm/jvm/trace/format/api/Message.java + * runtime ute/ut_trace.c + * TraceGen OldTrace.java + * Intentional fall through to next case. + */ + case 'g': + l = Util.constructUnsignedLong(buffer, offset).longValue(); + offset += Util.LONG; + result.append(format(Double.longBitsToDouble(l), fspec)); + str = str.substring(1, str.length()); + break; + + case 'X': + case 'x': + if (dataSize == 4) { + l = Util.constructUnsignedInt(buffer, offset); + l = l & 0xffffffffL; + } else { + l = Util.constructUnsignedLong(buffer, offset).longValue(); + } + offset += dataSize; + if (!prefix0x) { + result.append("0x"); + } + result.append(format(l, fspec, 16)); + str = str.substring(1, str.length()); + break; + + case 'c': + s = Util.constructString(buffer, offset, 1); + offset += 1; + s = Util.escapeControlCharacters(s); + result.append(format(s, fspec)); + str = str.substring(1, str.length()); + break; + + case '%': + result.append("%"); + str = str.substring(1, str.length()); + break; + + case '+': + case ' ': + case '#': + TraceFormat.outStream.println("Used a printf flag not supported " + first); + str = str.substring(1, str.length()); + break; + + default: + TraceFormat.outStream.println("error percent directive looked like => " + str); + str = str.substring(1, str.length()); + } + + fspec = null; + zero = false; + index = str.indexOf("%"); + } + result.append(str); + return result; + } + + /** process all the percent sign directives in a string, making them "???" + * + * @param str a string + * @return the string with percent directives replaced by "???" + * + */ + protected StringBuffer skipPercents(String str, byte[] buffer, int offset) + { + + StringBuffer result = new StringBuffer(); + int index = str.indexOf("%"); + + while ( (index != -1) && (offset < buffer.length)) + { + result.append(str.substring(0, index)); + str = str.substring(index+1, str.length()); + if ( str.charAt(0) == '-' || + str.charAt(0) == '0') + { + str = str.substring(1, str.length()); + } + + if ( Character.isDigit(str.charAt(0)) ) + { + String val = readDigits(str); + str = str.substring(val.length(), str.length()); + } + + if ( str.charAt(0) == '.' ) + { + str = str.substring(1, str.length()); + if (str.charAt(0) == '*') { + str = str.substring(1, str.length()); + } else { + String prec = readDigits(str); + str = str.substring(prec.length(), str.length()); + } + } + /* + * Check for a size modifier + */ + + char first = str.charAt(0); + + if (first == 'l') + { + str = str.substring((str.charAt(1) == 'l' ? 2 : 1), str.length()); + } + else if (first == 'I' && str.charAt(1) == '6' && str.charAt(2) == '4') + { + str = str.substring(3, str.length()); + } + else if (first == 'h') + { + str = str.substring(1, str.length()); + } + else if (first == 'z') + { + str = str.substring(1, str.length()); + } + + /* + * Now look for a type + */ + first = str.charAt(0); + switch (first) { + + case 'd': + case 'i': + case 'u': + case 'f': + case 'X': + case 'x': + case 'p': + case 's': + case 'c': + str = str.substring(1, str.length()); + result.append("???"); + break; + case '%': + result.append("%"); + str = str.substring(1, str.length()); + break; + case '+': + case ' ': + case '#': + TraceFormat.outStream.println("Used a printf flag not supported " + first); + str = str.substring(1, str.length()); + break; + default: + TraceFormat.outStream.println("Error: percent directive looked like => " + str); + str = str.substring(1, str.length()); + } + index = str.indexOf("%"); + } + result.append(str); + return result; + } + + protected static void setPointerSize() + { + ptrSize = Integer.valueOf(Util.getProperty("POINTER_SIZE")).intValue(); + } + + private String readDigits(String str) + { + + char[] digits = new char[10]; + int index = 0; + + while ( Character.isDigit(str.charAt(index)) ) + { + + if ( index < digits.length ) + { + digits[index] = str.charAt(index); + index++; + } + } + return new String(digits, 0, index); + } + + private StringBuffer format(BigInteger val, FormatSpec spec) + { + StringBuffer str = new StringBuffer(val.toString()); + if ( spec != null ) + { + if ( spec.precision != null ) + { + Util.padBuffer(str, spec.precision.intValue(), '0'); + } + if ( spec.width != null ) + { + Util.padBuffer(str, spec.width.intValue(), ' ', spec.leftJustified); + } + } + return str; + } + + private StringBuffer format(long val, FormatSpec spec) + { + return format(val, spec, 10); + } + + private StringBuffer format(long val, FormatSpec spec, int radix) + { + StringBuffer str = new StringBuffer(Long.toString(val, radix)); + if ( spec != null ) + { + if ( spec.precision != null ) + { + Util.padBuffer(str, spec.precision.intValue(), '0'); + } + if ( spec.width != null ) + { + Util.padBuffer(str, + spec.width.intValue(), + (zero && !spec.leftJustified) ? '0' : ' ', + spec.leftJustified); + } + } + return str; + } + + private StringBuffer format(float val, FormatSpec spec) + { + StringBuffer str = new StringBuffer(Float.toString(val)); + if ( spec != null ) + { + if ( spec.width != null ) + { + Util.padBuffer(str, spec.width.intValue(), ' ', spec.leftJustified); + } + } + return str; + } + + private StringBuffer format(double val, FormatSpec spec) + { + StringBuffer str = new StringBuffer(Double.toString(val)); + if ( spec != null ) + { + if ( spec.width != null ) + { + Util.padBuffer(str, spec.width.intValue(), ' ', spec.leftJustified); + } + } + return str; + } + + private StringBuffer format(String str, FormatSpec spec) + { + StringBuffer result = new StringBuffer(); + if ( spec != null ) + { + if ( spec.precision != null ) + { + int x = spec.precision.intValue(); + + if ( x < str.length() ) + { + + str = str.substring(0, x); + } + } + result.append(str); + if ( spec.width != null ) + { + Util.padBuffer(result, spec.width.intValue(), ' ', spec.leftJustified); + } + } + else + { + result.append(str); + } + return result; + } + + /** retrieve the text of the message, parsing any percent directives and replacing them with data from the buffer + * + * @param buffer an array of bytes + * @param offset an int + * @return a string that is the message from the file with any percent directives replaces by data from the buffer + */ + public String getMessage(byte[] buffer, int offset, int end) + { + String prefix = (TraceArgs.symbolic) ? symbol + " " : ""; + + if ( offset < end ) + { + // If this is preformatted application trace, skip the first 4 bytes + if (component == "ApplicationTrace") { + offset += 4; + } + return prefix + processPercents(message, buffer, offset).toString(); + } else { + return prefix + skipPercents(message, buffer, offset).toString(); + } + } + + /** returns the component this message corresponds to, as + * determined by the message file + * + * @return an String that is component from which this message came from + */ + protected String getComponent() + { + return component; + } + + /** returns the type of entry this message corresponds + * to, as determined by the message file and TraceRecord + * + * @return an int that is one of the types defined in TraceRecord + * @see TraceRecord + */ + protected int getType() + { + return type; + } + + protected String getFormattingTemplate(){ + return message; + } + + class FormatSpec + { + protected Integer width; // this are object types to have + protected Integer precision; // a null value mean not set. + protected boolean leftJustified = false; + + public FormatSpec(boolean left) + { + this.leftJustified = left; + } + + public FormatSpec() + { + this(false); + } + + public String toString() + { + return "FormatSpec w: " + width + " p:" + precision + " just: " + leftJustified; + } + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/MessageFile.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/MessageFile.java index 7d9640e3c8b..12401dc333d 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/MessageFile.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/MessageFile.java @@ -27,7 +27,7 @@ /** * Acts as a template for mapping trace ids to messages. - * + * * @author Jonathon Lee */ final public class MessageFile extends File @@ -43,7 +43,7 @@ final public class MessageFile extends File private static boolean first; private static Hashtable messages; - + private static final String fromDATFile = ".definedInDatFile"; public MessageFile(String s) throws IOException @@ -63,7 +63,7 @@ public float getVersion() /** * Initializes static variables. - * + * *

    * This is called each time the TraceFormatter is started, from the * initStatics() method in TraceFormat.java @@ -94,7 +94,7 @@ private void read() throws IOException * line has no spaces, it is determined to be a component; otherwise it * contains a trace id, an entry type, and a template string (separated by * spaces) - * + * * @param messageLine * a string */ @@ -117,7 +117,7 @@ protected void addMessage(String messageLine) } else { verMod = Float.valueOf(messageLine).floatValue(); } - + if (MessageFile.verMod < TraceFormat.verMod) { // Defect 101265 - suppress warnings if (!TraceFormat.SUPPRESS_VERSION_WARNINGS) { @@ -136,8 +136,8 @@ protected void addMessage(String messageLine) if (verMod >= 5.0F) { int fourthSpace = messageLine.indexOf(" ", thirdSpace + 1); componentName = new String(messageLine.substring(0, firstSpace)); - - /* + + /* * version 5.1 and above contain the component and trace id together as * a period separated pair: e.g. j9vm.123 */ @@ -152,7 +152,7 @@ protected void addMessage(String messageLine) componentName = compName; } } - + if (MessageFile.messages == null) { MessageFile.messages = new Hashtable(); } @@ -217,7 +217,7 @@ protected void addMessage(String messageLine) /** * retrieve the message associated with a given traceID - * + * * @param id * an int that is a trace identifier * @return a message that contains the type of entry, the component for the @@ -241,7 +241,7 @@ static protected Message getMessageFromID(int id) /** * retrieve the message associated with a given traceID and component - * + * * @param id * an int that is a trace identifier * @return a message that contains the type of entry, the component for the @@ -265,7 +265,7 @@ static protected Message getMessageFromID(String compName, int id) if (message == null) { if (componentIsFromDATFile(compName)){ - /* this means the component exists, but the dat files in use do not contain the + /* this means the component exists, but the dat files in use do not contain the * format specification for this tracepoint in that component. The almost certain * cause is that the tracepoint was introduced into a newer level of VM than the * current dat file came from. @@ -277,7 +277,7 @@ static protected Message getMessageFromID(String compName, int id) * will still proceed, but all new tracepoints will have catch all error message below. User should * rerun with newer dat files to get full tracepoint info. Those just needing some trace info will * get a complete tracefile, with errors flagged inline. - */ + */ message = new Message(TraceRecord.ERROR_TYPE ,"This tracepoint's format string was not available in dat file.", compName, " ") ; } else { /* this is almost certainly an AppTrace tracepoint */ @@ -288,7 +288,7 @@ static protected Message getMessageFromID(String compName, int id) return message; } - + static public boolean componentIsFromDATFile(String componentName){ String componentCameFromDATFileEntry = componentName + fromDATFile; if (MessageFile.messages != null && MessageFile.messages.containsKey(componentCameFromDATFileEntry)){ diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ProcessorSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ProcessorSection.java index 5bfd02cfb73..2876ac30d98 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ProcessorSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ProcessorSection.java @@ -25,80 +25,80 @@ import java.io.BufferedWriter; import java.io.IOException; -/** +/** * Processor section of a file header * * @author Tim Preece */ public class ProcessorSection { - private String eyecatcher_string; - private int length; - private int version; - private int modification; - private int arch; - private boolean big; - private int word; - private int procs; - private int subType; - private int counter; + private String eyecatcher_string; + private int length; + private int version; + private int modification; + private int arch; + private boolean big; + private int word; + private int procs; + private int subType; + private int counter; - public ProcessorSection (TraceFile traceFile, int start ) throws IOException - { - // Version 1.1 - traceFile.seek((long)start); - eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); - length = traceFile.readI(); - version = traceFile.readI(); - modification = traceFile.readI(); - traceFile.skipBytes(16); // Skip over HPI header information - arch = traceFile.readI(); - big = ( traceFile.readI() != 0 ); - word = traceFile.readI(); - procs = traceFile.readI(); - traceFile.skipBytes(16); // Skip over HPI header information - subType = traceFile.readI(); - counter = traceFile.readI(); + public ProcessorSection (TraceFile traceFile, int start ) throws IOException + { + // Version 1.1 + traceFile.seek((long)start); + eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); + length = traceFile.readI(); + version = traceFile.readI(); + modification = traceFile.readI(); + traceFile.skipBytes(16); // Skip over HPI header information + arch = traceFile.readI(); + big = ( traceFile.readI() != 0 ); + word = traceFile.readI(); + procs = traceFile.readI(); + traceFile.skipBytes(16); // Skip over HPI header information + subType = traceFile.readI(); + counter = traceFile.readI(); - Util.setTimerType(counter); + Util.setTimerType(counter); - Util.Debug.println("ProcessorSection: eyecatcher: " + eyecatcher_string); - Util.Debug.println("ProcessorSection: length: " + length); - Util.Debug.println("ProcessorSection: version: " + version); - Util.Debug.println("ProcessorSection: modification: " + modification); - Util.Debug.println("ProcessorSection: arch: " + arch); - Util.Debug.println("ProcessorSection: big: " + big); - Util.Debug.println("ProcessorSection: word: " + word); - Util.Debug.println("ProcessorSection: procs: " + procs); - Util.Debug.println("ProcessorSection: subType: " + subType); - Util.Debug.println("ProcessorSection: counter: " + counter); + Util.Debug.println("ProcessorSection: eyecatcher: " + eyecatcher_string); + Util.Debug.println("ProcessorSection: length: " + length); + Util.Debug.println("ProcessorSection: version: " + version); + Util.Debug.println("ProcessorSection: modification: " + modification); + Util.Debug.println("ProcessorSection: arch: " + arch); + Util.Debug.println("ProcessorSection: big: " + big); + Util.Debug.println("ProcessorSection: word: " + word); + Util.Debug.println("ProcessorSection: procs: " + procs); + Util.Debug.println("ProcessorSection: subType: " + subType); + Util.Debug.println("ProcessorSection: counter: " + counter); - } + } - protected void summary(BufferedWriter out) throws IOException - { - /* - * These String arrays refer to enum values in entries of the - * ProcessorInfo structure defined in xhpi.h . - */ - String[] Archs = { "Unknown", "x86", "S390", "Power", "IA64", "S390X", "AMD64", "RISCV", "AArch64" }; - String[] SubTypes = { "i486", "i586", "Pentium II", "Pentium III", "Merced", "McKinley", - "PowerRS", "PowerPC", "GigaProcessor", "ESA", "Pentium IV", "T-Rex", "Opteron", "RV64G", "Armv8-A" }; - String[] trCounter = { "Sequence Counter", "Special", "RDTSC Timer", "AIX Timer", - "MFSPR Timer", "MFTB Timer", "STCK Timer", "J9 timer"}; - out.write("Sys Processor Info :"); - out.newLine(); - out.write((Util.SUM_TAB + "Arch family "+Archs[arch])); - out.newLine(); - out.write((Util.SUM_TAB + "Processor Sub-type " + SubTypes[subType])); - out.newLine(); - out.write((Util.SUM_TAB + "Num Processors " +procs)); - out.newLine(); - out.write((Util.SUM_TAB + "Big Endian " + big)); - out.newLine(); - out.write((Util.SUM_TAB + "Word size " + word)); - out.newLine(); - out.write((Util.SUM_TAB + "Using Trace Counter " + trCounter[counter])); - out.newLine(); - out.newLine(); - } + protected void summary(BufferedWriter out) throws IOException + { + /* + * These String arrays refer to enum values in entries of the + * ProcessorInfo structure defined in xhpi.h . + */ + String[] Archs = { "Unknown", "x86", "S390", "Power", "IA64", "S390X", "AMD64", "RISCV", "AArch64" }; + String[] SubTypes = { "i486", "i586", "Pentium II", "Pentium III", "Merced", "McKinley", + "PowerRS", "PowerPC", "GigaProcessor", "ESA", "Pentium IV", "T-Rex", "Opteron", "RV64G", "Armv8-A" }; + String[] trCounter = { "Sequence Counter", "Special", "RDTSC Timer", "AIX Timer", + "MFSPR Timer", "MFTB Timer", "STCK Timer", "J9 timer"}; + out.write("Sys Processor Info :"); + out.newLine(); + out.write((Util.SUM_TAB + "Arch family "+Archs[arch])); + out.newLine(); + out.write((Util.SUM_TAB + "Processor Sub-type " + SubTypes[subType])); + out.newLine(); + out.write((Util.SUM_TAB + "Num Processors " +procs)); + out.newLine(); + out.write((Util.SUM_TAB + "Big Endian " + big)); + out.newLine(); + out.write((Util.SUM_TAB + "Word size " + word)); + out.newLine(); + out.write((Util.SUM_TAB + "Using Trace Counter " + trCounter[counter])); + out.newLine(); + out.newLine(); + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ServiceSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ServiceSection.java index d31b6f1e15c..fb4a846ef8a 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ServiceSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/ServiceSection.java @@ -25,127 +25,127 @@ import java.io.BufferedWriter; import java.io.IOException; -/** - * Service section of a file header. +/** + * Service section of a file header. * * @author Tim Preece */ public class ServiceSection { - private String eyecatcher_string; - private int length; - private int version; - private int modification; - private long level_offset; - private String serviceString; + private String eyecatcher_string; + private int length; + private int version; + private int modification; + private long level_offset; + private String serviceString; - private TraceFile traceFile; + private TraceFile traceFile; - public ServiceSection (TraceFile traceFile, int start ) throws IOException - { - int temp = 0; - // Version 1.1 - this.traceFile = traceFile; - traceFile.seek((long)start); - eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); - length = traceFile.readI(); - version = traceFile.readI(); - modification = traceFile.readI(); - level_offset = traceFile.getFilePointer(); + public ServiceSection (TraceFile traceFile, int start ) throws IOException + { + int temp = 0; + // Version 1.1 + this.traceFile = traceFile; + traceFile.seek((long)start); + eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); + length = traceFile.readI(); + version = traceFile.readI(); + modification = traceFile.readI(); + level_offset = traceFile.getFilePointer(); - serviceString = ""; - traceFile.seek(level_offset); - while ((temp = traceFile.readByte()) != 0) { - serviceString = serviceString + (char)temp; - } + serviceString = ""; + traceFile.seek(level_offset); + while ((temp = traceFile.readByte()) != 0) { + serviceString = serviceString + (char)temp; + } - Util.Debug.println("ServiceSection: eyecatcher: " + eyecatcher_string); - Util.Debug.println("ServiceSection: length: " + length); - Util.Debug.println("ServiceSection: version: " + version); - Util.Debug.println("ServiceSection: modification: " + modification); - Util.Debug.println("ServiceSection: string: " + serviceString); + Util.Debug.println("ServiceSection: eyecatcher: " + eyecatcher_string); + Util.Debug.println("ServiceSection: length: " + length); + Util.Debug.println("ServiceSection: version: " + version); + Util.Debug.println("ServiceSection: modification: " + modification); + Util.Debug.println("ServiceSection: string: " + serviceString); + } - } + protected void summary(BufferedWriter out) throws IOException + { + Util.Debug.println("ServiceSection: level_offset: " + level_offset); - protected void summary(BufferedWriter out) throws IOException - { - Util.Debug.println("ServiceSection: level_offset: " + level_offset); + out.write("Service Level :"); + out.newLine(); + out.write(Util.SUM_TAB + serviceString); + out.newLine(); + out.newLine(); + } - out.write("Service Level :"); - out.newLine(); - out.write(Util.SUM_TAB + serviceString); - out.newLine(); - out.newLine(); - } - protected String formatFileName() - { - /* - * Legacy search for J9TraceFormat.dat files. - */ - if (serviceString.indexOf(" IBM J9 ") != -1 || - serviceString.indexOf("Unknown version") != -1 || //ibm@77980 - TraceArgs.j9) { - /* this is a J9 dat file - they have the vm level encoded in the dat file name */ - String[] vmLevelParts = getVMLevel().split("[.]"); - String fileExtension = ""; /* not null! - see fileName below */ - for (int i = 0; (vmLevelParts != null) && (i < vmLevelParts.length); i++){ - fileExtension += vmLevelParts[i]; - } - String fileName = "J9TraceFormat" + fileExtension + ".dat"; - Util.Debug.println("ServiceSection: formatFile: "+ fileName); - return fileName; - } - Util.Debug.println("ServiceSection: formatFile unknown"); - return null; - } - - /** - * Method to search forward through dat files. Trace is forward compatible, - * so a newer JVM should always be able to format the trace from an older - * JVM. This means that, for example, a 2.3 tracefile can use J9TraceFormat24.dat - * correctly. - * @param previous - the last filename tried - * @return the next filename to try, or null if all options are exhausted - */ - protected String getNextFormatFileName(String previous){ - if (previous == null){ - return null; - } - if (previous.equals("J9TraceFormat22.dat")){ - return "J9TraceFormat23.dat"; - } else if (previous.equals("J9TraceFormat23.dat")){ - return "J9TraceFormat24.dat"; - } else if (previous.equals("J9TraceFormat24.dat")){ - return "J9TraceFormat25.dat"; - } else if (previous.equals("J9TraceFormat25.dat")){ - return "J9TraceFormat26.dat"; - } else { - return null; - } - } - - protected String getServiceLevel() - { - return serviceString; - } - - protected String getVMLevel() - { - if (serviceString.indexOf("2.2") != -1){ - return "2.2"; - } - if (serviceString.indexOf("2.3") != -1){ - return "2.3"; - } - if (serviceString.indexOf("2.4") != -1){ - return "2.4"; - } - if (serviceString.indexOf("2.5") != -1){ - return "2.5"; - } - if (serviceString.indexOf("2.6") != -1){ - return "2.6"; - } - return "unknown"; - } + protected String formatFileName() + { + /* + * Legacy search for J9TraceFormat.dat files. + */ + if (serviceString.indexOf(" IBM J9 ") != -1 || + serviceString.indexOf("Unknown version") != -1 || //ibm@77980 + TraceArgs.j9) { + /* this is a J9 dat file - they have the vm level encoded in the dat file name */ + String[] vmLevelParts = getVMLevel().split("[.]"); + String fileExtension = ""; /* not null! - see fileName below */ + for (int i = 0; (vmLevelParts != null) && (i < vmLevelParts.length); i++){ + fileExtension += vmLevelParts[i]; + } + String fileName = "J9TraceFormat" + fileExtension + ".dat"; + Util.Debug.println("ServiceSection: formatFile: "+ fileName); + return fileName; + } + Util.Debug.println("ServiceSection: formatFile unknown"); + return null; + } + + /** + * Method to search forward through dat files. Trace is forward compatible, + * so a newer JVM should always be able to format the trace from an older + * JVM. This means that, for example, a 2.3 tracefile can use J9TraceFormat24.dat + * correctly. + * @param previous - the last filename tried + * @return the next filename to try, or null if all options are exhausted + */ + protected String getNextFormatFileName(String previous){ + if (previous == null){ + return null; + } + if (previous.equals("J9TraceFormat22.dat")){ + return "J9TraceFormat23.dat"; + } else if (previous.equals("J9TraceFormat23.dat")){ + return "J9TraceFormat24.dat"; + } else if (previous.equals("J9TraceFormat24.dat")){ + return "J9TraceFormat25.dat"; + } else if (previous.equals("J9TraceFormat25.dat")){ + return "J9TraceFormat26.dat"; + } else { + return null; + } + } + + protected String getServiceLevel() + { + return serviceString; + } + + protected String getVMLevel() + { + if (serviceString.indexOf("2.2") != -1){ + return "2.2"; + } + if (serviceString.indexOf("2.3") != -1){ + return "2.3"; + } + if (serviceString.indexOf("2.4") != -1){ + return "2.4"; + } + if (serviceString.indexOf("2.5") != -1){ + return "2.5"; + } + if (serviceString.indexOf("2.6") != -1){ + return "2.6"; + } + return "unknown"; + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/StartupSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/StartupSection.java index ce1ba464903..65f06acd404 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/StartupSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/StartupSection.java @@ -26,88 +26,86 @@ import java.io.IOException; import java.util.*; -/** - * Startup section of a file header. +/** + * Startup section of a file header. * * @author Tim Preece */ public class StartupSection { - private String eyecatcher_string; - private int length; - private int version; - private int modification; - private long options_offset; + private String eyecatcher_string; + private int length; + private int version; + private int modification; + private long options_offset; - private long options_end; - private TraceFile traceFile; - private String[] startupOptions; + private long options_end; + private TraceFile traceFile; + private String[] startupOptions; - public StartupSection (TraceFile traceFile, int start ) throws IOException - { - // Version 1.1 - this.traceFile = traceFile; - traceFile.seek((long)start); - eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); - length = traceFile.readI(); - version = traceFile.readI(); - modification = traceFile.readI(); - options_offset = traceFile.getFilePointer(); + public StartupSection (TraceFile traceFile, int start ) throws IOException + { + // Version 1.1 + this.traceFile = traceFile; + traceFile.seek((long)start); + eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); + length = traceFile.readI(); + version = traceFile.readI(); + modification = traceFile.readI(); + options_offset = traceFile.getFilePointer(); - options_end = start + length; + options_end = start + length; - Util.Debug.println("StartupSection: eyecatcher: " + eyecatcher_string); - Util.Debug.println("StartupSection: length: " + length); - Util.Debug.println("StartupSection: version: " + version); - Util.Debug.println("StartupSection: modification: " + modification); - - startupOptions = readOptions(traceFile, options_offset); - } - - private String[] readOptions(TraceFile traceFile, long options_offset) throws IOException{ - String opts[] = null; - Vector optsVector = new Vector(); - traceFile.seek(options_offset); - byte[] optionsBuffer = new byte[(int)(options_end - options_offset)]; - Util.Debug.println("StartupSection: options_offset: " + options_offset); - Util.Debug.println("StartupSection: options_end: " + options_end); - StringBuffer buf; - int i = 0; - traceFile.read(optionsBuffer); - // Util.printDump(optionsBuffer,optionsBuffer.length); - for (i=0; (iThis is called each time the TraceFormatter is started, from the initStatics() - * method in TraceFormat.java

    - */ - final protected static void initStatics() - { - traceFile = null; - outputFile = null; - indent = false; - summary = false; - debug = false; - symbolic = false; - gui = false; - j9 = false; - userVMIdentifier = null; - is50orNewer = false; - override = false; - } - - /** parses the command line arguments - * - * @param args the arguments - * @throws UsageException - */ - public TraceArgs(String[] args) throws UsageException - { - if ( args.length > 0 ) { - int index; - - /* Catch a request for help in argument 0. */ - if ( args[0].equals("-help") ) { - isHelpOnly=true; - } else { - - traceFile = args[0]; - } - - if ( args.length > 1 ) { - - if ( args[1].startsWith("-") ) { - outputFile = args[0] + ".fmt"; - index = 1; - } else { - outputFile = args[1]; - index = 2; - } - - while ( index < args.length ) { - if ( args[index].equals("-summary") ) { - summary=true; - } else if ( args[index].startsWith("-entries:") ) { - parseComponentParameter(args[index]); - } else if ( args[index].startsWith("-thread:") ) { - parseThread(args[index]); - } else if ( args[index].equals("-indent") ) { - indent=true; - } else if ( args[index].equals("-symbolic") ) { - symbolic=true; - } else if ( args[index].equals("-help") ) { - isHelpOnly=true; - } else if (args[index].equals("-version") ) { - System.out.println("TraceFormat Version " + TraceFormat.traceFormatMajorVersion + "." + TraceFormat.traceFormatMinorVersion); - } else if ( args[index].equals("-debug") ) { - debug=true; - verbose=true; - } else if ( args[index].equals("-j9") ) { - j9=true; - } else if (args[index].equals("-verbose")) { - verbose=true; - } else if ( args[index].equalsIgnoreCase("-uservmid") ) { - index++; - if ( (index >= args.length) || (args[index].startsWith("-"))) { - throw new UsageException("no uservmid string provided"); - } - userVMIdentifier = args[index]; - } else if ( args[index].equalsIgnoreCase("-overridetimezone") ) { - index++; - if ( index >= args.length ) { - throw new UsageException("no time provided with overridetimezone option"); - } - try { - int offset = Integer.parseInt( args[index] ); - System.out.println("All formatted tracepoints will be formatted with an offset to the hours field of " + offset + "hours."); - timeZoneOffset = new BigInteger( args[index] ); - } catch ( NumberFormatException nfe ){ - System.err.println("Cannot format " + args[index] + " into an integer to use as an hour offset in Trace Formatter."); - System.err.println( nfe ); - throw new UsageException("please specify an integer value after -overridetimezone that will be used as an offset for the formatted hour field"); - } - } else if ( args[index].startsWith("-50") ){ - /* this offers a manual override to enforce 50 behaviour when the trace file has a version number of - * < 5.0. This could be useful if you have a development build that produced a snap but didn't yet have - * the ute.h patch to upgrade the version number in the headers. - */ - is50orNewer = true; - } else if ( args[index].startsWith("-11") ){ - /* this offers a manual override to enforce 50 behaviour when the trace file has a version number of - * < 5.0. This could be useful if you have a development build that produced a snap but didn't yet have - * the ute.h patch to upgrade the version number in the headers. - */ - is50orNewer = false; - override = true; - - } else if ( args[index].startsWith("-datdir") ){ - index++; - if ( (index >= args.length) || (args[index].startsWith("-"))) { - throw new UsageException("no dat file directory name provided"); - } - datFileDirectory = new String( args[index] ); - } else { - throw new UsageException(); - } - index++; - } - } else { - outputFile = args[0] + ".fmt"; - } - } else { - throw new UsageException(); - } - return; - } - - private void parseComponentParameter(String comp) throws UsageException - { - String compString = comp.substring("-entries:".length()); - parseComponents(compString); - } - - private void parseComponents(String compString) throws UsageException - { - - int paren = compString.indexOf("("); - int comma = compString.indexOf(","); - if ( comma != -1 ) { - if ( comma < paren ) { - parseComponent(compString.substring(0, comma)); - parseComponents(compString.substring(comma + 1, compString.length())); - } else { - int closeParen = compString.indexOf(")"); - parseComponent(compString.substring(0, closeParen+1)); - int nextComma = compString.indexOf(",", closeParen); - if ( nextComma != -1 ) { - parseComponents(compString.substring(nextComma + 1, compString.length())); - } - } - } else { - parseComponent(compString); - } - } - - private void parseComponent(String component) throws UsageException - { - int open = component.indexOf("("); - int close = component.indexOf(")"); - if ( close < open ) { - throw new UsageException(); - } else if ( close == open ) { // only possible if both == -1 - Util.putComponent(component); - } else { - Vector types = new Vector(10); - String temp = component.substring(open + 1, component.length()-1); - - int index; - while ( (index = temp.indexOf(",")) != -1 ) { - types.addElement(temp.substring(0, index)); - temp = temp.substring(index+1, temp.length()); - } - types.addElement(temp.substring(0, temp.length())); - Util.putComponent(component.substring(0, open), types); - } - } - - private void parseThread(String thread) throws UsageException - { - String id = null; - try { - String temp = thread.substring("-thread:".length()); - int index; - while ( (index = temp.indexOf(",")) != -1 ) { - id = temp.substring(0, index); - Util.putThreadID(Long.decode(id)); - temp = temp.substring(index+1, temp.length()); - } - id = temp.substring(0, temp.length()); - Util.putThreadID(Long.decode(id)); - } catch ( NumberFormatException nfe ) { - throw new UsageException("Bad thread ID: " + id); - } - } - - class UsageException extends Exception { - UsageException(String s) - { - super(s); - } - - UsageException() - { - super(); - } - } + public static String traceFile; + public static String outputFile; + public static boolean indent; + public static boolean summary; + public static boolean debug; + public static boolean symbolic; + public static boolean isHelpOnly; + public static boolean gui; + public static boolean j9; + public static boolean verbose; + public static String userVMIdentifier; + public static BigInteger timeZoneOffset = BigInteger.ZERO; + public static boolean is50orNewer; + public static boolean override; + public static String datFileDirectory = null; + + /** Initializes static variables. + * + *

    This is called each time the TraceFormatter is started, from the initStatics() + * method in TraceFormat.java

    + */ + final protected static void initStatics() + { + traceFile = null; + outputFile = null; + indent = false; + summary = false; + debug = false; + symbolic = false; + gui = false; + j9 = false; + userVMIdentifier = null; + is50orNewer = false; + override = false; + } + + /** parses the command line arguments + * + * @param args the arguments + * @throws UsageException + */ + public TraceArgs(String[] args) throws UsageException + { + if ( args.length > 0 ) { + int index; + + /* Catch a request for help in argument 0. */ + if ( args[0].equals("-help") ) { + isHelpOnly=true; + } else { + + traceFile = args[0]; + } + + if ( args.length > 1 ) { + + if ( args[1].startsWith("-") ) { + outputFile = args[0] + ".fmt"; + index = 1; + } else { + outputFile = args[1]; + index = 2; + } + + while ( index < args.length ) { + if ( args[index].equals("-summary") ) { + summary=true; + } else if ( args[index].startsWith("-entries:") ) { + parseComponentParameter(args[index]); + } else if ( args[index].startsWith("-thread:") ) { + parseThread(args[index]); + } else if ( args[index].equals("-indent") ) { + indent=true; + } else if ( args[index].equals("-symbolic") ) { + symbolic=true; + } else if ( args[index].equals("-help") ) { + isHelpOnly=true; + } else if (args[index].equals("-version") ) { + System.out.println("TraceFormat Version " + TraceFormat.traceFormatMajorVersion + "." + TraceFormat.traceFormatMinorVersion); + } else if ( args[index].equals("-debug") ) { + debug=true; + verbose=true; + } else if ( args[index].equals("-j9") ) { + j9=true; + } else if (args[index].equals("-verbose")) { + verbose=true; + } else if ( args[index].equalsIgnoreCase("-uservmid") ) { + index++; + if ( (index >= args.length) || (args[index].startsWith("-"))) { + throw new UsageException("no uservmid string provided"); + } + userVMIdentifier = args[index]; + } else if ( args[index].equalsIgnoreCase("-overridetimezone") ) { + index++; + if ( index >= args.length ) { + throw new UsageException("no time provided with overridetimezone option"); + } + try { + int offset = Integer.parseInt( args[index] ); + System.out.println("All formatted tracepoints will be formatted with an offset to the hours field of " + offset + "hours."); + timeZoneOffset = new BigInteger( args[index] ); + } catch ( NumberFormatException nfe ){ + System.err.println("Cannot format " + args[index] + " into an integer to use as an hour offset in Trace Formatter."); + System.err.println( nfe ); + throw new UsageException("please specify an integer value after -overridetimezone that will be used as an offset for the formatted hour field"); + } + } else if ( args[index].startsWith("-50") ) { + /* this offers a manual override to enforce 50 behaviour when the trace file has a version number of + * < 5.0. This could be useful if you have a development build that produced a snap but didn't yet have + * the ute.h patch to upgrade the version number in the headers. + */ + is50orNewer = true; + } else if ( args[index].startsWith("-11") ){ + /* this offers a manual override to enforce 50 behaviour when the trace file has a version number of + * < 5.0. This could be useful if you have a development build that produced a snap but didn't yet have + * the ute.h patch to upgrade the version number in the headers. + */ + is50orNewer = false; + override = true; + + } else if ( args[index].startsWith("-datdir") ){ + index++; + if ( (index >= args.length) || (args[index].startsWith("-"))) { + throw new UsageException("no dat file directory name provided"); + } + datFileDirectory = new String( args[index] ); + } else { + throw new UsageException(); + } + index++; + } + } else { + outputFile = args[0] + ".fmt"; + } + } else { + throw new UsageException(); + } + return; + } + + private void parseComponentParameter(String comp) throws UsageException + { + String compString = comp.substring("-entries:".length()); + parseComponents(compString); + } + + private void parseComponents(String compString) throws UsageException + { + + int paren = compString.indexOf("("); + int comma = compString.indexOf(","); + if ( comma != -1 ) { + if ( comma < paren ) { + parseComponent(compString.substring(0, comma)); + parseComponents(compString.substring(comma + 1, compString.length())); + } else { + int closeParen = compString.indexOf(")"); + parseComponent(compString.substring(0, closeParen+1)); + int nextComma = compString.indexOf(",", closeParen); + if ( nextComma != -1 ) { + parseComponents(compString.substring(nextComma + 1, compString.length())); + } + } + } else { + parseComponent(compString); + } + } + + private void parseComponent(String component) throws UsageException + { + int open = component.indexOf("("); + int close = component.indexOf(")"); + if ( close < open ) { + throw new UsageException(); + } else if ( close == open ) { // only possible if both == -1 + Util.putComponent(component); + } else { + Vector types = new Vector(10); + String temp = component.substring(open + 1, component.length()-1); + + int index; + while ( (index = temp.indexOf(",")) != -1 ) { + types.addElement(temp.substring(0, index)); + temp = temp.substring(index+1, temp.length()); + } + types.addElement(temp.substring(0, temp.length())); + Util.putComponent(component.substring(0, open), types); + } + } + + private void parseThread(String thread) throws UsageException + { + String id = null; + try { + String temp = thread.substring("-thread:".length()); + int index; + while ( (index = temp.indexOf(",")) != -1 ) { + id = temp.substring(0, index); + Util.putThreadID(Long.decode(id)); + temp = temp.substring(index+1, temp.length()); + } + id = temp.substring(0, temp.length()); + Util.putThreadID(Long.decode(id)); + } catch ( NumberFormatException nfe ) { + throw new UsageException("Bad thread ID: " + id); + } + } + + class UsageException extends Exception { + UsageException(String s) + { + super(s); + } + + UsageException() + { + super(); + } + } } - - diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFile.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFile.java index cc09242c945..a350c0f53ed 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFile.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFile.java @@ -26,146 +26,145 @@ import java.io.RandomAccessFile; import java.math.BigInteger; -/** +/** * Encapsulates a trace "file" - In this case it is a single file on the disk. * * @author Tim Preece */ final public class TraceFile extends RandomAccessFile { - private boolean bigendian = true; // assume bigendian until we know otherwise - protected TraceFileHeader traceFileHeader; - private String filespec; - protected BigInteger lastWriteSystem = BigInteger.ZERO; - protected long wrapOffset = 0; - - public TraceFile(String filespec, String mode) throws Exception - { - super(filespec,mode); - this.filespec = filespec; - traceFileHeader = new TraceFileHeader(this); - } - - - final protected int readI() throws IOException - { - int temp = readInt(); - //Util.Debug.println("SingleTraceFile: bigendian: " + TraceFileHeader.bigendian); - return( bigendian ) ? temp : Util.convertEndian(temp) ; - - } - - final protected long readL() throws IOException - { - long temp = readLong(); - long temp1 = - (temp >>> 56) - | (temp << 56) - |((temp >> 40) & 0x0000000000FF00L ) - |((temp >> 24) & 0x00000000FF0000L ) - |((temp >> 8) & 0x000000FF000000L ) - |((temp << 8) & 0x0000FF00000000L ) - |((temp << 24) & 0x00FF0000000000L ) - |((temp << 40) & 0xFF000000000000L ); - //Util.Debug.println("SingleTraceFile: readLong: temp " + Long.toHexString(temp)); - //Util.Debug.println("SingleTraceFile: readLong: temp1 " + Long.toHexString(temp1)); - return( bigendian ) ? temp : temp1 ; - } - - final protected BigInteger readBigInteger(int size)throws IOException - { - byte[] bytes = new byte[size]; - read(bytes); - //for (int i =0;i>> 56)); - // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString(temp << 56)); - // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp >> 40) & 0x0000000000FF00L)); - // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp >> 24) & 0x00000000FF0000L)); - // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp >> 8) & 0x000000FF000000L)); - // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp << 8) & 0x0000FF00000000L)); - // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp << 24) & 0x00FF0000000000L)); - // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp << 40) & 0xFF000000000000L)); - // Util.Debug.println("SingleTraceFile: readULong: temp " + Long.toHexString(temp)); - // Util.Debug.println("SingleTraceFile: readULong: temp1 " + Long.toHexString(temp1)); - return( bigendian ) ? temp : temp1 ; - } - - // readString will check for null terminators. - // readString assumes the character is in ASCII - final protected String readString(int Length) throws IOException - { - byte[] buffer = new byte[Length]; - int endOfString; - read(buffer,0,Length); - - // see if there is a null terminator before the end of the buffer - for ( endOfString = 0; endOfString < Length; endOfString++) { - if ( buffer[endOfString]==0 ) break; - } - - return new String(buffer,0,endOfString,"8859_1"); - } - - final protected void setBigEndian(boolean endian) - { - bigendian = endian; - return ; - } - - final protected String formatFileName() - { - return traceFileHeader.formatFileName(); - } - - final protected String getVMLevel() - { - return traceFileHeader.getVMLevel(); - } - - final protected String getNextFormatFileName(String previous) - { - return traceFileHeader.getNextFormatFileName(previous); - } - - final public String toString() - { - return filespec; - } - - final public TraceFileHeader getHeader(){ - return traceFileHeader; - } + private boolean bigendian = true; // assume bigendian until we know otherwise + protected TraceFileHeader traceFileHeader; + private String filespec; + protected BigInteger lastWriteSystem = BigInteger.ZERO; + protected long wrapOffset = 0; + + public TraceFile(String filespec, String mode) throws Exception + { + super(filespec,mode); + this.filespec = filespec; + traceFileHeader = new TraceFileHeader(this); + } + + final protected int readI() throws IOException + { + int temp = readInt(); + //Util.Debug.println("SingleTraceFile: bigendian: " + TraceFileHeader.bigendian); + return( bigendian ) ? temp : Util.convertEndian(temp) ; + + } + + final protected long readL() throws IOException + { + long temp = readLong(); + long temp1 = + (temp >>> 56) + | (temp << 56) + |((temp >> 40) & 0x0000000000FF00L) + |((temp >> 24) & 0x00000000FF0000L) + |((temp >> 8) & 0x000000FF000000L) + |((temp << 8) & 0x0000FF00000000L) + |((temp << 24) & 0x00FF0000000000L) + |((temp << 40) & 0xFF000000000000L); + //Util.Debug.println("SingleTraceFile: readLong: temp " + Long.toHexString(temp)); + //Util.Debug.println("SingleTraceFile: readLong: temp1 " + Long.toHexString(temp1)); + return (bigendian) ? temp : temp1; + } + + final protected BigInteger readBigInteger(int size)throws IOException + { + byte[] bytes = new byte[size]; + read(bytes); + //for (int i =0;i>> 56)); + // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString(temp << 56)); + // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp >> 40) & 0x0000000000FF00L)); + // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp >> 24) & 0x00000000FF0000L)); + // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp >> 8) & 0x000000FF000000L)); + // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp << 8) & 0x0000FF00000000L)); + // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp << 24) & 0x00FF0000000000L)); + // Util.Debug.println("SingleTraceFile: readULong: xxxx " + Long.toHexString((temp << 40) & 0xFF000000000000L)); + // Util.Debug.println("SingleTraceFile: readULong: temp " + Long.toHexString(temp)); + // Util.Debug.println("SingleTraceFile: readULong: temp1 " + Long.toHexString(temp1)); + return( bigendian ) ? temp : temp1 ; + } + + // readString will check for null terminators. + // readString assumes the character is in ASCII + final protected String readString(int Length) throws IOException + { + byte[] buffer = new byte[Length]; + int endOfString; + read(buffer,0,Length); + + // see if there is a null terminator before the end of the buffer + for ( endOfString = 0; endOfString < Length; endOfString++) { + if ( buffer[endOfString]==0 ) break; + } + + return new String(buffer,0,endOfString,"8859_1"); + } + + final protected void setBigEndian(boolean endian) + { + bigendian = endian; + return ; + } + + final protected String formatFileName() + { + return traceFileHeader.formatFileName(); + } + + final protected String getVMLevel() + { + return traceFileHeader.getVMLevel(); + } + + final protected String getNextFormatFileName(String previous) + { + return traceFileHeader.getNextFormatFileName(previous); + } + + final public String toString() + { + return filespec; + } + + final public TraceFileHeader getHeader(){ + return traceFileHeader; + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFileHeader.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFileHeader.java index 2b6863d1789..e65be24315e 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFileHeader.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFileHeader.java @@ -25,219 +25,226 @@ import java.io.BufferedWriter; import java.io.IOException; -/** +/** * Encapsulates the header for a trace file. * * @author Tim Preece */ final public class TraceFileHeader implements com.ibm.jvm.trace.TraceFileHeader { - private String eyecatcher_string; - private long length; - private int version; - private int modification; - private int bufferSize; - private int endianSignature; - - private int traceStart; - private int serviceStart; - private int startupStart; - private int activeStart; - private int processorStart; - - private final int BIG_ENDIAN_SIG = 0x12345678; - private final int LITTLE_ENDIAN_SIG = 0x78563412; - private TraceFile traceFile; - private static boolean UTEfile = false; - private static boolean validHeader = false; - - protected TraceSection traceSection; - private ServiceSection serviceSection; - private StartupSection startupSection; - private ActiveSection activeSection; - private ProcessorSection processorSection; - - protected static final int INTERNAL = 0; - protected static final int EXTERNAL = 1; - - protected TraceFileHeader(TraceFile traceFile) throws IOException - { - // version 1.1 - this.traceFile = traceFile; - - try { - eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); - if (eyecatcher_string.substring(0, 4).equals("UTTH")) { - UTEfile = true; - } - int ilength = traceFile.readI(); - version = traceFile.readI(); - modification = traceFile.readI(); - bufferSize = traceFile.readI(); - endianSignature = traceFile.readI(); - - switch (this.endianSignature) { - case BIG_ENDIAN_SIG: - Util.Debug.println("Endian is BIG"); - traceFile.setBigEndian(true); - Util.setBigEndian(true); - length = ilength; - break; - case LITTLE_ENDIAN_SIG: - Util.Debug.println("Endian is LITTLE"); - traceFile.setBigEndian(false); - Util.setBigEndian(false); - // convert to little endian - length = Util.convertEndian(ilength); - version = Util.convertEndian(version); - modification = Util.convertEndian(modification); - bufferSize = Util.convertEndian(bufferSize); - break; - default: - TraceFormat.outStream.println("TraceFileHeader has invalid endian signature"); - TraceFormat.outStream.println("Please check that the input file is a binary trace file"); - return; - } - - Util.Debug.println("TraceFileHeader: eyecatcher: " + eyecatcher_string); - Util.Debug.println("TraceFileHeader: length: " + length); - Util.Debug.println("TraceFileHeader: version: " + version); - Util.Debug.println("TraceFileHeader: modification: " + modification); - Util.Debug.println("TraceFileHeader: bufferSize: " + bufferSize); - - TraceFormat.verMod = (float)version + (float)modification / 10; - Util.Debug.println("TraceFileHeader: verMod: " + TraceFormat.verMod); - - // read in the five variable sections - traceStart = traceFile.readI(); - serviceStart = traceFile.readI(); - startupStart = traceFile.readI(); - activeStart = traceFile.readI(); - processorStart = traceFile.readI(); - - traceSection = new TraceSection (traceFile,traceStart); - serviceSection = new ServiceSection (traceFile,serviceStart); - startupSection = new StartupSection (traceFile,startupStart); - activeSection = new ActiveSection (traceFile,activeStart); - processorSection = new ProcessorSection(traceFile,processorStart); - - validHeader = true; - } catch(java.io.EOFException e) { - if (traceFile.length() == 0) { - TraceFormat.outStream.println("Trace file " + traceFile + " is empty"); - } else { - TraceFormat.outStream.println("TraceFileHeader in " + traceFile + " is truncated or corrupt - cannot complete formatting"); - } - throw e; - } - } - - final protected void processTraceBufferHeaders() throws IOException - { - long bufferStart = length; - int numberOfRecords=0; - while ( bufferStart < traceFile.length()) { - numberOfRecords++; - if (traceSection.getTraceType() == INTERNAL) { - new TraceRecordInternal(traceFile, bufferStart); // this will add itself to the correct traceThread - } else { - new TraceRecordExternal(traceFile, bufferStart); // this will add itself to the correct traceThread - } - bufferStart += bufferSize; - } - TraceFormat.outStream.println("Found " + numberOfRecords + - " Trace Buffers in file " + traceFile.toString()); - if (TraceFormat.invalidBuffers > 0 ) { - TraceFormat.outStream.println("*** WARNING *** found " + TraceFormat.invalidBuffers + - " invalid Trace Buffers"); - TraceFormat.outStream.println("attempting to format the remainder"); - } - Util.Debug.println("TraceFileHeader: number of buffers = " + numberOfRecords); - TraceFormat.expectedRecords = numberOfRecords; - } - - final protected void summarize(BufferedWriter out) throws IOException - { - // traceSection.summary(out); not summarized yet - but contains no of generations - if (!validHeader) { - return; - } - serviceSection.summary(out); - startupSection.summary(out); - activeSection.summary(out); - processorSection.summary(out); - } - - /** returns the length of this file header - * - * @return a long - */ - final protected long getLength() - { - return length; - } - - /** returns the size of the buffers in the associated trace file - * - * @return an int - */ - final protected int getBufferSize() - { - return bufferSize; - } - - final protected String formatFileName() - { - return serviceSection.formatFileName(); - } - - final protected String getVMLevel() - { - return serviceSection.getVMLevel(); - } - - final protected String getNextFormatFileName(String previous) - { - return serviceSection.getNextFormatFileName(previous); - } - - /** returns true if a UTE trace file is being processed - * - * @return a boolean - */ - final static protected boolean isUTE() - { - return UTEfile; - } - - final public long getTraceDataStart() - { - return length; - } - - /* methods to implement the com.ibm.jvm.trace.TraceFileHeader interface */ + private String eyecatcher_string; + private long length; + private int version; + private int modification; + private int bufferSize; + private int endianSignature; + + private int traceStart; + private int serviceStart; + private int startupStart; + private int activeStart; + private int processorStart; + + private final int BIG_ENDIAN_SIG = 0x12345678; + private final int LITTLE_ENDIAN_SIG = 0x78563412; + private TraceFile traceFile; + private static boolean UTEfile = false; + private static boolean validHeader = false; + + protected TraceSection traceSection; + private ServiceSection serviceSection; + private StartupSection startupSection; + private ActiveSection activeSection; + private ProcessorSection processorSection; + + protected static final int INTERNAL = 0; + protected static final int EXTERNAL = 1; + + protected TraceFileHeader(TraceFile traceFile) throws IOException + { + // version 1.1 + this.traceFile = traceFile; + + try { + eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); + if (eyecatcher_string.substring(0, 4).equals("UTTH")) { + UTEfile = true; + } + int ilength = traceFile.readI(); + version = traceFile.readI(); + modification = traceFile.readI(); + bufferSize = traceFile.readI(); + endianSignature = traceFile.readI(); + + switch (this.endianSignature) { + case BIG_ENDIAN_SIG: + Util.Debug.println("Endian is BIG"); + traceFile.setBigEndian(true); + Util.setBigEndian(true); + length = ilength; + break; + case LITTLE_ENDIAN_SIG: + Util.Debug.println("Endian is LITTLE"); + traceFile.setBigEndian(false); + Util.setBigEndian(false); + // convert to little endian + length = Util.convertEndian(ilength); + version = Util.convertEndian(version); + modification = Util.convertEndian(modification); + bufferSize = Util.convertEndian(bufferSize); + break; + default: + TraceFormat.outStream.println("TraceFileHeader has invalid endian signature"); + TraceFormat.outStream.println("Please check that the input file is a binary trace file"); + return; + } + + Util.Debug.println("TraceFileHeader: eyecatcher: " + eyecatcher_string); + Util.Debug.println("TraceFileHeader: length: " + length); + Util.Debug.println("TraceFileHeader: version: " + version); + Util.Debug.println("TraceFileHeader: modification: " + modification); + Util.Debug.println("TraceFileHeader: bufferSize: " + bufferSize); + + TraceFormat.verMod = (float)version + (float)modification / 10; + Util.Debug.println("TraceFileHeader: verMod: " + TraceFormat.verMod); + + // read in the five variable sections + traceStart = traceFile.readI(); + serviceStart = traceFile.readI(); + startupStart = traceFile.readI(); + activeStart = traceFile.readI(); + processorStart = traceFile.readI(); + + traceSection = new TraceSection (traceFile,traceStart); + serviceSection = new ServiceSection (traceFile,serviceStart); + startupSection = new StartupSection (traceFile,startupStart); + activeSection = new ActiveSection (traceFile,activeStart); + processorSection = new ProcessorSection(traceFile,processorStart); + + validHeader = true; + } catch(java.io.EOFException e) { + if (traceFile.length() == 0) { + TraceFormat.outStream.println("Trace file " + traceFile + " is empty"); + } else { + TraceFormat.outStream.println("TraceFileHeader in " + traceFile + " is truncated or corrupt - cannot complete formatting"); + } + throw e; + } + } + + final protected void processTraceBufferHeaders() throws IOException + { + long bufferStart = length; + int numberOfRecords=0; + while ( bufferStart < traceFile.length()) { + numberOfRecords++; + if (traceSection.getTraceType() == INTERNAL) { + new TraceRecordInternal(traceFile, bufferStart); // this will add itself to the correct traceThread + } else { + new TraceRecordExternal(traceFile, bufferStart); // this will add itself to the correct traceThread + } + bufferStart += bufferSize; + } + TraceFormat.outStream.println("Found " + numberOfRecords + + " Trace Buffers in file " + traceFile.toString()); + if (TraceFormat.invalidBuffers > 0 ) { + TraceFormat.outStream.println("*** WARNING *** found " + TraceFormat.invalidBuffers + + " invalid Trace Buffers"); + TraceFormat.outStream.println("attempting to format the remainder"); + } + Util.Debug.println("TraceFileHeader: number of buffers = " + numberOfRecords); + TraceFormat.expectedRecords = numberOfRecords; + } + + final protected void summarize(BufferedWriter out) throws IOException + { + // traceSection.summary(out); not summarized yet - but contains no of generations + if (!validHeader) { + return; + } + serviceSection.summary(out); + startupSection.summary(out); + activeSection.summary(out); + processorSection.summary(out); + } + + /** returns the length of this file header + * + * @return a long + */ + final protected long getLength() + { + return length; + } + + /** returns the size of the buffers in the associated trace file + * + * @return an int + */ + final protected int getBufferSize() + { + return bufferSize; + } + + final protected String formatFileName() + { + return serviceSection.formatFileName(); + } + + final protected String getVMLevel() + { + return serviceSection.getVMLevel(); + } + + final protected String getNextFormatFileName(String previous) + { + return serviceSection.getNextFormatFileName(previous); + } + + /** returns true if a UTE trace file is being processed + * + * @return a boolean + */ + final static protected boolean isUTE() + { + return UTEfile; + } + + final public long getTraceDataStart() + { + return length; + } + + /* methods to implement the com.ibm.jvm.trace.TraceFileHeader interface */ public String getVMVersion(){ return serviceSection.getServiceLevel(); } + public String[] getVMStartUpParameters(){ return startupSection.getStartUpOptions(); } - public String[] getTraceParameters(){ + + public String[] getTraceParameters() { return null; } - public String[] getSysProcessorInfo(){ + + public String[] getSysProcessorInfo() { return null; } - public long getJVMStartedMillis(){ + + public long getJVMStartedMillis() { return 0L; } - public long getLastBufferWriteMillis(){ + + public long getLastBufferWriteMillis() { return 0L; } - public long getFirstTracePointMillis(){ + + public long getFirstTracePointMillis() { return 0L; } - public long getLastTracePointMillis(){ + + public long getLastTracePointMillis() { return 0L; } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFormat.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFormat.java index 2f66971125d..06e926d8deb 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFormat.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceFormat.java @@ -27,16 +27,16 @@ import java.util.*; /** - * Main routine for formatting the trace file. Reads raw trace data and formats + * Main routine for formatting the trace file. Reads raw trace data and formats * in a platform independent manner - * + * * @author Tim Preece */ final public class TraceFormat { protected static final int traceFormatMajorVersion = 1; protected static final int traceFormatMinorVersion = 0; - + private TraceArgs traceArgs = null; private Vector traceFiles = new Vector(); @@ -81,7 +81,7 @@ final public class TraceFormat protected static int expectedRecords; private boolean traceFileIsTruncatedOrCorrupt = false; - + private boolean primed = false; // constants @@ -131,7 +131,7 @@ final public class TraceFormat + "\t -overridetimezone -4\n" + "\tindent = specify indentation at Entry/Exit trace points.\n" + "\t Default is not to indent.\n" - +"\thelp = display this message and stop."; + +"\thelp = display this message and stop."; protected static final String header = " Trace Formatted Data "; @@ -145,7 +145,7 @@ final public class TraceFormat /** * Main entry point for running the formatter. - * + * * @param args */ public static void main(String[] args) @@ -156,7 +156,7 @@ public static void main(String[] args) /** * Null constructor for the formatter. - * + * * @param None *

    * This is the version used when you run TraceFormat from the @@ -172,7 +172,7 @@ public TraceFormat() /** * Constructor used to instantiate the formatter programmatically. - * + * * @param args - * the same as you would specify on the command line. *

    @@ -226,17 +226,17 @@ private void initStatics() TraceRecord.initStatics(); MessageFile.initStatics(); } - + /** * parses command-line args, if in command-line mode, reads the input * file(s) and outputs the result - * + * * @param args * the command line arguments * @param processFully * if true, the formatter will read the trace file and format the tracepoints into a file * if false, the formatter will prime the trace file so that an external program can iterate - * over the tracepoints. + * over the tracepoints. * @see main */ public void readAndFormat(String[] args, boolean processFully) @@ -250,17 +250,17 @@ public void readAndFormat(String[] args, boolean processFully) return; } - /* Catch the -help option and terminate. */ - if (TraceArgs.isHelpOnly) - { - TraceFormat.outStream.println("TraceFormat " + usageMessage); - return; - } - - if (TraceArgs.verbose) { - errStream = System.err; - } - + /* Catch the -help option and terminate. */ + if (TraceArgs.isHelpOnly) + { + TraceFormat.outStream.println("TraceFormat " + usageMessage); + return; + } + + if (TraceArgs.verbose) { + errStream = System.err; + } + userVMIdentifier = TraceArgs.userVMIdentifier; try { @@ -268,7 +268,7 @@ public void readAndFormat(String[] args, boolean processFully) if (getTraceFiles() != 0) { return; } - + if (verMod >= 0.0) { // check that the header was parsed correctly. out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(TraceArgs.outputFile))); @@ -371,7 +371,7 @@ private void instantiateMessageFileOldStyle() } } - + private MessageFile tryMessageFileInstantiation(String fileName){ if (fileName != null){ try { @@ -385,7 +385,7 @@ private MessageFile tryMessageFileInstantiation(String fileName){ } /** - * find the most applicable dat file available to this formatter, using the + * find the most applicable dat file available to this formatter, using the * dirsToSearch list of locations. * @param dirsToSearch - a non null list of directories to search, in the order * to search (i.e. index zero is first location to search). @@ -414,14 +414,14 @@ private String findDatFile(String dirsToSearch[], String firstFileName){ return datfile; } - + private void instantiateMessageFiles(String lowestPriorityDefault) { String dirsToSearch[]; final String legacyJVMFormatFileName = traceFile.formatFileName(); - + TraceFormat.outStream.println("*** Locating formatting template files"); - + if (TraceArgs.datFileDirectory == null) { /* give current directory preference */ dirsToSearch = new String[]{".", lowestPriorityDefault}; @@ -438,16 +438,16 @@ private void instantiateMessageFiles(String lowestPriorityDefault) */ jvmFormatFilePath = findDatFile(dirsToSearch, "J9TraceFormat.dat"); } - + if (jvmFormatFilePath != null) { /* we found a suitable dat file */ messageFile = tryMessageFileInstantiation(jvmFormatFilePath); } - + if( messageFile == null ) { TraceFormat.outStream.println("*** Could not find a J9TraceFormat.dat file. JVM trace points may be formatted incorrectly."); } - + /* * Now load OMRTraceFormat.dat if available. */ @@ -471,7 +471,7 @@ private void instantiateMessageFiles(String lowestPriorityDefault) messageFile = messageFileBase; } } - + if (messageFile == null) { TraceFormat.outStream.println("Could not find a dat file. No trace point parameters will be formatted."); @@ -505,10 +505,10 @@ private void prime() throws IOException tracedThreads = null; numberOfThreads = 0; timeStamps = null; - + /* process trace files from a 5.0 vm or above */ long numberOfBuffers = 0; - + int bufferSize = 0; Hashtable listOfThreadBuffers = new Hashtable(); @@ -588,7 +588,7 @@ private void prime() throws IOException TraceFormat.first = overallStartPlatform; TraceFormat.last = overallStartPlatform; } - + TraceFormat.outStream.println("*** Sorting buffers"); TraceThread traceThread; for (Iterator i = threads.iterator(); i.hasNext();) { @@ -609,7 +609,7 @@ private void prime() throws IOException // return; } } - + // write out the header info TraceFormat.outStream .println("*** Starting formatting of entries into text file " @@ -617,14 +617,14 @@ private void prime() throws IOException out.write(header, 0, header.length()); out.newLine(); out.newLine(); - + int ptrWidth = Integer.valueOf(Util.getProperty("POINTER_SIZE")).intValue(); - + StringBuffer blanks = new StringBuffer(""); for (int i = 0; userVMIdentifier!= null && i <= userVMIdentifier.length(); i++) { blanks.append(" "); } - + if (ptrWidth == 4) { headings = blanks + " ThreadID TP id Type TraceEntry "; @@ -646,7 +646,7 @@ private void prime() throws IOException populateTimeStamps(tracedThreads, timeStamps, numberOfThreads); primed = true; } - + private void readAndFormatNewStyle() throws IOException { if (!primed){ @@ -660,14 +660,14 @@ private void readAndFormatNewStyle() throws IOException TraceThread tthread; int tracePointsFormatted = 0; StringBuffer tempTPString; - + while ((tp = findNextTracePoint(tracedThreads, timeStamps, numberOfThreads)) != null) { if (!tp.isNormalTracepoint()) { /* let the tracepoint give us it's text */ out.write(tp.toString()); out.newLine(); - + continue; } @@ -725,7 +725,7 @@ private void readAndFormatNewStyle() throws IOException String formattedData = tp.getFormattedParameters(); tempTPString.append(formattedData); - + if (TraceArgs.debug){ /* tie the formatted tracepoint to the binary file location */ tempTPString.append(" " + tp.from()); @@ -792,7 +792,7 @@ protected int doSummary(BufferedWriter out) throws IOException tf.traceFileHeader.summarize(out); out.write("Active Threads :"); out.newLine(); - + // Write out list of threads in trace files for (Iterator i = threads.iterator(); i.hasNext();) { traceThread = (TraceThread) i.next(); @@ -823,7 +823,7 @@ protected int doSummary(BufferedWriter out) throws IOException } else { timeConversion = BigInteger.ONE; } - + Util.Debug.println("timeConversion: " + timeConversion); out.write("JVM started : " @@ -965,11 +965,11 @@ private TraceThread getCurrentTraceThread(TraceThread[] tracedThreads) return tracedThreads[tracedThreadWithNewestTracePoint]; } } - + public com.ibm.jvm.trace.TraceThread[] getTraceThreads(){ return tracedThreads; } - + /* allow external iterators access to the next tracepoint */ public com.ibm.jvm.trace.TracePoint getNextTracePoint(){ TracePoint tp = findNextTracePoint(tracedThreads, timeStamps, numberOfThreads); @@ -1012,7 +1012,7 @@ private TracePoint findNextTracePoint(TraceThread[] tracedThreads, .getNextTracePoint(); } } - + public com.ibm.jvm.trace.TraceFileHeader getTraceFileHeader(){ TraceFile tf = (TraceFile)traceFiles.firstElement(); if (tf == null){ diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TracePoint.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TracePoint.java index ba0d1cb8670..956e30cee85 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TracePoint.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TracePoint.java @@ -40,10 +40,10 @@ public class TracePoint implements Comparable, com.ibm.jvm.trace.TracePoint private static String compNamePadding = " "; private static String tpIDPadding = " "; private boolean isLongTracePoint = false; - private int longTracePointLength = 0; // if this is a long tracepoint, this number is the number of bytes in the + private int longTracePointLength = 0; // if this is a long tracepoint, this number is the number of bytes in the // buffer that constitute the actual tracepoint (will be the next previous - // block). + // block). private boolean isNormalTracepoint = true; // means the same thing as isNotInternalTraceEngineTracePoint! private boolean isInvalid = false; // a flag that is set if the tracepoint contains any surprises. private boolean isLostRecord = false; @@ -51,7 +51,7 @@ public class TracePoint implements Comparable, com.ibm.jvm.trace.TracePoint // hopefully it will be possible to write a parser that takes a look // at all the isInvalid tracepoints and makes a call about what was wrong with them - // or at least gives the debugger an idea of where they are in the tracefile. + // or at least gives the debugger an idea of where they are in the tracefile. private long startOffsetInTraceFile = -1; // private long endOffsetInTraceFile = -1; // private boolean fragmented = false; // if true, this tracepoint was created from non-contiguous data in the binary trace file. @@ -60,7 +60,7 @@ public class TracePoint implements Comparable, com.ibm.jvm.trace.TracePoint private long newTimerUpperWord = -1; BigInteger upperWord = null; - /** + /** * */ public TracePoint(byte[] rawTracePoint, int length, BigInteger upperWord, @@ -121,8 +121,8 @@ private TracePoint parseDataIntoTracepoint(byte[] rawTracePoint, int length) tracepointID = Util.constructTraceID(rawTracePoint, 1); tracepointID &= 0x3FFF; /* work around for comp id coded into cmvc */ - /* special lost record tracepoint == 0x0010nnnn8 == < 0 ^ UT_TRC_LOST_COUNT_ID ^ nnn ^ 8 > where nnn is - * the number of lost records they should always be the first tracepoint in a buffer too, but we can't + /* special lost record tracepoint == 0x0010nnnn8 == < 0 ^ UT_TRC_LOST_COUNT_ID ^ nnn ^ 8 > where nnn is + * the number of lost records they should always be the first tracepoint in a buffer too, but we can't * really check that here as we don't really know where we are in the buffer in this class */ if (rawTracePoint[0] == 0x0 && rawTracePoint[1] == 0x0 && rawTracePoint[2] == 0x1 && rawTracePoint[3] == 0x0 @@ -151,7 +151,7 @@ private TracePoint parseDataIntoTracepoint(byte[] rawTracePoint, int length) return this; } /* act on the sequence wrap */ - long sequenceWrap = Util.constructUnsignedInt(rawTracePoint, 4); /* this is the new upper word for all + long sequenceWrap = Util.constructUnsignedInt(rawTracePoint, 4); /* this is the new upper word for all tracepoints in the rest of this buffer */ isNormalTracepoint = false; /* although this is an internal tracepoint, it needs to end up in all the arrays as its location is important! */ isNewTimerUpperWord = true; @@ -242,7 +242,7 @@ private TracePoint parseDataIntoTracepoint(byte[] rawTracePoint, int length) String newComponentName = componentName.substring(0, openBracketIndex); componentName = newComponentName; } - + /* add the rest of the bytes as the parmData */ int parmDataStartsAt = 12 + (int) compNameLength; int parmDataLength = tplen - parmDataStartsAt; @@ -301,11 +301,11 @@ public String toString() } tpFormatted.append(" "); tpFormatted.append(componentName); - + if (containerComponentName != null){ tpFormatted.append("(" + containerComponentName + ")"); } - + tpFormatted.append("."); tpFormatted.append(tracepointID); if ((Integer.toString(tracepointID)).length() < tpIDPadding.length()) { @@ -335,7 +335,7 @@ public String getComponentName() { return componentName; } - + public String getContainerComponentName(){ return containerComponentName; } @@ -365,7 +365,7 @@ public String getParameterDataFormatted() formattedData = "FORMATTING PROBLEM OCCURRED WHILE PROCESSING THE RAW DATA FOR THIS TRACEPOINT - PARAMETER DATA UNAVAILABLE"; } } - + return formattedData; } @@ -464,7 +464,7 @@ public int getTypeAsInt(){ Message msg = MessageFile.getMessageFromID(getComponentName(), getTPID()); return msg.getType(); } - + /* methods implementing the com.ibm.jvm.trace.TracePoint interface */ public int getID(){ return getTPID(); @@ -502,13 +502,13 @@ public String getType(){ public String from() { StringBuffer sb = new StringBuffer(); - + sb.append("from: 0x"); sb.append(Long.toHexString(startOffsetInTraceFile)); sb.append("->0x"); sb.append(Long.toHexString(endOffsetInTraceFile)); sb.append(":" ); - + if (fragmented){ sb.append("F"); if (startOffsetInTraceFile == TraceRecord50.INTERNAL_WRAP_SPLIT_TP){ @@ -518,12 +518,12 @@ public String from() } else { sb.append("X"); } - } + } sb.append(":" ); sb.append(nameOfTraceFile); - + return sb.toString(); - + } - + } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecord.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecord.java index 87e45fb6bc9..47af9c33204 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecord.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecord.java @@ -28,532 +28,531 @@ import java.util.Iterator; import java.util.Stack; -/** - * The Trace Record corresponds to a runtime Trace Buffer, it is responsible for formatting +/** + * The Trace Record corresponds to a runtime Trace Buffer, it is responsible for formatting * individual trace entries. * * @author Tim Preece */ public class TraceRecord implements Comparable { - /*ibm@52623-start*/ - // Class Variables - protected static Hashtable indentLevels; /*ibm@53159*/ - protected static long lastThread; /*ibm@53159*/ - - protected static final byte EVENT_TYPE = 0; - protected static final byte EXCEPTION_TYPE = 1; - protected static final byte ENTRY_TYPE = 2; - protected static final byte ENTRY_EXCPT_TYPE = 3; - protected static final byte EXIT_TYPE = 4; - protected static final byte EXIT_EXCPT_TYPE = 5; - protected static final byte MEM_TYPE = 6; - protected static final byte MEM_EXCPT_TYPE = 7; - protected static final byte DEBUG_TYPE = 8; - protected static final byte DEBUG_EXCPT_TYPE = 9; - protected static final byte PERF_TYPE = 10; - protected static final byte PERF_EXCPT_TYPE = 11; - protected static final byte ASSERT_TYPE = 12; - protected static final byte APP_TYPE = 13; - protected static final byte ERROR_TYPE = 14; - - protected static final String[] Chars = new String[] { - "-", - ">", - ">", - "<", - "<", - " ", - " ", - " ", - " ", - " ", - " ", - "*", - " ", - "E" - }; - - protected static final String[] types = new String[] { - "Event ", - "Exception ", - "Entry ", - "Entry ", - "Exit ", - "Exit ", - "Mem ", - "Mem ", - "Debug ", - "Debug ", - "Perf ", - "Perf ", - "Assert ", - "AppTrace ", - "ERROR " - }; - - - // Class Constants - protected static final StringBuffer BASE_INDENT = new StringBuffer(); - protected static final String TAB = " "; - protected static final int TRACEID_OFFSET = 1; - protected static final int TIMESTAMP_OFFSET = 4; - - // Instance Variables - protected byte[] buffer = null; - protected byte[] nextEight = new byte[8]; //ibm@56594 - - protected BigInteger timeStamp; - protected BigInteger wrapTime; - protected BigInteger writePlatform = BigInteger.ZERO; - protected BigInteger writeSystem = BigInteger.ZERO; - protected long threadID = 0; - protected long threadSyn1 = 0; /*ibm@67471*/ - protected long threadSyn2 = 0; /*ibm@67471*/ - protected String threadName; - protected long nextEntry; - - private String padding; - private boolean doIndent; - private String threadIDString; - - protected boolean recordFinished = false; - - protected TraceThread traceThread = null; - protected TraceFile traceFile; - protected int bufferSize; - protected long start; - protected int offset; - - protected byte[] currentBuffer; - protected int currentOffset; - protected int currentTraceID; - protected int currentLength; - protected BigInteger currentTimeStamp; - private Message currentMessage; - private int currentType; - private String currentComponent; - - protected BigInteger upperWord = BigInteger.ZERO; - protected Stack wrapTimes = new Stack(); - protected Stack longEntryTraceIDs = new Stack(); /*ibm@26172*/ - protected boolean notFormatted = false; - private int lastErrorRecord = -1; /*ibm@50367*/ - - //Set default size for old trace versions - protected int headerSize = 72; /*ibm@67471*/ - - protected TraceRecord(TraceFile traceFile, long start) throws IOException - { - traceFile.seek(start); - timeStamp = traceFile.readBigInteger(8); - wrapTime = traceFile.readBigInteger(8); - writePlatform = traceFile.readBigInteger(8); - writeSystem = traceFile.readBigInteger(8); - threadID = traceFile.readL(); - if (TraceFileHeader.isUTE()) { /*ibm@67471*/ - threadSyn1 = traceFile.readL(); /*ibm@67471*/ - threadSyn2 = traceFile.readL(); /*ibm@67471*/ - headerSize = traceFile.readI(); /*ibm@67471*/ - nextEntry = traceFile.readI(); /*ibm@67471*/ - threadName = traceFile.readString(headerSize - 64); /*ibm@67471*/ - } else { /*ibm@67471*/ - threadName = traceFile.readString(28); - nextEntry = traceFile.readI(); - } /*ibm@67471*/ - traceFile.read(nextEight, 0, 8); //ibm@56594 - - upperWord = timeStamp.shiftRight(32); - wrapTimes.push(upperWord); - - threadIDString = Util.formatAsHexString(threadID); - - Util.Debug.println("reading timeStamp " + timeStamp); - Util.Debug.println("reading wrapTime " + wrapTime); - Util.Debug.println("reading writePlatform " + writePlatform); - Util.Debug.println("reading writeSystem " + writeSystem); - - this.bufferSize = traceFile.traceFileHeader.getBufferSize(); - this.traceFile = traceFile; - this.start = start; - this.currentTimeStamp = timeStamp; // for initial sort - - // Validity check the nextEntry field. Note that a value of -1 ibm@51252 - // indicates that this record does not contain the start of a trace ibm@51252 - // entry. i.e it is a middle segment of a spanned entry ibm@51252 - if ( nextEntry >= 0 && (nextEntry < headerSize || nextEntry > bufferSize) ) { /*ibm@51252*/ - Util.Debug.println("Invalid Buffer - nextEntry = " + nextEntry + ", headerSize = " + headerSize +", bufferSize = " + bufferSize ); //ibm@51252 - TraceFormat.invalidBuffers++; - return; - } - - // record if this is the lastest time but why not compare system - if (writePlatform.compareTo(TraceFormat.lastWritePlatform) > 0) { - Util.Debug.println("updating lastWritePlatform" + writePlatform); - Util.Debug.println("updating lastWriteSystem " + writeSystem); - TraceFormat.lastWritePlatform = writePlatform; - TraceFormat.lastWriteSystem = writeSystem; - } - - if (wrapTime.compareTo(TraceFormat.first) < 0) { - TraceFormat.first = wrapTime; - } - if (timeStamp.compareTo(TraceFormat.last) > 0) { - TraceFormat.last = timeStamp; - } - - if (Integer.valueOf(Util.getProperty("POINTER_SIZE")).intValue() == 4) { - padding = "00000000"; - } else { - padding = "0000000000000000"; - } - - doIndent = TraceArgs.indent; - - Util.Debug.println("*********************************************************"); - Util.Debug.println("TraceBufferHeader: timeStamp : 0x" + timeStamp.toString(16)); - Util.Debug.println("TraceBufferHeader: threadID : 0x" + Long.toString(threadID, 16)); - Util.Debug.println("TraceBufferHeader: threadName: " + threadName + "\n"); - Util.Debug.println("TraceBufferHeader: nextEntry : " + nextEntry); - Util.Debug.println("*********************************************************"); - - boolean foundThreadID = false; - Util.Debug.println("Processing Record Header"); - foundThreadID = false; - - if ( Util.findThreadID(Long.valueOf(threadID)) == false ) { - return; - } - - for (Iterator i=TraceFormat.threads.iterator(); i.hasNext();) { - traceThread = (TraceThread)i.next(); - if (threadID == traceThread.threadID && threadName.equals(traceThread.threadName)) { /*ibm@67471*/ - foundThreadID = true; - Util.Debug.println("Found existing threadID " + threadID ); - break ; - } - } - if (foundThreadID == false) { - traceThread = new TraceThread(threadID,threadName); - TraceFormat.threads.addElement(traceThread); - } - traceThread.addElement(this); - } - - /** Initializes static variables. - * - *

    This is called each time the TraceFormatter is started, from the initStatics() - * method in TraceFormat.java

    - */ /* added by ibm@53159 */ - final protected static void initStatics() - { - indentLevels = null; - lastThread = 0; - } - - /** returns the latest time stamp read so far - * - * @param info - * @return a biginteger that is that timestamp - */ - final protected BigInteger getCurrentTimeStamp() - { - return currentTimeStamp; - } - - /** returns the latest time stamp read so far - * - * @param info - * @return a biginteger that is that timestamp - */ - final protected TraceRecord getNextRecord() - { - int next = traceThread.indexOf(this) + 1; - - if (next >= traceThread.size()) { - return null; // not more records for this thread. - } else { - /* ibm@50367: - * There is a defect (51252) which can cause a trace record to be written - * out twice. If the timestamps of the current and next record are - * identical, then this must have happened. This code is inserted to - * skip over the repeated record. - */ - BigInteger thisTimeStamp = ((TraceRecord)traceThread.elementAt(next-1)).timeStamp ; /*ibm@50367*/ - BigInteger nextTimeStamp = ((TraceRecord)traceThread.elementAt(next)).timeStamp ; /*ibm@50367*/ - /*ibm@50367*/ - if(thisTimeStamp.equals(nextTimeStamp)) { /*ibm@50367*/ - /* Only issue message once per duplicate record */ /*ibm@50367*/ - if(lastErrorRecord != next) { /*ibm@50367*/ - lastErrorRecord = next; /*ibm@50367*/ - TraceFormat.outStream.println("\nWARNING: duplicate trace record discarded "+ /*ibm@52623*/ - "(record "+(next+1)+ /*ibm@50367*/ - " for thread " + Util.formatAsHexString(threadID)+")"); /*ibm@50367*/ - // One less record to expect... - TraceFormat.expectedRecords--; /*ibm@52623*/ - } /*ibm@50367*/ - /*ibm@50367*/ - /* - * return the next but one record rather than next record. - * If it doesn't exist, return null. - */ - if (next+1 >= traceThread.size()) { /*ibm@50367*/ - return null; // last two were the same, so we've finished - } else { /*ibm@50367*/ - return(TraceRecord)traceThread.elementAt(next+1); /*ibm@50367*/ - } - } else { - return(TraceRecord)traceThread.elementAt(next); - } - } - } - - /** - * sets up current* fields for later formatting - */ - final protected int processNextEntryHeader(byte[] entry,int start) throws IOException - { - - currentLength = Util.constructUnsignedByte(entry, start); - currentTraceID = Util.constructTraceID(entry, start + TRACEID_OFFSET); - - /* - * Check for timestamp wrap. Ignore record if it is not 8 bytes long - */ - if (currentTraceID == 0) { /*ibm@38118*/ - if (currentLength == 8) { /*ibm@38118*/ - upperWord = (BigInteger)wrapTimes.pop(); - Util.Debug.println("TraceRecord: timewrap new upperWord=" + upperWord); - } /*ibm@38118*/ - //notFormatted = false; // no need to print and format this one now never attempted - return 2; // special - } else { - if ((currentTraceID == 256) && (currentLength == 8)) { // special trace entry - currentTimeStamp = wrapTime; - Util.Debug.println("TraceRecord: lost records"); - } else { - currentTimeStamp = upperWord.shiftLeft(32).or(Util.constructUnsignedLong(entry, start + TIMESTAMP_OFFSET, Util.INT)); - } - } - - if (currentTraceID < 256) { /*ibm@26172*/ - Util.Debug.println("processing long record: start " + start); /*ibm@26172*/ - Util.Debug.println("processing long record: previous currentLength " + currentLength); /*ibm@26172*/ - Util.Debug.println("processing long record: previous currentTraceID " + currentTraceID); /*ibm@26172*/ - currentLength = currentLength + currentTraceID*256; /*ibm@26172*/ - currentTraceID = ((Integer)longEntryTraceIDs.pop()).intValue(); /*ibm@26172*/ - Util.Debug.println("processing long record: currentLength " + currentLength); /*ibm@26172*/ - Util.Debug.println("processing long record: currentTraceID " + currentTraceID); /*ibm@26172*/ - } - - if ( (currentMessage = MessageFile.getMessageFromID(currentTraceID)) == null ) { - // Handle preformatted application trace records. Added by ibm@62941 - if (TraceFormat.messageFile != null) { - TraceFormat.messageFile.addMessage("ApplicationTrace"); - } - if (currentLength == 8) { - Util.Debug.println("TraceRecord: Adding unrecognized event message format for tracepoint: " + currentTraceID); - TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " 1 01 1 N ApplicationTraceEntry \"Unrecognized tracepoint\""); - currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); - } else { - switch (entry[start + 10]) { - case '>': { - Util.Debug.println("TraceRecord: Adding entry message format for tracepoint: " + currentTraceID); - TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " 2 01 1 N ApplicationTraceEntry \"%s\""); - currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); - break; - } - case '<': { - int exception = entry[start + 8] == '*' ? 1 : 0; - Util.Debug.println("TraceRecord: Adding exit message format for tracepoint: " + currentTraceID); - TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " " + (exception + 4) + " 01 1 N ApplicationTraceExit \"%s\""); - currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); - break; - } - case '-': { - Util.Debug.println("TraceRecord: Adding event message format for tracepoint: " + currentTraceID); - TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " 0 01 1 N ApplicationTraceEvent \"%s\""); - currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); - break; - } - case '*': { - Util.Debug.println("TraceRecord: Adding exception message format for tracepoint: " + currentTraceID); - TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " 1 00 0 N ApplicationTraceException \"%s\""); - currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); - break; - } - default: { - Util.Debug.println("TraceRecord: message is null "); - Util.Debug.println("TraceRecord: currentTraceID " + currentTraceID); - Util.Debug.println("TraceRecord: currentLength " + currentLength); - Util.Debug.println("TraceRecord: notFormatted " + notFormatted); - Util.Debug.println("TraceRecord: start " + start); /*ibm@26172*/ - Util.printDump(entry,start + currentLength); /*ibm@26172*/ - TraceFormat.outStream.println(" "); /*ibm@52623*/ - TraceFormat.outStream.println("*** Invalid trace entry TraceID="+ /*ibm@52623*/ - Util.formatAsHexString(currentTraceID)+" found in Trace Buffer"); - return 0; - //System.exit(1); - //return -1; // is this an error? - } - } - } - } - currentType = currentMessage.getType(); - currentComponent = currentMessage.getComponent(); - currentBuffer = entry; - currentOffset = start; - - //Util.Debug.println("TraceRecord: length " + currentLength); - //Util.Debug.println("TraceRecord: traceID " + currentTraceID); - //Util.Debug.println("TraceRecord: timeStamp " + currentTimeStamp); - //Util.Debug.println("TraceRecord: f(timeStamp) " + Util.getFormattedTime(currentTimeStamp)); - //Util.Debug.println("TraceRecord: upperWord->32 " + upperWord.shiftLeft(32)); - //Util.Debug.println("TraceRecord: f(upperWord->32) " + Util.getFormattedTime(upperWord.shiftLeft(32))); - //Util.Debug.println("TraceRecord: start " + start); - //Util.Debug.println("TraceRecord: type " + currentType); - //Util.Debug.println("TraceRecord: component " + currentComponent); - - if (currentLength == 0) { - Util.Debug.println("TraceRecord: currentLength 0 start=" + start); /*ibm@26172*/ - Util.printDump(entry,16); /*ibm@26172*/ - TraceFormat.outStream.println("Internal Error"); /*ibm@52623*/ - throw new IOException(); - } - - if (Util.findComponentAndType(currentComponent.toLowerCase(), types[currentType].toLowerCase()) == false) { - return 2; - } - - return 1; - } - - /** - * return: the formatted trace entry. - */ - final protected String formatCurrentEntry() throws IOException - { - - boolean threadSwitch = (threadID != lastThread); - lastThread = threadID; // lastThread is a static should go to merge? - StringBuffer indent = getIndent(threadIDString, doIndent); - StringBuffer sBuffer = new StringBuffer(Util.getFormattedTime(currentTimeStamp)); - String entryData; - String stringId; - - try { /*ibm@28983*/ - if (currentTraceID == 256) { - entryData = currentMessage.getMessage(currentBuffer, currentOffset + 4, currentOffset+8); - } else { - entryData = currentMessage.getMessage(currentBuffer, currentOffset + 8, currentOffset + currentLength); /*ibm@4945*/ - } - } catch ( ArrayIndexOutOfBoundsException e ) { /*ibm@28983*/ - // e.printStackTrace(); /*ibm@28983*/ - // Util.Debug.println("TraceRecord - tep : currentOffset " + currentOffset); /*ibm@28983*/ - // Util.Debug.println("TraceRecord - tep : sBuffer " + sBuffer.toString()); /*ibm@28983*/ - // Util.Debug.println("TraceRecord - tep : currentTraceID " + currentTraceID); /*ibm@28983*/ - // Util.Debug.println("TraceRecord - tep : currentLength " + currentLength); /*ibm@28983*/ - // Util.Debug.println("TraceRecord - tep : currentType " + currentType); /*ibm@28983*/ - // Util.Debug.println("TraceRecord - tep : currentComponent " + currentComponent); /*ibm@28983*/ - // Util.printDump(currentBuffer,currentOffset+8); /*ibm@28983*/ - entryData="*** Invalid data in Trace Entry ***"; /*ibm@28983*/ - } /*ibm@28983*/ - - sBuffer.ensureCapacity(100); - - stringId = Util.formatAsHexString(currentTraceID); - stringId = " ".substring(stringId.length()) + stringId; - if (TraceFormat.verMod >= 1.1) { - sBuffer.append(threadSwitch?"*":" "); - sBuffer.append(padding.substring(Math.min(threadIDString.length(), padding.length())) + threadIDString); - sBuffer.append(" ").append(stringId); - sBuffer.append(((currentType & EXCEPTION_TYPE) == EXCEPTION_TYPE)?"*":" "); - sBuffer.append(types[currentType]); - //Util.Debug.println("TraceBuffer: sBuffer1a " + sBuffer.toString()); - } else { - sBuffer.append(threadSwitch?"*":" "); - sBuffer.append(padding.substring(Math.min(threadIDString.length(), padding.length())) + threadIDString); - sBuffer.append(" ").append(stringId); - sBuffer.append((currentType == EXCEPTION_TYPE)?Chars[currentType]:" "); - sBuffer.append(types[currentType]); - //Util.Debug.println("TraceBuffer: sBuffer1b " + sBuffer.toString()); - } - - if ( doIndent && ((currentType == EXIT_TYPE) ||(currentType == EXIT_EXCPT_TYPE)) ) { // need to decrease the indent for this thread id - indent.delete(0, TAB.length()); - setIndent(threadIDString, indent); - } - - //Util.Debug.println("TraceBuffer: sBuffer2 " + sBuffer.toString()); - sBuffer.append(BASE_INDENT.toString()).append(doIndent?indent.toString():"").append(Chars[currentType]).append(" ").append(entryData); - - if ( doIndent && ((currentType == ENTRY_TYPE) || (currentType == ENTRY_EXCPT_TYPE))) { // need to increase the indent for this thread id - indent.append(TAB); - setIndent(threadIDString, indent); - } - - //Util.Debug.println("TraceBuffer: sBuffer " + sBuffer.toString()); - //Util.Debug.println(" "); - notFormatted = false; - return sBuffer.toString(); - } - - /** - * release the record data for this TraceRecord so GC can do it's stuff - * - */ - final protected void release() - { - buffer = null; - currentBuffer = null; /*ibm@55702*/ - return; - } - - /** compares this TraceRecord to another based on the time stamp. - * - * @return an int which is negative if this entry is older than other, 0, - * if they are the same age, and positive if this is newer - */ - final public int compareTo(Object other) - { - // Util.Debug.println("TraceRecord compareTo: currentTimeStamp " + currentTimeStamp ); - // Util.Debug.println("TraceRecord compareTo: ((TraceRecord)other).getCurrentTimeStamp() " + ((TraceRecord)other).getCurrentTimeStamp() ); - return currentTimeStamp.compareTo(((TraceRecord)other).getCurrentTimeStamp()); - } - - /** sets the indent associated with a given thread id - * - * @param threadid a string that is the id of the thread which is to be indented - * @return a stringbuffer of spaces that is the amount to indent the entry associates with the specified thread id - */ - final protected static StringBuffer getIndent(String threadID, boolean doIndent) - { - if (!doIndent) { - return BASE_INDENT; - } else { - if ( indentLevels == null ) { - indentLevels = new Hashtable(); - } - StringBuffer sb = (StringBuffer)indentLevels.get(threadID); - return(sb == null ) ? new StringBuffer() : sb; - } - } - - /** sets the indent associated with a given thread id - * - * @param threadid a string that is the id of the thread which is to have its indent level set - * @param buffer a stringbuffer of spaces that is the amount to indent the entries associates with the specified thread id - */ - final protected static void setIndent(String threadID, StringBuffer buffer) - { - if ( indentLevels == null ) { - indentLevels = new Hashtable(); - } - indentLevels.remove(threadID); - indentLevels.put(threadID, buffer); - } - - protected void prime() throws IOException {} // this method is overridden - protected int getNextEntry() throws IOException { return 0;} // this method is overridden + /*ibm@52623-start*/ + // Class Variables + protected static Hashtable indentLevels; /*ibm@53159*/ + protected static long lastThread; /*ibm@53159*/ + + protected static final byte EVENT_TYPE = 0; + protected static final byte EXCEPTION_TYPE = 1; + protected static final byte ENTRY_TYPE = 2; + protected static final byte ENTRY_EXCPT_TYPE = 3; + protected static final byte EXIT_TYPE = 4; + protected static final byte EXIT_EXCPT_TYPE = 5; + protected static final byte MEM_TYPE = 6; + protected static final byte MEM_EXCPT_TYPE = 7; + protected static final byte DEBUG_TYPE = 8; + protected static final byte DEBUG_EXCPT_TYPE = 9; + protected static final byte PERF_TYPE = 10; + protected static final byte PERF_EXCPT_TYPE = 11; + protected static final byte ASSERT_TYPE = 12; + protected static final byte APP_TYPE = 13; + protected static final byte ERROR_TYPE = 14; + + protected static final String[] Chars = new String[] { + "-", + ">", + ">", + "<", + "<", + " ", + " ", + " ", + " ", + " ", + " ", + "*", + " ", + "E" + }; + + protected static final String[] types = new String[] { + "Event ", + "Exception ", + "Entry ", + "Entry ", + "Exit ", + "Exit ", + "Mem ", + "Mem ", + "Debug ", + "Debug ", + "Perf ", + "Perf ", + "Assert ", + "AppTrace ", + "ERROR " + }; + + // Class Constants + protected static final StringBuffer BASE_INDENT = new StringBuffer(); + protected static final String TAB = " "; + protected static final int TRACEID_OFFSET = 1; + protected static final int TIMESTAMP_OFFSET = 4; + + // Instance Variables + protected byte[] buffer = null; + protected byte[] nextEight = new byte[8]; //ibm@56594 + + protected BigInteger timeStamp; + protected BigInteger wrapTime; + protected BigInteger writePlatform = BigInteger.ZERO; + protected BigInteger writeSystem = BigInteger.ZERO; + protected long threadID = 0; + protected long threadSyn1 = 0; /*ibm@67471*/ + protected long threadSyn2 = 0; /*ibm@67471*/ + protected String threadName; + protected long nextEntry; + + private String padding; + private boolean doIndent; + private String threadIDString; + + protected boolean recordFinished = false; + + protected TraceThread traceThread = null; + protected TraceFile traceFile; + protected int bufferSize; + protected long start; + protected int offset; + + protected byte[] currentBuffer; + protected int currentOffset; + protected int currentTraceID; + protected int currentLength; + protected BigInteger currentTimeStamp; + private Message currentMessage; + private int currentType; + private String currentComponent; + + protected BigInteger upperWord = BigInteger.ZERO; + protected Stack wrapTimes = new Stack(); + protected Stack longEntryTraceIDs = new Stack(); /*ibm@26172*/ + protected boolean notFormatted = false; + private int lastErrorRecord = -1; /*ibm@50367*/ + + //Set default size for old trace versions + protected int headerSize = 72; /*ibm@67471*/ + + protected TraceRecord(TraceFile traceFile, long start) throws IOException + { + traceFile.seek(start); + timeStamp = traceFile.readBigInteger(8); + wrapTime = traceFile.readBigInteger(8); + writePlatform = traceFile.readBigInteger(8); + writeSystem = traceFile.readBigInteger(8); + threadID = traceFile.readL(); + if (TraceFileHeader.isUTE()) { /*ibm@67471*/ + threadSyn1 = traceFile.readL(); /*ibm@67471*/ + threadSyn2 = traceFile.readL(); /*ibm@67471*/ + headerSize = traceFile.readI(); /*ibm@67471*/ + nextEntry = traceFile.readI(); /*ibm@67471*/ + threadName = traceFile.readString(headerSize - 64); /*ibm@67471*/ + } else { /*ibm@67471*/ + threadName = traceFile.readString(28); + nextEntry = traceFile.readI(); + } /*ibm@67471*/ + traceFile.read(nextEight, 0, 8); //ibm@56594 + + upperWord = timeStamp.shiftRight(32); + wrapTimes.push(upperWord); + + threadIDString = Util.formatAsHexString(threadID); + + Util.Debug.println("reading timeStamp " + timeStamp); + Util.Debug.println("reading wrapTime " + wrapTime); + Util.Debug.println("reading writePlatform " + writePlatform); + Util.Debug.println("reading writeSystem " + writeSystem); + + this.bufferSize = traceFile.traceFileHeader.getBufferSize(); + this.traceFile = traceFile; + this.start = start; + this.currentTimeStamp = timeStamp; // for initial sort + + // Validity check the nextEntry field. Note that a value of -1 ibm@51252 + // indicates that this record does not contain the start of a trace ibm@51252 + // entry. i.e it is a middle segment of a spanned entry ibm@51252 + if ( nextEntry >= 0 && (nextEntry < headerSize || nextEntry > bufferSize) ) { /*ibm@51252*/ + Util.Debug.println("Invalid Buffer - nextEntry = " + nextEntry + ", headerSize = " + headerSize +", bufferSize = " + bufferSize ); //ibm@51252 + TraceFormat.invalidBuffers++; + return; + } + + // record if this is the lastest time but why not compare system + if (writePlatform.compareTo(TraceFormat.lastWritePlatform) > 0) { + Util.Debug.println("updating lastWritePlatform" + writePlatform); + Util.Debug.println("updating lastWriteSystem " + writeSystem); + TraceFormat.lastWritePlatform = writePlatform; + TraceFormat.lastWriteSystem = writeSystem; + } + + if (wrapTime.compareTo(TraceFormat.first) < 0) { + TraceFormat.first = wrapTime; + } + if (timeStamp.compareTo(TraceFormat.last) > 0) { + TraceFormat.last = timeStamp; + } + + if (Integer.valueOf(Util.getProperty("POINTER_SIZE")).intValue() == 4) { + padding = "00000000"; + } else { + padding = "0000000000000000"; + } + + doIndent = TraceArgs.indent; + + Util.Debug.println("*********************************************************"); + Util.Debug.println("TraceBufferHeader: timeStamp : 0x" + timeStamp.toString(16)); + Util.Debug.println("TraceBufferHeader: threadID : 0x" + Long.toString(threadID, 16)); + Util.Debug.println("TraceBufferHeader: threadName: " + threadName + "\n"); + Util.Debug.println("TraceBufferHeader: nextEntry : " + nextEntry); + Util.Debug.println("*********************************************************"); + + boolean foundThreadID = false; + Util.Debug.println("Processing Record Header"); + foundThreadID = false; + + if ( Util.findThreadID(Long.valueOf(threadID)) == false ) { + return; + } + + for (Iterator i=TraceFormat.threads.iterator(); i.hasNext();) { + traceThread = (TraceThread)i.next(); + if (threadID == traceThread.threadID && threadName.equals(traceThread.threadName)) { /*ibm@67471*/ + foundThreadID = true; + Util.Debug.println("Found existing threadID " + threadID ); + break ; + } + } + if (foundThreadID == false) { + traceThread = new TraceThread(threadID,threadName); + TraceFormat.threads.addElement(traceThread); + } + traceThread.addElement(this); + } + + /** Initializes static variables. + * + *

    This is called each time the TraceFormatter is started, from the initStatics() + * method in TraceFormat.java

    + */ /* added by ibm@53159 */ + final protected static void initStatics() + { + indentLevels = null; + lastThread = 0; + } + + /** returns the latest time stamp read so far + * + * @param info + * @return a biginteger that is that timestamp + */ + final protected BigInteger getCurrentTimeStamp() + { + return currentTimeStamp; + } + + /** returns the latest time stamp read so far + * + * @param info + * @return a biginteger that is that timestamp + */ + final protected TraceRecord getNextRecord() + { + int next = traceThread.indexOf(this) + 1; + + if (next >= traceThread.size()) { + return null; // not more records for this thread. + } else { + /* ibm@50367: + * There is a defect (51252) which can cause a trace record to be written + * out twice. If the timestamps of the current and next record are + * identical, then this must have happened. This code is inserted to + * skip over the repeated record. + */ + BigInteger thisTimeStamp = ((TraceRecord)traceThread.elementAt(next-1)).timeStamp ; /*ibm@50367*/ + BigInteger nextTimeStamp = ((TraceRecord)traceThread.elementAt(next)).timeStamp ; /*ibm@50367*/ + /*ibm@50367*/ + if(thisTimeStamp.equals(nextTimeStamp)) { /*ibm@50367*/ + /* Only issue message once per duplicate record */ /*ibm@50367*/ + if(lastErrorRecord != next) { /*ibm@50367*/ + lastErrorRecord = next; /*ibm@50367*/ + TraceFormat.outStream.println("\nWARNING: duplicate trace record discarded "+ /*ibm@52623*/ + "(record "+(next+1)+ /*ibm@50367*/ + " for thread " + Util.formatAsHexString(threadID)+")"); /*ibm@50367*/ + // One less record to expect... + TraceFormat.expectedRecords--; /*ibm@52623*/ + } /*ibm@50367*/ + /*ibm@50367*/ + /* + * return the next but one record rather than next record. + * If it doesn't exist, return null. + */ + if (next+1 >= traceThread.size()) { /*ibm@50367*/ + return null; // last two were the same, so we've finished + } else { /*ibm@50367*/ + return(TraceRecord)traceThread.elementAt(next+1); /*ibm@50367*/ + } + } else { + return(TraceRecord)traceThread.elementAt(next); + } + } + } + + /** + * sets up current* fields for later formatting + */ + final protected int processNextEntryHeader(byte[] entry,int start) throws IOException + { + + currentLength = Util.constructUnsignedByte(entry, start); + currentTraceID = Util.constructTraceID(entry, start + TRACEID_OFFSET); + + /* + * Check for timestamp wrap. Ignore record if it is not 8 bytes long + */ + if (currentTraceID == 0) { /*ibm@38118*/ + if (currentLength == 8) { /*ibm@38118*/ + upperWord = (BigInteger)wrapTimes.pop(); + Util.Debug.println("TraceRecord: timewrap new upperWord=" + upperWord); + } /*ibm@38118*/ + //notFormatted = false; // no need to print and format this one now never attempted + return 2; // special + } else { + if ((currentTraceID == 256) && (currentLength == 8)) { // special trace entry + currentTimeStamp = wrapTime; + Util.Debug.println("TraceRecord: lost records"); + } else { + currentTimeStamp = upperWord.shiftLeft(32).or(Util.constructUnsignedLong(entry, start + TIMESTAMP_OFFSET, Util.INT)); + } + } + + if (currentTraceID < 256) { /*ibm@26172*/ + Util.Debug.println("processing long record: start " + start); /*ibm@26172*/ + Util.Debug.println("processing long record: previous currentLength " + currentLength); /*ibm@26172*/ + Util.Debug.println("processing long record: previous currentTraceID " + currentTraceID); /*ibm@26172*/ + currentLength = currentLength + currentTraceID*256; /*ibm@26172*/ + currentTraceID = ((Integer)longEntryTraceIDs.pop()).intValue(); /*ibm@26172*/ + Util.Debug.println("processing long record: currentLength " + currentLength); /*ibm@26172*/ + Util.Debug.println("processing long record: currentTraceID " + currentTraceID); /*ibm@26172*/ + } + + if ( (currentMessage = MessageFile.getMessageFromID(currentTraceID)) == null ) { + // Handle preformatted application trace records. Added by ibm@62941 + if (TraceFormat.messageFile != null) { + TraceFormat.messageFile.addMessage("ApplicationTrace"); + } + if (currentLength == 8) { + Util.Debug.println("TraceRecord: Adding unrecognized event message format for tracepoint: " + currentTraceID); + TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " 1 01 1 N ApplicationTraceEntry \"Unrecognized tracepoint\""); + currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); + } else { + switch (entry[start + 10]) { + case '>': { + Util.Debug.println("TraceRecord: Adding entry message format for tracepoint: " + currentTraceID); + TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " 2 01 1 N ApplicationTraceEntry \"%s\""); + currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); + break; + } + case '<': { + int exception = entry[start + 8] == '*' ? 1 : 0; + Util.Debug.println("TraceRecord: Adding exit message format for tracepoint: " + currentTraceID); + TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " " + (exception + 4) + " 01 1 N ApplicationTraceExit \"%s\""); + currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); + break; + } + case '-': { + Util.Debug.println("TraceRecord: Adding event message format for tracepoint: " + currentTraceID); + TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " 0 01 1 N ApplicationTraceEvent \"%s\""); + currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); + break; + } + case '*': { + Util.Debug.println("TraceRecord: Adding exception message format for tracepoint: " + currentTraceID); + TraceFormat.messageFile.addMessage(Util.formatAsHexString(currentTraceID) + " 1 00 0 N ApplicationTraceException \"%s\""); + currentMessage = TraceFormat.messageFile.getMessageFromID(currentTraceID); + break; + } + default: { + Util.Debug.println("TraceRecord: message is null "); + Util.Debug.println("TraceRecord: currentTraceID " + currentTraceID); + Util.Debug.println("TraceRecord: currentLength " + currentLength); + Util.Debug.println("TraceRecord: notFormatted " + notFormatted); + Util.Debug.println("TraceRecord: start " + start); /*ibm@26172*/ + Util.printDump(entry,start + currentLength); /*ibm@26172*/ + TraceFormat.outStream.println(" "); /*ibm@52623*/ + TraceFormat.outStream.println("*** Invalid trace entry TraceID="+ /*ibm@52623*/ + Util.formatAsHexString(currentTraceID)+" found in Trace Buffer"); + return 0; + //System.exit(1); + //return -1; // is this an error? + } + } + } + } + currentType = currentMessage.getType(); + currentComponent = currentMessage.getComponent(); + currentBuffer = entry; + currentOffset = start; + + //Util.Debug.println("TraceRecord: length " + currentLength); + //Util.Debug.println("TraceRecord: traceID " + currentTraceID); + //Util.Debug.println("TraceRecord: timeStamp " + currentTimeStamp); + //Util.Debug.println("TraceRecord: f(timeStamp) " + Util.getFormattedTime(currentTimeStamp)); + //Util.Debug.println("TraceRecord: upperWord->32 " + upperWord.shiftLeft(32)); + //Util.Debug.println("TraceRecord: f(upperWord->32) " + Util.getFormattedTime(upperWord.shiftLeft(32))); + //Util.Debug.println("TraceRecord: start " + start); + //Util.Debug.println("TraceRecord: type " + currentType); + //Util.Debug.println("TraceRecord: component " + currentComponent); + + if (currentLength == 0) { + Util.Debug.println("TraceRecord: currentLength 0 start=" + start); /*ibm@26172*/ + Util.printDump(entry,16); /*ibm@26172*/ + TraceFormat.outStream.println("Internal Error"); /*ibm@52623*/ + throw new IOException(); + } + + if (Util.findComponentAndType(currentComponent.toLowerCase(), types[currentType].toLowerCase()) == false) { + return 2; + } + + return 1; + } + + /** + * return: the formatted trace entry. + */ + final protected String formatCurrentEntry() throws IOException + { + + boolean threadSwitch = (threadID != lastThread); + lastThread = threadID; // lastThread is a static should go to merge? + StringBuffer indent = getIndent(threadIDString, doIndent); + StringBuffer sBuffer = new StringBuffer(Util.getFormattedTime(currentTimeStamp)); + String entryData; + String stringId; + + try { /*ibm@28983*/ + if (currentTraceID == 256) { + entryData = currentMessage.getMessage(currentBuffer, currentOffset + 4, currentOffset+8); + } else { + entryData = currentMessage.getMessage(currentBuffer, currentOffset + 8, currentOffset + currentLength); /*ibm@4945*/ + } + } catch ( ArrayIndexOutOfBoundsException e ) { /*ibm@28983*/ + // e.printStackTrace(); /*ibm@28983*/ + // Util.Debug.println("TraceRecord - tep : currentOffset " + currentOffset); /*ibm@28983*/ + // Util.Debug.println("TraceRecord - tep : sBuffer " + sBuffer.toString()); /*ibm@28983*/ + // Util.Debug.println("TraceRecord - tep : currentTraceID " + currentTraceID); /*ibm@28983*/ + // Util.Debug.println("TraceRecord - tep : currentLength " + currentLength); /*ibm@28983*/ + // Util.Debug.println("TraceRecord - tep : currentType " + currentType); /*ibm@28983*/ + // Util.Debug.println("TraceRecord - tep : currentComponent " + currentComponent); /*ibm@28983*/ + // Util.printDump(currentBuffer,currentOffset+8); /*ibm@28983*/ + entryData="*** Invalid data in Trace Entry ***"; /*ibm@28983*/ + } /*ibm@28983*/ + + sBuffer.ensureCapacity(100); + + stringId = Util.formatAsHexString(currentTraceID); + stringId = " ".substring(stringId.length()) + stringId; + if (TraceFormat.verMod >= 1.1) { + sBuffer.append(threadSwitch?"*":" "); + sBuffer.append(padding.substring(Math.min(threadIDString.length(), padding.length())) + threadIDString); + sBuffer.append(" ").append(stringId); + sBuffer.append(((currentType & EXCEPTION_TYPE) == EXCEPTION_TYPE)?"*":" "); + sBuffer.append(types[currentType]); + //Util.Debug.println("TraceBuffer: sBuffer1a " + sBuffer.toString()); + } else { + sBuffer.append(threadSwitch?"*":" "); + sBuffer.append(padding.substring(Math.min(threadIDString.length(), padding.length())) + threadIDString); + sBuffer.append(" ").append(stringId); + sBuffer.append((currentType == EXCEPTION_TYPE)?Chars[currentType]:" "); + sBuffer.append(types[currentType]); + //Util.Debug.println("TraceBuffer: sBuffer1b " + sBuffer.toString()); + } + + if ( doIndent && ((currentType == EXIT_TYPE) ||(currentType == EXIT_EXCPT_TYPE)) ) { // need to decrease the indent for this thread id + indent.delete(0, TAB.length()); + setIndent(threadIDString, indent); + } + + //Util.Debug.println("TraceBuffer: sBuffer2 " + sBuffer.toString()); + sBuffer.append(BASE_INDENT.toString()).append(doIndent?indent.toString():"").append(Chars[currentType]).append(" ").append(entryData); + + if ( doIndent && ((currentType == ENTRY_TYPE) || (currentType == ENTRY_EXCPT_TYPE))) { // need to increase the indent for this thread id + indent.append(TAB); + setIndent(threadIDString, indent); + } + + //Util.Debug.println("TraceBuffer: sBuffer " + sBuffer.toString()); + //Util.Debug.println(" "); + notFormatted = false; + return sBuffer.toString(); + } + + /** + * release the record data for this TraceRecord so GC can do it's stuff + * + */ + final protected void release() + { + buffer = null; + currentBuffer = null; /*ibm@55702*/ + return; + } + + /** compares this TraceRecord to another based on the time stamp. + * + * @return an int which is negative if this entry is older than other, 0, + * if they are the same age, and positive if this is newer + */ + final public int compareTo(Object other) + { + // Util.Debug.println("TraceRecord compareTo: currentTimeStamp " + currentTimeStamp ); + // Util.Debug.println("TraceRecord compareTo: ((TraceRecord)other).getCurrentTimeStamp() " + ((TraceRecord)other).getCurrentTimeStamp() ); + return currentTimeStamp.compareTo(((TraceRecord)other).getCurrentTimeStamp()); + } + + /** sets the indent associated with a given thread id + * + * @param threadid a string that is the id of the thread which is to be indented + * @return a stringbuffer of spaces that is the amount to indent the entry associates with the specified thread id + */ + final protected static StringBuffer getIndent(String threadID, boolean doIndent) + { + if (!doIndent) { + return BASE_INDENT; + } else { + if ( indentLevels == null ) { + indentLevels = new Hashtable(); + } + StringBuffer sb = (StringBuffer)indentLevels.get(threadID); + return(sb == null ) ? new StringBuffer() : sb; + } + } + + /** sets the indent associated with a given thread id + * + * @param threadid a string that is the id of the thread which is to have its indent level set + * @param buffer a stringbuffer of spaces that is the amount to indent the entries associates with the specified thread id + */ + final protected static void setIndent(String threadID, StringBuffer buffer) + { + if ( indentLevels == null ) { + indentLevels = new Hashtable(); + } + indentLevels.remove(threadID); + indentLevels.put(threadID, buffer); + } + + protected void prime() throws IOException {} // this method is overridden + protected int getNextEntry() throws IOException { return 0;} // this method is overridden } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecord50.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecord50.java index 3cda71b86e2..00f33db22a7 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecord50.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecord50.java @@ -28,13 +28,13 @@ /** * Extends Trace Record. Special processing needed for internal trace records. - * + * * @author Simon Rowland */ public class TraceRecord50 implements Comparable { public static final int INTERNAL_WRAP_SPLIT_TP = -1; public static final int EXTERNAL_WRAP_SPLIT_TP = -2; - + /* * the following fields represent the UtTraceRecord struct's fields that * were written as the header to this file @@ -99,9 +99,9 @@ public class TraceRecord50 implements Comparable { private byte[] dataAtEndOfBuffer; private boolean isMiddleOfTracePoint = false; - + private long lostRecordCount = 0; - + private BigInteger earliestTimeStamp = null; public int processTraceBufferHeader(TraceFile traceFile, long start, @@ -135,10 +135,10 @@ public int processTraceBufferHeader(TraceFile traceFile, long start, dataLength = bufferLength - dataStart; Util.Debug.println("Found a middle section - dataLength == " + dataLength); - } else { + } else { dataLength = dataEnd - dataStart; } - + if ( nextEntry >= 0 && (nextEntry < dataStart || nextEntry > bufferLength) ) { dataLength = 0; TraceFormat.invalidBuffers++; @@ -167,7 +167,7 @@ public int processTraceBufferHeader(TraceFile traceFile, long start, if (timeStamp.compareTo(TraceFormat.last) > 0) { TraceFormat.last = timeStamp; } - + // If this is the latest record so far, update the file wrap point for this trace file if (writeSystem.compareTo(traceFile.lastWriteSystem) > 0) { traceFile.lastWriteSystem = writeSystem; @@ -230,9 +230,9 @@ public byte[] getExtraData() { } } - /** + /** * read the bytes of this UtTraceRecord into a byte array. - * + * * @param traceFile to read from. * @return an array of bytes that constitute this UtTraceRecord. * @throws IOException if there is a problem reading from the trace file @@ -253,7 +253,7 @@ private byte[] readRecord(TraceFile traceFile) throws IOException { throw new IOException("Can't read record from tracefile"); } - /* A tracepoint runs straight through this buffer, + /* A tracepoint runs straight through this buffer, * so save the data but don't format anything yet. This * formatting will be done by the TraceRecord that contains * the end of this tracepoint. */ @@ -275,7 +275,7 @@ private byte[] readRecord(TraceFile traceFile) throws IOException { if (dataLeftAtEndOfBufLength > 0) { /* the data at the end of the tracepoint may be the beginning of a tracepoint * that runs into the next TraceRecord. We can't know until we format the next - * TraceRecord, so we need to store the extra data for the next TraceRecord to + * TraceRecord, so we need to store the extra data for the next TraceRecord to * retrieve if it needs it. */ dataAtEndOfBuffer = new byte[dataLeftAtEndOfBufLength]; startOfExtraData = (long) dataEnd + offsetInFile; @@ -298,17 +298,17 @@ private byte[] readRecord(TraceFile traceFile) throws IOException { } return recordBytes; } - + /** * primeRecord readies this UtTraceRecord to have its tracepoint data read. - * + * * Each tracepoint's length field is at the end of the tracepoint, so the tracepoints are - * formatted backwards out of the record. To enable forward iteration, the whole record + * formatted backwards out of the record. To enable forward iteration, the whole record * must be formatted into a queue, which is then iterated over in reverse order. - * + * * The record should already have been primed with e.g. it's location in the tracefile * through it's constructor. - * + * * @param traceFile * @return true if it works, false if any errors are encountered. Errors are reported * internally. @@ -322,7 +322,7 @@ public boolean primeRecord(TraceFile traceFile) throws IOException { if (offset < 0){ return true; } - + /* keep debug records of where the current tracepoint is and what it looks like */ long endOfCurrentTP = absolutePositionInFile + offset; long startOfCurrentTP = -3; @@ -331,7 +331,7 @@ public boolean primeRecord(TraceFile traceFile) throws IOException { /* allocate once, and allow for max normal size! */ byte[] tpdata = new byte[bufferLength]; - boolean recordHasWrapped = false; + boolean recordHasWrapped = false; boolean longTPLen = false; /* we determine here if this record starts with a lost record tracepoint. @@ -342,13 +342,13 @@ public boolean primeRecord(TraceFile traceFile) throws IOException { /* possible lost record, check for signature but make sure we have enough bytes to construct an int */ if (traceRecordBytes[1] == 0x0 && traceRecordBytes[2] == 0x1 && traceRecordBytes[3] == 0x0 && traceRecordBytes.length >= 8) { lostRecordCount = Util.constructUnsignedInt(traceRecordBytes, 4); - TraceFormat.lostRecordCount+= lostRecordCount; - + TraceFormat.lostRecordCount+= lostRecordCount; + /* discard remainder data from previous buffer, it'll be invalid */ - overspillData = null; + overspillData = null; } } - + /* parse each tracepoint */ do { if (!longTPLen) { @@ -375,7 +375,7 @@ public boolean primeRecord(TraceFile traceFile) throws IOException { sp = null; if (tplength > offset) { - /* + /* * This tracepoint runs for longer than the available data. Therefore * it is the *end* of a tracepoint that is in more than one buffer. */ @@ -505,7 +505,7 @@ public boolean primeRecord(TraceFile traceFile) throws IOException { } else { sp.setRawTimeStamp(timeStamp); } - + if (tps.size() > 0) { tps.insertElementAt(sp, tps.size() -1); } else { @@ -518,7 +518,7 @@ public boolean primeRecord(TraceFile traceFile) throws IOException { tps.add(sp); earliestTimeStamp = sp.getRawTimeStamp(); } /* else it is an internal tracepoint so discard it */ - + /* move pointers to next tracepoint */ endOfCurrentTP -= tplength; } while ((tplength > 0) && (offset >= 0)); @@ -567,26 +567,26 @@ public void setTimeStamp(BigInteger newTimeStamp) { public int compareTo(Object other) { /* CMVC 177932. Fix to use system write time for sorting trace records rather than the nanosecond tracepoint - * timer, because the nanosecond timer is known to hop around across CPUs on some systems. The records for a + * timer, because the nanosecond timer is known to hop around across CPUs on some systems. The records for a * thread are always written FIFO, so sorting is only actually needed in case the trace file was wrapped, i.e. * if trace option -Xtrace:output={file,size} was used. - * + * * The system write time is only millisecs precision. So adjacent trace records may have identical system times, - * particularly in trace snap files. This is mostly OK, as the buffers are written FIFO, and Collections.sort will + * particularly in trace snap files. This is mostly OK, as the buffers are written FIFO, and Collections.sort will * not re-order if the times are identical. We do however need a tie-breaker for cases where we have wrapped from * the end of a trace file to the start. - * - * Note that the new trace formatter (com.ibm.jvm.TraceFormat) does not sort records (it does not yet support + * + * Note that the new trace formatter (com.ibm.jvm.TraceFormat) does not sort records (it does not yet support * wrapped or generation trace files). - * + * * Invoked indirectly via call to Collections.sort() in com.ibm.jvm.format.TraceFormat.prime(). */ - + if (writeSystem == BigInteger.ZERO || ((TraceRecord50)other).writeSystem == BigInteger.ZERO) { Util.Debug.println("TraceRecord50.compareTo() found trace record with a zero system write time"); return 0; } - + int result = writeSystem.compareTo(((TraceRecord50)other).writeSystem); if (result == 0) { // record write times are the same, calculate tie-breaker for records in wrapped trace files @@ -612,7 +612,7 @@ public void setTraceType(int traceType) { public BigInteger getLastUpperWord() { return upperTimeWord; } - + public String toString(){ StringBuffer sb = new StringBuffer(); diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecordExternal.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecordExternal.java index 2440b7f9a9e..42e43522d4e 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecordExternal.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecordExternal.java @@ -24,249 +24,248 @@ import java.io.IOException; -/** +/** * Extends Trace Record. Special processing needed for external trace records. * * @author Tim Preece */ final public class TraceRecordExternal extends TraceRecord { - protected byte[] spannedEntrySoFar; - protected byte[] spanEntry; - private int spannedEntrySizeSoFar = 0; + protected byte[] spannedEntrySoFar; + protected byte[] spanEntry; + private int spannedEntrySizeSoFar = 0; - protected TraceRecordExternal(TraceFile traceFile, long start) throws IOException - { - super(traceFile, start); - } + protected TraceRecordExternal(TraceFile traceFile, long start) throws IOException + { + super(traceFile, start); + } - /** - * reads in the record data for this TraceRecord - * - */ - protected void prime() throws IOException - { - // Allow room for the all trace entries including the spanned record - buffer = new byte[bufferSize-headerSize+spannedEntrySizeSoFar]; - int oldestEntry; - int length; - int longEntryID = 0; - int longEntryLength = 0; - int entry; // running pointer to each trace entry in buffer. + /** + * reads in the record data for this TraceRecord + * + */ + protected void prime() throws IOException + { + // Allow room for the all trace entries including the spanned record + buffer = new byte[bufferSize-headerSize+spannedEntrySizeSoFar]; + int oldestEntry; + int length; + int longEntryID = 0; + int longEntryLength = 0; + int entry; // running pointer to each trace entry in buffer. - // construct the buffer. The entry starts off as the next available slot. - entry = (int)(nextEntry-headerSize+spannedEntrySizeSoFar); - if ( spannedEntrySizeSoFar > 0 ) { - System.arraycopy(spannedEntrySoFar,0,buffer,0,spannedEntrySizeSoFar); - } - traceFile.seek((long)(start+headerSize)); // skip over the header - traceFile.read(buffer,spannedEntrySizeSoFar,bufferSize-headerSize); + // construct the buffer. The entry starts off as the next available slot. + entry = (int)(nextEntry-headerSize+spannedEntrySizeSoFar); + if ( spannedEntrySizeSoFar > 0 ) { + System.arraycopy(spannedEntrySoFar,0,buffer,0,spannedEntrySizeSoFar); + } + traceFile.seek((long)(start+headerSize)); // skip over the header + traceFile.read(buffer,spannedEntrySizeSoFar,bufferSize-headerSize); - Util.Debug.println(" "); - Util.Debug.println("TraceRecord: reading buffer size=: " + bufferSize); - Util.Debug.println("TraceRecord: nextEntry : " + (int)nextEntry); + Util.Debug.println(" "); + Util.Debug.println("TraceRecord: reading buffer size=: " + bufferSize); + Util.Debug.println("TraceRecord: nextEntry : " + (int)nextEntry); - if (nextEntry < 0) { - Util.Debug.println("TraceRecord: entry spans entire record"); - // anything left is part of a spanned record and needs to be copied to the next record - copySpannedEntryForNextRecord(buffer,0,bufferSize-headerSize+spannedEntrySizeSoFar); - return; - } else { - Util.Debug.println("TraceRecord: buffer[nextEntry]: " + buffer[entry]); - } + if (nextEntry < 0) { + Util.Debug.println("TraceRecord: entry spans entire record"); + // anything left is part of a spanned record and needs to be copied to the next record + copySpannedEntryForNextRecord(buffer,0,bufferSize-headerSize+spannedEntrySizeSoFar); + return; + } else { + Util.Debug.println("TraceRecord: buffer[nextEntry]: " + buffer[entry]); + } + //Util.printDump(buffer,bufferSize-headerSize+spannedEntrySizeSoFar); - //Util.printDump(buffer,bufferSize-headerSize+spannedEntrySizeSoFar); + // anything left is part of a spanned record and needs to be copied to the next record + copySpannedEntryForNextRecord(buffer,entry,bufferSize-headerSize+spannedEntrySizeSoFar); - // anything left is part of a spanned record and needs to be copied to the next record - copySpannedEntryForNextRecord(buffer,entry,bufferSize-headerSize+spannedEntrySizeSoFar); + // patch up buffer so we can process it in time order + // does not allow for > 256 entries + int entryLength = Util.constructUnsignedByte(buffer,entry); + int temp; + while (entry != 0) { + entry = entry - entryLength; // step back to previous entry + //Util.Debug.println("TraceBuffer: entry = " + entry + " " + entryLength ); - // patch up buffer so we can process it in time order - // does not allow for > 256 entries - int entryLength = Util.constructUnsignedByte(buffer,entry); - int temp; - while (entry != 0) { - entry = entry - entryLength; // step back to previous entry - //Util.Debug.println("TraceBuffer: entry = " + entry + " " + entryLength ); + // Since we now prepend the spanned buffer entry will always end at 0 unless it's a + // partial trace entry in the very first buffer and has no span continuation + if (entry < 0 ) { + Util.Debug.println("entry < 0 must be a partial entry in first record"); + Util.Debug.println("spannedEntrySizeSoFar " + spannedEntrySizeSoFar); + if ( spannedEntrySizeSoFar != 0 ) { + throw new InvalidSpannedRecordException("Invalid spanned trace record"); + } + entry = entry + entryLength; // step back to first complete entry + break; + } - // Since we now prepend the spanned buffer entry will always end at 0 unless it's a - // partial trace entry in the very first buffer and has no span continuation - if (entry < 0 ) { - Util.Debug.println("entry < 0 must be a partial entry in first record"); - Util.Debug.println("spannedEntrySizeSoFar " + spannedEntrySizeSoFar); - if ( spannedEntrySizeSoFar != 0 ) { - throw new InvalidSpannedRecordException("Invalid spanned trace record"); - } - entry = entry + entryLength; // step back to first complete entry - break; - } + // if we have a time wrap add it to the stack + if ( entryLength == 8 ) { + // If we have a time wrap and it is not the first entry + // in the buffer + if ( entry != 0 + && buffer[entry+3]==0 + && buffer[entry+2]==0 + && buffer[entry+1]==0 ) { // trying to be quick, 3 bytes zero means time wrap + // since we will read the records forward swap this time with the calculated upperWord + //upperWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT).shiftLeft(32); + wrapTimes.push(upperWord); + upperWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT); + Util.Debug.println("TraceBuffer: timewrap entry =" +entry+ " upperWord=" + upperWord); + } + } - // if we have a time wrap add it to the stack - if ( entryLength == 8 ) { - // If we have a time wrap and it is not the first entry - // in the buffer - if ( entry != 0 - && buffer[entry+3]==0 - && buffer[entry+2]==0 - && buffer[entry+1]==0 ) { // trying to be quick, 3 bytes zero means time wrap - // since we will read the records forward swap this time with the calculated upperWord - //upperWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT).shiftLeft(32); - wrapTimes.push(upperWord); - upperWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT); - Util.Debug.println("TraceBuffer: timewrap entry =" +entry+ " upperWord=" + upperWord); - } - } + // deal with the case the last entry was a special >256 entry + // we have to copy the entire trace entry because entry contains the length + // we have to push the original trace entry to cope with spanned buffers + // if we have a > 256 entry lets deal with it + if ( entryLength == 4 ) { + if ( buffer[entry+2]==0 && buffer[entry+1]==0 ) { + Util.Debug.println("Entry with data length > 256"); - // deal with the case the last entry was a special >256 entry - // we have to copy the entire trace entry because entry contains the length - // we have to push the original trace entry to cope with spanned buffers - // if we have a > 256 entry lets deal with it - if ( entryLength == 4 ) { - if ( buffer[entry+2]==0 && buffer[entry+1]==0 ) { - Util.Debug.println("Entry with data length > 256"); + // remember the ID and length of the special entry + longEntryID = buffer[entry+3]; + longEntryLength = Util.constructUnsignedByte(buffer,entry); - // remember the ID and length of the special entry - longEntryID = buffer[entry+3]; - longEntryLength = Util.constructUnsignedByte(buffer,entry); + if ((entry - (longEntryLength + longEntryID*256)) < 0) { + Util.Debug.println("entry < 0 must be a partial entry in first record"); + Util.Debug.println("spannedEntrySizeSoFar " + spannedEntrySizeSoFar); + if ( spannedEntrySizeSoFar != 0 ) { + throw new InvalidSpannedRecordException("Invalid spanned trace record"); + } + entry = entry + entryLength; // step back to first complete entry + break; + } - if ((entry - (longEntryLength + longEntryID*256)) < 0) { - Util.Debug.println("entry < 0 must be a partial entry in first record"); - Util.Debug.println("spannedEntrySizeSoFar " + spannedEntrySizeSoFar); - if ( spannedEntrySizeSoFar != 0 ) { - throw new InvalidSpannedRecordException("Invalid spanned trace record"); - } - entry = entry + entryLength; // step back to first complete entry - break; - } + buffer[entry] = (byte)entryLength; // in the end this is not used - buffer[entry] = (byte)entryLength; // in the end this is not used + // step back to previous entry + entry = entry - (longEntryLength + longEntryID*256); - // step back to previous entry - entry = entry - (longEntryLength + longEntryID*256); + // push the real TraceID and copy in the special trace entry + longEntryTraceIDs.push(Integer.valueOf(Util.constructTraceID(buffer, entry + 1))); + buffer[entry+1]=0; + buffer[entry+2]=0; + buffer[entry+3]=(byte)longEntryID; + entryLength = longEntryLength; + } + } - // push the real TraceID and copy in the special trace entry - longEntryTraceIDs.push(Integer.valueOf(Util.constructTraceID(buffer, entry + 1))); - buffer[entry+1]=0; - buffer[entry+2]=0; - buffer[entry+3]=(byte)longEntryID; - entryLength = longEntryLength; - } - } + if (entryLength == 0 ) { + // verify this is the first record! + if(longEntryID == 0){ + // We have reached a zero length record. + Util.Debug.println("TraceRecord: Hit 0 length entry"); + break; + } else { + // We have encountered a long record which is an exact multiple + // of 256 in length. This is quite possible and acceptable. + // Do nothing. + Util.Debug.println("TraceRecord: 0 length entry "+ + "(long record length is exact multiple of 256)"); + } + } - if (entryLength == 0 ) { - // verify this is the first record! - if(longEntryID == 0){ - // We have reached a zero length record. - Util.Debug.println("TraceRecord: Hit 0 length entry"); - break; - } else { - // We have encountered a long record which is an exact multiple - // of 256 in length. This is quite possible and acceptable. - // Do nothing. - Util.Debug.println("TraceRecord: 0 length entry "+ - "(long record length is exact multiple of 256)"); - } - } + // patch up the lengths of the entries. + temp = Util.constructUnsignedByte(buffer,entry); + buffer[entry] = (byte)entryLength; + entryLength = temp; + //Util.Debug.println("entry " + entry + " now " + (byte)buffer[entry]); - // patch up the lengths of the entries. - temp = Util.constructUnsignedByte(buffer,entry); - buffer[entry] = (byte)entryLength; - entryLength = temp; - //Util.Debug.println("entry " + entry + " now " + (byte)buffer[entry]); + } - } + // If the first record is a timewrap, ignore it as it belongs + // to the previous record + if (buffer[entry] == 8 && + buffer[entry+1]==0 && + buffer[entry+2]==0 && + buffer[entry+3]==0 ) { + entry += 8; + Util.Debug.println("TraceBuffer: ignoring time wrap at offset 0"); + } + offset = entry; // this is the first ( oldest) entry in this Record + currentTimeStamp = upperWord.shiftLeft(32).or(Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT)); + //currentTimeStamp = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT); + Util.Debug.println("TraceRecord: oldest offset for thread "+threadID+" = " + offset + " timeStamp = " + currentTimeStamp); + //Util.printDump(buffer,bufferSize-headerSize+spannedEntrySizeSoFar); + return; + } - // If the first record is a timewrap, ignore it as it belongs - // to the previous record - if (buffer[entry] == 8 && - buffer[entry+1]==0 && - buffer[entry+2]==0 && - buffer[entry+3]==0 ) { - entry += 8; - Util.Debug.println("TraceBuffer: ignoring time wrap at offset 0"); - } - offset = entry; // this is the first ( oldest) entry in this Record - currentTimeStamp = upperWord.shiftLeft(32).or(Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT)); - //currentTimeStamp = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT); - Util.Debug.println("TraceRecord: oldest offset for thread "+threadID+" = " + offset + " timeStamp = " + currentTimeStamp); - //Util.printDump(buffer,bufferSize-headerSize+spannedEntrySizeSoFar); - return; - } + /** Get the next Trace Entry + * return 0=no more entries 1=last entry not yet formatted + */ + protected int getNextEntry() throws IOException + { + int rc; + if (notFormatted) { + return 1; + } + notFormatted = true; - /** Get the next Trace Entry - * return 0=no more entries 1=last entry not yet formatted - */ - protected int getNextEntry() throws IOException - { - int rc; - if (notFormatted) { - return 1; - } - notFormatted = true; + do { + //Util.Debug.println(" "); + //Util.Debug.println("TraceRecordExternal: getNextEntry >>>>>>>>>>>>>>>>>>>>>>>>>>"); + if (nextEntry < 0 || + offset >= nextEntry-headerSize+spannedEntrySizeSoFar) { + // Util.Debug.println("TraceRecord: no more entries"); + rc = 0; + } else { + rc = processNextEntryHeader(buffer,offset); + if ( currentLength >= 256 ) offset += 4; // step over excess entry + offset += currentLength; // for next entry + } + } while ( rc == 2 ); + //Util.Debug.println("TraceRecordExternal: getNextEntry <<<<<<<<<<<<<<<<<<<<<<<<<< " +rc); + //Util.Debug.println(" "); + return rc; + } - do { - //Util.Debug.println(" "); - //Util.Debug.println("TraceRecordExternal: getNextEntry >>>>>>>>>>>>>>>>>>>>>>>>>>"); - if (nextEntry < 0 || - offset >= nextEntry-headerSize+spannedEntrySizeSoFar) { - // Util.Debug.println("TraceRecord: no more entries"); - rc = 0; - } else { - rc = processNextEntryHeader(buffer,offset); - if ( currentLength >= 256 ) offset += 4; // step over excess entry - offset += currentLength; // for next entry - } - } while ( rc == 2 ); - //Util.Debug.println("TraceRecordExternal: getNextEntry <<<<<<<<<<<<<<<<<<<<<<<<<< " +rc); - //Util.Debug.println(" "); - return rc; - } + /** + * This is called from previous TraceRecord and contains the start of the spanned entry + * + */ + final protected void spanStart(byte[] startofSpanEntry, int startofSpanEntrySize) + { + //Util.Debug.println("spanStart: startofSpanEntrySize " + startofSpanEntrySize); + spannedEntrySoFar = startofSpanEntry; + spannedEntrySizeSoFar = startofSpanEntrySize; + //Util.Debug.println("spanStart: spannedEntrySizeSoFar " + spannedEntrySizeSoFar); + } - /** - * This is called from previous TraceRecord and contains the start of the spanned entry - * - */ - final protected void spanStart(byte[] startofSpanEntry, int startofSpanEntrySize) - { - //Util.Debug.println("spanStart: startofSpanEntrySize " + startofSpanEntrySize); - spannedEntrySoFar = startofSpanEntry; - spannedEntrySizeSoFar = startofSpanEntrySize; - //Util.Debug.println("spanStart: spannedEntrySizeSoFar " + spannedEntrySizeSoFar); - } + /** The end of our Trace Record is copied to the next record + * + * + */ + final protected void copySpannedEntryForNextRecord(byte[] buffer,int start,int end) + { + //Util.Debug.println("copySpannedEntryForNextRecord: start end " + start + " " + end); + TraceRecordExternal nextTraceRecord=(TraceRecordExternal)getNextRecord(); + if (nextTraceRecord == null) { + return; // no need to save as we are the last Trace Record for this thread + } + byte[] startofSpanEntry = new byte[end-start]; + System.arraycopy(buffer,start,startofSpanEntry,0,end-start); + // pass this to the next TraceRecord for this thread + //Util.Debug.println("spanStart: end-start " + (end-start)); + nextTraceRecord.spanStart(startofSpanEntry,end-start); - /** The end of our Trace Record is copied to the next record - * - * - */ - final protected void copySpannedEntryForNextRecord(byte[] buffer,int start,int end) - { - //Util.Debug.println("copySpannedEntryForNextRecord: start end " + start + " " + end); - TraceRecordExternal nextTraceRecord=(TraceRecordExternal)getNextRecord(); - if (nextTraceRecord == null) { - return; // no need to save as we are the last Trace Record for this thread - } - byte[] startofSpanEntry = new byte[end-start]; - System.arraycopy(buffer,start,startofSpanEntry,0,end-start); - // pass this to the next TraceRecord for this thread - //Util.Debug.println("spanStart: end-start " + (end-start)); - nextTraceRecord.spanStart(startofSpanEntry,end-start); - - // Need to check for a timewrap record that spans into the - // next record, as it applies to this record. - if (end - start < 8) { - byte[] next9 = new byte[9]; - System.arraycopy(buffer, start, next9, 0, end-start); - System.arraycopy(nextTraceRecord.nextEight, 0, next9, - end-start, 9 - (end - start)); - if (next9[8] == 8 && - next9[1] == 0 && - next9[2] == 0 && - next9[3] == 0 ) { - upperWord = Util.constructUnsignedLong(next9, TIMESTAMP_OFFSET, Util.INT); - Util.Debug.println("TraceBuffer: spanned timewrap entry=" +start+ " upperWord=" + upperWord); - } - } - return; - } + // Need to check for a timewrap record that spans into the + // next record, as it applies to this record. + if (end - start < 8) { + byte[] next9 = new byte[9]; + System.arraycopy(buffer, start, next9, 0, end-start); + System.arraycopy(nextTraceRecord.nextEight, 0, next9, + end-start, 9 - (end - start)); + if (next9[8] == 8 && + next9[1] == 0 && + next9[2] == 0 && + next9[3] == 0 ) { + upperWord = Util.constructUnsignedLong(next9, TIMESTAMP_OFFSET, Util.INT); + Util.Debug.println("TraceBuffer: spanned timewrap entry=" +start+ " upperWord=" + upperWord); + } + } + return; + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecordInternal.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecordInternal.java index aeed77add12..db4438be683 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecordInternal.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceRecordInternal.java @@ -25,197 +25,195 @@ import java.io.IOException; import java.math.BigInteger; -/** +/** * Extends Trace Record. Special processing needed for internal trace records. * * @author Tim Preece */ final public class TraceRecordInternal extends TraceRecord { - private int lastEntry; - - protected TraceRecordInternal(TraceFile traceFile, long start) throws IOException - { - super(traceFile, start); - } - - /** - * reads in the record data for this TraceRecord - * - * - */ - final protected void prime() throws IOException - { - buffer = new byte[bufferSize - headerSize]; - int oldestEntry; - int length; - int longEntryID = 0; - int longEntryLength = 0; - boolean newestEntry = true; - boolean checkEntries = false; - long lastTime = Long.MAX_VALUE; - - /* - * If the buffer has wrapped, read in the older data first - */ - if ((bufferSize - nextEntry) > 1) { - traceFile.seek((long)(start + nextEntry + 1)); // skip to the oldest part of the buffer - traceFile.read(buffer, 0, bufferSize - (int)nextEntry - 1); - } - traceFile.seek((long)(start + headerSize)); - traceFile.read(buffer, bufferSize - (int)nextEntry - 1, (int)nextEntry - headerSize + 1); - int entry = (int)bufferSize - headerSize - 1; - - Util.Debug.println("TraceBuffer: reading buffer size=: " + (bufferSize - headerSize)); - Util.Debug.println("TraceBuffer: nextEntry : " + (int)nextEntry); - Util.Debug.println("TraceBuffer: buffer[nextEntry]: " + buffer[entry]); - Util.Debug.println("TraceBuffer: File offset: " + start); - - // Util.printDump(buffer,bufferSize - headerSize); - - // patch up buffer so we can process it in time order - int entryLength = Util.constructUnsignedByte(buffer,entry); - int temp = 0; - while (true) { - entry = entry - entryLength; // step back to previous entry - // Util.Debug.println("TraceBuffer: entry = " + entry + " " + entryLength ); - - if (entry < 0 ) { // Top of buffer ? - entry = entry + entryLength; // step back up to first entry in record - break; // our exit point from this loop - } - - // if we have a time wrap add it to the stack. - if ( entryLength == 8 ) { - if ( buffer[entry+3]==0 - && buffer[entry+2]==0 - && buffer[entry+1]==0 ) { // trying to be quick 3 bytes zero means time wrap - // since we will read the records forward swap this time with the calculated upperWord - //upperWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT).shiftLeft(32); - wrapTimes.push(upperWord); - upperWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT); - Util.Debug.println("TraceBuffer: timewrap entry=" +entry+ " upperWord=" + upperWord); - lastTime = Long.MAX_VALUE; - } - } - - /*35363 starts..................*/ - if (entryLength == 4) { - if (buffer[entry+2] == 0 && buffer[entry+1]==0) { - Util.Debug.println("Entry with data length>256"); - longEntryID = buffer[entry+3]; - longEntryLength = Util.constructUnsignedByte(buffer,entry); - if ((entry - (longEntryLength + longEntryID*256)) < 0) { - Util.Debug.println("entry < 0 must be a partial entry"); - entry = entry + entryLength; // step back to first complete entry - break; - } - entry = entry - (longEntryLength + longEntryID*256); - longEntryTraceIDs.push(Integer.valueOf(Util.constructTraceID(buffer,entry+1))); - buffer[entry+1] = 0; - buffer[entry+2] = 0; - buffer[entry+3] = (byte)longEntryID; - entryLength = longEntryLength; - } - } - - if (newestEntry) { - long lowerWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT).longValue(); - if (lowerWord != timeStamp.and(BigInteger.valueOf(0xffffffffL)).longValue()) { - checkEntries = true; - Util.Debug.println("Possible damage to first trace entry"); - Util.Debug.println("Trace time = " + lowerWord + " header = " + timeStamp.and(BigInteger.valueOf(0xffffffffL)).longValue()); - } - newestEntry = false; - } - - if (checkEntries) { - - - int traceId = Util.constructTraceID(buffer, entry + TRACEID_OFFSET); - long lowerWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT).longValue(); - if (traceId > 256) { - /* if (tracefile level < 5.0){ - if (MessageFile.getMessageFromID(traceId) == null) { - Util.Debug.println("Bad trace identifier: " + traceId); - Util.Debug.println("Ignoring " + (entry + entryLength) + " bytes of the buffer"); - entry = entry + entryLength; - break; - } - } else { - don't! - }*/ - if (lowerWord > lastTime) { - Util.Debug.println("Bad trace timeStamp :" + lowerWord); - Util.Debug.println("Ignoring " + (entry + entryLength) + "bytes of the buffer"); - entry = entry + entryLength; - break; - } - lastTime = lowerWord; - } - } - - /*35363 ends........................ */ - if (entryLength == 0 ) { - // verify this is the first record! - if(longEntryID == 0){ - // We have reached a zero length record. - Util.Debug.println("TraceRecord: Hit 0 length entry"); - break; - } else { - // We have encountered a long record which is an exact multiple - // of 256 in length. This is quite possible and acceptable. - // Do nothing. - Util.Debug.println("TraceRecord: 0 length entry "+ - "(long record length is exact multiple of 256)"); - } - } - - temp = Util.constructUnsignedByte(buffer,entry); - buffer[entry] = (byte)entryLength; - entryLength = temp; - // Util.Debug.println("entry " + entry + " now " + (byte)buffer[entry]); - - } - - offset = entry; // this is the first ( oldest) entry in this Record - currentTimeStamp = upperWord.shiftLeft(32).or(Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT)); - //currentTimeStamp = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT); - //Util.Debug.println("TraceBuffer: oldest offset = " + offset + " timeStamp = " + currentTimeStamp); - //Util.printDump(buffer,bufferSize - headerSize); - return; - } - - /** Gets the next trace entry - * returns 0=no more entries in this buffer 1=ok to format - * - */ - final protected int getNextEntry() throws IOException - { - int rc; - int endPoint; - - // Util.Debug.println("TraceRecord: currentLength "+currentLength); - // Util.Debug.println("TraceRecord: offset "+offset); - - if (notFormatted) { // in case we haven't formatted the last entry yet. - return 1; - } - notFormatted = true; - - do { - //Util.Debug.println(" "); - //Util.Debug.println("TraceRecordInternal: getNextEntry >>>>>>>>>>>>>>>>>>>>>>>>>>"); - if (offset >= bufferSize - headerSize - 1) { - //Util.Debug.println("TraceRecord: no more entries"); - rc = 0; - } else { - rc = processNextEntryHeader(buffer,offset); - if ( currentLength >= 256 ) offset += 4; // step over excess entry - offset += currentLength; // for next entry - } - } while ( rc == 2 ); - return rc; - } + private int lastEntry; + + protected TraceRecordInternal(TraceFile traceFile, long start) throws IOException + { + super(traceFile, start); + } + + /** + * reads in the record data for this TraceRecord + * + * + */ + final protected void prime() throws IOException + { + buffer = new byte[bufferSize - headerSize]; + int oldestEntry; + int length; + int longEntryID = 0; + int longEntryLength = 0; + boolean newestEntry = true; + boolean checkEntries = false; + long lastTime = Long.MAX_VALUE; + + /* + * If the buffer has wrapped, read in the older data first + */ + if ((bufferSize - nextEntry) > 1) { + traceFile.seek((long)(start + nextEntry + 1)); // skip to the oldest part of the buffer + traceFile.read(buffer, 0, bufferSize - (int)nextEntry - 1); + } + traceFile.seek((long)(start + headerSize)); + traceFile.read(buffer, bufferSize - (int)nextEntry - 1, (int)nextEntry - headerSize + 1); + int entry = (int)bufferSize - headerSize - 1; + + Util.Debug.println("TraceBuffer: reading buffer size=: " + (bufferSize - headerSize)); + Util.Debug.println("TraceBuffer: nextEntry : " + (int)nextEntry); + Util.Debug.println("TraceBuffer: buffer[nextEntry]: " + buffer[entry]); + Util.Debug.println("TraceBuffer: File offset: " + start); + + // Util.printDump(buffer,bufferSize - headerSize); + + // patch up buffer so we can process it in time order + int entryLength = Util.constructUnsignedByte(buffer,entry); + int temp = 0; + while (true) { + entry = entry - entryLength; // step back to previous entry + // Util.Debug.println("TraceBuffer: entry = " + entry + " " + entryLength ); + + if (entry < 0 ) { // Top of buffer ? + entry = entry + entryLength; // step back up to first entry in record + break; // our exit point from this loop + } + + // if we have a time wrap add it to the stack. + if ( entryLength == 8 ) { + if ( buffer[entry+3]==0 + && buffer[entry+2]==0 + && buffer[entry+1]==0 ) { // trying to be quick 3 bytes zero means time wrap + // since we will read the records forward swap this time with the calculated upperWord + // upperWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT).shiftLeft(32); + wrapTimes.push(upperWord); + upperWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT); + Util.Debug.println("TraceBuffer: timewrap entry=" +entry+ " upperWord=" + upperWord); + lastTime = Long.MAX_VALUE; + } + } + + /*35363 starts..................*/ + if (entryLength == 4) { + if (buffer[entry+2] == 0 && buffer[entry+1]==0) { + Util.Debug.println("Entry with data length>256"); + longEntryID = buffer[entry+3]; + longEntryLength = Util.constructUnsignedByte(buffer,entry); + if ((entry - (longEntryLength + longEntryID*256)) < 0) { + Util.Debug.println("entry < 0 must be a partial entry"); + entry = entry + entryLength; // step back to first complete entry + break; + } + entry = entry - (longEntryLength + longEntryID*256); + longEntryTraceIDs.push(Integer.valueOf(Util.constructTraceID(buffer,entry+1))); + buffer[entry+1] = 0; + buffer[entry+2] = 0; + buffer[entry+3] = (byte)longEntryID; + entryLength = longEntryLength; + } + } + + if (newestEntry) { + long lowerWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT).longValue(); + if (lowerWord != timeStamp.and(BigInteger.valueOf(0xffffffffL)).longValue()) { + checkEntries = true; + Util.Debug.println("Possible damage to first trace entry"); + Util.Debug.println("Trace time = " + lowerWord + " header = " + timeStamp.and(BigInteger.valueOf(0xffffffffL)).longValue()); + } + newestEntry = false; + } + + if (checkEntries) { + + int traceId = Util.constructTraceID(buffer, entry + TRACEID_OFFSET); + long lowerWord = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT).longValue(); + if (traceId > 256) { + /* if (tracefile level < 5.0){ + if (MessageFile.getMessageFromID(traceId) == null) { + Util.Debug.println("Bad trace identifier: " + traceId); + Util.Debug.println("Ignoring " + (entry + entryLength) + " bytes of the buffer"); + entry = entry + entryLength; + break; + } + } else { + don't! + }*/ + if (lowerWord > lastTime) { + Util.Debug.println("Bad trace timeStamp :" + lowerWord); + Util.Debug.println("Ignoring " + (entry + entryLength) + "bytes of the buffer"); + entry = entry + entryLength; + break; + } + lastTime = lowerWord; + } + } + + /*35363 ends........................ */ + if (entryLength == 0 ) { + // verify this is the first record! + if(longEntryID == 0){ + // We have reached a zero length record. + Util.Debug.println("TraceRecord: Hit 0 length entry"); + break; + } else { + // We have encountered a long record which is an exact multiple + // of 256 in length. This is quite possible and acceptable. + // Do nothing. + Util.Debug.println("TraceRecord: 0 length entry "+ + "(long record length is exact multiple of 256)"); + } + } + + temp = Util.constructUnsignedByte(buffer,entry); + buffer[entry] = (byte)entryLength; + entryLength = temp; + // Util.Debug.println("entry " + entry + " now " + (byte)buffer[entry]); + } + + offset = entry; // this is the first ( oldest) entry in this Record + currentTimeStamp = upperWord.shiftLeft(32).or(Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT)); + //currentTimeStamp = Util.constructUnsignedLong(buffer, entry + TIMESTAMP_OFFSET, Util.INT); + //Util.Debug.println("TraceBuffer: oldest offset = " + offset + " timeStamp = " + currentTimeStamp); + //Util.printDump(buffer,bufferSize - headerSize); + return; + } + + /** Gets the next trace entry + * returns 0=no more entries in this buffer 1=ok to format + * + */ + final protected int getNextEntry() throws IOException + { + int rc; + int endPoint; + + // Util.Debug.println("TraceRecord: currentLength "+currentLength); + // Util.Debug.println("TraceRecord: offset "+offset); + + if (notFormatted) { // in case we haven't formatted the last entry yet. + return 1; + } + notFormatted = true; + + do { + //Util.Debug.println(" "); + //Util.Debug.println("TraceRecordInternal: getNextEntry >>>>>>>>>>>>>>>>>>>>>>>>>>"); + if (offset >= bufferSize - headerSize - 1) { + //Util.Debug.println("TraceRecord: no more entries"); + rc = 0; + } else { + rc = processNextEntryHeader(buffer,offset); + if ( currentLength >= 256 ) offset += 4; // step over excess entry + offset += currentLength; // for next entry + } + } while ( rc == 2 ); + return rc; + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceSection.java index fa1b094e599..cfabf70ba25 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceSection.java @@ -25,82 +25,82 @@ import java.io.IOException; import java.math.BigInteger; -/** - * Trace section of a file header. +/** + * Trace section of a file header. * * @author Tim Preece */ public class TraceSection { - private String eyecatcher_string; - private int length; - private int version; - private int modification; - private BigInteger startPlatform; - private BigInteger startSystem; - private int type; - private int generations; - private int pointerSize = 4; + private String eyecatcher_string; + private int length; + private int version; + private int modification; + private BigInteger startPlatform; + private BigInteger startSystem; + private int type; + private int generations; + private int pointerSize = 4; - public TraceSection (TraceFile traceFile, int start ) throws IOException - { - // Version 1.1 - traceFile.seek((long)start); - eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); - length = traceFile.readI(); - version = traceFile.readI(); - modification = traceFile.readI(); - startPlatform = traceFile.readBigInteger(8); - startSystem = traceFile.readBigInteger(8); - type = traceFile.readI(); - generations = traceFile.readI(); - pointerSize = traceFile.readI(); + public TraceSection (TraceFile traceFile, int start ) throws IOException + { + // Version 1.1 + traceFile.seek((long)start); + eyecatcher_string = Util.convertAndCheckEyecatcher(traceFile.readI()); + length = traceFile.readI(); + version = traceFile.readI(); + modification = traceFile.readI(); + startPlatform = traceFile.readBigInteger(8); + startSystem = traceFile.readBigInteger(8); + type = traceFile.readI(); + generations = traceFile.readI(); + pointerSize = traceFile.readI(); - Util.setProperty("POINTER_SIZE", String.valueOf(pointerSize)); - Message.setPointerSize(); - TraceFormat.setStartSystem(startSystem); - TraceFormat.setStartPlatform(startPlatform); - TraceFormat.setGenerations(generations); + Util.setProperty("POINTER_SIZE", String.valueOf(pointerSize)); + Message.setPointerSize(); + TraceFormat.setStartSystem(startSystem); + TraceFormat.setStartPlatform(startPlatform); + TraceFormat.setGenerations(generations); - Util.Debug.println("TraceSection: eyecatcher: " + eyecatcher_string); - Util.Debug.println("TraceSection: length: " + length); - Util.Debug.println("TraceSection: version: " + version); - Util.Debug.println("TraceSection: modification: " + modification); - Util.Debug.println("TraceSection: startPlatform: " + startPlatform); - Util.Debug.println("TraceSection: startSystem: " + startSystem); - Util.Debug.println("TraceSection: type: " + type); // 0=internal 1=external - Util.Debug.println("TraceSection: generations: " + generations); - Util.Debug.println("TraceSection: pointerSize: " + pointerSize); + Util.Debug.println("TraceSection: eyecatcher: " + eyecatcher_string); + Util.Debug.println("TraceSection: length: " + length); + Util.Debug.println("TraceSection: version: " + version); + Util.Debug.println("TraceSection: modification: " + modification); + Util.Debug.println("TraceSection: startPlatform: " + startPlatform); + Util.Debug.println("TraceSection: startSystem: " + startSystem); + Util.Debug.println("TraceSection: type: " + type); // 0=internal 1=external + Util.Debug.println("TraceSection: generations: " + generations); + Util.Debug.println("TraceSection: pointerSize: " + pointerSize); - } + } - /** summarizes the trace section - * - * @return null - */ - //final protected void summary(BufferedWriter out) throws IOException - //{ - // int off = offset; - // String temp = Util.constructString(data, off); - // - // out.write("Internal Trace Data :"); - // out.newLine(); - // while ( !temp.equals("") ) { - // out.write((Util.SUM_TAB+temp)); - // out.newLine(); - // off += (temp.length() + 1); - // temp = Util.constructString(data, off); - // } - // out.newLine(); - //} + /** summarizes the trace section + * + * @return null + */ + //final protected void summary(BufferedWriter out) throws IOException + //{ + // int off = offset; + // String temp = Util.constructString(data, off); + // + // out.write("Internal Trace Data :"); + // out.newLine(); + // while ( !temp.equals("") ) { + // out.write((Util.SUM_TAB+temp)); + // out.newLine(); + // off += (temp.length() + 1); + // temp = Util.constructString(data, off); + // } + // out.newLine(); + //} - /** returns the type of trace ( INTERNAL or EXTERNAL ) - * - * @return an int - */ - final protected int getTraceType() - { - return type; - } + /** returns the type of trace ( INTERNAL or EXTERNAL ) + * + * @return an int + */ + final protected int getTraceType() + { + return type; + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceThread.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceThread.java index 93f619f38ef..91924a9c7ac 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceThread.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/TraceThread.java @@ -26,173 +26,173 @@ import java.util.Iterator; import java.util.Vector; -/** +/** * Vector containing all trace records for a specific thread. * * @author Tim Preece */ final public class TraceThread extends Vector implements com.ibm.jvm.trace.TraceThread { - protected long threadID = 0; - protected String threadName; - - private TracePoint tp = null; - private boolean primed = false; - - private TraceRecord50 currentTraceRecord = null; - private int currentIndent = 0; - /** construct a new trace thread vector - * - * @param ID ( hex value of threadID ) - * @param threadName - */ - protected TraceThread(long ID, String threadName) - { - super(); - this.threadID = ID; - this.threadName = threadName; - } - - public static int numBufs = 0; - - public static int getBuffersProcessed(){ - return numBufs; - } - - private static synchronized void incrementBuffersProcessed(){ - numBufs++; - } - - private synchronized void prime(){ - if (!primed) { - popTopTraceRecord(); - primed = true; - } - } - - private void popTopTraceRecord(){ - TraceRecord50 oldTraceRecord = currentTraceRecord; - if (isEmpty()){ - Util.Debug.println("last trace record popped from trace thread"); - Util.Debug.println("TraceThread " + Util.formatAsHexString( threadID ) + " emptied"); - currentTraceRecord = null; - return; - } - currentTraceRecord = (TraceRecord50) elementAt( 0 ); - byte[] extraData = null; - BigInteger lastUpperWord = null; - if (oldTraceRecord != null) { - lastUpperWord = oldTraceRecord.getLastUpperWord(); - extraData = oldTraceRecord.getExtraData(); - } - while ( currentTraceRecord != null && currentTraceRecord.isMiddleOfTracePoint() ) { - byte[] temp = null; - byte[] current = extraData; - - Util.Debug.println("\nTraceThread has found a pure middle of tracepoint buffer\n"); - - temp = currentTraceRecord.getExtraData(); - Util.Debug.println("It's on thread " + Util.formatAsHexString(currentTraceRecord.getThreadIDAsLong()) ); - Util.printDump(temp, temp.length ); - if (extraData == null) { - Util.Debug.println("Adding the middle in - temp.length " + temp.length); - extraData = new byte[temp.length]; - System.arraycopy( temp, 0, extraData, 0, temp.length); - } else { - extraData = new byte[ current.length + temp.length]; - Util.Debug.println("Adding the middle in - current " + current.length + " temp.length " + temp.length); - System.arraycopy(current, 0, extraData, 0, current.length ); - System.arraycopy(temp, 0, extraData, current.length, temp.length); - } - - if (size() > 1) { - removeElementAt(0); - incrementBuffersProcessed(); - currentTraceRecord = (TraceRecord50) elementAt( 0 ); - } else { - currentTraceRecord = null; - } - } - if ( currentTraceRecord != null ) { - if (extraData != null) { - currentTraceRecord.addOverspillData( extraData, lastUpperWord ); - } - tp = currentTraceRecord.getNextTracePoint(); - while ((tp == null) && (size() > 1)) { - /* skip e.g. empty buffers or buffers containing only control points */ - removeElementAt( 0 ); - incrementBuffersProcessed(); - currentTraceRecord = (TraceRecord50) elementAt( 0 ); - if ( currentTraceRecord != null ) { - tp = currentTraceRecord.getNextTracePoint(); - } - } - } - /* remove it so it can be taken off the heap - by this time it will have been heavily populated with data! */ - removeElementAt( 0 ); - incrementBuffersProcessed(); - return; - } - - public TracePoint getNextTracePoint(){ - TracePoint ret = tp; - if (!primed) { - prime(); - } - if (currentTraceRecord != null) { - tp = currentTraceRecord.getNextTracePoint(); - if (tp == null) { - /* currentTraceRecord is exhausted */ - popTopTraceRecord(); - } - } else { - tp = null; - } - return ret; - } - - public int getIndent(){ - return currentIndent; - } - - public void indent(){ - currentIndent++; - } - - public void outdent(){ - currentIndent--; - if (currentIndent < 0) { - currentIndent = 0; - } - } - - /* - * return the timestamp of the next tracepoint in the buffer, or null if there is no tracepoint - */ - public BigInteger getTimeOfNextTracePoint(){ - if (!primed) { - prime(); - } - if (tp != null) { - return tp.getRawTimeStamp(); - } else { - /* occasionally we get duped by a corrupt or empty trace record - this clause will pick those instances up */ - if (size() > 0) { - popTopTraceRecord(); - if (tp != null) { - return tp.getRawTimeStamp(); - } /* else fall through to return null below */ - } - return null; - } - } - - /* methods implementing the com.ibm.jvm.trace.TraceThread interface */ - public Iterator getChronologicalTracePointIterator(){ - return new com.ibm.jvm.trace.TracePointThreadChronologicalIterator(this); - } - + protected long threadID = 0; + protected String threadName; + + private TracePoint tp = null; + private boolean primed = false; + + private TraceRecord50 currentTraceRecord = null; + private int currentIndent = 0; + /** construct a new trace thread vector + * + * @param ID ( hex value of threadID ) + * @param threadName + */ + protected TraceThread(long ID, String threadName) + { + super(); + this.threadID = ID; + this.threadName = threadName; + } + + public static int numBufs = 0; + + public static int getBuffersProcessed(){ + return numBufs; + } + + private static synchronized void incrementBuffersProcessed(){ + numBufs++; + } + + private synchronized void prime(){ + if (!primed) { + popTopTraceRecord(); + primed = true; + } + } + + private void popTopTraceRecord(){ + TraceRecord50 oldTraceRecord = currentTraceRecord; + if (isEmpty()){ + Util.Debug.println("last trace record popped from trace thread"); + Util.Debug.println("TraceThread " + Util.formatAsHexString( threadID ) + " emptied"); + currentTraceRecord = null; + return; + } + currentTraceRecord = (TraceRecord50) elementAt( 0 ); + byte[] extraData = null; + BigInteger lastUpperWord = null; + if (oldTraceRecord != null) { + lastUpperWord = oldTraceRecord.getLastUpperWord(); + extraData = oldTraceRecord.getExtraData(); + } + while ( currentTraceRecord != null && currentTraceRecord.isMiddleOfTracePoint() ) { + byte[] temp = null; + byte[] current = extraData; + + Util.Debug.println("\nTraceThread has found a pure middle of tracepoint buffer\n"); + + temp = currentTraceRecord.getExtraData(); + Util.Debug.println("It's on thread " + Util.formatAsHexString(currentTraceRecord.getThreadIDAsLong()) ); + Util.printDump(temp, temp.length ); + if (extraData == null) { + Util.Debug.println("Adding the middle in - temp.length " + temp.length); + extraData = new byte[temp.length]; + System.arraycopy( temp, 0, extraData, 0, temp.length); + } else { + extraData = new byte[ current.length + temp.length]; + Util.Debug.println("Adding the middle in - current " + current.length + " temp.length " + temp.length); + System.arraycopy(current, 0, extraData, 0, current.length ); + System.arraycopy(temp, 0, extraData, current.length, temp.length); + } + + if (size() > 1) { + removeElementAt(0); + incrementBuffersProcessed(); + currentTraceRecord = (TraceRecord50) elementAt( 0 ); + } else { + currentTraceRecord = null; + } + } + if ( currentTraceRecord != null ) { + if (extraData != null) { + currentTraceRecord.addOverspillData( extraData, lastUpperWord ); + } + tp = currentTraceRecord.getNextTracePoint(); + while ((tp == null) && (size() > 1)) { + /* skip e.g. empty buffers or buffers containing only control points */ + removeElementAt( 0 ); + incrementBuffersProcessed(); + currentTraceRecord = (TraceRecord50) elementAt( 0 ); + if ( currentTraceRecord != null ) { + tp = currentTraceRecord.getNextTracePoint(); + } + } + } + /* remove it so it can be taken off the heap - by this time it will have been heavily populated with data! */ + removeElementAt( 0 ); + incrementBuffersProcessed(); + return; + } + + public TracePoint getNextTracePoint(){ + TracePoint ret = tp; + if (!primed) { + prime(); + } + if (currentTraceRecord != null) { + tp = currentTraceRecord.getNextTracePoint(); + if (tp == null) { + /* currentTraceRecord is exhausted */ + popTopTraceRecord(); + } + } else { + tp = null; + } + return ret; + } + + public int getIndent(){ + return currentIndent; + } + + public void indent(){ + currentIndent++; + } + + public void outdent(){ + currentIndent--; + if (currentIndent < 0) { + currentIndent = 0; + } + } + + /* + * return the timestamp of the next tracepoint in the buffer, or null if there is no tracepoint + */ + public BigInteger getTimeOfNextTracePoint(){ + if (!primed) { + prime(); + } + if (tp != null) { + return tp.getRawTimeStamp(); + } else { + /* occasionally we get duped by a corrupt or empty trace record + this clause will pick those instances up */ + if (size() > 0) { + popTopTraceRecord(); + if (tp != null) { + return tp.getRawTimeStamp(); + } /* else fall through to return null below */ + } + return null; + } + } + + /* methods implementing the com.ibm.jvm.trace.TraceThread interface */ + public Iterator getChronologicalTracePointIterator(){ + return new com.ibm.jvm.trace.TracePointThreadChronologicalIterator(this); + } + public String getThreadName(){ return threadName; } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Util.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Util.java index 840395306ee..aa52ee709c0 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Util.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/format/Util.java @@ -33,729 +33,725 @@ * @author Jonathon Lee */ final public class Util { - private static Properties properties; - private static Hashtable threads; - private static int timerType; - private static Hashtable components; - private static boolean bigendian; - final static String[] timerDesc= {"Sequence number ", - "Special ", - "Pentium TSC ", - "Time (UTC) ", - "MSPR ", - "MFTB ", - "Time (UTC) ", - "J9 timer(UTC) "}; - - protected static final int BYTE = 1; // length of a byte in bytes - protected static final int INT = 4; // length of an int in bytes - protected static final int LONG = 8; // length of a long in bytes - protected static final String SUM_TAB = " "; - - protected static final BigInteger MILLIS2SECONDS = BigInteger.valueOf(1000); - protected static final BigInteger SECONDS2MINUTES = BigInteger.valueOf(60); - protected static final BigInteger MINUTES2HOURS = BigInteger.valueOf(60); - protected static final BigInteger HOURS2DAYS = BigInteger.valueOf(24); - protected static final BigInteger MILLION = BigInteger.valueOf(1000000); - - // don't let anyone instantiate this class - private Util() - { - } - - /** Initializes static variables. - * - *

    This is called each time the TraceFormatter is started, from the initStatics() - * method in TraceFormat.java

    - */ - final protected static void initStatics() - { - properties = null; - threads = null; - components = null; - } - - /** puts a thread ID into a hashtable telling the formatter that this thread ID - * is one that should be traced - * - * @param threadID a string representation of a hexidecimal thread id - */ - final protected static void putThreadID(Long threadID) - { - if ( threads == null ) { - threads = new Hashtable(); - } - threads.put(threadID, threadID); - } - - /** retrieve whether of not the given id is in a hashtable. if the table is null that means - * that no ids were added, since the default behavior is all id this returns true - * - * @param threadID a string representation of a hexidecimal thread id - * @return a boolean that is true if the id was added to the table or if the table is null - */ - final protected static boolean findThreadID(Long threadID) - { - if ( threads == null ) { - return true; //defaults to all - } - return threads.containsKey(threadID); - } - - /** puts a component name into a hashtable telling the formatter that this component - * is one that should be traced. In this case all types of entries are formatted for this - * component - * - * @param comp a string representation of a component in the jvm - */ - final protected static void putComponent(String comp) - { - if ( components == null ) { - components = new Hashtable(); - } - components.put(comp.toLowerCase(), new TypeList()); - } - - /** puts a component name into a hashtable telling the formatter that this component - * is one that should be traced. In this case only the types of entries specified in types - * are formatted for this component - * - * @param comp a string representation of a component in the jvm - * @param types a vector of string for the type of trace entries to format (ie, Entry, Exit, Exception, etc) - */ - final protected static void putComponent(String comp, Vector types) - { - if ( components == null ) { - components = new Hashtable(); - } - components.put(comp.toLowerCase(), new TypeList(types)); - } - - - /** determines if a particular component and type is to be formatted - * - * @param comp a string representation of a component in the jvm - * @param types a string for the type of trace entry to format (ie, Entry, Exit, Exception, etc) - * @return a boolean that is true if this component and type was added to the table or if the table is null - */ - final protected static boolean findComponentAndType(String comp, String type) - { - if ( components == null ) { - return true; // defaults to all(all) - } - if (comp.equals("dg")) { - return true; - } - return(components.containsKey(comp) && ((TypeList) components.get(comp)).contains(type)); - } - - /** determines the encoding based on the byte passed in. If the byte is - * a \u0044 (ASCII 'D') the encoding is ASCII - * - * @param info - */ - final static void determineEncoding(byte testChar) - { - Debug.println("Encoding is Ascii: " + (char) testChar + "= \u0044"); - setProperty("ENCODING", "ASCII"); - } - - /** Reverses the order of the bytes in the byte array - * - * @param data an array of bytes to be reversed - */ - final static private void reverseByteOrder(byte[] data) - { - for ( int i = 0; i < data.length / 2 ; i++ ) { - int temp = data[i]; - data[i] = data[(data.length - 1) - i]; - data[(data.length - 1) - i] = (byte) temp; - } - } - - /** - * Construct a BigInteger from an array of bytes. BigIntegers are used to get around problems - * caused by the lack of unsigned primitive type. - * - * @param data an array of bytes - * @param offset offset to the first byte to use to create the BigInteger - * @return a positive BigInteger constructed from the byte array - */ - final protected static BigInteger constructUnsignedLong(byte[] data, int offset) - { - return constructUnsignedLong(data, offset, Util.LONG); - } - - /** - * Construct a BigInteger from an array of bytes. BigIntegers are used to get around problems - * caused by the lack of unsigned primitive type. - * - * @param data an array of bytes - * @param offset offset to the first byte to use to create the BigInteger - * @param numBytes the length of this BigInteger in bytes - * @return a positive BigInteger constructed from the byte array - */ - final protected static BigInteger constructUnsignedLong(byte[] data, int offset, int numBytes) - { - byte[] bytes = new byte[numBytes]; - try { - System.arraycopy(data, offset, bytes, 0, numBytes); - if (!bigendian) { - reverseByteOrder(bytes); - } - BigInteger temp = new BigInteger(1, bytes); // 1 means positive - return temp; - } catch (Exception e) { - TraceFormat.outStream.println("******************* Exception:" - + " data.length " + data.length - + " offset " + offset - + " numBytes " + numBytes); - return BigInteger.ZERO; - } - } - - final protected static int constructTraceID(byte[] data, int offset) - { - return((((int) data[offset] << 16) & 0xff0000) | (((int) data[offset+1] << 8) & 0xff00) | ((int) data[offset+2] & 0xff)); - } - - - final protected static long constructUnsignedInt(byte[] data, int offset) - { - return( bigendian == false ) - ? (( ((long) data[offset+3] << 24) & 0xff000000L) - | (((long) data[offset+2] << 16) & 0xff0000L) - | (((long) data[offset+1] << 8) & 0xff00L) - | ((long) data[offset] & 0xffL)) - : (( ((long) data[offset] << 24) & 0xff000000L) - | (((long) data[offset+1] << 16) & 0xff0000L) - | (((long) data[offset+2] << 8) & 0xff00L) - | ((long) data[offset+3] & 0xffL)); - } - - final protected static int constructUnsignedByte(byte[] data, int offset) - { - return(int) data[offset] & 0xff; - } - - final static private int findNull(byte[] data, int index) - { - while ( index < data.length ) { - if ( data[index] == 0 ) { - return index; - } - index++; - } - return -1; - } - - /** Constructs a string from an array of bytes, encoding is as specified in the properties - * - */ - final protected static String constructString(byte[] data, int offset) - { - return constructString(data, offset, getProperty("ENCODING", "ASCII")); - } - - /** Constructs a string from an array of bytes, with the specified encoding (ASCII or EBCDIC?) - * - */ - final protected static String constructString(byte[] data, int offset, String enc) - { - int nullChar = findNull(data, offset); - if ( nullChar == -1 ) { - return ""; - } - return constructString(data, offset, (nullChar-offset), enc); - } - - /** Constructs a string from an array of bytes with a count, encoding is as specified in the properties - * - */ - final protected static String constructString(byte[] data, int offset, int count) - { - return constructString(data, offset, count, getProperty("ENCODING", "ASCII")); - } - - static boolean charIsOneOfControlCharactersToRemove(char c){ - if (c < 9) { - /* ignore 0 - NUL - * ignore 1 - SOH - * ignore 2 - STX - * ignore 3 - ETX - * ignore 4 - EOT - * ignore 5 - ENQ - * ignore 6 - ACK - * ignore 7 - BEL - * ignore 8 - BS - */ - return true; - } else { - return false; - } - } - - /** - * Escapes control characters in the given string. - * - * @param string - */ - public static final String escapeControlCharacters(String string) { - return escapeControlCharacters(string, getProperty("ENCODING", "ASCII")); - } - - /** - * Escapes control characters in the given string. - * - * @param string - * @param encoding - */ - public static final String escapeControlCharacters(String string, String encoding) { - if ("ASCII".equalsIgnoreCase(encoding)) { /* leave other encodings to fend for themselves */ - int length = string.length(); - StringBuffer escaped = null; - - for (int i = 0; i < length; ++i) { - char ch = string.charAt(i); - - if (charIsOneOfControlCharactersToRemove(ch)) { - if (escaped == null) { - escaped = new StringBuffer(length + 50); /* leave room for a few escapes */ - if (i > 0) { - escaped.append(string.substring(0, i)); - } - } - escaped.append(String.format("\\u%04x", Integer.valueOf(ch))); - } else { - if (escaped != null) { - escaped.append(ch); - } - } - } - - if (escaped != null) { - return escaped.toString(); - } - } - - return string; - } - - /** - * Constructs a string from an array of bytes with an offset and count, - * with the specified encoding (ASCII or EBCDIC). - */ - final protected static String constructString(byte[] data, int offset, int count, String enc) - { - try { - String string = ""; - - if ((offset + count) <= data.length) { - string = new String(data, offset, count, enc); - } - - return string; - } catch (Exception e) { - TraceFormat.outStream.println("Util.constructString (1) ****> offset: " + offset + ", count = " + count + " data = " + data); - TraceFormat.outStream.println("Util.constructString (2) ****> " + e); - return ""; - } - } - - /** sets an property that affects the behavior of the formatter - * - * @param key - * @param val - */ - final protected static void setProperty(String key, String val) - { - if ( properties == null ) { - properties = new Properties(); - } - properties.setProperty(key, val); - } - - /** gets an the value property that affecting behavior of the formatter - * - * @param key - * @return a string - */ - final protected static String getProperty(String key) - { - if ( properties == null ) { - properties = new Properties(); - } - return properties.getProperty(key); - } - - /** gets an the value property that affecting behavior of the formatter, if no such - * property is set the default value is returned - * - * @param key - * @param defaultValue - * @return a string - */ - final protected static String getProperty(String key, String defaultValue) - { - if ( properties == null ) { - properties = new Properties(); - } - return properties.getProperty(key, defaultValue); - } - - final protected static void padBuffer(StringBuffer sb, int i, char c) - { - padBuffer(sb, i, c, false); - } - - final protected static void padBuffer(StringBuffer sb, int i, char c, boolean leftJustified) - { - while ( sb.length() < i ) { - if (leftJustified) { - sb.append(c); - } else { - sb.insert(0, c); - } - } - } - - - /* 0 Sequence Counter - * 1 Special - * 2 RDTSC Timer - * 3 AIX Timer - * 4 MFSPR Timer - * 5 MFTB Timer - * 6 STCK Timer - * 7 J9 Timer - */ - - final static void setTimerType(int type) - { - timerType = type; - } - - final static String getTimerDescription() - { - return timerDesc[timerType]; - } - - final static void printDump(byte[] buffer,int length) - { - int i,j,k; - StringBuffer buf1,buf2; - for (i=0;i<((length/16)+1);i++) { - buf1 = new StringBuffer(100); - buf2 = new StringBuffer(100); - for (j=0;j<4;j++) { - for (k=0;k<4;k++) { - if ((k+j*4+i*16) >= length) break; - byte2hex(buffer[k+j*4+i*16],buf1); - if ( (buffer[k+j*4+i*16]) > 40 && (buffer[k+j*4+i*16]) < 128) { - buf2.append((char)buffer[k+j*4+i*16]); - } - else - { - buf2.append("."); - } - } - buf1.append(" "); - } - Util.Debug.println(Util.formatAsHexString(i * 16) + ": " + buf1 + " " + buf2); - } - } - - /** - * Formats a number as a hex string, prefixing the "0x" - * radix specifier so that it can be unambiguously - * interpreted as a hex string. - * @param number the number to format - */ - final static public String formatAsHexString(long number) - { - return "0x" + Long.toHexString(number); - } - - /** - * Converts a byte to hex digit and writes to the supplied buffer - */ - private static void byte2hex(byte b, StringBuffer buf) { - char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', - '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - int high = ((b & 0xf0) >> 4); - int low = (b & 0x0f); - buf.append(hexChars[high]); - buf.append(hexChars[low]); - } - - - final static String getFormattedTime(BigInteger time) - { - //Util.Debug.println("formatting time " + time); - //Util.Debug.println("Util: timerType " + timerType); - switch (timerType) { - - case 2: - case 4: - case 5: - case 7: - { - /* - * X86 with RDTSC, MFTB, MSPR, J9 - */ - if (TraceFormat.verMod >= 1.1) { - BigInteger splitTime[]; - BigInteger nanos; - BigInteger secondsMillis[]; - BigInteger minutesSeconds[]; - BigInteger hoursMinutes[]; - BigInteger daysHours[]; - - time = time.subtract(TraceFormat.overallStartPlatform); - splitTime = time.divideAndRemainder(TraceFormat.timeConversion); - secondsMillis = splitTime[0].add(TraceFormat.overallStartSystem).divideAndRemainder(MILLIS2SECONDS); - nanos = secondsMillis[1].multiply(MILLION).add(splitTime[1].multiply(MILLION).divide(TraceFormat.timeConversion)); - minutesSeconds = secondsMillis[0].divideAndRemainder(SECONDS2MINUTES); - hoursMinutes = minutesSeconds[0].divideAndRemainder(MINUTES2HOURS); - daysHours = hoursMinutes[0].divideAndRemainder(HOURS2DAYS); - - daysHours[1] = daysHours[1].add(TraceArgs.timeZoneOffset); /* allow user to modify timezone */ - try{ - return "00".substring(daysHours[1].toString().length()) + daysHours[1].toString() + ":" + - "00".substring(hoursMinutes[1].toString().length()) + hoursMinutes[1].toString() + ":" + - "00".substring(minutesSeconds[1].toString().length()) + minutesSeconds[1].toString() + "." + - "000000000".substring(nanos.toString().length()) + nanos.toString(); - } catch(Exception e) { - Debug.println(daysHours[1].toString() + ":" + - hoursMinutes[1].toString() + ":" + - minutesSeconds[1].toString() + "." + - nanos.toString()); - return "Bad Time: " + time.toString(16); - - } - } else { - return "0000000000000000".substring(time.toString(16).length()) + time.toString(16); - } - } - - case 3: - { - /* - * Power/Power PC - */ - long seconds; - long nanos; - long ss; - long mm; - long hh; - - seconds = time.shiftRight(32).longValue() & 0xffffffffL; - nanos = time.longValue() & 0xffffffffL; - ss = seconds % 60; - mm = (seconds / 60) % 60; - hh = (seconds / 3600) % 24; - try{ - return "00".substring(Long.toString(hh).length()) + Long.toString(hh) + ":" + - "00".substring(Long.toString(mm).length()) + Long.toString(mm) + ":" + - "00".substring(Long.toString(ss).length()) + Long.toString(ss) + "." + - "000000000".substring(Long.toString(nanos).length()) + Long.toString(nanos); - } catch(Exception e) { - Debug.println("hh: " + Long.toString(hh) + " mm: " + - Long.toString(mm) + " ss: " + - Long.toString(ss) + " Nanos: " + - Long.toString(nanos)); - return "Bad Time: " + time.toString(16); - - } - } - case 6: - { - /* - * System/390 - */ - long picos; - long micros; - long ss; - long mm; - long hh; - - micros = time.shiftRight(12).longValue() & 0xfffffffffffffL; - ss = (micros / 1000000) % 60; - mm = (micros / 60000000) % 60; - hh = (micros / 3600000000L) % 24; - micros = micros % 1000000; - picos = (((time.longValue() & 0xfffL) | (micros << 12)) * 244140625) / 1000000; - try{ - return "00".substring(Long.toString(hh).length()) + Long.toString(hh) + ":" + - "00".substring(Long.toString(mm).length()) + Long.toString(mm) + ":" + - "00".substring(Long.toString(ss).length()) + Long.toString(ss) + "." + - "000000000000".substring(Long.toString(picos).length()) + Long.toString(picos); - } catch(Exception e) { - Debug.println("hh: " + Long.toString(hh) + " mm: " + - Long.toString(mm) + " ss: " + - Long.toString(ss) + " Picos: " + - Long.toString(picos)); - return "Bad Time: " + time.toString(16); - } - } - default: - { - return "0000000000000000".substring(time.toString(16).length()) + time.toString(16); - } - } - - } - - static class Debug { - static java.io.PrintStream out = TraceFormat.outStream; - - static void println(Object o) - { - if ( TraceArgs.debug ) { - out.println(o); - } - } - static void print(Object o) - { - if ( TraceArgs.debug ) { - out.print(o); - } - } - } - - /** keeps track of the types to format for a given component - * - * @author Jonathon Lee - * @version 1.0, Date: 7/7/1999 - */ - final static class TypeList { - Hashtable types; - - TypeList() - { - - } - - TypeList(Vector typeNames) - { - types = new Hashtable(); - for ( int i = 0; i < typeNames.size(); i++ ) { - String t = ((String) typeNames.elementAt(i)).toLowerCase(); - types.put(t, t); - } - } - - final boolean contains(String type) - { - if ( types == null ) { - return true; //defaults to all - } - return types.containsKey(type); - } - } - - final protected static int convertEndian(int in) - { - return ( (in >>> 24) | (in << 24 ) | - (( in << 8 ) & 0x00FF0000) | ((in >> 8 ) & 0x0000FF00)); - } - - final protected static String convertAndCheckEyecatcher(int eyecatcher) - { - String eyeCatcherString; - // convert back !!!!!!!!!!!!!!!!! - eyecatcher = bigendian ? eyecatcher : Util.convertEndian(eyecatcher); - switch (eyecatcher) { - case 0x48545455: // allow for endian - eyeCatcherString = "UTTH (in ASCII)"; - break; - case 0x55545448: - eyeCatcherString = "UTTH (in ASCII)"; - break; - case 0x55545453: - eyeCatcherString = "UTTS (in ASCII)"; - break; - case 0x55545353: - eyeCatcherString = "UTSS (in ASCII)"; - break; - case 0x5554534F: - eyeCatcherString = "UTSO (in ASCII)"; - break; - case 0x55545441: - eyeCatcherString = "UTTA (in ASCII)"; - break; - case 0x55545052: - eyeCatcherString = "UTPR (in ASCII)"; - break; - case 0xe4e3e3c8: - eyeCatcherString = "UTTH (in EBCDIC)"; - break; - case 0xe4e3e3e2: - eyeCatcherString = "UTTS (in EBCDIC)"; - break; - case 0xe4e3e2e2: - eyeCatcherString = "UTSS (in EBCDIC)"; - break; - case 0xe4e3e2d6: - eyeCatcherString = "UTSO (in EBCDIC)"; - break; - case 0xe4e3e3c1: - eyeCatcherString = "UTTA (in EBCDIC)"; - break; - case 0xe4e3d7d9: - eyeCatcherString = "UTPR (in EBCDIC)"; - break; - case 0x48544744: // allow for endian - eyeCatcherString = "DGTH (in ASCII)"; - break; - case 0x44475448: - eyeCatcherString = "DGTH (in ASCII)"; - break; - case 0x44475453: - eyeCatcherString = "DGTS (in ASCII)"; - break; - case 0x44475353: - eyeCatcherString = "DGSS (in ASCII)"; - break; - case 0x4447534F: - eyeCatcherString = "DGSO (in ASCII)"; - break; - case 0x44475441: - eyeCatcherString = "DGTA (in ASCII)"; - break; - case 0x44475052: - eyeCatcherString = "DGPR (in ASCII)"; - break; - case 0xc4c7e3c8: - eyeCatcherString = "DGTH (in EBCDIC)"; - break; - case 0xc4c7e3e2: - eyeCatcherString = "DGTS (in EBCDIC)"; - break; - case 0xc4c7e2e2: - eyeCatcherString = "DGSS (in EBCDIC)"; - break; - case 0xc4c7e2d6: - eyeCatcherString = "DGSO (in EBCDIC)"; - break; - case 0xc4c7e3c1: - eyeCatcherString = "DGTA (in EBCDIC)"; - break; - case 0xc4c7d7d9: - eyeCatcherString = "DGPR (in EBCDIC)"; - break; - - default: - eyeCatcherString = "eyecatcher is bad " + Util.formatAsHexString(eyecatcher) + " *********************************"; - break; - } - - return eyeCatcherString; - } - - final protected static void setBigEndian(boolean endian) - { - bigendian = endian; - } + private static Properties properties; + private static Hashtable threads; + private static int timerType; + private static Hashtable components; + private static boolean bigendian; + final static String[] timerDesc= {"Sequence number ", + "Special ", + "Pentium TSC ", + "Time (UTC) ", + "MSPR ", + "MFTB ", + "Time (UTC) ", + "J9 timer(UTC) "}; + + protected static final int BYTE = 1; // length of a byte in bytes + protected static final int INT = 4; // length of an int in bytes + protected static final int LONG = 8; // length of a long in bytes + protected static final String SUM_TAB = " "; + + protected static final BigInteger MILLIS2SECONDS = BigInteger.valueOf(1000); + protected static final BigInteger SECONDS2MINUTES = BigInteger.valueOf(60); + protected static final BigInteger MINUTES2HOURS = BigInteger.valueOf(60); + protected static final BigInteger HOURS2DAYS = BigInteger.valueOf(24); + protected static final BigInteger MILLION = BigInteger.valueOf(1000000); + + // don't let anyone instantiate this class + private Util() + { + } + + /** Initializes static variables. + * + *

    This is called each time the TraceFormatter is started, from the initStatics() + * method in TraceFormat.java

    + */ + final protected static void initStatics() + { + properties = null; + threads = null; + components = null; + } + + /** puts a thread ID into a hashtable telling the formatter that this thread ID + * is one that should be traced + * + * @param threadID a string representation of a hexidecimal thread id + */ + final protected static void putThreadID(Long threadID) + { + if ( threads == null ) { + threads = new Hashtable(); + } + threads.put(threadID, threadID); + } + + /** retrieve whether of not the given id is in a hashtable. if the table is null that means + * that no ids were added, since the default behavior is all id this returns true + * + * @param threadID a string representation of a hexidecimal thread id + * @return a boolean that is true if the id was added to the table or if the table is null + */ + final protected static boolean findThreadID(Long threadID) + { + if ( threads == null ) { + return true; //defaults to all + } + return threads.containsKey(threadID); + } + + /** puts a component name into a hashtable telling the formatter that this component + * is one that should be traced. In this case all types of entries are formatted for this + * component + * + * @param comp a string representation of a component in the jvm + */ + final protected static void putComponent(String comp) + { + if ( components == null ) { + components = new Hashtable(); + } + components.put(comp.toLowerCase(), new TypeList()); + } + + /** puts a component name into a hashtable telling the formatter that this component + * is one that should be traced. In this case only the types of entries specified in types + * are formatted for this component + * + * @param comp a string representation of a component in the jvm + * @param types a vector of string for the type of trace entries to format (ie, Entry, Exit, Exception, etc) + */ + final protected static void putComponent(String comp, Vector types) + { + if ( components == null ) { + components = new Hashtable(); + } + components.put(comp.toLowerCase(), new TypeList(types)); + } + + /** determines if a particular component and type is to be formatted + * + * @param comp a string representation of a component in the jvm + * @param types a string for the type of trace entry to format (ie, Entry, Exit, Exception, etc) + * @return a boolean that is true if this component and type was added to the table or if the table is null + */ + final protected static boolean findComponentAndType(String comp, String type) + { + if ( components == null ) { + return true; // defaults to all(all) + } + if (comp.equals("dg")) { + return true; + } + return(components.containsKey(comp) && ((TypeList) components.get(comp)).contains(type)); + } + + /** determines the encoding based on the byte passed in. If the byte is + * a \u0044 (ASCII 'D') the encoding is ASCII + * + * @param info + */ + final static void determineEncoding(byte testChar) + { + Debug.println("Encoding is Ascii: " + (char) testChar + "= \u0044"); + setProperty("ENCODING", "ASCII"); + } + + /** Reverses the order of the bytes in the byte array + * + * @param data an array of bytes to be reversed + */ + final static private void reverseByteOrder(byte[] data) + { + for ( int i = 0; i < data.length / 2 ; i++ ) { + int temp = data[i]; + data[i] = data[(data.length - 1) - i]; + data[(data.length - 1) - i] = (byte) temp; + } + } + + /** + * Construct a BigInteger from an array of bytes. BigIntegers are used to get around problems + * caused by the lack of unsigned primitive type. + * + * @param data an array of bytes + * @param offset offset to the first byte to use to create the BigInteger + * @return a positive BigInteger constructed from the byte array + */ + final protected static BigInteger constructUnsignedLong(byte[] data, int offset) + { + return constructUnsignedLong(data, offset, Util.LONG); + } + + /** + * Construct a BigInteger from an array of bytes. BigIntegers are used to get around problems + * caused by the lack of unsigned primitive type. + * + * @param data an array of bytes + * @param offset offset to the first byte to use to create the BigInteger + * @param numBytes the length of this BigInteger in bytes + * @return a positive BigInteger constructed from the byte array + */ + final protected static BigInteger constructUnsignedLong(byte[] data, int offset, int numBytes) + { + byte[] bytes = new byte[numBytes]; + try { + System.arraycopy(data, offset, bytes, 0, numBytes); + if (!bigendian) { + reverseByteOrder(bytes); + } + BigInteger temp = new BigInteger(1, bytes); // 1 means positive + return temp; + } catch (Exception e) { + TraceFormat.outStream.println("******************* Exception:" + + " data.length " + data.length + + " offset " + offset + + " numBytes " + numBytes); + return BigInteger.ZERO; + } + } + + final protected static int constructTraceID(byte[] data, int offset) + { + return((((int) data[offset] << 16) & 0xff0000) | (((int) data[offset+1] << 8) & 0xff00) | ((int) data[offset+2] & 0xff)); + } + + final protected static long constructUnsignedInt(byte[] data, int offset) + { + return( bigendian == false ) + ? ( (((long) data[offset+3] << 24) & 0xff000000L) + | (((long) data[offset+2] << 16) & 0xff0000L) + | (((long) data[offset+1] << 8) & 0xff00L) + | ((long) data[offset] & 0xffL)) + : ( (((long) data[offset] << 24) & 0xff000000L) + | (((long) data[offset+1] << 16) & 0xff0000L) + | (((long) data[offset+2] << 8) & 0xff00L) + | ((long) data[offset+3] & 0xffL)); + } + + final protected static int constructUnsignedByte(byte[] data, int offset) + { + return(int) data[offset] & 0xff; + } + + final static private int findNull(byte[] data, int index) + { + while ( index < data.length ) { + if ( data[index] == 0 ) { + return index; + } + index++; + } + return -1; + } + + /** Constructs a string from an array of bytes, encoding is as specified in the properties + * + */ + final protected static String constructString(byte[] data, int offset) + { + return constructString(data, offset, getProperty("ENCODING", "ASCII")); + } + + /** Constructs a string from an array of bytes, with the specified encoding (ASCII or EBCDIC?) + * + */ + final protected static String constructString(byte[] data, int offset, String enc) + { + int nullChar = findNull(data, offset); + if ( nullChar == -1 ) { + return ""; + } + return constructString(data, offset, (nullChar-offset), enc); + } + + /** Constructs a string from an array of bytes with a count, encoding is as specified in the properties + * + */ + final protected static String constructString(byte[] data, int offset, int count) + { + return constructString(data, offset, count, getProperty("ENCODING", "ASCII")); + } + + static boolean charIsOneOfControlCharactersToRemove(char c){ + if (c < 9) { + /* ignore 0 - NUL + * ignore 1 - SOH + * ignore 2 - STX + * ignore 3 - ETX + * ignore 4 - EOT + * ignore 5 - ENQ + * ignore 6 - ACK + * ignore 7 - BEL + * ignore 8 - BS + */ + return true; + } else { + return false; + } + } + + /** + * Escapes control characters in the given string. + * + * @param string + */ + public static final String escapeControlCharacters(String string) { + return escapeControlCharacters(string, getProperty("ENCODING", "ASCII")); + } + + /** + * Escapes control characters in the given string. + * + * @param string + * @param encoding + */ + public static final String escapeControlCharacters(String string, String encoding) { + if ("ASCII".equalsIgnoreCase(encoding)) { /* leave other encodings to fend for themselves */ + int length = string.length(); + StringBuffer escaped = null; + + for (int i = 0; i < length; ++i) { + char ch = string.charAt(i); + + if (charIsOneOfControlCharactersToRemove(ch)) { + if (escaped == null) { + escaped = new StringBuffer(length + 50); /* leave room for a few escapes */ + if (i > 0) { + escaped.append(string.substring(0, i)); + } + } + escaped.append(String.format("\\u%04x", Integer.valueOf(ch))); + } else { + if (escaped != null) { + escaped.append(ch); + } + } + } + + if (escaped != null) { + return escaped.toString(); + } + } + + return string; + } + + /** + * Constructs a string from an array of bytes with an offset and count, + * with the specified encoding (ASCII or EBCDIC). + */ + final protected static String constructString(byte[] data, int offset, int count, String enc) + { + try { + String string = ""; + + if ((offset + count) <= data.length) { + string = new String(data, offset, count, enc); + } + + return string; + } catch (Exception e) { + TraceFormat.outStream.println("Util.constructString (1) ****> offset: " + offset + ", count = " + count + " data = " + data); + TraceFormat.outStream.println("Util.constructString (2) ****> " + e); + return ""; + } + } + + /** sets an property that affects the behavior of the formatter + * + * @param key + * @param val + */ + final protected static void setProperty(String key, String val) + { + if ( properties == null ) { + properties = new Properties(); + } + properties.setProperty(key, val); + } + + /** gets an the value property that affecting behavior of the formatter + * + * @param key + * @return a string + */ + final protected static String getProperty(String key) + { + if ( properties == null ) { + properties = new Properties(); + } + return properties.getProperty(key); + } + + /** gets an the value property that affecting behavior of the formatter, if no such + * property is set the default value is returned + * + * @param key + * @param defaultValue + * @return a string + */ + final protected static String getProperty(String key, String defaultValue) + { + if ( properties == null ) { + properties = new Properties(); + } + return properties.getProperty(key, defaultValue); + } + + final protected static void padBuffer(StringBuffer sb, int i, char c) + { + padBuffer(sb, i, c, false); + } + + final protected static void padBuffer(StringBuffer sb, int i, char c, boolean leftJustified) + { + while ( sb.length() < i ) { + if (leftJustified) { + sb.append(c); + } else { + sb.insert(0, c); + } + } + } + + /* 0 Sequence Counter + * 1 Special + * 2 RDTSC Timer + * 3 AIX Timer + * 4 MFSPR Timer + * 5 MFTB Timer + * 6 STCK Timer + * 7 J9 Timer + */ + + final static void setTimerType(int type) + { + timerType = type; + } + + final static String getTimerDescription() + { + return timerDesc[timerType]; + } + + final static void printDump(byte[] buffer,int length) + { + int i,j,k; + StringBuffer buf1,buf2; + for (i=0;i<((length/16)+1);i++) { + buf1 = new StringBuffer(100); + buf2 = new StringBuffer(100); + for (j=0;j<4;j++) { + for (k=0;k<4;k++) { + if ((k+j*4+i*16) >= length) break; + byte2hex(buffer[k+j*4+i*16],buf1); + if ( (buffer[k+j*4+i*16]) > 40 && (buffer[k+j*4+i*16]) < 128) { + buf2.append((char)buffer[k+j*4+i*16]); + } + else + { + buf2.append("."); + } + } + buf1.append(" "); + } + Util.Debug.println(Util.formatAsHexString(i * 16) + ": " + buf1 + " " + buf2); + } + } + + /** + * Formats a number as a hex string, prefixing the "0x" + * radix specifier so that it can be unambiguously + * interpreted as a hex string. + * @param number the number to format + */ + final static public String formatAsHexString(long number) + { + return "0x" + Long.toHexString(number); + } + + /** + * Converts a byte to hex digit and writes to the supplied buffer + */ + private static void byte2hex(byte b, StringBuffer buf) { + char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + int high = ((b & 0xf0) >> 4); + int low = (b & 0x0f); + buf.append(hexChars[high]); + buf.append(hexChars[low]); + } + + final static String getFormattedTime(BigInteger time) + { + //Util.Debug.println("formatting time " + time); + //Util.Debug.println("Util: timerType " + timerType); + switch (timerType) { + + case 2: + case 4: + case 5: + case 7: + { + /* + * X86 with RDTSC, MFTB, MSPR, J9 + */ + if (TraceFormat.verMod >= 1.1) { + BigInteger splitTime[]; + BigInteger nanos; + BigInteger secondsMillis[]; + BigInteger minutesSeconds[]; + BigInteger hoursMinutes[]; + BigInteger daysHours[]; + + time = time.subtract(TraceFormat.overallStartPlatform); + splitTime = time.divideAndRemainder(TraceFormat.timeConversion); + secondsMillis = splitTime[0].add(TraceFormat.overallStartSystem).divideAndRemainder(MILLIS2SECONDS); + nanos = secondsMillis[1].multiply(MILLION).add(splitTime[1].multiply(MILLION).divide(TraceFormat.timeConversion)); + minutesSeconds = secondsMillis[0].divideAndRemainder(SECONDS2MINUTES); + hoursMinutes = minutesSeconds[0].divideAndRemainder(MINUTES2HOURS); + daysHours = hoursMinutes[0].divideAndRemainder(HOURS2DAYS); + + daysHours[1] = daysHours[1].add(TraceArgs.timeZoneOffset); /* allow user to modify timezone */ + try{ + return "00".substring(daysHours[1].toString().length()) + daysHours[1].toString() + ":" + + "00".substring(hoursMinutes[1].toString().length()) + hoursMinutes[1].toString() + ":" + + "00".substring(minutesSeconds[1].toString().length()) + minutesSeconds[1].toString() + "." + + "000000000".substring(nanos.toString().length()) + nanos.toString(); + } catch(Exception e) { + Debug.println(daysHours[1].toString() + ":" + + hoursMinutes[1].toString() + ":" + + minutesSeconds[1].toString() + "." + + nanos.toString()); + return "Bad Time: " + time.toString(16); + + } + } else { + return "0000000000000000".substring(time.toString(16).length()) + time.toString(16); + } + } + + case 3: + { + /* + * Power/Power PC + */ + long seconds; + long nanos; + long ss; + long mm; + long hh; + + seconds = time.shiftRight(32).longValue() & 0xffffffffL; + nanos = time.longValue() & 0xffffffffL; + ss = seconds % 60; + mm = (seconds / 60) % 60; + hh = (seconds / 3600) % 24; + try { + return "00".substring(Long.toString(hh).length()) + Long.toString(hh) + ":" + + "00".substring(Long.toString(mm).length()) + Long.toString(mm) + ":" + + "00".substring(Long.toString(ss).length()) + Long.toString(ss) + "." + + "000000000".substring(Long.toString(nanos).length()) + Long.toString(nanos); + } catch(Exception e) { + Debug.println("hh: " + Long.toString(hh) + " mm: " + + Long.toString(mm) + " ss: " + + Long.toString(ss) + " Nanos: " + + Long.toString(nanos)); + return "Bad Time: " + time.toString(16); + } + } + case 6: + { + /* + * System/390 + */ + long picos; + long micros; + long ss; + long mm; + long hh; + + micros = time.shiftRight(12).longValue() & 0xfffffffffffffL; + ss = (micros / 1000000) % 60; + mm = (micros / 60000000) % 60; + hh = (micros / 3600000000L) % 24; + micros = micros % 1000000; + picos = (((time.longValue() & 0xfffL) | (micros << 12)) * 244140625) / 1000000; + try { + return "00".substring(Long.toString(hh).length()) + Long.toString(hh) + ":" + + "00".substring(Long.toString(mm).length()) + Long.toString(mm) + ":" + + "00".substring(Long.toString(ss).length()) + Long.toString(ss) + "." + + "000000000000".substring(Long.toString(picos).length()) + Long.toString(picos); + } catch(Exception e) { + Debug.println("hh: " + Long.toString(hh) + " mm: " + + Long.toString(mm) + " ss: " + + Long.toString(ss) + " Picos: " + + Long.toString(picos)); + return "Bad Time: " + time.toString(16); + } + } + default: + { + return "0000000000000000".substring(time.toString(16).length()) + time.toString(16); + } + } + + } + + static class Debug { + static java.io.PrintStream out = TraceFormat.outStream; + + static void println(Object o) + { + if ( TraceArgs.debug ) { + out.println(o); + } + } + + static void print(Object o) + { + if ( TraceArgs.debug ) { + out.print(o); + } + } + } + + /** keeps track of the types to format for a given component + * + * @author Jonathon Lee + * @version 1.0, Date: 7/7/1999 + */ + final static class TypeList { + Hashtable types; + + TypeList() + { + + } + + TypeList(Vector typeNames) + { + types = new Hashtable(); + for ( int i = 0; i < typeNames.size(); i++ ) { + String t = ((String) typeNames.elementAt(i)).toLowerCase(); + types.put(t, t); + } + } + + final boolean contains(String type) + { + if ( types == null ) { + return true; //defaults to all + } + return types.containsKey(type); + } + } + + final protected static int convertEndian(int in) + { + return ( (in >>> 24) | (in << 24 ) | + (( in << 8 ) & 0x00FF0000) | ((in >> 8 ) & 0x0000FF00)); + } + + final protected static String convertAndCheckEyecatcher(int eyecatcher) + { + String eyeCatcherString; + // convert back !!!!!!!!!!!!!!!!! + eyecatcher = bigendian ? eyecatcher : Util.convertEndian(eyecatcher); + switch (eyecatcher) { + case 0x48545455: // allow for endian + eyeCatcherString = "UTTH (in ASCII)"; + break; + case 0x55545448: + eyeCatcherString = "UTTH (in ASCII)"; + break; + case 0x55545453: + eyeCatcherString = "UTTS (in ASCII)"; + break; + case 0x55545353: + eyeCatcherString = "UTSS (in ASCII)"; + break; + case 0x5554534F: + eyeCatcherString = "UTSO (in ASCII)"; + break; + case 0x55545441: + eyeCatcherString = "UTTA (in ASCII)"; + break; + case 0x55545052: + eyeCatcherString = "UTPR (in ASCII)"; + break; + case 0xe4e3e3c8: + eyeCatcherString = "UTTH (in EBCDIC)"; + break; + case 0xe4e3e3e2: + eyeCatcherString = "UTTS (in EBCDIC)"; + break; + case 0xe4e3e2e2: + eyeCatcherString = "UTSS (in EBCDIC)"; + break; + case 0xe4e3e2d6: + eyeCatcherString = "UTSO (in EBCDIC)"; + break; + case 0xe4e3e3c1: + eyeCatcherString = "UTTA (in EBCDIC)"; + break; + case 0xe4e3d7d9: + eyeCatcherString = "UTPR (in EBCDIC)"; + break; + case 0x48544744: // allow for endian + eyeCatcherString = "DGTH (in ASCII)"; + break; + case 0x44475448: + eyeCatcherString = "DGTH (in ASCII)"; + break; + case 0x44475453: + eyeCatcherString = "DGTS (in ASCII)"; + break; + case 0x44475353: + eyeCatcherString = "DGSS (in ASCII)"; + break; + case 0x4447534F: + eyeCatcherString = "DGSO (in ASCII)"; + break; + case 0x44475441: + eyeCatcherString = "DGTA (in ASCII)"; + break; + case 0x44475052: + eyeCatcherString = "DGPR (in ASCII)"; + break; + case 0xc4c7e3c8: + eyeCatcherString = "DGTH (in EBCDIC)"; + break; + case 0xc4c7e3e2: + eyeCatcherString = "DGTS (in EBCDIC)"; + break; + case 0xc4c7e2e2: + eyeCatcherString = "DGSS (in EBCDIC)"; + break; + case 0xc4c7e2d6: + eyeCatcherString = "DGSO (in EBCDIC)"; + break; + case 0xc4c7e3c1: + eyeCatcherString = "DGTA (in EBCDIC)"; + break; + case 0xc4c7d7d9: + eyeCatcherString = "DGPR (in EBCDIC)"; + break; + + default: + eyeCatcherString = "eyecatcher is bad " + Util.formatAsHexString(eyecatcher) + " *********************************"; + break; + } + + return eyeCatcherString; + } + + final protected static void setBigEndian(boolean endian) + { + bigendian = endian; + } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceFile.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceFile.java index d97bcb7152b..d716f890a68 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceFile.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceFile.java @@ -29,7 +29,7 @@ * @author srowland */ public class TraceFile { - + TraceFormat formatter = null; String formatterArgs[] = null; /** @@ -43,7 +43,7 @@ public TraceFile(String traceFileNameURI){ } /** - * Create an empty TraceFile object to which TraceBuffers and a TraceFileHeader can + * Create an empty TraceFile object to which TraceBuffers and a TraceFileHeader can * be added. */ public TraceFile(){ @@ -57,17 +57,17 @@ public TraceFile(){ * the traceBuffer must be exactly as generated by the trace engine of an IBM Java * VM. The byte array must not contain any padding. * @return true on success, false on failure to add the buffer to the current TraceFile. - * @throws InvalidTraceBufferException if the byte array does not contain a valid + * @throws InvalidTraceBufferException if the byte array does not contain a valid * binary trace buffer. */ public boolean addTraceBuffer(byte[] traceBuffer) throws InvalidTraceBufferException{ System.err.println("addTraceBuffer not yet implemented."); return false; } - + /** * Add a binary representation of a TraceFileHeader to the current TraceFile. - * @param traceFileHeader a byte array containing precisely a TraceFileHeader as + * @param traceFileHeader a byte array containing precisely a TraceFileHeader as * generated by the IBM Java VM trace engine. The byte array must not contain * any padding. * @return true if the header is added, false if a header has already been added. @@ -79,7 +79,6 @@ public boolean addTraceFileHeader(byte[] traceFileHeader) throws InvalidTraceFil return false; } - /** * Get the object representation of the current TraceFile's TraceFileHeader * @return a TraceFileHeader object representing the current TraceFile's TraceFileHeader, @@ -88,29 +87,29 @@ public boolean addTraceFileHeader(byte[] traceFileHeader) throws InvalidTraceFil public TraceFileHeader getHeaderInfo(){ return formatter.getTraceFileHeader(); } - + /** * Get an array representing all of the traced threads in the current TraceFile. - * @return an array of TraceThread objects, containing one TraceThread object per + * @return an array of TraceThread objects, containing one TraceThread object per * thread found in the current TraceFile, or null if the current TraceFile does * not contain any traced threads. */ public TraceThread[] getTraceThreads(){ return formatter.getTraceThreads(); } - + /** * Get a TracePoint Iterator for the current TraceFile. * @return an Iterator that can be used to walk every TracePoint in the current - * TraceFile in chronological order. The iterator can be used a single time only, - * since it consumes the data as it walks it. Requesting an Iterator for a + * TraceFile in chronological order. The iterator can be used a single time only, + * since it consumes the data as it walks it. Requesting an Iterator for a * consumed TraceFile with return an empty Iterator. An empty Iterator will also - * be returned in cases where the current TraceFile does not contain any TracePoints. + * be returned in cases where the current TraceFile does not contain any TracePoints. */ public Iterator getGlobalChronologicalTracePointIterator(){ return new TracePointGlobalChronologicalIterator(formatter); } - + /** * Get a tracepoint from the trace file. * @return the next trace point for this file. @@ -121,7 +120,7 @@ public TracePoint getNextTracePoint(){ } class InvalidTraceBufferException extends Exception{ - + } class InvalidTraceFileHeaderException extends Exception{ diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceFileHeader.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceFileHeader.java index 2d30a790788..6b7a2261987 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceFileHeader.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceFileHeader.java @@ -45,7 +45,7 @@ public interface TraceFileHeader { */ public String[] getTraceParameters(); /** - * @return a String array representation of the system on which the JVM that produced + * @return a String array representation of the system on which the JVM that produced * the current TraceFile was run, null if no valid data. */ public String[] getSysProcessorInfo(); @@ -55,8 +55,8 @@ public interface TraceFileHeader { */ public long getJVMStartedMillis(); /** - * @return the millisecond time at which the JVM that produced the current TraceFile wrote - * its most recent TracePoint before the production of the current TraceFile. Returns -1 if + * @return the millisecond time at which the JVM that produced the current TraceFile wrote + * its most recent TracePoint before the production of the current TraceFile. Returns -1 if * no valid data. */ public long getLastBufferWriteMillis(); @@ -71,4 +71,3 @@ public interface TraceFileHeader { */ public long getLastTracePointMillis(); } - diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePoint.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePoint.java index 18b2fc4495f..c280ecd8ae1 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePoint.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePoint.java @@ -30,7 +30,7 @@ public interface TracePoint { /** * @return the numeric sub-identifier of the current tracepoint within the current component. - * A tracepoint is identified by componentName](containerCompName)].numericID, + * A tracepoint is identified by componentName](containerCompName)].numericID, * for example, comp1.14, or comp1(comp2).12. */ public int getID(); @@ -39,10 +39,10 @@ public interface TracePoint { * @return the GMT time in milliseconds at which this TracePoint was produced. */ public long getTimestampMillis(); - /* this time is intended to be appended to the getTimeStampMillis time, i.e. it adds + /* this time is intended to be appended to the getTimeStampMillis time, i.e. it adds resolution rather than being a formattable entity in its own right */ /** - * @return the high resolution timer value stored at the time this tracepoint was + * @return the high resolution timer value stored at the time this tracepoint was * generated. */ public int getMicrosecondsCount(); @@ -58,14 +58,14 @@ public interface TracePoint { public long getThreadID(); /** * @return the name of the component that produced this TracePoint. - * A tracepoint is identified by componentName](containerCompName)].numericID, + * A tracepoint is identified by componentName](containerCompName)].numericID, * for example, comp1.14, or comp1(comp2).12. */ public String getComponent(); /** * @return the name of the container component that produced the current TracePoint, * or null if the TracePoint did not have a container component. - * A tracepoint is identified by componentName](containerCompName)].numericID, + * A tracepoint is identified by componentName](containerCompName)].numericID, * for example, comp1.14, or comp1(comp2).12. */ public String getContainerComponent(); @@ -88,7 +88,7 @@ public interface TracePoint { */ public Object[] getParameters(); /** - * @return a list of groups to which this TracePoint belongs, or none if it doesn't + * @return a list of groups to which this TracePoint belongs, or none if it doesn't * belong to any. */ public String[] getGroups(); diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePointGlobalChronologicalIterator.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePointGlobalChronologicalIterator.java index f8ed7ad2346..90a5657a9f0 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePointGlobalChronologicalIterator.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePointGlobalChronologicalIterator.java @@ -26,24 +26,24 @@ /** * This is a Cursor that thinks it's an Iterator really. - * + * * @author Simon Rowland - * + * */ public class TracePointGlobalChronologicalIterator implements Iterator { private com.ibm.jvm.format.TraceFormat formatter = null; - + protected TracePointGlobalChronologicalIterator(com.ibm.jvm.format.TraceFormat formatter){ this.formatter = formatter; updateNext(); /* prime */ } - + private com.ibm.jvm.trace.TracePoint next = null; private synchronized void updateNext(){ next = formatter.getNextTracePoint(); } - + /* (non-Javadoc) * @see java.util.Iterator#hasNext() */ diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePointThreadChronologicalIterator.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePointThreadChronologicalIterator.java index f1aa2edf14d..6d308d8c020 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePointThreadChronologicalIterator.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TracePointThreadChronologicalIterator.java @@ -31,18 +31,18 @@ public class TracePointThreadChronologicalIterator implements Iterator { private com.ibm.jvm.format.TraceThread thread = null; - + public TracePointThreadChronologicalIterator(com.ibm.jvm.format.TraceThread thread){ this.thread = thread; updateNext(); /* prime */ } - + private com.ibm.jvm.trace.TracePoint next = null; private synchronized void updateNext(){ next = thread.getNextTracePoint(); } - + /* (non-Javadoc) * @see java.util.Iterator#hasNext() */ diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceThread.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceThread.java index b5044ff23aa..3a63ce5dac1 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceThread.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/TraceThread.java @@ -32,7 +32,7 @@ public interface TraceThread { /** * @return a TracePoint Iterator that can be used to walk each TracePoint on the * current TraceThread in chronological order. Note that the Iterator consumes data - * as it walks, and as such each TraceThread can be Iterated over once only. + * as it walks, and as such each TraceThread can be Iterated over once only. * Subsequent attempts to Iterate will return an empty Iterator, as will an attempt * to iterate over an unpopulated TraceThread. */ diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ActiveSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ActiveSection.java index 262c87b84b4..deccb777c64 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ActiveSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ActiveSection.java @@ -28,13 +28,13 @@ /** * Active section of a file header. - * + * * @author Tim Preece */ public class ActiveSection { TraceContext context; String textSummary; - + private Vector options = new Vector(); public ActiveSection(TraceContext context, ByteBuffer data) throws IllegalArgumentException { @@ -44,7 +44,7 @@ public ActiveSection(TraceContext context, ByteBuffer data) throws IllegalArgume if (context.debugStream != null) { context.debug(this, 1, dataHeader); } - + byte activationData[] = new byte[dataHeader.length - DataHeader.DATAHEADER_SIZE]; data.get(activationData); splitActivationData(activationData); @@ -69,7 +69,7 @@ private void splitActivationData(byte data[]) { j = i + 1; } } - + if (context.debugStream != null) { context.debug(this, 1, summary()); } @@ -78,19 +78,19 @@ private void splitActivationData(byte data[]) { public String toString() { return "Trace activation information:"; } - + public String summary() { if (textSummary == null) { StringBuilder s = new StringBuilder(toString()+":"+System.getProperty("line.separator")); - + for (int i = 0; i < options.size(); i++) { s.append(" "); /* indent the options */ s.append(options.get(i)).append(System.getProperty("line.separator")); } - + textSummary = s.toString(); } - + return textSummary; } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ByteStream.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ByteStream.java index 9085353d4aa..baf0a7d2ce3 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ByteStream.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ByteStream.java @@ -78,7 +78,7 @@ public ByteStream() { /** * This method ensures that there is sufficient data to satisfy a * request - * + * * @param bytes * @throws BufferUnderflowException */ @@ -105,7 +105,7 @@ synchronized private void commit(int bytes) throws BufferUnderflowException { * recover */ Slice slice = (Slice)rawData.get(0); - + /* if we can guard out of raw data and there's enough in the buffer */ if (buffer != null && buffer.remaining() >= bytes && slice.length >= guardBytes) { return; @@ -123,7 +123,7 @@ synchronized private void commit(int bytes) throws BufferUnderflowException { */ int remaining = buffer.remaining(); byte mergeData[]; - + /* snip what's needed off the front of the next slice if the slice is big enough * for us to care about copying it */ if (slice.length > requiredBytes) { @@ -133,7 +133,7 @@ synchronized private void commit(int bytes) throws BufferUnderflowException { System.arraycopy(slice.data, slice.offset, mergeData, remaining, shortfall); slice.offset+= shortfall; slice.length-= shortfall; - + /* don't need to recurse here because the fact we're here says there's enough in place */ recurse = false; } else { @@ -171,7 +171,7 @@ public void add(byte[] data, int offset) { if (data == null) { return; } - + add(data, offset, data.length - offset); } @@ -343,7 +343,7 @@ public String getASCIIString() { buffer.position(s+length); return value; } - + try { commit(buffer.remaining() + 20); } catch (BufferUnderflowException e) { @@ -361,7 +361,7 @@ public String getASCIIString() { /** * Constructs a string. This has a prerequisite that the string is * prefixed with a short specifying it's length. - * + * * @return */ public String getUTF8String() throws UnsupportedEncodingException { @@ -372,7 +372,6 @@ public String getUTF8String() throws UnsupportedEncodingException { commit(length); get(data); - String s = new String(data, "UTF-8"); /* defect 143460: work around for java5 presenting some strings in pseudo utf16 */ @@ -389,7 +388,7 @@ public String getUTF8String() throws UnsupportedEncodingException { } } } - + if (utf16) { if (swap) { /* swap bytes at odd/even indexes*/ @@ -410,7 +409,7 @@ public String getUTF8String() throws UnsupportedEncodingException { /** * reads the specified number of bytes and turns them in to a positive * BigInteger - * + * * @param bytes * @return */ @@ -444,7 +443,7 @@ public ByteOrder order() { /** * Default order is big endian and that's what you'll get if you pass * null in. - * + * * @param order */ synchronized public void order(ByteOrder order) { @@ -473,7 +472,7 @@ public int getGuardBytes() { * beginning of the stream, then will throw an exception. If an * exception is thrown the stream will be completely empty, all data * discarded. - * + * * @param bytes * - the number of bytes to remove * @throws BufferUnderflowException @@ -521,7 +520,7 @@ synchronized public void truncate(int bytes) { * will be placed into the provided array, filling from the end (i.e. if * there's insufficient data in the stream to fill the array then the * initial bytes in the array will be zero. - * + * * @param bytes * - the number of bytes to remove * @return - the number of bytes truncated @@ -621,11 +620,11 @@ public void skip(int bytes) { * indexes from the end of the data. This is primarily because it's hard * to be sure where the start of the data is in relation to the bytes we * know we can modify, i.e. those bytes that are guarded. - * + * * put(data, -1) will insert the bytes in data in the last but one * position of the stream, moving the last byte in the stream out by * data.length and increase the count of guarded bytes by data.length - * + * * @param data * - the data to insert * @param index @@ -704,7 +703,7 @@ synchronized public void put(byte data[], int index) { * array allowing negative addressing. Positive indexes throw index out * of bounds. It is worth noting that an index of -1 means the last byte * present, i.e. we are not zero indexed. - * + * * @param index * @param b * - the original byte we're replacing diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/Component.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/Component.java index c2efcd5975d..3f3a95c8982 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/Component.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/Component.java @@ -26,7 +26,7 @@ /* * represents a trace component (eg: j9vm) and is responsible for holding on to - * all known trace messages for the component. + * all known trace messages for the component. */ public class Component { diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/DataHeader.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/DataHeader.java index ccbe18e78d2..24b568469ba 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/DataHeader.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/DataHeader.java @@ -59,7 +59,7 @@ public class DataHeader { public DataHeader(TraceContext context, ByteBuffer data, String signature) throws IllegalArgumentException { this(context, data, signature, true); } - + protected DataHeader(TraceContext context, ByteBuffer data, String signature, boolean confirmBody) throws IllegalArgumentException { /* check there's enough data to reconstruct the UtDataHeader */ if (data.remaining() < DATAHEADER_SIZE) { @@ -105,7 +105,7 @@ protected DataHeader(TraceContext context, ByteBuffer data, String signature, bo version = data.getInt(); modification = data.getInt(); this.signature = signature; - + if (confirmBody) { /* check there's sufficient data available to read the structure */ if (data.remaining() < length - DATAHEADER_SIZE) { diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/Message.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/Message.java index d3c785d81ab..2ca231f95db 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/Message.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/Message.java @@ -41,7 +41,7 @@ final public class Message { private int id; private int level; private Properties statistics = new Properties(); - + public Message(int type, String message, int id, int level, String component, String symbol, TraceContext context) { this.context = context; this.type = type; @@ -54,12 +54,12 @@ public Message(int type, String message, int id, int level, String component, St this.level = level; this.statistics.put("component", component); } - + private Message(String message, int pointerSize) { this.message = message; this.ptrSize = pointerSize; } - + public void addStatistic(String key, long value) { long total = 0; if (statistics.containsKey(key)) { @@ -68,11 +68,11 @@ public void addStatistic(String key, long value) { total+= value; statistics.put(key, Long.valueOf(total)); } - + public Properties getStatistics() { return statistics; } - + public static Arg[] getArgumentDetails(String template, int bytesPerPointer, StringBuffer templateErrors) { Message msg = new Message(template, bytesPerPointer); Arg[] parameters = msg.parseMessageTemplate(templateErrors); @@ -116,12 +116,12 @@ final protected static void padBuffer(StringBuilder sb, int i, char c, boolean l /** * process all the percent sign directives in a string, much like a call * to printf - * + * * @param str * a string * @return the string with percent directive replaces by their * associated values - * + * */ protected StringBuilder processPercents(String str, byte[] buffer, int offset) { int totalElems = parameterTypes.length; @@ -149,11 +149,11 @@ protected StringBuilder processPercents(String str, byte[] buffer, int offset) { /** * process all the percent sign directives in a string, making them * "???" - * + * * @param str * a string * @return the string with percent directives replaced by "???" - * + * */ protected StringBuilder skipPercents(String str, byte[] buffer, int offset) { int totalElems = parameterTypes.length; @@ -223,7 +223,7 @@ static private String readDigits(String str) { /** * retrieve the text of the message, parsing any percent directives and * replacing them with data from the buffer - * + * * @param buffer * an array of bytes * @param offset @@ -249,7 +249,7 @@ public String getMessage(byte[] buffer, int offset, int end) { /** * returns the component this message corresponds to, as determined by * the message file - * + * * @return an String that is component from which this message came from */ protected String getComponent() { @@ -259,7 +259,7 @@ protected String getComponent() { /** * returns the level of the component so it's possible to distinguish between the * default always on set and user enabled trace points - * + * * @return the level of the trace point, -1 if not applicable */ protected int getLevel() { @@ -269,7 +269,7 @@ protected int getLevel() { /** * returns the type of entry this message corresponds to, as determined * by the message file and TraceRecord - * + * * @return an int that is one of the types defined in TraceRecord * @see com.ibm.jvm.format.TraceRecord */ @@ -283,13 +283,13 @@ protected String getFormattingTemplate() { /** * parse the raw message into an array of the appropriate wrapped types. - * + * * @param buffer * an array of bytes that is the raw data to format * @param offset * an int representing the offset into buffer to start. * @return an array of wrapped types representing the parsed raw data. - * + * */ protected Object[] parseMessage(byte[] buffer, int offset) { int totalElems = nonConstantParameterTypes.length; @@ -440,14 +440,14 @@ Arg[] parseMessageTemplate(StringBuffer templateErrors) { break; case 'f': - /* CMVC 164940 All %f tracepoints were promoted to double in runtime trace code. - * Affects: - * TraceFormat com/ibm/jvm/format/Message.java - * TraceFormat com/ibm/jvm/trace/format/api/Message.java - * runtime ute/ut_trace.c - * TraceGen OldTrace.java - * Intentional fall through to next case. - */ + /* CMVC 164940 All %f tracepoints were promoted to double in runtime trace code. + * Affects: + * TraceFormat com/ibm/jvm/format/Message.java + * TraceFormat com/ibm/jvm/trace/format/api/Message.java + * runtime ute/ut_trace.c + * TraceGen OldTrace.java + * Intentional fall through to next case. + */ case 'g': str = str.substring(1, str.length()); @@ -533,11 +533,11 @@ public abstract class Arg { abstract Object getValue(ByteStream msg); abstract void format(ByteStream msg, StringBuilder out); - + public int sizeof() { return sizeof; } - + public String signature() { return signature; } @@ -665,7 +665,7 @@ public class I32_Arg extends Arg { super(size); if (size == TraceContext.SIZE_T) { signature = "IDATA"; - this.sizeof = ptrSize; + this.sizeof = ptrSize; } else { signature = "I_32"; } @@ -834,7 +834,7 @@ public void addOxPrefix() { public boolean needsOxPrefix() { return addOxPrefix; } - + public void setZeroPad(boolean pad) { zeroPad = pad; } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/MessageFile.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/MessageFile.java index 0330825df34..903905dd605 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/MessageFile.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/MessageFile.java @@ -28,7 +28,7 @@ /** * Acts as a template for mapping trace ids to messages. - * + * * @author Jonathon Lee */ final public class MessageFile { @@ -54,11 +54,11 @@ final public class MessageFile { public HashMap getStatistics() { HashMap stats = new HashMap(); - + Iterator mItr = messages.keySet().iterator(); while (mItr.hasNext()) { Object mKey = mItr.next(); - Message msg = (Message)messages.get(mKey); + Message msg = (Message)messages.get(mKey); if (msg != null) { stats.put(mKey, msg.getStatistics()); } @@ -153,7 +153,7 @@ private void readHeader(String messageLine) throws IOException { * the line has no spaces, it is determined to be a component; otherwise * it contains a trace id, an entry type, and a template string * (separated by spaces) - * + * * @param messageLine * a string */ @@ -166,7 +166,7 @@ protected void addMessage(String messageLine) { * the line has no spaces, it is determined to be a component; otherwise * it contains a trace id, an entry type, and a template string * (separated by spaces) - * + * * @param messageLine * a string */ @@ -235,7 +235,7 @@ private void addMessage_50(String messageLine) { * the line has no spaces, it is determined to be a component; otherwise * it contains a trace id, an entry type, and a template string * (separated by spaces) - * + * * @param messageLine * a string */ @@ -271,7 +271,7 @@ private void addMessage_12(String messageLine) { /** * retrieve the message associated with a given traceID - * + * * @param id * an int that is a trace identifier * @return a message that contains the type of entry, the component for @@ -288,7 +288,7 @@ protected Message getMessageFromID(int id) { /** * retrieve the message associated with a given traceID and component - * + * * @param id * an int that is a trace identifier * @return a message that contains the type of entry, the component for diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ProcessorSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ProcessorSection.java index 01826c7dd8c..4b5c79415c9 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ProcessorSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ProcessorSection.java @@ -28,7 +28,7 @@ /** * Processor section of a file header - * + * * @author Tim Preece */ public class ProcessorSection { @@ -43,7 +43,7 @@ public class ProcessorSection { private final static String[] SubTypes = { "i486", "i586", "Pentium II", "Pentium III", "Merced", "McKinley", "PowerRS", "PowerPC", "GigaProcessor", "ESA", "Pentium IV", "T-Rex", "Opteron", "RV64G", "Armv8-A" }; private final static String[] trCounter = { "Sequence Counter", "Special", "RDTSC Timer", "AIX Timer", "MFSPR Timer", "MFTB Timer", "STCK Timer", "J9 timer" }; - + TraceContext context; int arch; @@ -52,7 +52,7 @@ public class ProcessorSection { int procs; int subType; int counter; - + String textSummary; public ProcessorSection(TraceContext context, ByteBuffer data) throws IllegalArgumentException { @@ -68,7 +68,6 @@ public ProcessorSection(TraceContext context, ByteBuffer data) throws IllegalArg subType = data.getInt(); counter = data.getInt(); - if (context.debugStream != null) { context.debug(this, 1, summary()); } @@ -77,7 +76,7 @@ public ProcessorSection(TraceContext context, ByteBuffer data) throws IllegalArg public String toString() { return "Processor information"; } - + public String summary() { if (textSummary == null) { StringBuilder s = new StringBuilder(toString()+":"+System.getProperty("line.separator")); @@ -90,7 +89,7 @@ public String summary() { textSummary = s.toString(); } - + return textSummary; } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ServiceSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ServiceSection.java index a763986db73..b67d0c53993 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ServiceSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/ServiceSection.java @@ -29,13 +29,13 @@ /** * Service section of a file header. - * + * * @author Tim Preece */ public class ServiceSection { TraceContext context; String serviceString; - + String textSummary; public ServiceSection(TraceContext context, ByteBuffer data) throws IllegalArgumentException { @@ -64,7 +64,7 @@ public ServiceSection(TraceContext context, ByteBuffer data) throws IllegalArgum public String toString() { return "Service level"; } - + public String summary() { if (textSummary == null) { StringBuilder s = new StringBuilder(toString()+":"+System.getProperty("line.separator")); @@ -74,7 +74,7 @@ public String summary() { textSummary = s.toString(); } - + return textSummary; } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/StartupSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/StartupSection.java index b54c31abc84..b194177c5b6 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/StartupSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/StartupSection.java @@ -28,13 +28,13 @@ /** * Startup section of a file header. - * + * * @author Tim Preece */ public class StartupSection { TraceContext context; String textSummary = null; - + private Vector options = new Vector(); public StartupSection(TraceContext context, ByteBuffer data) throws IllegalArgumentException { @@ -73,7 +73,7 @@ private void splitOptions(byte data[]) { public String toString() { return "JVM startup options"; } - + public String summary() { if (textSummary == null) { StringBuilder s = new StringBuilder(toString()+":"+System.getProperty("line.separator")); @@ -82,10 +82,10 @@ public String summary() { s.append(options.get(i)); s.append(System.getProperty("line.separator")); } - + textSummary = s.toString(); } - + return textSummary; } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceContext.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceContext.java index 1d3a613d055..58cc847efcd 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceContext.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceContext.java @@ -267,7 +267,6 @@ public void setMessageStream(PrintStream stream) { messageStream = stream; } - /** * @return */ @@ -302,7 +301,7 @@ public int getRecordSize() { /** * Returns the size of the meta-data. This allows a file processor to skip to the - * offset of the first record. + * offset of the first record. * @return the length of the meta-data */ public int getHeaderSize() { @@ -311,7 +310,7 @@ public int getHeaderSize() { /** * Constructs a temporary TraceFileHeader from the supplied data and returns it's size - * offset of the first record. + * offset of the first record. * @return the length of the meta-data */ public int getHeaderSize(ByteBuffer data) { @@ -335,17 +334,17 @@ public ByteOrder order() { public int getTraceType() { return metadata.traceSection.type; } - + /** * This forces the trace to a given type. This should only be necessary if you have metadata from * a VM when no subscribers were attached and data from a subscriber that was registered afterwards. * The inverted case could be true as well, but is much less likely to occur. - * + * * If you're calling this then you should think about altering the sequence of calls used to get the * metadata and trace data. - * + * * @param type - the type of the trace data to process, either TraceContext.INTERNAL or TraceContext.EXTERNAL - * + * * @deprecated this method is deprecated as it's use implies a problem elsewhere */ @Deprecated @@ -374,7 +373,7 @@ public void setTraceType(int type) { if (metadata == null || metadata.traceSection == null) { this.error(this, "Unable to set trace type due to incomplete trace context"); } else { - this.error(this, "Unable to set trace type to invalid type "+type); + this.error(this, "Unable to set trace type to invalid type "+type); } } } @@ -481,7 +480,7 @@ public static TraceContext getContext(byte[] data, int length, InputStream messa /** * This method constructs a context that can be used to format trace records produced by the VM instance that created the meta-data provided. * The message file is used to format trace points into a human readable form and the print streams provided are where messages of that type are written to - * @param data - trace meta-data + * @param data - trace meta-data * @param length - the length of the meta-data in the array * @param messageFile - a file containing format strings * @param message - informational message destination @@ -498,7 +497,7 @@ public static TraceContext getContext(byte[] data, int length, InputStream messa /** * This method constructs a context that can be used to format trace records produced by the VM instance that created the meta-data provided. * The message file is used to format trace points into a human readable form and the print streams provided are where messages of that type are written to - * @param data - trace meta-data + * @param data - trace meta-data * @param messageFile - a file containing format strings * @param message - informational message destination * @param error - error message destination @@ -514,7 +513,7 @@ public static TraceContext getContext(ByteBuffer data, File messageFile, PrintSt /** * This method constructs a context that can be used to format trace records produced by the VM instance that created the meta-data provided. * The message file is used to format trace points into a human readable form and the print streams provided are where messages of that type are written to - * @param data - trace meta-data + * @param data - trace meta-data * @param messageFile - an input stream providing access to format strings * @param message - informational message destination * @param error - error message destination @@ -557,7 +556,7 @@ ByteStream createByteStream(byte data[], int offset) { /** * Constructs a ByteStream with an endian representation suitable for use with data related * to the context creating it. - * + * * @param data - initial contents of the stream * @param offset - offset into the data for the first byte of the stream * @param length - length past the offset for the last byte of data in the stream @@ -573,10 +572,10 @@ ByteStream createByteStream(byte data[], int offset, int length) { /** * This method is called to inform the context that we think the specified thread has * terminated. This allows us to tidy up after dead threads so we don't leak memory. - * + * * If the thread has been re-used later on then we do not remove it as there will still be * more data available. - * + * * @param thread - the terminated thread * @param moreData - true if the thread has more trace points after this one, false otherwise. */ @@ -602,7 +601,7 @@ synchronized void threadTerminated(TraceThread thread, boolean moreData) { */ private synchronized TraceThread addData(TraceRecord record) { TraceThread thread; - + /* which thread does it belong to? */ // Use the J9VMThread pointer as the unique id. Long ident = Long.valueOf(record.threadID); @@ -626,7 +625,7 @@ private synchronized TraceThread addData(TraceRecord record) { knownThreads.put(ident, names); } } - + thread = (TraceThread)threadMap.get(ident); if (thread == null || thread.stream == null) { thread = new TraceThread(this, record.threadID, record.threadSyn1, record.threadName); @@ -648,7 +647,7 @@ private synchronized TraceThread addData(TraceRecord record) { * have created a context with metadata from before they subscribed. * If we've got multiple buffers from a single thread then we're external * regardless of what the metadata said. - * + * * TODO: create a proper heuristic for TraceRecord to determine the wrapping style */ metadata.traceSection.type = TraceContext.EXTERNAL; @@ -684,7 +683,7 @@ private synchronized TraceThread addData(TraceRecord record) { /** * @see com.ibm.jvm.trace.format.api.TraceContext#addData(TraceRecord) - * @param file - file containing trace data + * @param file - file containing trace data * @param offset - the offset in the file of the buffer * @return - the thread that generated the buffer * @throws IOException @@ -708,22 +707,22 @@ public TraceThread addData(byte[] data) { * that are awaiting data for completion across all threads. When a trace point iterator * encounters one of the locations where data was discarded it will throw a MissingDataException * as for records discarded by the trace engine. - * - * This makes the assumption that the records are being supplied chronologically. + * + * This makes the assumption that the records are being supplied chronologically. */ public synchronized void discardedData() { Iterator itr = threads.iterator(); while (itr.hasNext()) { TraceThread thread = (TraceThread)itr.next(); - + thread.userDiscardedData(); } } - + /** * The time of trace initialization in the traced JVM in high precision format * This should be used in conjunction with the system start time - * + * * @return - high precision start time */ public BigInteger getStartPlatform() { @@ -773,19 +772,19 @@ public Object next() { if (threadCursor == null) { threadCursor = iterator.next(); } - + obj = threadCursor; threadCursor = iterator.next(); - + return obj; } catch (ConcurrentModificationException e) { if (threadCursor != null) { - Iterator itr = threads.iterator(); - + Iterator itr = threads.iterator(); + /* skip to our cursor again - use object equality as threads can recur*/ while (itr.hasNext() && itr.next() != threadCursor); iterator = itr; - + return next(); } else { throw e; @@ -909,7 +908,7 @@ public void remove() { * This method provides an iterator to walk the set of known threads; those that have not * returned trace points that indicate the thread is exiting. This iterator may be invalidated * by adding new trace data to the context. - * + * * @return - iterator over non-dead threads */ public Iterator getThreads() { @@ -926,7 +925,7 @@ public Iterator getThreads() { public Iterator getTracepoints() { return new SortedTracepointIterator(); } - + /** * This method adds a thread id to the thread filter. Only those threads in the filter will have data * returned via any of the iterators. @@ -936,7 +935,7 @@ public void addThreadToFilter(Long threadID) { if (filteredThreads == null) { filteredThreads = new TreeSet(); } - + filteredThreads.add(threadID); } @@ -947,7 +946,7 @@ public void addThreadToFilter(Long threadID) { public void setTimeZoneOffset(int minutes) { timezoneOffset = minutes; } - + /** * Formats a time stamp into a human readable form to nanosecond precision (not accuracy) * @param time - 64bit time stamp @@ -1070,7 +1069,7 @@ public String formatPointer(long value) { /* we don't want to append an additional zero to the end when value is 0 */ sb.append(Long.toHexString(value)); } - + return sb.toString(); } @@ -1127,25 +1126,25 @@ public String statistics() { int nameWidth = 0; long hitMax = 0; long bytesMax = 0; - + HashMap stats = this.messageFile.getStatistics(); for (int i = 0; i < this.auxiliaryMessageFiles.size(); i++) { stats.putAll(((MessageFile)this.auxiliaryMessageFiles.get(i)).getStatistics()); } - + TreeMap componentByteTotals = new TreeMap(); List componentTotals = new Vector(); TreeMap hitCount = new TreeMap(); List tracePointCounts = new Vector(); List tracePointBytes = new Vector(); - + /* generate totals per component and trace point */ Iterator itr = stats.keySet().iterator(); long totalBytes = 0; while (itr.hasNext()) { String tp = (String)itr.next(); Properties props = (Properties)stats.get(tp); - + String component = props.getProperty("component", ""); int width = tp.length(); if (width > nameWidth) { @@ -1157,9 +1156,9 @@ public String statistics() { if (count > hitMax) { hitMax = count; } - + hitCount.put(tp, Long.valueOf(count)); - tracePointCounts.add(new NameValueTuple(tp, (Long)props.get("count"))); + tracePointCounts.add(new NameValueTuple(tp, (Long)props.get("count"))); } if (props.containsKey("bytes")) { Long l = (Long)props.get("bytes"); @@ -1170,7 +1169,7 @@ public String statistics() { } totalBytes+= bytes; tracePointBytes.add(new NameValueTuple(tp, (Long)props.get("bytes"))); - + long total = 0; if (componentByteTotals.containsKey(component)) { total = ((Long)componentByteTotals.get(component)).longValue(); @@ -1179,11 +1178,10 @@ public String statistics() { } } } - + StringBuffer sb = new StringBuffer(); String nl = System.getProperty("line.separator"); - /* Write out the component byte totals */ sb.append("Component totals (bytes)"+nl); itr = componentByteTotals.keySet().iterator(); @@ -1191,7 +1189,7 @@ public String statistics() { String component = (String)itr.next(); componentTotals.add(new NameValueTuple(component, (Long)componentByteTotals.get(component))); } - + Collections.sort(componentTotals); itr = componentTotals.iterator(); while (itr.hasNext()) { @@ -1201,7 +1199,6 @@ public String statistics() { sb.append("Total bytes: "+totalBytes).append(nl); sb.append(nl); - /* Write out the trace point hit count totals */ sb.append("Trace point counts:"+nl); Collections.sort(tracePointCounts); @@ -1213,7 +1210,7 @@ public String statistics() { sb.append(String.format("%-"+nameWidth+"s %d (level: %2d)%n", tuple.name()+":", tuple.value(), msg.getLevel())); } sb.append(nl); - + /* Write out the trace point byte totals */ sb.append("Trace point totals (bytes):"+nl); Collections.sort(tracePointBytes); @@ -1232,7 +1229,7 @@ public String statistics() { class NameValueTuple implements Comparable { String name; Comparable value; - + NameValueTuple(String name, Comparable value) { this.name = name; this.value = value; @@ -1242,18 +1239,18 @@ public int compareTo(Object o) { if (o instanceof NameValueTuple) { return value.compareTo(((NameValueTuple)o).value); } - + return 0; } - + public String name() { return name; } - + public Comparable value() { return value; } - + public void setValue(Comparable value) { this.value = value; } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceFileHeader.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceFileHeader.java index 67e4c015738..5339be8078c 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceFileHeader.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceFileHeader.java @@ -27,7 +27,7 @@ /** * Encapsulates the header for a trace file. - * + * * @author Tim Preece */ final public class TraceFileHeader { @@ -86,15 +86,15 @@ protected TraceFileHeader(TraceContext context, ByteBuffer data) throws IllegalA default: throw new IllegalArgumentException("Invalid endian signature in trace file header: " + Long.toString(endianSignature, 16)); } - + context.debug(this, 1, "Data is " + byteOrder.toString()); - + /* set up the byte order for the rest of our accesses */ data.order(byteOrder); - + /* set up the basic header for this structure */ dataHeader = new DataHeader(context, data, "UTTH"); - + /* * Check the eyecatcher to make sure this is a valid trace file. * Written as characters so no need to worry about endian-ness @@ -106,10 +106,10 @@ protected TraceFileHeader(TraceContext context, ByteBuffer data) throws IllegalA context.debug(this, 1, "Eyecatchers are in EBCDIC"); ascii = false; } - + recordSize = data.getInt(); endianSignature = data.getInt(); - + /* * get the offsets for the various sections within our data * buffer @@ -119,29 +119,29 @@ protected TraceFileHeader(TraceContext context, ByteBuffer data) throws IllegalA int startupStart = data.getInt(); int activeStart = data.getInt(); int processorStart = data.getInt(); - + if (context.debugStream != null) { context.debug(this, 1, summary()); } - + /* some of the other sections format time stamps which depends on the processor type so we read this first */ processorSection = new ProcessorSection(context, (ByteBuffer) data.position(processorStart + traceFileHeaderStart)); traceSection = new TraceSection(context, (ByteBuffer) data.position(traceStart + traceFileHeaderStart)); serviceSection = new ServiceSection(context, (ByteBuffer) data.position(serviceStart + traceFileHeaderStart)); startupSection = new StartupSection(context, (ByteBuffer) data.position(startupStart + traceFileHeaderStart)); activeSection = new ActiveSection(context, (ByteBuffer) data.position(activeStart + traceFileHeaderStart)); - + /* now set up the context variables for other people to use */ context.version = (float) dataHeader.version + (((float) dataHeader.modification) / 10); } catch (IndexOutOfBoundsException e) { - throw new IllegalArgumentException("Truncated trace file header"); + throw new IllegalArgumentException("Truncated trace file header"); } } public String toString() { return "Trace file header"; } - + public String summary() { if (textSummary == null) { StringBuilder s = new StringBuilder(toString()+":"+System.getProperty("line.separator")); @@ -151,7 +151,7 @@ public String summary() { textSummary = s.toString(); } - + return textSummary; } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePoint.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePoint.java index 9ff5540c244..85b3ca2363a 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePoint.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePoint.java @@ -26,9 +26,9 @@ /** * Class to represent a tracepoint produced by IBM JVM's trace engine. - * + * * @author Simon Rowland - * + * */ public interface TracePoint { /* The types of tracepoints available */ diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePointDebugInfo.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePointDebugInfo.java index e1168dea974..2c2e5c4761e 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePointDebugInfo.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePointDebugInfo.java @@ -25,12 +25,12 @@ public class TracePointDebugInfo { int record; int offset; - + TracePointDebugInfo(int record, int offset) { this.record = record; this.offset = offset; } - + public int compareTo(Object o) { if (o instanceof TracePointDebugInfo) { TracePointDebugInfo tpdi = (TracePointDebugInfo)o; @@ -40,7 +40,7 @@ public int compareTo(Object o) { return offset - tpdi.offset; } } - + return 0; } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePointImpl.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePointImpl.java index c539e16eba4..f0cc7efb0b3 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePointImpl.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TracePointImpl.java @@ -54,7 +54,7 @@ public class TracePointImpl implements TracePoint { byte debugData[]; TracePointDebugInfo debugInfo; - /** + /** * */ public TracePointImpl(TraceContext context, ByteStream stream, TraceThread thread) { @@ -157,7 +157,7 @@ private TracePointImpl parseDataIntoTracepoint(ByteStream stream) { * if this trace point has a length of 8 and is the first * trace point in the buffer then we check to see if it's a lost * record trace point. - * + * * This trace point could well have overwritten the end of * trace point spanning from the previous buffer because of the * assumption by the lost record code that it is an empty buffer @@ -214,7 +214,7 @@ private TracePointImpl parseDataIntoTracepoint(ByteStream stream) { isNormalTracepoint = false; return this; } - + /* read in the timestamp */ time_lowerWord = stream.getUnsignedInt(); @@ -296,7 +296,7 @@ private TracePointImpl parseDataIntoTracepoint(ByteStream stream) { } message = file.getMessageFromID(componentName, tracepointID); } - + if (message.getType() == TracePoint.APP_TYPE && !componentName.equals("ApplicationTrace")) { if (parmDataLength > 0) { /* This is going to output any parameter data as raw data so it takes a precision string. @@ -305,7 +305,7 @@ private TracePointImpl parseDataIntoTracepoint(ByteStream stream) { byte newParmData[] = new byte[parmDataLength + 2]; System.arraycopy(parameterData, 0, newParmData, 2, parameterData.length); parameterData = newParmData; - + short len = (short)parmDataLength; if (stream.order() == ByteOrder.LITTLE_ENDIAN) { parameterData[0] = (byte)(0xFF & len); @@ -351,7 +351,7 @@ long getLostRecordCount() { private boolean internListCompare(byte traceData[], int offset, int internedNamesIndex, int length) { int l = internedNamesAsBytes[internedNamesIndex].length; int j; - + /* check the lengths match */ if (l != length) { return false; @@ -535,7 +535,7 @@ public String getDebugInfo() { if (debugInfo != null) { return "Record: "+debugInfo.record+", offset: "+debugInfo.offset; } - + return ""; } } diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceRecord.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceRecord.java index 6396eb0ac23..274f0690acc 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceRecord.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceRecord.java @@ -36,50 +36,50 @@ public class TraceRecord implements Comparable { /* * the following fields represent the UtTraceRecord struct's fields that * were written as the header to this file - */ + */ private BigInteger endTime = BigInteger.ZERO; BigInteger wrapTime = BigInteger.ZERO; BigInteger writePlatform = BigInteger.ZERO; private byte endTimeBytes[] = new byte[8]; private byte wrapTimeBytes[] = new byte[8]; BigInteger writeSystem = BigInteger.ZERO; - + long threadID; long threadSyn1; long threadSyn2; int firstEntry; int nextEntry; - String threadName = ""; + String threadName = ""; /* end of UtTraceRecord struct - see ute_internal.h */ private byte[] data; /* does the record start with a lostRecord. Valid once appendToStream has run */ boolean lostRecord = false; - + /* if a user discards records we can rely on lost record trace points so we record it here. * True means that data immediately prior to this record may have been discarded so we won't * try to merge with any partial data on the end of the stream */ boolean userDiscardedData = false; - + private static final byte userDiscardTracePoint[] = new byte[]{8, 0, 1, 0, 0, 0, 0, 0}; /* This is the size of the static portion of the tracerecord header, ie excluding the thread name */ public static final int TRACERECORD_HEADER_SIZE = 64; - + private static final int GUESSED_MAX_THREAD_NAME = 128; - + /* These fields are only used if this is a file backed trace record */ RandomAccessFile file; long offset; - + /* a record of the offsets that we've preprocessed to aid in debugging */ List debugOffsets = null; /** * This will create a TraceRecord from a byte array. The byte array must be of the correct length * for a trace record in this context. - * + * * @param data * @param context * @throws IllegalArgumentException @@ -87,7 +87,7 @@ public class TraceRecord implements Comparable { public TraceRecord(TraceContext context, byte[] data) throws IllegalArgumentException { this.context = context; this.data = data; - + if (data.length != context.getRecordSize()) { throw new IllegalArgumentException(); } @@ -95,10 +95,10 @@ public TraceRecord(TraceContext context, byte[] data) throws IllegalArgumentExce if (context.debugLevel > 0) { debugOffsets = new Vector(); } - + parseHeader(data); } - + public TraceRecord(TraceContext context, RandomAccessFile file, long offset) throws IOException, IllegalArgumentException { this.context = context; this.file = file; @@ -109,13 +109,13 @@ public TraceRecord(TraceContext context, RandomAccessFile file, long offset) thr if (context.debugLevel > 0) { debugOffsets = new Vector(); } - + while (required != 0) { /* should only run twice at most, and only more than once with thread * names of more than GUESSED_MAX_THREAD_NAME chars. */ byte data[] = new byte[required]; - + file.seek(offset); if (file.read(data) != data.length) { throw new IllegalArgumentException(); @@ -128,7 +128,7 @@ public TraceRecord(TraceContext context, RandomAccessFile file, long offset) thr context.debug(this, 3, summary()); } } - + private int parseHeader(byte[] data) throws IllegalArgumentException { ByteStream stream = context.createByteStream(data); @@ -138,14 +138,13 @@ private int parseHeader(byte[] data) throws IllegalArgumentException { wrapTime = stream.getBigInteger(8); writePlatform = stream.getBigInteger(8); writeSystem = stream.getBigInteger(8); - + threadID = stream.getLong(); threadSyn1 = stream.getLong(); threadSyn2 = stream.getLong(); firstEntry = stream.getInt(); nextEntry = stream.getInt(); - /* do some sanity checks */ String error = null; if (error == null && firstEntry < TRACERECORD_HEADER_SIZE) { @@ -176,7 +175,7 @@ private int parseHeader(byte[] data) throws IllegalArgumentException { return 0; } - + /** * This method ensures that if the record is backed by data in a file that the data is present in memory. * If it's not backed by a file it will return the current size of the records data array. @@ -191,13 +190,13 @@ private int load() { } int bytesRead = 0; - + try { file.seek(offset); bytesRead = file.read(data); if (bytesRead != data.length) { context.error(this, "couldn't read an entire record from the file"); - + if (bytesRead <= nextEntry) { return 0; } @@ -211,24 +210,24 @@ private int load() { System.arraycopy(data, 0, shrunk, 0, bytesRead); data = shrunk; } - + return bytesRead; } catch (IOException e) { context.error(this, "IOException while reading record at offset "+offset); context.error(this, e.getMessage()); - + return 0; } } - + return data.length; } - + /** * Appends the body of the data from this trace record to the stream IN * CHRONOLOGICAL ORDER. This means that if the buffer wrapped at all the * data will be reordered so that reading from the bytestream will return - * data correctly ordered for reading as a continuous temporal stream. + * data correctly ordered for reading as a continuous temporal stream. * @param stream - the stream onto which the record should be appended * @param newThread - indicates whether this is the first record on a thread * @return the number of bytes appended @@ -240,20 +239,20 @@ public int appendToStream(ByteStream stream, boolean newThread) { } context.totalRecords++; - + /* does the lostRecord tracepoint get written into the record that wrapped or * the one after? * If it's the latter can we put it at the start of the one that wrapped and * then spin in the remainder of the buffer? */ - + /* if we're spanning an entire record */ if (nextEntry == -1) { if (context.getTraceType() == TraceContext.EXTERNAL) { /* we can't yet fix up the length */ stream.setGuardBytes(stream.getGuardBytes() + data.length - firstEntry); stream.add(data, firstEntry); - + return data.length - firstEntry; } else { /* we can't deal with this for internal trace, but it could happen */ @@ -261,14 +260,13 @@ public int appendToStream(ByteStream stream, boolean newThread) { return 0; } } - + /* if we've a perfect fit in the buffer then nextEntry will be == buffersize. We want it to * point to the last byte in the buffer */ if (nextEntry == context.getRecordSize()) { nextEntry--; } - /* if this is an internal record that could have wrapped then glue it back together before we start fixing up trace points */ if (context.getTraceType() == TraceContext.INTERNAL) { @@ -277,17 +275,17 @@ public int appendToStream(ByteStream stream, boolean newThread) { System.arraycopy(data, pivotIndex, tmp, firstEntry, data.length - pivotIndex); System.arraycopy(data, firstEntry, tmp, data.length - pivotIndex + firstEntry, pivotIndex - firstEntry); - + nextEntry = data.length -1; data = tmp; } - + /* fix up the record, moving lengths to the front of the tracepoints */ int indexSource = nextEntry; int indexTarget = nextEntry; byte entryLengthSource = data[indexSource]; - + /* defect workaround for 147869 - out-by-one nextEntry value when a sequence wrap trace point is * written by the non-fastpath section of the trace writing code. */ @@ -300,7 +298,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { indexTarget--; nextEntry--; entryLengthSource = data[indexSource]; - + context.warning(this, "Fixed up misaligned sequence wrap trace point from defect 147869"); } } @@ -313,7 +311,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { */ int leadin = 0; - /* number of bytes reserved from earlier buffers */ + /* number of bytes reserved from earlier buffers */ int guardBytes = stream.getGuardBytes(); /* controls whether we're keeping or discarding the last bytes of the previous buffer and the first @@ -327,7 +325,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { * 3 bytes of id (0,0,0) * 4 bytes of timestamp * */ - byte startTimestamp[] = new byte[8]; + byte startTimestamp[] = new byte[8]; startTimestamp[0] = 8; startTimestamp[1] = 0; startTimestamp[2] = 0; @@ -336,10 +334,9 @@ public int appendToStream(ByteStream stream, boolean newThread) { if (context.metadata.byteOrder == ByteOrder.LITTLE_ENDIAN) { System.arraycopy(endTimeBytes, 4, startTimestamp, 4, 4); } else { - System.arraycopy(endTimeBytes, 0, startTimestamp, 4, 4); + System.arraycopy(endTimeBytes, 0, startTimestamp, 4, 4); } - - + /* if indexTarget == firstEntry then the length byte for the previous record is the first byte * in this and we need to do the fixup. */ @@ -368,7 +365,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { /* this is a special tracepoint, indicating that the tracepoint preceding this in the * buffer has a length that can't be stored in a single byte. Instead the length is * a short that is constructed from two non-contiguous bytes. - * + * * The length for this special tracepoint specifies that it's 4 bytes long, however it * is actually only 3bytes. Byte [0] is the length byte for the regular tracepoint that * it corresponds to and contains the low order bits, [1] and [2] are null, [3] contains @@ -377,7 +374,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { */ byte longTPSize[] = new byte[4]; - + /* is the entire special trace point in this record? */ if (indexTarget < firstEntry) { /* nope, so retrieve what's missing */ @@ -399,7 +396,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { discard = true; break; } - + System.arraycopy(missing, 0, longTPSize, 0, missing.length); System.arraycopy(data, firstEntry, longTPSize, missing.length, 4 - missing.length); } else { @@ -412,10 +409,9 @@ public int appendToStream(ByteStream stream, boolean newThread) { /* what's the target index of the actual tracepoint? */ byte highBits = longTPSize[3]; byte lowBits = longTPSize[0]; - + len = (((highBits & 0xff)<< 8) | (lowBits & 0xff)); - - + /* sanity check the mid bytes */ if (longTPSize[1] != '\0' || longTPSize[2] != '\0') { if (indexTarget < firstEntry) { @@ -426,7 +422,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { } else { context.error(this, "center 2 bytes for long tracepoint are not null, discarding remaining data"); } - + /* we don't want to process any more no matter where we are because we'll just put * garbage into the stream */ @@ -443,7 +439,6 @@ public int appendToStream(ByteStream stream, boolean newThread) { */ indexTarget = indexSource - 4 - len; - /* if it fits in the buffer then we operate in place. We check against firstEntry -1 because if we're only one * over then it's just the length byte and we discard the trailing null from the previous buffer we when fall though * into the regular tracepoint processing @@ -471,7 +466,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { discard = true; break; } - + if (localLen > 0) { /* move the data in this record up over the 4 bytes of the special */ System.arraycopy(data, firstEntry, data, firstEntry + 4, localLen); @@ -499,7 +494,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { System.arraycopy(startTimestamp, 1, data, indexTarget + 1, 7); startTimestamp = timestamp; - + /* DEBUG accounting */ if (context.debugLevel > 0) { debugOffsets.add(Integer.valueOf(indexTarget)); @@ -544,14 +539,13 @@ public int appendToStream(ByteStream stream, boolean newThread) { context.debug(this, 5, "fixing up special tracepoint, length "+len); } } - - + byte entryLengthTarget = data[indexTarget]; data[indexTarget] = entryLengthSource; entryLengthSource = entryLengthTarget; - + indexSource = indexTarget; - + /* DEBUG accounting */ if (context.debugLevel > 0) { debugOffsets.add(Integer.valueOf(indexTarget)); @@ -561,12 +555,12 @@ public int appendToStream(ByteStream stream, boolean newThread) { * data. In the case we've flushed the record before hand there may be dangling data from the * preceding record that we want to discard. */ - + /* this discards dangling data and also the trailing length byte which we no longer need */ if (guardBytes > 0) { discard = true; } - + /* we use that empty space at firstEntry to hold the length */ data[indexTarget] = entryLengthSource; /* so that we add the first tracepoint */ @@ -583,25 +577,25 @@ public int appendToStream(ByteStream stream, boolean newThread) { * spilled from the preceding buffer so we fix up the current tracepoint, then test this again * when indexTarget will be negative. */ - + /* we do exactly the same here as we would for a tracepoint that fits entirely */ byte entryLengthTarget = data[indexTarget]; data[indexTarget] = entryLengthSource; entryLengthSource = entryLengthTarget; - + indexSource = indexTarget; } else { /* indexTarget < firstEntry */ if (context.getTraceType() == TraceContext.EXTERNAL) { - + int negativeOffset = indexTarget - firstEntry - leadin; if (context.debugStream != null) { context.debug(this, 5, "Negative offset for fixup is "+negativeOffset); } - + if (negativeOffset == -1) { /* the tracepoint is entirely in this record, it's just the length we're trying to promote */ - + if (guardBytes == 1) { /* get rid of the 0'd length byte at the end of the stream that we're expecting */ stream.truncate(1); @@ -610,16 +604,16 @@ public int appendToStream(ByteStream stream, boolean newThread) { /* we're discarding more data than anticipated */ discard = true; } - + /* put the length into firstEntry -1 as we're done with the header data */ data[indexTarget] = entryLengthSource; indexSource = indexTarget; - + /* DEBUG accounting */ if (context.debugLevel > 0) { debugOffsets.add(Integer.valueOf(indexTarget)); } - } else { + } else { if (guardBytes + negativeOffset != 0 || userDiscardedData) { discard = true; } else { @@ -628,7 +622,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { } try { byte b = stream.put(entryLengthSource, negativeOffset); - + if (b != '\0') { discard = true; } else { @@ -636,7 +630,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { context.debug(this, 5, "successfully fixed up earlier buffer"); } discard = false; - + /* DEBUG accounting */ if (context.debugLevel > 0) { debugOffsets.add(Integer.valueOf(indexTarget)); @@ -655,7 +649,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { stream.add(data, firstEntry + leadin, indexSource - firstEntry - leadin); } } - + /* we're done with this record */ break; } @@ -672,7 +666,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { discard = true; } } - + context.totalTracePoints++; } @@ -682,7 +676,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { * a. missing data inbetween the end of the stream and the start of this buffer * b. corrupted trace data * c. incorrect parsing - * + * * We throw away the mismatched parts as they're inconsistent. */ long expected = Math.abs(indexTarget - firstEntry - leadin); @@ -707,7 +701,7 @@ public int appendToStream(ByteStream stream, boolean newThread) { } } } - + /* figure out how many bytes at the end of the record could be the start of a spanning * tracepoint and guard them */ @@ -731,11 +725,11 @@ public int appendToStream(ByteStream stream, boolean newThread) { public String toString() { return getIdentifier(); } - + private String getIdentifier() { return (threadID + threadName).intern(); } - + public String summary() { if (textSummary == null) { StringBuilder s = new StringBuilder("TraceRecord:"+System.getProperty("line.separator")); @@ -745,9 +739,9 @@ public String summary() { } else { s.append("non file data").append(System.getProperty("line.separator")); } - + s.append("internal id: ").append(toString()).append(System.getProperty("line.separator")); - + s.append("endTime: ").append(endTime).append(System.getProperty("line.separator")); s.append("wrapTime: ").append(wrapTime).append(System.getProperty("line.separator")); s.append("writePlatform: ").append(writePlatform).append(System.getProperty("line.separator")); diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceSection.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceSection.java index 57980de7b86..d7b446d572f 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceSection.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceSection.java @@ -27,7 +27,7 @@ /** * Trace section of a file header. - * + * * @author Tim Preece */ public class TraceSection { @@ -58,11 +58,11 @@ public TraceSection(TraceContext context, ByteBuffer data) throws IllegalArgumen context.debug(this, 1, summary()); } } - + public String toString() { return "Trace file header"; } - + public String summary() { if (textSummary == null) { StringBuilder s = new StringBuilder(toString()+":"+System.getProperty("line.separator")); diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceThread.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceThread.java index 29df97f6389..0d60be99269 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceThread.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/TraceThread.java @@ -51,20 +51,20 @@ public class TraceThread implements Comparable { TracePointImpl live = null; ThreadIterator iterator; - - Vector records = new Vector(); + + Vector records = new Vector(); /* if a user discards records we can rely on lost record trace points so we record it here. * True means that data immediately after the current contents of the threads stream has been * discarded and that there are no records in the store in which to record the fact. */ boolean userDiscardedData = false; - + /* To aid in debugging, this holds the record number and offset of the preprocessed length from * appendToStream for the current record. */ List debugOffsets = new Vector(); - + class ThreadIterator implements Iterator { MissingDataException lostBytes; TraceThread thread; @@ -83,12 +83,12 @@ public boolean hasNext() { * where there's no more tracepoints available as it's possible * more will become available on this iterator in the future. * Instead null is returned. - * + * * MissingDataException (that extends NoSuchElementException) is * thrown if there was data missing where the next tracepoint * was expected. The iterator remains valid and will continue to * return tracepoints after the missing data. - * + * * @see java.util.Iterator#next() */ public Object next() throws MissingDataException { @@ -201,7 +201,7 @@ record = (TraceRecord)records.firstElement(); /* record the time of the most recent record that's been appended. While in the records store * the order of addition doesn't matter, but once appended the ordering is fixed for records - * earlier than this time stamp. + * earlier than this time stamp. */ newestWrapTime = record.wrapTime; @@ -270,7 +270,7 @@ record = (TraceRecord)records.firstElement(); * when we run out of data in the current record we append another from the store rather than reporting * an underflow. This allows the adding of all records from trace files before processing starts. * This method maintains ordering in the list - * + * * @param record */ synchronized protected void addRecord(TraceRecord record) throws IllegalArgumentException { @@ -279,7 +279,7 @@ synchronized protected void addRecord(TraceRecord record) throws IllegalArgument * ones we've had on this thread */ int i = 1; - + /* if it's been noted that there was user discarded data then propagate that to the record */ if (userDiscardedData) { record.userDiscardedData = true; @@ -288,16 +288,16 @@ synchronized protected void addRecord(TraceRecord record) throws IllegalArgument records.add(record); } - + /** * This records the fact that we've been told that the user discarded data at this point in the series of records. * This fact will be tagged onto the next record to be added to the thread and will cause a lost record trace point - * to be injected + * to be injected */ synchronized void userDiscardedData() { userDiscardedData = true; } - + public int compareTo(Object obj) { TraceThread thread = (TraceThread)obj; diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/package-info.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/package-info.java index 10cd571a4e4..38aa94dfc82 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/package-info.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/trace/format/api/package-info.java @@ -85,4 +85,3 @@ * } */ package com.ibm.jvm.trace.format.api; - diff --git a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/traceformat/TraceFormat.java b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/traceformat/TraceFormat.java index e9810196ba1..337be96f400 100644 --- a/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/traceformat/TraceFormat.java +++ b/jcl/src/openj9.traceformat/share/classes/com/ibm/jvm/traceformat/TraceFormat.java @@ -654,11 +654,11 @@ void setValue(String value) throws IllegalArgumentException { if (value.length() != 6) { // initial validation, string length must be 6 throw new NumberFormatException(); } - int hours = Integer.parseInt(value.substring(1,3)); - int minutes = Integer.parseInt(value.substring(4,6)); - if ((hours > 12) || (minutes > 60)) { - throw new NumberFormatException(); - } + int hours = Integer.parseInt(value.substring(1, 3)); + int minutes = Integer.parseInt(value.substring(4, 6)); + if ((hours > 12) || (minutes > 60)) { + throw new NumberFormatException(); + } timezone = (hours * 60) + minutes; if (value.substring(0,1).equals("-")) { timezone = -timezone; @@ -759,7 +759,6 @@ void setDefault() { } } - class InputFile extends ProgramOption { List inputFiles = new LinkedList(); @@ -960,7 +959,6 @@ void setAutomatic() { throw new IllegalArgumentException("Value must be specified for "+getName()); } - /* If an option is allowed but isn't specified on the command line the it is still added to the * options set, but with it's default value. If a subclass describes an optional argument then this * method should be overridden with a default value. @@ -1001,7 +999,6 @@ static void addArgument(String arg) throws IllegalArgumentException { return; } - /* fast path to check if help is specified */ if (key.equals("help")) { throw new IllegalArgumentException(help()); @@ -1045,7 +1042,6 @@ static void addArgument(String arg) throws IllegalArgumentException { throw new IllegalArgumentException("Usage error: unknown argument, \""+arg+"\""+System.getProperty("line.separator")+System.getProperty("line.separator")+help()); } - /* For all options that weren't specified in any way on the command line, add their default values. If * a required option was omitted this will throw an exception. */ From dcbd3c1213511446481330a1407963a215e5040d Mon Sep 17 00:00:00 2001 From: "Keith W. Campbell" Date: Fri, 6 Sep 2024 17:08:54 -0400 Subject: [PATCH 16/16] Tidy up whitespace in openj9.zosconditionhandling * remove trailing whitespace Signed-off-by: Keith W. Campbell --- .../conditionhandling/ConditionException.java | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/jcl/src/openj9.zosconditionhandling/share/classes/com/ibm/le/conditionhandling/ConditionException.java b/jcl/src/openj9.zosconditionhandling/share/classes/com/ibm/le/conditionhandling/ConditionException.java index 4adf42c037d..a2965041423 100644 --- a/jcl/src/openj9.zosconditionhandling/share/classes/com/ibm/le/conditionhandling/ConditionException.java +++ b/jcl/src/openj9.zosconditionhandling/share/classes/com/ibm/le/conditionhandling/ConditionException.java @@ -27,7 +27,7 @@ /** * A ConditionException is used to represent a z/OS Language Environment condition. *

    - * References + * References *

      *
    • z/OS Language Environment Programming Reference: CEEDCOD-Decompose a condition token *
    • z/OS XL C/C++ Run-Time Library Reference: __le_condition_token_build() @@ -36,7 +36,7 @@ */ public class ConditionException extends RuntimeException { - + static final long serialVersionUID = -6740638630352857974L; private String failingRoutine; private long offset; @@ -50,20 +50,20 @@ public class ConditionException extends RuntimeException { private long iSInfo; /** - * + * * This constructor is intentionally not public so that only the JVM can instantiate a ConditionException - * + * * @param failingRoutine The routine that triggered the condition * @param offset This offset into the routine where the condition was triggered * @param rawTokenBytes The raw bytes representing the condition token * @param facilityID The condition's facility ID - * @param c1 c_1, as stored in the condition token + * @param c1 c_1, as stored in the condition token * @param c2 c_2, as stored in the condition token * @param caze The condition's case * @param severity The condition's severity - * @param control The condition's control field + * @param control The condition's control field * @param iSInfo The condition's ISI - * + * */ ConditionException(String failingRoutine, long offset, byte []rawTokenBytes, String facilityID, int c1, int c2, int caze, int severity, int control, long iSInfo) { @@ -76,75 +76,75 @@ public class ConditionException extends RuntimeException { this.caze = caze; this.severity = severity; this.control = control; - this.iSInfo = iSInfo; + this.iSInfo = iSInfo; } /** * Returns the condition's facility ID. - * + * * @return the condition's facility ID */ public String getFacilityID() { return facilityID; } - + /** * Returns c_1, as stored in the condition token. - * + * * @return c_1, as stored in the condition token */ public int getC1() { return c1; } - + /** * Returns c_2, as stored in the condition token. - * + * * @return c_2, as stored in the condition token */ public int getC2() { return c2; } - + /** * Returns the format of c_1 and c_2. - * - * @return the format of c_1 and c_2 + * + * @return the format of c_1 and c_2 */ public int getCase() { return caze; } - + /** * Returns the condition's control field. - * + * * @return the condition's control field */ public int getControl() { return control; } - + /** * Returns the condition's severity. - * + * * @return the condition's severity */ public int getSeverity() { return severity; } - + /** * Returns the condition's ISI. - * + * * @return the condition's ISI */ public long getISInfo() { return iSInfo; } - + /** * Returns the raw 12-byte representation of the condition. - * + * * @return the raw 12-byte representation of the condition */ public byte[] getToken() { @@ -153,7 +153,7 @@ public byte[] getToken() { /** * Returns the condition's message number. - * + * * @return the condition's message number */ public int getMessageNumber() { @@ -162,16 +162,16 @@ public int getMessageNumber() { /** * Returns the routine that triggered the condition. - * + * * @return the routine that triggered the condition */ public String getRoutine() { return failingRoutine; } - + /** * Returns the offset into the routine that triggered the condition. - * + * * @return the offset into the routine that triggered the condition */ public long getOffsetInRoutine() {