comparison src/hotspot/share/code/compressedStream.cpp @ 54531:6dd6f988b4e4

8219860: Cleanup ClassFileParser::parse_linenumber_table Reviewed-by: rehn, lfoltan, hseigel
author redestad
date Fri, 08 Mar 2019 23:02:06 +0100
parents 71c04702a3d5
children
comparison
equal deleted inserted replaced
0:369b2debc782 1:34143b28815a
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "code/compressedStream.hpp" 26 #include "code/compressedStream.hpp"
27 #include "utilities/ostream.hpp" 27 #include "utilities/ostream.hpp"
28 28
29 // 32-bit one-to-one sign encoding taken from Pack200
30 // converts leading sign bits into leading zeroes with trailing sign bit
31 inline juint CompressedStream::encode_sign(jint value) {
32 return (value << 1) ^ (value >> 31);
33 }
34 inline jint CompressedStream::decode_sign(juint value) {
35 return (value >> 1) ^ -(jint)(value & 1);
36 }
37
38 // 32-bit self-inverse encoding of float bits 29 // 32-bit self-inverse encoding of float bits
39 // converts trailing zeroes (common in floats) to leading zeroes 30 // converts trailing zeroes (common in floats) to leading zeroes
40 inline juint CompressedStream::reverse_int(juint i) { 31 inline juint CompressedStream::reverse_int(juint i) {
41 // Hacker's Delight, Figure 7-1 32 // Hacker's Delight, Figure 7-1
42 i = (i & 0x55555555) << 1 | ((i >> 1) & 0x55555555); 33 i = (i & 0x55555555) << 1 | ((i >> 1) & 0x55555555);
43 i = (i & 0x33333333) << 2 | ((i >> 2) & 0x33333333); 34 i = (i & 0x33333333) << 2 | ((i >> 2) & 0x33333333);
44 i = (i & 0x0f0f0f0f) << 4 | ((i >> 4) & 0x0f0f0f0f); 35 i = (i & 0x0f0f0f0f) << 4 | ((i >> 4) & 0x0f0f0f0f);
45 i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); 36 i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
46 return i; 37 return i;
47 } 38 }
48
49 39
50 jint CompressedReadStream::read_signed_int() { 40 jint CompressedReadStream::read_signed_int() {
51 return decode_sign(read_int()); 41 return decode_sign(read_int());
52 } 42 }
53 43
88 memcpy(_new_buffer, _buffer, _position); 78 memcpy(_new_buffer, _buffer, _position);
89 _buffer = _new_buffer; 79 _buffer = _new_buffer;
90 _size = _size * 2; 80 _size = _size * 2;
91 } 81 }
92 82
93 void CompressedWriteStream::write_signed_int(jint value) {
94 // this encoding, called SIGNED5, is taken from Pack200
95 write_int(encode_sign(value));
96 }
97
98 void CompressedWriteStream::write_float(jfloat value) { 83 void CompressedWriteStream::write_float(jfloat value) {
99 juint f = jint_cast(value); 84 juint f = jint_cast(value);
100 juint rf = reverse_int(f); 85 juint rf = reverse_int(f);
101 assert(f == reverse_int(rf), "can re-read same bits"); 86 assert(f == reverse_int(rf), "can re-read same bits");
102 write_int(rf); 87 write_int(rf);
115 100
116 void CompressedWriteStream::write_long(jlong value) { 101 void CompressedWriteStream::write_long(jlong value) {
117 write_signed_int(low(value)); 102 write_signed_int(low(value));
118 write_signed_int(high(value)); 103 write_signed_int(high(value));
119 } 104 }
120
121
122 /// The remaining details
123
124 #ifndef PRODUCT
125 // set this to trigger unit test
126 void test_compressed_stream(int trace);
127 bool test_compressed_stream_enabled = false;
128 #endif
129
130 void CompressedWriteStream::write_int_mb(jint value) {
131 debug_only(int pos1 = position());
132 juint sum = value;
133 for (int i = 0; ; ) {
134 if (sum < L || i == MAX_i) {
135 // remainder is either a "low code" or the 5th byte
136 assert(sum == (u_char)sum, "valid byte");
137 write((u_char)sum);
138 break;
139 }
140 sum -= L;
141 int b_i = L + (sum % H); // this is a "high code"
142 sum >>= lg_H; // extracted 6 bits
143 write(b_i); ++i;
144 }
145
146 #ifndef PRODUCT
147 if (test_compressed_stream_enabled) { // hack to enable this stress test
148 test_compressed_stream_enabled = false;
149 test_compressed_stream(0);
150 }
151 #endif
152 }
153
154
155 #ifndef PRODUCT
156 /// a unit test (can be run by hand from a debugger)
157
158 // Avoid a VS2005 compiler stack overflow w/ fastdebug build.
159 // The following pragma optimize turns off optimization ONLY
160 // for this block (a matching directive turns it back on later).
161 // These directives can be removed once the MS VS.NET 2005
162 // compiler stack overflow is fixed.
163 #if defined(_MSC_VER) && _MSC_VER >=1400 && !defined(_WIN64)
164 #pragma optimize("", off)
165 #pragma warning(disable: 4748)
166 #endif
167
168 // generator for an "interesting" set of critical values
169 enum { stretch_limit = (1<<16) * (64-16+1) };
170 static jlong stretch(jint x, int bits) {
171 // put x[high 4] into place
172 jlong h = (jlong)((x >> (16-4))) << (bits - 4);
173 // put x[low 12] into place, sign extended
174 jlong l = ((jlong)x << (64-12)) >> (64-12);
175 // move l upwards, maybe
176 l <<= (x >> 16);
177 return h ^ l;
178 }
179
180 PRAGMA_DIAG_PUSH
181 PRAGMA_FORMAT_IGNORED // Someone needs to deal with this.
182 void test_compressed_stream(int trace) {
183 CompressedWriteStream bytes(stretch_limit * 100);
184 jint n;
185 int step = 0, fails = 0;
186 #define CHECKXY(x, y, fmt) { \
187 ++step; \
188 int xlen = (pos = decode.position()) - lastpos; lastpos = pos; \
189 if (trace > 0 && (step % trace) == 0) { \
190 tty->print_cr("step %d, n=%08x: value=" fmt " (len=%d)", \
191 step, n, x, xlen); } \
192 if (x != y) { \
193 tty->print_cr("step %d, n=%d: " fmt " != " fmt, step, n, x, y); \
194 fails++; \
195 } }
196 for (n = 0; n < (1<<8); n++) {
197 jbyte x = (jbyte)n;
198 bytes.write_byte(x); ++step;
199 }
200 for (n = 0; n < stretch_limit; n++) {
201 jint x = (jint)stretch(n, 32);
202 bytes.write_int(x); ++step;
203 bytes.write_signed_int(x); ++step;
204 bytes.write_float(jfloat_cast(x)); ++step;
205 }
206 for (n = 0; n < stretch_limit; n++) {
207 jlong x = stretch(n, 64);
208 bytes.write_long(x); ++step;
209 bytes.write_double(jdouble_cast(x)); ++step;
210 }
211 int length = bytes.position();
212 if (trace != 0)
213 tty->print_cr("set up test of %d stream values, size %d", step, length);
214 step = 0;
215 // now decode it all
216 CompressedReadStream decode(bytes.buffer());
217 int pos, lastpos = decode.position();
218 for (n = 0; n < (1<<8); n++) {
219 jbyte x = (jbyte)n;
220 jbyte y = decode.read_byte();
221 CHECKXY(x, y, "%db");
222 }
223 for (n = 0; n < stretch_limit; n++) {
224 jint x = (jint)stretch(n, 32);
225 jint y1 = decode.read_int();
226 CHECKXY(x, y1, "%du");
227 jint y2 = decode.read_signed_int();
228 CHECKXY(x, y2, "%di");
229 jint y3 = jint_cast(decode.read_float());
230 CHECKXY(x, y3, "%df");
231 }
232 for (n = 0; n < stretch_limit; n++) {
233 jlong x = stretch(n, 64);
234 jlong y1 = decode.read_long();
235 CHECKXY(x, y1, INT64_FORMAT "l");
236 jlong y2 = jlong_cast(decode.read_double());
237 CHECKXY(x, y2, INT64_FORMAT "d");
238 }
239 int length2 = decode.position();
240 if (trace != 0)
241 tty->print_cr("finished test of %d stream values, size %d", step, length2);
242 guarantee(length == length2, "bad length");
243 guarantee(fails == 0, "test failures");
244 }
245 PRAGMA_DIAG_POP
246
247 #if defined(_MSC_VER) &&_MSC_VER >=1400 && !defined(_WIN64)
248 #pragma warning(default: 4748)
249 #pragma optimize("", on)
250 #endif
251
252 #endif // PRODUCT