Mercurial > hg > graal-compiler
annotate src/share/vm/code/compressedStream.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | 5fa559508216 |
children | 47bc9800972c |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1997, 2010, 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 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "code/compressedStream.hpp" | |
27 #include "utilities/ostream.hpp" | |
0 | 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 | |
39 // converts trailing zeroes (common in floats) to leading zeroes | |
40 inline juint CompressedStream::reverse_int(juint i) { | |
41 // Hacker's Delight, Figure 7-1 | |
42 i = (i & 0x55555555) << 1 | (i >> 1) & 0x55555555; | |
43 i = (i & 0x33333333) << 2 | (i >> 2) & 0x33333333; | |
44 i = (i & 0x0f0f0f0f) << 4 | (i >> 4) & 0x0f0f0f0f; | |
45 i = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); | |
46 return i; | |
47 } | |
48 | |
49 | |
50 jint CompressedReadStream::read_signed_int() { | |
51 return decode_sign(read_int()); | |
52 } | |
53 | |
54 // Compressing floats is simple, because the only common pattern | |
55 // is trailing zeroes. (Compare leading sign bits on ints.) | |
56 // Since floats are left-justified, as opposed to right-justified | |
57 // ints, we can bit-reverse them in order to take advantage of int | |
58 // compression. | |
59 | |
60 jfloat CompressedReadStream::read_float() { | |
61 int rf = read_int(); | |
62 int f = reverse_int(rf); | |
63 return jfloat_cast(f); | |
64 } | |
65 | |
66 jdouble CompressedReadStream::read_double() { | |
67 jint rh = read_int(); | |
68 jint rl = read_int(); | |
69 jint h = reverse_int(rh); | |
70 jint l = reverse_int(rl); | |
71 return jdouble_cast(jlong_from(h, l)); | |
72 } | |
73 | |
74 jlong CompressedReadStream::read_long() { | |
75 jint low = read_signed_int(); | |
76 jint high = read_signed_int(); | |
77 return jlong_from(high, low); | |
78 } | |
79 | |
80 CompressedWriteStream::CompressedWriteStream(int initial_size) : CompressedStream(NULL, 0) { | |
81 _buffer = NEW_RESOURCE_ARRAY(u_char, initial_size); | |
82 _size = initial_size; | |
83 _position = 0; | |
84 } | |
85 | |
86 void CompressedWriteStream::grow() { | |
87 u_char* _new_buffer = NEW_RESOURCE_ARRAY(u_char, _size * 2); | |
88 memcpy(_new_buffer, _buffer, _position); | |
89 _buffer = _new_buffer; | |
90 _size = _size * 2; | |
91 } | |
92 | |
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) { | |
99 juint f = jint_cast(value); | |
100 juint rf = reverse_int(f); | |
101 assert(f == reverse_int(rf), "can re-read same bits"); | |
102 write_int(rf); | |
103 } | |
104 | |
105 void CompressedWriteStream::write_double(jdouble value) { | |
106 juint h = high(jlong_cast(value)); | |
107 juint l = low( jlong_cast(value)); | |
108 juint rh = reverse_int(h); | |
109 juint rl = reverse_int(l); | |
110 assert(h == reverse_int(rh), "can re-read same bits"); | |
111 assert(l == reverse_int(rl), "can re-read same bits"); | |
112 write_int(rh); | |
113 write_int(rl); | |
114 } | |
115 | |
116 void CompressedWriteStream::write_long(jlong value) { | |
117 write_signed_int(low(value)); | |
118 write_signed_int(high(value)); | |
119 } | |
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 // This encoding, called UNSIGNED5, is taken from J2SE Pack200. | |
131 // It assumes that most values have lots of leading zeroes. | |
132 // Very small values, in the range [0..191], code in one byte. | |
133 // Any 32-bit value (including negatives) can be coded, in | |
134 // up to five bytes. The grammar is: | |
135 // low_byte = [0..191] | |
136 // high_byte = [192..255] | |
137 // any_byte = low_byte | high_byte | |
138 // coding = low_byte | |
139 // | high_byte low_byte | |
140 // | high_byte high_byte low_byte | |
141 // | high_byte high_byte high_byte low_byte | |
142 // | high_byte high_byte high_byte high_byte any_byte | |
143 // Each high_byte contributes six bits of payload. | |
144 // The encoding is one-to-one (except for integer overflow) | |
145 // and easy to parse and unparse. | |
146 | |
147 jint CompressedReadStream::read_int_mb(jint b0) { | |
148 int pos = position() - 1; | |
149 u_char* buf = buffer() + pos; | |
150 assert(buf[0] == b0 && b0 >= L, "correctly called"); | |
151 jint sum = b0; | |
152 // must collect more bytes: b[1]...b[4] | |
153 int lg_H_i = lg_H; | |
154 for (int i = 0; ; ) { | |
155 jint b_i = buf[++i]; // b_i = read(); ++i; | |
156 sum += b_i << lg_H_i; // sum += b[i]*(64**i) | |
157 if (b_i < L || i == MAX_i) { | |
158 set_position(pos+i+1); | |
159 return sum; | |
160 } | |
161 lg_H_i += lg_H; | |
162 } | |
163 } | |
164 | |
165 void CompressedWriteStream::write_int_mb(jint value) { | |
166 debug_only(int pos1 = position()); | |
167 juint sum = value; | |
168 for (int i = 0; ; ) { | |
169 if (sum < L || i == MAX_i) { | |
170 // remainder is either a "low code" or the 5th byte | |
171 assert(sum == (u_char)sum, "valid byte"); | |
172 write((u_char)sum); | |
173 break; | |
174 } | |
175 sum -= L; | |
176 int b_i = L + (sum % H); // this is a "high code" | |
177 sum >>= lg_H; // extracted 6 bits | |
178 write(b_i); ++i; | |
179 } | |
180 | |
181 #ifndef PRODUCT | |
182 if (test_compressed_stream_enabled) { // hack to enable this stress test | |
183 test_compressed_stream_enabled = false; | |
184 test_compressed_stream(0); | |
185 } | |
186 #endif | |
187 } | |
188 | |
189 | |
190 #ifndef PRODUCT | |
191 /// a unit test (can be run by hand from a debugger) | |
192 | |
193 // Avoid a VS2005 compiler stack overflow w/ fastdebug build. | |
194 // The following pragma optimize turns off optimization ONLY | |
195 // for this block (a matching directive turns it back on later). | |
196 // These directives can be removed once the MS VS.NET 2005 | |
197 // compiler stack overflow is fixed. | |
198 #if _MSC_VER >=1400 && !defined(_WIN64) | |
199 #pragma optimize("", off) | |
2000
5fa559508216
7007229: Fix warnings with VS2010 in compressedStream.cpp
iveresov
parents:
1972
diff
changeset
|
200 #pragma warning(disable: 4748) |
0 | 201 #endif |
202 | |
203 // generator for an "interesting" set of critical values | |
204 enum { stretch_limit = (1<<16) * (64-16+1) }; | |
205 static jlong stretch(jint x, int bits) { | |
206 // put x[high 4] into place | |
207 jlong h = (jlong)((x >> (16-4))) << (bits - 4); | |
208 // put x[low 12] into place, sign extended | |
209 jlong l = ((jlong)x << (64-12)) >> (64-12); | |
210 // move l upwards, maybe | |
211 l <<= (x >> 16); | |
212 return h ^ l; | |
213 } | |
214 | |
215 void test_compressed_stream(int trace) { | |
216 CompressedWriteStream bytes(stretch_limit * 100); | |
217 jint n; | |
218 int step = 0, fails = 0; | |
219 #define CHECKXY(x, y, fmt) { \ | |
220 ++step; \ | |
221 int xlen = (pos = decode.position()) - lastpos; lastpos = pos; \ | |
222 if (trace > 0 && (step % trace) == 0) { \ | |
223 tty->print_cr("step %d, n=%08x: value=" fmt " (len=%d)", \ | |
224 step, n, x, xlen); } \ | |
225 if (x != y) { \ | |
226 tty->print_cr("step %d, n=%d: " fmt " != " fmt, step, n, x, y); \ | |
227 fails++; \ | |
228 } } | |
229 for (n = 0; n < (1<<8); n++) { | |
230 jbyte x = (jbyte)n; | |
231 bytes.write_byte(x); ++step; | |
232 } | |
233 for (n = 0; n < stretch_limit; n++) { | |
234 jint x = (jint)stretch(n, 32); | |
235 bytes.write_int(x); ++step; | |
236 bytes.write_signed_int(x); ++step; | |
237 bytes.write_float(jfloat_cast(x)); ++step; | |
238 } | |
239 for (n = 0; n < stretch_limit; n++) { | |
240 jlong x = stretch(n, 64); | |
241 bytes.write_long(x); ++step; | |
242 bytes.write_double(jdouble_cast(x)); ++step; | |
243 } | |
244 int length = bytes.position(); | |
245 if (trace != 0) | |
246 tty->print_cr("set up test of %d stream values, size %d", step, length); | |
247 step = 0; | |
248 // now decode it all | |
249 CompressedReadStream decode(bytes.buffer()); | |
250 int pos, lastpos = decode.position(); | |
251 for (n = 0; n < (1<<8); n++) { | |
252 jbyte x = (jbyte)n; | |
253 jbyte y = decode.read_byte(); | |
254 CHECKXY(x, y, "%db"); | |
255 } | |
256 for (n = 0; n < stretch_limit; n++) { | |
257 jint x = (jint)stretch(n, 32); | |
258 jint y1 = decode.read_int(); | |
259 CHECKXY(x, y1, "%du"); | |
260 jint y2 = decode.read_signed_int(); | |
261 CHECKXY(x, y2, "%di"); | |
262 jint y3 = jint_cast(decode.read_float()); | |
263 CHECKXY(x, y3, "%df"); | |
264 } | |
265 for (n = 0; n < stretch_limit; n++) { | |
266 jlong x = stretch(n, 64); | |
267 jlong y1 = decode.read_long(); | |
268 CHECKXY(x, y1, INT64_FORMAT "l"); | |
269 jlong y2 = jlong_cast(decode.read_double()); | |
270 CHECKXY(x, y2, INT64_FORMAT "d"); | |
271 } | |
272 int length2 = decode.position(); | |
273 if (trace != 0) | |
274 tty->print_cr("finished test of %d stream values, size %d", step, length2); | |
275 guarantee(length == length2, "bad length"); | |
276 guarantee(fails == 0, "test failures"); | |
277 } | |
278 | |
279 #if _MSC_VER >=1400 && !defined(_WIN64) | |
2000
5fa559508216
7007229: Fix warnings with VS2010 in compressedStream.cpp
iveresov
parents:
1972
diff
changeset
|
280 #pragma warning(default: 4748) |
0 | 281 #pragma optimize("", on) |
282 #endif | |
283 | |
284 #endif // PRODUCT |