From 0c50b210738a2d3facb53598a7208d456f214364 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Mon, 1 Jan 2018 02:15:40 +0100 Subject: Restore exec files compatibility regarding Java 9 class files (#636) --- .../src/org/jacoco/core/analysis/Analyzer.java | 2 +- .../src/org/jacoco/core/internal/data/CRC64.java | 60 ++++++++++++++++++---- .../internal/instr/ProbeArrayStrategyFactory.java | 2 +- 3 files changed, 52 insertions(+), 12 deletions(-) (limited to 'org.jacoco.core/src') diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java index 32384b86..5d1a9262 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java @@ -107,7 +107,7 @@ public class Analyzer { */ public void analyzeClass(final ClassReader reader) { final ClassVisitor visitor = createAnalyzingVisitor( - CRC64.checksum(reader.b), reader.getClassName()); + CRC64.classId(reader.b), reader.getClassName()); reader.accept(visitor, 0); } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java b/org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java index 64cb18ae..5094c709 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.jacoco.core.internal.data; +import org.objectweb.asm.Opcodes; + /** * CRC64 checksum calculator based on the polynom specified in ISO 3309. The * implementation is based on the following publications: @@ -42,21 +44,59 @@ public final class CRC64 { } /** - * Calculates the CRC64 checksum for the given data array. - * - * @param data - * data to calculate checksum for - * @return checksum value + * Updates given checksum by given byte. + * + * @param sum + * initial checksum value + * @param b + * byte to update the checksum with + * @return updated checksum value + */ + private static long update(final long sum, final byte b) { + final int lookupidx = ((int) sum ^ b) & 0xff; + return (sum >>> 8) ^ LOOKUPTABLE[lookupidx]; + } + + /** + * Updates given checksum by bytes from given array. + * + * @param sum + * initial checksum value + * @param bytes + * byte array to update the checksum with + * @param fromIndexInclusive + * start index in array, inclusive + * @param toIndexExclusive + * end index in array, exclusive + * @return updated checksum value */ - public static long checksum(final byte[] data) { - long sum = 0; - for (final byte b : data) { - final int lookupidx = ((int) sum ^ b) & 0xff; - sum = (sum >>> 8) ^ LOOKUPTABLE[lookupidx]; + private static long update(long sum, final byte[] bytes, + final int fromIndexInclusive, final int toIndexExclusive) { + for (int i = fromIndexInclusive; i < toIndexExclusive; i++) { + sum = update(sum, bytes[i]); } return sum; } + /** + * Calculates class identifier for the given class bytes. + * + * @param bytes + * class bytes + * @return class identifier + */ + public static long classId(final byte[] bytes) { + if (bytes.length > 7 && bytes[6] == 0x00 && bytes[7] == Opcodes.V9) { + // To support early versions of Java 9 we did a trick - change of + // Java 9 class files version on Java 8. Unfortunately this also + // affected class identifiers. + long sum = update(0, bytes, 0, 7); + sum = update(sum, (byte) Opcodes.V1_8); + return update(sum, bytes, 8, bytes.length); + } + return update(0, bytes, 0, bytes.length); + } + private CRC64() { } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeArrayStrategyFactory.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeArrayStrategyFactory.java index d5f4d49d..9ec2730b 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeArrayStrategyFactory.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeArrayStrategyFactory.java @@ -42,7 +42,7 @@ public final class ProbeArrayStrategyFactory { final String className = reader.getClassName(); final int version = getVersion(reader); - final long classId = CRC64.checksum(reader.b); + final long classId = CRC64.classId(reader.b); final boolean withFrames = version >= Opcodes.V1_6; if (isInterfaceOrModule(reader)) { -- cgit v1.2.3