Mercurial > hg > truffle
comparison graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/UnsafeArrayTypeWriter.java @ 20832:43b3db5e8a9e
UnsafeArrayType(Writer|Reader): Use naturally aligned Unsafe access (Important for SPARC)
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Thu, 09 Apr 2015 15:35:29 +0200 |
parents | 5bf195ce816a |
children | 220ecaa0cc9b |
comparison
equal
deleted
inserted
replaced
20830:4dbbc4b3bb4d | 20832:43b3db5e8a9e |
---|---|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 * or visit www.oracle.com if you need additional information or have any | 20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. | 21 * questions. |
22 */ | 22 */ |
23 package com.oracle.graal.compiler.common.util; | 23 package com.oracle.graal.compiler.common.util; |
24 | |
25 import static com.oracle.graal.compiler.common.util.TypeConversion.*; | |
26 | |
27 import java.nio.*; | |
24 | 28 |
25 import sun.misc.*; | 29 import sun.misc.*; |
26 | 30 |
27 import com.oracle.graal.compiler.common.*; | 31 import com.oracle.graal.compiler.common.*; |
28 | 32 |
70 } | 74 } |
71 | 75 |
72 @Override | 76 @Override |
73 public void putS1(long value) { | 77 public void putS1(long value) { |
74 long offset = writeOffset(Byte.BYTES); | 78 long offset = writeOffset(Byte.BYTES); |
75 UnsafeAccess.unsafe.putByte(writeChunk.data, offset, TypeConversion.asS1(value)); | 79 UnsafeAccess.unsafe.putByte(writeChunk.data, offset, asS1(value)); |
80 commitWrite(Byte.BYTES); | |
76 } | 81 } |
77 | 82 |
78 @Override | 83 @Override |
79 public void putU1(long value) { | 84 public void putU1(long value) { |
80 long offset = writeOffset(Byte.BYTES); | 85 long offset = writeOffset(Byte.BYTES); |
81 UnsafeAccess.unsafe.putByte(writeChunk.data, offset, TypeConversion.asU1(value)); | 86 UnsafeAccess.unsafe.putByte(writeChunk.data, offset, asU1(value)); |
87 commitWrite(Byte.BYTES); | |
82 } | 88 } |
83 | 89 |
84 @Override | 90 @Override |
85 public void putS2(long value) { | 91 public void putS2(long value) { |
86 long offset = writeOffset(Short.BYTES); | 92 long offset = writeOffset(Short.BYTES); |
87 UnsafeAccess.unsafe.putShort(writeChunk.data, offset, TypeConversion.asS2(value)); | 93 if (offset % Short.BYTES == 0) { |
94 UnsafeAccess.unsafe.putShort(writeChunk.data, offset, asS2(value)); | |
95 commitWrite(Short.BYTES); | |
96 } else { | |
97 ByteBuffer buf = ByteBuffer.wrap(new byte[Short.BYTES]); | |
98 buf.putShort(asS2(value)); | |
99 putS1(buf.get(0)); | |
100 putS1(buf.get(Byte.BYTES)); | |
101 } | |
88 } | 102 } |
89 | 103 |
90 @Override | 104 @Override |
91 public void putU2(long value) { | 105 public void putU2(long value) { |
92 long offset = writeOffset(Short.BYTES); | 106 putS2(asU2(value)); |
93 UnsafeAccess.unsafe.putShort(writeChunk.data, offset, TypeConversion.asU2(value)); | |
94 } | 107 } |
95 | 108 |
96 @Override | 109 @Override |
97 public void putS4(long value) { | 110 public void putS4(long value) { |
98 long offset = writeOffset(Integer.BYTES); | 111 long offset = writeOffset(Integer.BYTES); |
99 UnsafeAccess.unsafe.putInt(writeChunk.data, offset, TypeConversion.asS4(value)); | 112 if (offset % Integer.BYTES == 0) { |
113 UnsafeAccess.unsafe.putInt(writeChunk.data, offset, asS4(value)); | |
114 commitWrite(Integer.BYTES); | |
115 } else { | |
116 ByteBuffer buf = ByteBuffer.wrap(new byte[Integer.BYTES]); | |
117 buf.putInt(asS4(value)); | |
118 if (offset % Short.BYTES == 0) { | |
119 putS2(buf.getShort(0)); | |
120 putS2(buf.getShort(2)); | |
121 } else { | |
122 putS1(buf.get(0)); | |
123 putS2(buf.getShort(1)); | |
124 putS1(buf.get(3)); | |
125 } | |
126 } | |
100 } | 127 } |
101 | 128 |
102 @Override | 129 @Override |
103 public void putU4(long value) { | 130 public void putU4(long value) { |
104 long offset = writeOffset(Integer.BYTES); | 131 putS4(asU4(value)); |
105 UnsafeAccess.unsafe.putInt(writeChunk.data, offset, TypeConversion.asU4(value)); | |
106 } | 132 } |
107 | 133 |
108 @Override | 134 @Override |
109 public void putS8(long value) { | 135 public void putS8(long value) { |
110 long offset = writeOffset(Long.BYTES); | 136 long offset = writeOffset(Long.BYTES); |
111 UnsafeAccess.unsafe.putLong(writeChunk.data, offset, value); | 137 if (offset % Long.BYTES == 0) { |
138 UnsafeAccess.unsafe.putLong(writeChunk.data, offset, value); | |
139 commitWrite(Long.BYTES); | |
140 } else { | |
141 ByteBuffer buf = ByteBuffer.wrap(new byte[Long.BYTES]); | |
142 buf.putLong(value); | |
143 if (offset % Integer.BYTES == 0) { | |
144 putS4(buf.getInt(0)); | |
145 putS4(buf.getInt(4)); | |
146 } else { | |
147 putS2(buf.getShort(0)); | |
148 putS4(buf.getInt(2)); | |
149 putS2(buf.getShort(6)); | |
150 } | |
151 } | |
112 } | 152 } |
113 | 153 |
114 private long writeOffset(int writeBytes) { | 154 private long writeOffset(int writeBytes) { |
115 if (writeChunk.size + writeBytes >= writeChunk.data.length) { | 155 if (writeChunk.size + writeBytes >= writeChunk.data.length) { |
116 Chunk newChunk = new Chunk(); | 156 Chunk newChunk = new Chunk(); |
119 } | 159 } |
120 | 160 |
121 assert Unsafe.ARRAY_BYTE_INDEX_SCALE == 1; | 161 assert Unsafe.ARRAY_BYTE_INDEX_SCALE == 1; |
122 long result = writeChunk.size + Unsafe.ARRAY_BYTE_BASE_OFFSET; | 162 long result = writeChunk.size + Unsafe.ARRAY_BYTE_BASE_OFFSET; |
123 | 163 |
164 return result; | |
165 } | |
166 | |
167 private void commitWrite(int writeBytes) { | |
124 totalSize += writeBytes; | 168 totalSize += writeBytes; |
125 writeChunk.size += writeBytes; | 169 writeChunk.size += writeBytes; |
126 assert writeChunk.size <= writeChunk.data.length; | 170 assert writeChunk.size <= writeChunk.data.length; |
127 | |
128 return result; | |
129 } | 171 } |
130 } | 172 } |