Skip to content

Commit 07a8620

Browse files
JoshRosenrxin
authored andcommitted
[SPARK-7288] Suppress compiler warnings due to use of sun.misc.Unsafe; add facade in front of Unsafe; remove use of Unsafe.setMemory
This patch suppresses compiler warnings due to our use of `sun.misc.Unsafe` (introduced in apache#5725). These warnings can only be suppressed via the `-XDignore.symbol.file` javac flag; the `SuppressWarnings` annotation won't work for these. In order to restrict uses of this compiler flag to the `unsafe` module, I placed a facade in front of `Unsafe` so that other modules won't call it directly. This facade also will also help us to avoid accidental usage of deprecated Unsafe methods or methods that aren't supported in Java 6. I also removed an unnecessary use of `Unsafe.setMemory`, which isn't present in certain versions of Java 6, and excluded the new `unsafe` module from Javadoc. Author: Josh Rosen <[email protected]> Closes apache#5814 from JoshRosen/unsafe-compiler-warnings-fixes and squashes the following commits: 9e8c483 [Josh Rosen] Exclude new unsafe module from Javadoc ba75ecf [Josh Rosen] Only apply -XDignore.symbol.file flag in unsafe project. 7403345 [Josh Rosen] Put facade in front of Unsafe. 50230c0 [Josh Rosen] Remove usage of Unsafe.setMemory 96d41c9 [Josh Rosen] Use -XDignore.symbol.file to suppress warnings about sun.misc.Unsafe usage
1 parent 6702324 commit 07a8620

File tree

7 files changed

+125
-24
lines changed

7 files changed

+125
-24
lines changed

project/SparkBuild.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ object SparkBuild extends PomBuild {
163163
x => enable(MimaBuild.mimaSettings(sparkHome, x))(x)
164164
}
165165

166+
/* Unsafe settings */
167+
enable(Unsafe.settings)(unsafe)
168+
166169
/* Enable Assembly for all assembly projects */
167170
assemblyProjects.foreach(enable(Assembly.settings))
168171

@@ -216,6 +219,13 @@ object SparkBuild extends PomBuild {
216219

217220
}
218221

222+
object Unsafe {
223+
lazy val settings = Seq(
224+
// This option is needed to suppress warnings from sun.misc.Unsafe usage
225+
javacOptions in Compile += "-XDignore.symbol.file"
226+
)
227+
}
228+
219229
object Flume {
220230
lazy val settings = sbtavro.SbtAvro.avroSettings
221231
}
@@ -424,6 +434,7 @@ object Unidoc {
424434
.map(_.filterNot(_.getCanonicalPath.contains("org/apache/spark/network")))
425435
.map(_.filterNot(_.getCanonicalPath.contains("org/apache/spark/shuffle")))
426436
.map(_.filterNot(_.getCanonicalPath.contains("org/apache/spark/executor")))
437+
.map(_.filterNot(_.getCanonicalPath.contains("org/apache/spark/unsafe")))
427438
.map(_.filterNot(_.getCanonicalPath.contains("python")))
428439
.map(_.filterNot(_.getCanonicalPath.contains("org/apache/spark/util/collection")))
429440
.map(_.filterNot(_.getCanonicalPath.contains("org/apache/spark/sql/catalyst")))

unsafe/pom.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,29 @@
6565
<build>
6666
<outputDirectory>target/scala-${scala.binary.version}/classes</outputDirectory>
6767
<testOutputDirectory>target/scala-${scala.binary.version}/test-classes</testOutputDirectory>
68+
<pluginManagement>
69+
<plugins>
70+
<plugin>
71+
<groupId>net.alchim31.maven</groupId>
72+
<artifactId>scala-maven-plugin</artifactId>
73+
<configuration>
74+
<javacArgs>
75+
<!-- This option is needed to suppress warnings from sun.misc.Unsafe usage -->
76+
<javacArg>-XDignore.symbol.file</javacArg>
77+
</javacArgs>
78+
</configuration>
79+
</plugin>
80+
<plugin>
81+
<groupId>org.apache.maven.plugins</groupId>
82+
<artifactId>maven-compiler-plugin</artifactId>
83+
<configuration>
84+
<compilerArgs>
85+
<!-- This option is needed to suppress warnings from sun.misc.Unsafe usage -->
86+
<arg>-XDignore.symbol.file</arg>
87+
</compilerArgs>
88+
</configuration>
89+
</plugin>
90+
</plugins>
91+
</pluginManagement>
6892
</build>
6993
</project>

unsafe/src/main/java/org/apache/spark/unsafe/PlatformDependent.java

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,82 @@
2323

2424
public final class PlatformDependent {
2525

26-
public static final Unsafe UNSAFE;
26+
/**
27+
* Facade in front of {@link sun.misc.Unsafe}, used to avoid directly exposing Unsafe outside of
28+
* this package. This also lets us aovid accidental use of deprecated methods or methods that
29+
* aren't present in Java 6.
30+
*/
31+
public static final class UNSAFE {
32+
33+
private UNSAFE() { }
34+
35+
public static int getInt(Object object, long offset) {
36+
return _UNSAFE.getInt(object, offset);
37+
}
38+
39+
public static void putInt(Object object, long offset, int value) {
40+
_UNSAFE.putInt(object, offset, value);
41+
}
42+
43+
public static boolean getBoolean(Object object, long offset) {
44+
return _UNSAFE.getBoolean(object, offset);
45+
}
46+
47+
public static void putBoolean(Object object, long offset, boolean value) {
48+
_UNSAFE.putBoolean(object, offset, value);
49+
}
50+
51+
public static byte getByte(Object object, long offset) {
52+
return _UNSAFE.getByte(object, offset);
53+
}
54+
55+
public static void putByte(Object object, long offset, byte value) {
56+
_UNSAFE.putByte(object, offset, value);
57+
}
58+
59+
public static short getShort(Object object, long offset) {
60+
return _UNSAFE.getShort(object, offset);
61+
}
62+
63+
public static void putShort(Object object, long offset, short value) {
64+
_UNSAFE.putShort(object, offset, value);
65+
}
66+
67+
public static long getLong(Object object, long offset) {
68+
return _UNSAFE.getLong(object, offset);
69+
}
70+
71+
public static void putLong(Object object, long offset, long value) {
72+
_UNSAFE.putLong(object, offset, value);
73+
}
74+
75+
public static float getFloat(Object object, long offset) {
76+
return _UNSAFE.getFloat(object, offset);
77+
}
78+
79+
public static void putFloat(Object object, long offset, float value) {
80+
_UNSAFE.putFloat(object, offset, value);
81+
}
82+
83+
public static double getDouble(Object object, long offset) {
84+
return _UNSAFE.getDouble(object, offset);
85+
}
86+
87+
public static void putDouble(Object object, long offset, double value) {
88+
_UNSAFE.putDouble(object, offset, value);
89+
}
90+
91+
public static long allocateMemory(long size) {
92+
return _UNSAFE.allocateMemory(size);
93+
}
94+
95+
public static void freeMemory(long address) {
96+
_UNSAFE.freeMemory(address);
97+
}
98+
99+
}
100+
101+
private static final Unsafe _UNSAFE;
27102

28103
public static final int BYTE_ARRAY_OFFSET;
29104

@@ -48,13 +123,13 @@ public final class PlatformDependent {
48123
} catch (Throwable cause) {
49124
unsafe = null;
50125
}
51-
UNSAFE = unsafe;
126+
_UNSAFE = unsafe;
52127

53-
if (UNSAFE != null) {
54-
BYTE_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
55-
INT_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(int[].class);
56-
LONG_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(long[].class);
57-
DOUBLE_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(double[].class);
128+
if (_UNSAFE != null) {
129+
BYTE_ARRAY_OFFSET = _UNSAFE.arrayBaseOffset(byte[].class);
130+
INT_ARRAY_OFFSET = _UNSAFE.arrayBaseOffset(int[].class);
131+
LONG_ARRAY_OFFSET = _UNSAFE.arrayBaseOffset(long[].class);
132+
DOUBLE_ARRAY_OFFSET = _UNSAFE.arrayBaseOffset(double[].class);
58133
} else {
59134
BYTE_ARRAY_OFFSET = 0;
60135
INT_ARRAY_OFFSET = 0;
@@ -71,7 +146,7 @@ static public void copyMemory(
71146
long length) {
72147
while (length > 0) {
73148
long size = Math.min(length, UNSAFE_COPY_THRESHOLD);
74-
UNSAFE.copyMemory(src, srcOffset, dst, dstOffset, size);
149+
_UNSAFE.copyMemory(src, srcOffset, dst, dstOffset, size);
75150
length -= size;
76151
srcOffset += size;
77152
dstOffset += size;
@@ -82,6 +157,6 @@ static public void copyMemory(
82157
* Raises an exception bypassing compiler checks for checked exceptions.
83158
*/
84159
public static void throwException(Throwable t) {
85-
UNSAFE.throwException(t);
160+
_UNSAFE.throwException(t);
86161
}
87162
}

unsafe/src/main/java/org/apache/spark/unsafe/map/BytesToBytesMap.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,11 @@ public void putNewKey(
401401

402402
// Copy the key
403403
PlatformDependent.UNSAFE.putLong(pageBaseObject, keySizeOffsetInPage, keyLengthBytes);
404-
PlatformDependent.UNSAFE.copyMemory(
404+
PlatformDependent.copyMemory(
405405
keyBaseObject, keyBaseOffset, pageBaseObject, keyDataOffsetInPage, keyLengthBytes);
406406
// Copy the value
407407
PlatformDependent.UNSAFE.putLong(pageBaseObject, valueSizeOffsetInPage, valueLengthBytes);
408-
PlatformDependent.UNSAFE.copyMemory(
408+
PlatformDependent.copyMemory(
409409
valueBaseObject, valueBaseOffset, pageBaseObject, valueDataOffsetInPage, valueLengthBytes);
410410

411411
final long storedKeyAddress = memoryManager.encodePageNumberAndOffset(
@@ -429,7 +429,7 @@ public void putNewKey(
429429
private void allocate(int capacity) {
430430
capacity = Math.max((int) Math.min(Integer.MAX_VALUE, nextPowerOf2(capacity)), 64);
431431
longArray = new LongArray(memoryManager.allocate(capacity * 8 * 2));
432-
bitset = new BitSet(memoryManager.allocate(capacity / 8).zero());
432+
bitset = new BitSet(MemoryBlock.fromLongArray(new long[capacity / 64]));
433433

434434
this.growthThreshold = (int) (capacity * loadFactor);
435435
this.mask = capacity - 1;
@@ -447,7 +447,7 @@ public void free() {
447447
longArray = null;
448448
}
449449
if (bitset != null) {
450-
memoryManager.free(bitset.memoryBlock());
450+
// The bitset's heap memory isn't managed by a memory manager, so no need to free it here.
451451
bitset = null;
452452
}
453453
Iterator<MemoryBlock> dataPagesIterator = dataPages.iterator();
@@ -535,7 +535,6 @@ private void growAndRehash() {
535535

536536
// Deallocate the old data structures.
537537
memoryManager.free(oldLongArray.memoryBlock());
538-
memoryManager.free(oldBitSet.memoryBlock());
539538
if (enablePerfMetrics) {
540539
timeSpentResizingNs += System.nanoTime() - resizeStartTime;
541540
}

unsafe/src/main/java/org/apache/spark/unsafe/memory/MemoryBlock.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,6 @@ public long size() {
4646
return length;
4747
}
4848

49-
/**
50-
* Clear the contents of this memory block. Returns `this` to facilitate chaining.
51-
*/
52-
public MemoryBlock zero() {
53-
PlatformDependent.UNSAFE.setMemory(obj, offset, length, (byte) 0);
54-
return this;
55-
}
56-
5749
/**
5850
* Creates a memory block pointing to the memory used by the long array.
5951
*/

unsafe/src/test/java/org/apache/spark/unsafe/bitset/BitSetSuite.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class BitSetSuite {
2727

2828
private static BitSet createBitSet(int capacity) {
2929
assert capacity % 64 == 0;
30-
return new BitSet(MemoryBlock.fromLongArray(new long[capacity / 64]).zero());
30+
return new BitSet(MemoryBlock.fromLongArray(new long[capacity / 64]));
3131
}
3232

3333
@Test

unsafe/src/test/java/org/apache/spark/unsafe/map/AbstractBytesToBytesMapSuite.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void tearDown() {
5757

5858
private static byte[] getByteArray(MemoryLocation loc, int size) {
5959
final byte[] arr = new byte[size];
60-
PlatformDependent.UNSAFE.copyMemory(
60+
PlatformDependent.copyMemory(
6161
loc.getBaseObject(),
6262
loc.getBaseOffset(),
6363
arr,

0 commit comments

Comments
 (0)