Mercurial > hg > truffle
annotate src/share/vm/code/compressedStream.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_compressedStream.cpp.incl" | |
27 | |
28 // 32-bit one-to-one sign encoding taken from Pack200 | |
29 // converts leading sign bits into leading zeroes with trailing sign bit | |
30 inline juint CompressedStream::encode_sign(jint value) { | |
31 return (value << 1) ^ (value >> 31); | |
32 } | |
33 inline jint CompressedStream::decode_sign(juint value) { | |
34 return (value >> 1) ^ -(jint)(value & 1); | |
35 } | |
36 | |
37 // 32-bit self-inverse encoding of float bits | |
38 // converts trailing zeroes (common in floats) to leading zeroes | |
39 inline juint CompressedStream::reverse_int(juint i) { | |
40 // Hacker's Delight, Figure 7-1 | |
41 i = (i & 0x55555555) << 1 | (i >> 1) & 0x55555555; | |
42 i = (i & 0x33333333) << 2 | (i >> 2) & 0x33333333; | |
43 i = (i & 0x0f0f0f0f) << 4 | (i >> 4) & 0x0f0f0f0f; | |
44 i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); | |
45 return i; | |
46 } | |
47 | |
48 | |
49 jint CompressedReadStream::read_signed_int() { | |
50 return decode_sign(read_int()); | |
51 } | |
52 | |
53 // Compressing floats is simple, because the only common pattern | |
54 // is trailing zeroes. (Compare leading sign bits on ints.) | |
55 // Since floats are left-justified, as opposed to right-justified | |
56 // ints, we can bit-reverse them in order to take advantage of int | |
57 // compression. | |
58 | |
59 jfloat CompressedReadStream::read_float() { | |
60 int rf = read_int(); | |
61 int f = reverse_int(rf); | |
62 return jfloat_cast(f); | |
63 } | |
64 | |
65 jdouble CompressedReadStream::read_double() { | |
66 jint rh = read_int(); | |
67 jint rl = read_int(); | |
68 jint h = reverse_int(rh); | |
69 jint l = reverse_int(rl); | |
70 return jdouble_cast(jlong_from(h, l)); | |
71 } | |
72 | |
73 jlong CompressedReadStream::read_long() { | |
74 jint low = read_signed_int(); | |
75 jint high = read_signed_int(); | |
76 return jlong_from(high, low); | |
77 } | |
78 | |
79 CompressedWriteStream::CompressedWriteStream(int initial_size) : CompressedStream(NULL, 0) { | |
80 _buffer = NEW_RESOURCE_ARRAY(u_char, initial_size); | |
81 _size = initial_size; | |
82 _position = 0; | |
83 } | |
84 | |
85 void CompressedWriteStream::grow() { | |
86 u_char* _new_buffer = NEW_RESOURCE_ARRAY(u_char, _size * 2); | |
87 memcpy(_new_buffer, _buffer, _position); | |
88 _buffer = _new_buffer; | |
89 _size = _size * 2; | |
90 } | |
91 | |
92 void CompressedWriteStream::write_signed_int(jint value) { | |
93 // this encoding, called SIGNED5, is taken from Pack200 | |
94 write_int(encode_sign(value)); | |
95 } | |
96 | |
97 void CompressedWriteStream::write_float(jfloat value) { | |
98 juint f = jint_cast(value); | |
99 juint rf = reverse_int(f); | |
100 assert(f == reverse_int(rf), "can re-read same bits"); | |
101 write_int(rf); | |
102 } | |
103 | |
104 void CompressedWriteStream::write_double(jdouble value) { | |
105 juint h = high(jlong_cast(value)); | |
106 juint l = low( jlong_cast(value)); | |
107 juint rh = reverse_int(h); | |
108 juint rl = reverse_int(l); | |
109 assert(h == reverse_int(rh), "can re-read same bits"); | |
110 assert(l == reverse_int(rl), "can re-read same bits"); | |
111 write_int(rh); | |
112 write_int(rl); | |
113 } | |
114 | |
115 void CompressedWriteStream::write_long(jlong value) { | |
116 write_signed_int(low(value)); | |
117 write_signed_int(high(value)); | |
118 } | |
119 | |
120 | |
121 /// The remaining details | |
122 | |
123 #ifndef PRODUCT | |
124 // set this to trigger unit test | |
125 void test_compressed_stream(int trace); | |
126 bool test_compressed_stream_enabled = false; | |
127 #endif | |
128 | |
129 // This encoding, called UNSIGNED5, is taken from J2SE Pack200. | |
130 // It assumes that most values have lots of leading zeroes. | |
131 // Very small values, in the range [0..191], code in one byte. | |
132 // Any 32-bit value (including negatives) can be coded, in | |
133 // up to five bytes. The grammar is: | |
134 // low_byte = [0..191] | |
135 // high_byte = [192..255] | |
136 // any_byte = low_byte | high_byte | |
137 // coding = low_byte | |
138 // | high_byte low_byte | |
139 // | high_byte high_byte low_byte | |
140 // | high_byte high_byte high_byte low_byte | |
141 // | high_byte high_byte high_byte high_byte any_byte | |
142 // Each high_byte contributes six bits of payload. | |
143 // The encoding is one-to-one (except for integer overflow) | |
144 // and easy to parse and unparse. | |
145 | |
146 jint CompressedReadStream::read_int_mb(jint b0) { | |
147 int pos = position() - 1; | |
148 u_char* buf = buffer() + pos; | |
149 assert(buf[0] == b0 && b0 >= L, "correctly called"); | |
150 jint sum = b0; | |
151 // must collect more bytes: b[1]...b[4] | |
152 int lg_H_i = lg_H; | |
153 for (int i = 0; ; ) { | |
154 jint b_i = buf[++i]; // b_i = read(); ++i; | |
155 sum += b_i << lg_H_i; // sum += b[i]*(64**i) | |
156 if (b_i < L || i == MAX_i) { | |
157 set_position(pos+i+1); | |
158 return sum; | |
159 } | |
160 lg_H_i += lg_H; | |
161 } | |
162 } | |
163 | |
164 void CompressedWriteStream::write_int_mb(jint value) { | |
165 debug_only(int pos1 = position()); | |
166 juint sum = value; | |
167 for (int i = 0; ; ) { | |
168 if (sum < L || i == MAX_i) { | |
169 // remainder is either a "low code" or the 5th byte | |
170 assert(sum == (u_char)sum, "valid byte"); | |
171 write((u_char)sum); | |
172 break; | |
173 } | |
174 sum -= L; | |
175 int b_i = L + (sum % H); // this is a "high code" | |
176 sum >>= lg_H; // extracted 6 bits | |
177 write(b_i); ++i; | |
178 } | |
179 | |
180 #ifndef PRODUCT | |
181 if (test_compressed_stream_enabled) { // hack to enable this stress test | |
182 test_compressed_stream_enabled = false; | |
183 test_compressed_stream(0); | |
184 } | |
185 #endif | |
186 } | |
187 | |
188 | |
189 #ifndef PRODUCT | |
190 /// a unit test (can be run by hand from a debugger) | |
191 | |
192 // Avoid a VS2005 compiler stack overflow w/ fastdebug build. | |
193 // The following pragma optimize turns off optimization ONLY | |
194 // for this block (a matching directive turns it back on later). | |
195 // These directives can be removed once the MS VS.NET 2005 | |
196 // compiler stack overflow is fixed. | |
197 #if _MSC_VER >=1400 && !defined(_WIN64) | |
198 #pragma optimize("", off) | |
199 #endif | |
200 | |
201 // generator for an "interesting" set of critical values | |
202 enum { stretch_limit = (1<<16) * (64-16+1) }; | |
203 static jlong stretch(jint x, int bits) { | |
204 // put x[high 4] into place | |
205 jlong h = (jlong)((x >> (16-4))) << (bits - 4); | |
206 // put x[low 12] into place, sign extended | |
207 jlong l = ((jlong)x << (64-12)) >> (64-12); | |
208 // move l upwards, maybe | |
209 l <<= (x >> 16); | |
210 return h ^ l; | |
211 } | |
212 | |
213 void test_compressed_stream(int trace) { | |
214 CompressedWriteStream bytes(stretch_limit * 100); | |
215 jint n; | |
216 int step = 0, fails = 0; | |
217 #define CHECKXY(x, y, fmt) { \ | |
218 ++step; \ | |
219 int xlen = (pos = decode.position()) - lastpos; lastpos = pos; \ | |
220 if (trace > 0 && (step % trace) == 0) { \ | |
221 tty->print_cr("step %d, n=%08x: value=" fmt " (len=%d)", \ | |
222 step, n, x, xlen); } \ | |
223 if (x != y) { \ | |
224 tty->print_cr("step %d, n=%d: " fmt " != " fmt, step, n, x, y); \ | |
225 fails++; \ | |
226 } } | |
227 for (n = 0; n < (1<<8); n++) { | |
228 jbyte x = (jbyte)n; | |
229 bytes.write_byte(x); ++step; | |
230 } | |
231 for (n = 0; n < stretch_limit; n++) { | |
232 jint x = (jint)stretch(n, 32); | |
233 bytes.write_int(x); ++step; | |
234 bytes.write_signed_int(x); ++step; | |
235 bytes.write_float(jfloat_cast(x)); ++step; | |
236 } | |
237 for (n = 0; n < stretch_limit; n++) { | |
238 jlong x = stretch(n, 64); | |
239 bytes.write_long(x); ++step; | |
240 bytes.write_double(jdouble_cast(x)); ++step; | |
241 } | |
242 int length = bytes.position(); | |
243 if (trace != 0) | |
244 tty->print_cr("set up test of %d stream values, size %d", step, length); | |
245 step = 0; | |
246 // now decode it all | |
247 CompressedReadStream decode(bytes.buffer()); | |
248 int pos, lastpos = decode.position(); | |
249 for (n = 0; n < (1<<8); n++) { | |
250 jbyte x = (jbyte)n; | |
251 jbyte y = decode.read_byte(); | |
252 CHECKXY(x, y, "%db"); | |
253 } | |
254 for (n = 0; n < stretch_limit; n++) { | |
255 jint x = (jint)stretch(n, 32); | |
256 jint y1 = decode.read_int(); | |
257 CHECKXY(x, y1, "%du"); | |
258 jint y2 = decode.read_signed_int(); | |
259 CHECKXY(x, y2, "%di"); | |
260 jint y3 = jint_cast(decode.read_float()); | |
261 CHECKXY(x, y3, "%df"); | |
262 } | |
263 for (n = 0; n < stretch_limit; n++) { | |
264 jlong x = stretch(n, 64); | |
265 jlong y1 = decode.read_long(); | |
266 CHECKXY(x, y1, INT64_FORMAT "l"); | |
267 jlong y2 = jlong_cast(decode.read_double()); | |
268 CHECKXY(x, y2, INT64_FORMAT "d"); | |
269 } | |
270 int length2 = decode.position(); | |
271 if (trace != 0) | |
272 tty->print_cr("finished test of %d stream values, size %d", step, length2); | |
273 guarantee(length == length2, "bad length"); | |
274 guarantee(fails == 0, "test failures"); | |
275 } | |
276 | |
277 #if _MSC_VER >=1400 && !defined(_WIN64) | |
278 #pragma optimize("", on) | |
279 #endif | |
280 | |
281 #endif // PRODUCT |