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 }