Mercurial > hg > truffle
annotate agent/src/os/win32/IOBuf.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2000, 2003, 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 <stdio.h> | |
26 | |
27 // This file is currently used for os/solaris/agent too. At some point in time | |
28 // the source will be reorganized to avoid these ifdefs. | |
29 | |
30 #ifdef __sun | |
31 #include <string.h> | |
32 #include <inttypes.h> | |
33 #include <sys/byteorder.h> | |
34 #endif | |
35 | |
36 #include "IOBuf.hpp" | |
37 | |
38 // Formats for printing pointers | |
39 #ifdef _LP64 | |
40 # define INTPTR_FORMAT "0x%016lx" | |
41 #else /* ! _LP64 */ | |
42 # define INTPTR_FORMAT "0x%08lx" | |
43 #endif /* _LP64 */ | |
44 | |
45 // Uncomment the #define below to get messages on stderr | |
46 // #define DEBUGGING | |
47 | |
48 IOBuf::IOBuf(int inLen, int outLen) { | |
49 inBuf = new Buffer(inLen); | |
50 outBuf = new Buffer(outLen); | |
51 fd = INVALID_SOCKET; | |
52 outHandle = NULL; | |
53 usingSocket = true; | |
54 reset(); | |
55 } | |
56 | |
57 IOBuf::~IOBuf() { | |
58 delete inBuf; | |
59 delete outBuf; | |
60 } | |
61 | |
62 void | |
63 IOBuf::setSocket(SOCKET sock) { | |
64 fd = sock; | |
65 usingSocket = true; | |
66 } | |
67 | |
68 // Reading/writing files is only needed and used on windows. | |
69 #ifdef WIN32 | |
70 void | |
71 IOBuf::setOutputFileHandle(HANDLE handle) { | |
72 outHandle = handle; | |
73 usingSocket = false; | |
74 } | |
75 #endif | |
76 | |
77 void | |
78 IOBuf::reset() { | |
79 gotDataLastTime = false; | |
80 state = TEXT_STATE; | |
81 binPos = 0; | |
82 binLength = 0; | |
83 } | |
84 | |
85 IOBuf::ReadLineResult | |
86 IOBuf::tryReadLine() { | |
87 return doReadLine(false); | |
88 } | |
89 | |
90 char* | |
91 IOBuf::readLine() { | |
92 ReadLineResult rr = doReadLine(true); | |
93 if (rr != RL_GOT_DATA) { | |
94 return NULL; | |
95 } | |
96 return getLine(); | |
97 } | |
98 | |
99 IOBuf::ReadLineResult | |
100 IOBuf::doReadLine(bool shouldWait) { | |
101 | |
102 if (!usingSocket) { | |
103 return IOBuf::RL_ERROR; | |
104 } | |
105 | |
106 if (gotDataLastTime) { | |
107 curLine.clear(); | |
108 } | |
109 | |
110 int c; | |
111 do { | |
112 c = readChar(shouldWait); | |
113 if (c >= 0) { | |
114 Action act = processChar((char) c); | |
115 if (act == GOT_LINE) { | |
116 curLine.push_back('\0'); | |
117 gotDataLastTime = true; | |
118 return IOBuf::RL_GOT_DATA; | |
119 } else if (act == SKIP_EOL_CHAR) { | |
120 // Do nothing | |
121 } else { | |
122 curLine.push_back((char) c); | |
123 } | |
124 } | |
125 } while (shouldWait || c >= 0); | |
126 | |
127 gotDataLastTime = false; | |
128 return IOBuf::RL_NO_DATA; | |
129 } | |
130 | |
131 bool | |
132 IOBuf::flushImpl(bool moreDataToCome) { | |
133 int numWritten = 0; | |
134 | |
135 #ifdef WIN32 | |
136 // When running on Windows and using IOBufs for inter-process | |
137 // communication, we need to write metadata into the stream | |
138 // indicating how many bytes are coming down. Five bytes are written | |
139 // per flush() call, four containing the integer number of bytes | |
140 // coming (not including the five-byte header) and one (a 0 or 1) | |
141 // indicating whether there is more data coming. | |
142 if (!usingSocket) { | |
143 int numToWrite = outBuf->drainRemaining(); | |
144 char moreToCome = (moreDataToCome ? 1 : 0); | |
145 DWORD numBytesWritten; | |
146 if (!WriteFile(outHandle, &numToWrite, sizeof(int), &numBytesWritten, NULL)) { | |
147 return false; | |
148 } | |
149 if (numBytesWritten != sizeof(int)) { | |
150 return false; | |
151 } | |
152 if (!WriteFile(outHandle, &moreToCome, 1, &numBytesWritten, NULL)) { | |
153 return false; | |
154 } | |
155 if (numBytesWritten != 1) { | |
156 return false; | |
157 } | |
158 } | |
159 #endif | |
160 | |
161 while (outBuf->drainRemaining() != 0) { | |
162 #ifdef DEBUGGING | |
163 fprintf(stderr, "Flushing %d bytes\n", outBuf->drainRemaining()); | |
164 #endif | |
165 if (usingSocket) { | |
166 numWritten = send(fd, outBuf->drainPos(), outBuf->drainRemaining(), 0); | |
167 } else { | |
168 #ifdef WIN32 | |
169 DWORD numBytesWritten; | |
170 if (!WriteFile(outHandle, outBuf->drainPos(), outBuf->drainRemaining(), &numBytesWritten, NULL)) { | |
171 numWritten = -1; | |
172 } else { | |
173 numWritten = numBytesWritten; | |
174 } | |
175 #endif | |
176 } | |
177 if (numWritten != -1) { | |
178 #ifdef DEBUGGING | |
179 fprintf(stderr, "Flushed %d bytes\n", numWritten); | |
180 #endif | |
181 outBuf->incrDrainPos(numWritten); | |
182 } else { | |
183 return false; | |
184 } | |
185 } | |
186 | |
187 outBuf->compact(); | |
188 | |
189 return true; | |
190 } | |
191 | |
192 int | |
193 IOBuf::readChar(bool block) { | |
194 do { | |
195 int c = inBuf->readByte(); | |
196 if (c >= 0) { | |
197 return c; | |
198 } | |
199 // See whether we need to compact the input buffer | |
200 if (inBuf->remaining() < inBuf->size() / 2) { | |
201 inBuf->compact(); | |
202 } | |
203 // See whether socket is ready | |
204 fd_set fds; | |
205 FD_ZERO(&fds); | |
206 FD_SET(fd, &fds); | |
207 struct timeval timeout; | |
208 timeout.tv_sec = 0; | |
209 timeout.tv_usec = 0; | |
210 if (block || select(1 + fd, &fds, NULL, NULL, &timeout) > 0) { | |
211 if (block || FD_ISSET(fd, &fds)) { | |
212 #ifdef DEBUGGING | |
213 int b = (block ? 1 : 0); | |
214 fprintf(stderr, "calling recv: block = %d\n", b); | |
215 #endif | |
216 // Read data from socket | |
217 int numRead = recv(fd, inBuf->fillPos(), inBuf->remaining(), 0); | |
218 if (numRead < 0) { | |
219 #ifdef DEBUGGING | |
220 fprintf(stderr, "recv failed\n"); | |
221 #endif | |
222 return -1; | |
223 } | |
224 inBuf->incrFillPos(numRead); | |
225 } | |
226 } | |
227 } while (block); | |
228 | |
229 return inBuf->readByte(); | |
230 } | |
231 | |
232 char* | |
233 IOBuf::getLine() { | |
234 #ifdef DEBUGGING | |
235 fprintf(stderr, "Returning (first 10 chars) \"%.10s\"\n", curLine.begin()); | |
236 #endif | |
237 return curLine.begin(); | |
238 } | |
239 | |
240 bool | |
241 IOBuf::flush() { | |
242 return flushImpl(false); | |
243 } | |
244 | |
245 bool | |
246 IOBuf::writeString(const char* str) { | |
247 int len = strlen(str); | |
248 | |
249 if (len > outBuf->size()) { | |
250 return false; | |
251 } | |
252 | |
253 if (len > outBuf->remaining()) { | |
254 if (!flushImpl(true)) { | |
255 return false; | |
256 } | |
257 } | |
258 | |
259 // NOTE we do not copy the null terminator of the string. | |
260 | |
261 strncpy(outBuf->fillPos(), str, len); | |
262 outBuf->incrFillPos(len); | |
263 return true; | |
264 } | |
265 | |
266 bool | |
267 IOBuf::writeInt(int val) { | |
268 char buf[128]; | |
269 sprintf(buf, "%d", val); | |
270 return writeString(buf); | |
271 } | |
272 | |
273 bool | |
274 IOBuf::writeUnsignedInt(unsigned int val) { | |
275 char buf[128]; | |
276 sprintf(buf, "%u", val); | |
277 return writeString(buf); | |
278 } | |
279 | |
280 bool | |
281 IOBuf::writeBoolAsInt(bool val) { | |
282 if (val) { | |
283 return writeString("1"); | |
284 } else { | |
285 return writeString("0"); | |
286 } | |
287 } | |
288 | |
289 bool | |
290 IOBuf::writeAddress(void* val) { | |
291 char buf[128]; | |
292 sprintf(buf, INTPTR_FORMAT, val); | |
293 return writeString(buf); | |
294 } | |
295 | |
296 bool | |
297 IOBuf::writeSpace() { | |
298 return writeString(" "); | |
299 } | |
300 | |
301 bool | |
302 IOBuf::writeEOL() { | |
303 return writeString("\n\r"); | |
304 } | |
305 | |
306 bool | |
307 IOBuf::writeBinChar(char c) { | |
308 return writeBinBuf((char*) &c, sizeof(c)); | |
309 } | |
310 | |
311 bool | |
312 IOBuf::writeBinUnsignedShort(unsigned short i) { | |
313 i = htons(i); | |
314 return writeBinBuf((char*) &i, sizeof(i)); | |
315 } | |
316 | |
317 bool | |
318 IOBuf::writeBinUnsignedInt(unsigned int i) { | |
319 i = htonl(i); | |
320 return writeBinBuf((char*) &i, sizeof(i)); | |
321 } | |
322 | |
323 bool | |
324 IOBuf::writeBinBuf(char* buf, int size) { | |
325 while (size > 0) { | |
326 int spaceRemaining = outBuf->remaining(); | |
327 if (spaceRemaining == 0) { | |
328 if (!flushImpl(true)) { | |
329 return false; | |
330 } | |
331 spaceRemaining = outBuf->remaining(); | |
332 } | |
333 int toCopy = (size > spaceRemaining) ? spaceRemaining : size; | |
334 memcpy(outBuf->fillPos(), buf, toCopy); | |
335 outBuf->incrFillPos(toCopy); | |
336 buf += toCopy; | |
337 size -= toCopy; | |
338 if (size > 0) { | |
339 if (!flushImpl(true)) { | |
340 return false; | |
341 } | |
342 } | |
343 } | |
344 return true; | |
345 } | |
346 | |
347 #ifdef WIN32 | |
348 IOBuf::FillState | |
349 IOBuf::fillFromFileHandle(HANDLE fh, DWORD* numBytesRead) { | |
350 int totalToRead; | |
351 char moreToCome; | |
352 | |
353 outBuf->compact(); | |
354 | |
355 DWORD numRead; | |
356 if (!ReadFile(fh, &totalToRead, sizeof(int), &numRead, NULL)) { | |
357 return FAILED; | |
358 } | |
359 if (numRead != sizeof(int)) { | |
360 return FAILED; | |
361 } | |
362 if (!ReadFile(fh, &moreToCome, 1, &numRead, NULL)) { | |
363 return FAILED; | |
364 } | |
365 if (numRead != 1) { | |
366 return FAILED; | |
367 } | |
368 if (outBuf->remaining() < totalToRead) { | |
369 return FAILED; | |
370 } | |
371 | |
372 int tmp = totalToRead; | |
373 | |
374 while (totalToRead > 0) { | |
375 if (!ReadFile(fh, outBuf->fillPos(), totalToRead, &numRead, NULL)) { | |
376 return FAILED; | |
377 } | |
378 outBuf->incrFillPos((int) numRead); | |
379 totalToRead -= numRead; | |
380 } | |
381 | |
382 *numBytesRead = tmp; | |
383 return ((moreToCome == 0) ? DONE : MORE_DATA_PENDING); | |
384 } | |
385 #endif | |
386 | |
387 bool | |
388 IOBuf::isBinEscapeChar(char c) { | |
389 return (c == '|'); | |
390 } | |
391 | |
392 IOBuf::Action | |
393 IOBuf::processChar(char c) { | |
394 Action action = NO_ACTION; | |
395 switch (state) { | |
396 case TEXT_STATE: { | |
397 // Looking for text char, bin escape char, or EOL | |
398 if (isBinEscapeChar(c)) { | |
399 #ifdef DEBUGGING | |
400 fprintf(stderr, "[a: '%c'] ", inBuf[0]); | |
401 #endif | |
402 binPos = 0; | |
403 #ifdef DEBUGGING | |
404 fprintf(stderr, "[b: '%c'] ", inBuf[0]); | |
405 #endif | |
406 binLength = 0; | |
407 #ifdef DEBUGGING | |
408 fprintf(stderr, "[c: '%c'] ", inBuf[0]); | |
409 #endif | |
410 state = BIN_STATE; | |
411 #ifdef DEBUGGING | |
412 fprintf(stderr, "[d: '%c'] ", inBuf[0]); | |
413 #endif | |
414 #ifdef DEBUGGING | |
415 fprintf(stderr, "\nSwitching to BIN_STATE\n"); | |
416 #endif | |
417 } else if (isEOL(c)) { | |
418 state = EOL_STATE; | |
419 action = GOT_LINE; | |
420 #ifdef DEBUGGING | |
421 fprintf(stderr, "\nSwitching to EOL_STATE (GOT_LINE)\n"); | |
422 #endif | |
423 } | |
424 #ifdef DEBUGGING | |
425 else { | |
426 fprintf(stderr, "'%c' ", c); | |
427 fflush(stderr); | |
428 } | |
429 #endif | |
430 break; | |
431 } | |
432 | |
433 case BIN_STATE: { | |
434 // Seeking to finish read of input | |
435 if (binPos < 4) { | |
436 int cur = c & 0xFF; | |
437 binLength <<= 8; | |
438 binLength |= cur; | |
439 ++binPos; | |
440 } else { | |
441 #ifdef DEBUGGING | |
442 fprintf(stderr, "Reading binary byte %d of %d\n", | |
443 binPos - 4, binLength); | |
444 #endif | |
445 ++binPos; | |
446 if (binPos == 4 + binLength) { | |
447 state = TEXT_STATE; | |
448 #ifdef DEBUGGING | |
449 fprintf(stderr, "Switching to TEXT_STATE\n"); | |
450 #endif | |
451 } | |
452 } | |
453 break; | |
454 } | |
455 | |
456 case EOL_STATE: { | |
457 // More EOL characters just cause us to re-enter this state | |
458 if (isEOL(c)) { | |
459 action = SKIP_EOL_CHAR; | |
460 } else if (isBinEscapeChar(c)) { | |
461 binPos = 0; | |
462 binLength = 0; | |
463 state = BIN_STATE; | |
464 } else { | |
465 state = TEXT_STATE; | |
466 #ifdef DEBUGGING | |
467 fprintf(stderr, "'%c' ", c); | |
468 fflush(stderr); | |
469 #endif | |
470 } | |
471 break; | |
472 } | |
473 | |
474 } // switch | |
475 | |
476 return action; | |
477 } | |
478 | |
479 | |
480 bool | |
481 IOBuf::isEOL(char c) { | |
482 #ifdef WIN32 | |
483 return ((c == '\n') || (c == '\r')); | |
484 #elif defined(__sun) | |
485 return c == '\n'; | |
486 #else | |
487 #error Please port isEOL() to your platform | |
488 return false; | |
489 #endif | |
490 } |