2
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
25
#include "precompiled.hpp"
26
#include "memory/allocation.inline.hpp"
27
#include "runtime/orderAccess.hpp"
28
#include "utilities/istream.hpp"
29
#include "utilities/ostream.hpp"
30
#include "utilities/xmlstream.hpp"
35
// Support for coverage testing. Used by the gtest.
36
/* $ sed < istream.cpp '/^.* COV(\([A-Z][^)]*\)).*$/!d;s//COV_FN(\1)/' |
37
tr '\12' ' ' | fold -sw72 | sed 's| $||;s|.*| & \\|'
39
#define DO_COV_CASES(COV_FN) \
40
COV_FN(NXT_L) COV_FN(NXT_N) COV_FN(FIB_P) COV_FN(FIB_E) COV_FN(FIB_N) \
41
COV_FN(FIB_L) COV_FN(PFB_C) COV_FN(PFB_P) COV_FN(PFB_A) \
42
COV_FN(PFB_G) COV_FN(PFB_H) COV_FN(SBC_C) COV_FN(SBC_B) COV_FN(SBC_N) \
43
COV_FN(SBC_L) COV_FN(EXB_R) COV_FN(EXB_A)
45
#define COV_COUNT(casename) coverage_case_##casename
46
#define DECLARE_COV_CASE(casename) static int COV_COUNT(casename);
47
DO_COV_CASES(DECLARE_COV_CASE)
48
#undef DECLARE_COV_CASE
50
static int current_coverage_mode = 0;
51
#define COV(casename) { \
52
if (current_coverage_mode != 0) { \
53
COV_COUNT(casename)++; \
57
bool inputStream::next() {
58
// We have to look at the current line first, just in case nobody
59
// actually called current_line() or done().
61
if (definitely_done()) {
62
return false; // OK to call this->next() after done is true
64
// current line is at buffer[beg..end]; now skip past its '\0'
65
assert(have_current_line(), "");
67
set_buffer_content(_next, _content_end);
68
if (!need_to_read()) { // any next line was already in the buffer
70
assert(have_current_line(), "");
72
} else { // go back to the source for more
78
void inputStream::set_done() {
79
size_t end = _beg = _end = _content_end;
80
_next = end + NEXT_PHANTOM;
82
assert(definitely_done(), "");
85
void inputStream::set_error(bool error_condition) {
86
if (error_condition) {
88
_input_state = IState::ERR_STATE;
91
_input_state = definitely_done() ? IState::EOF_STATE : IState::NTR_STATE;
95
void inputStream::clear_buffer() {
96
_content_end = _beg = _end = _next = 0;
100
const char* inputStream::next_content(size_t& next_content_length) const {
101
assert(is_sane(), "");
102
size_t len = buffered_content_length(false);
103
next_content_length = len;
104
return len == 0 ? "" : &_buffer[_next];
107
void inputStream::set_input(inputStream::Input* input) {
110
_input_state = IState::NTR_STATE;
113
bool inputStream::fill_buffer() {
114
size_t fill_offset, fill_length;
115
assert(!definitely_done(), ""); // caller responsibility
116
while (need_to_read()) {
117
prepare_to_fill_buffer(fill_offset, fill_length);
118
if (error()) return false;
119
assert(fill_length > 0, "");
120
assert(fill_offset < _buffer_size, "");
121
assert(fill_offset + fill_length <= _buffer_size, "");
123
if (_input != nullptr && _input_state == IState::NTR_STATE) {
124
nr = _input->read(&_buffer[fill_offset], fill_length);
125
if (nr == 0) _input_state = IState::EOF_STATE; // do not get EOF twice
127
bool last_partial = false;
130
} else if (_beg == _end) { // no partial line, so end it now
131
// we hit the end of the file (or there was never anything there)
133
assert(!definitely_done(), "");
135
assert(definitely_done(), "");
138
// pretend to read a newline, to complete the last partial line
140
_buffer[fill_offset++] = '\n'; // insert phantom newline
143
set_buffer_content(_beg, fill_offset);
144
assert(!definitely_done(), "");
145
if (need_to_read()) { COV(FIB_N); }
148
assert(have_current_line(), "");
150
_content_end -= 1; // reverse insertion of phantom newline
151
assert(_next == _content_end + NEXT_PHANTOM, "");
152
assert(have_current_line(), "");
158
// Find some space in the buffer for reading. If there is already a
159
// partial line in the buffer, new space must follow it immediately.
160
// The partial line is between _beg and _end, and no other parts of
161
// the buffer are in use.
162
void inputStream::prepare_to_fill_buffer(size_t& fill_offset,
163
size_t& fill_length) {
164
assert(need_to_read(), ""); // _next pointer out of the way
165
size_t end = _content_end;
166
if (_beg == end) { // if no partial line present...
170
fill_length = _buffer_size;
171
return; // use the whole buffer
173
// at this point we have a pending line that needs more input
174
if (_beg > 0 && (_input != nullptr || end == _buffer_size)) {
176
// compact the buffer by overwriting characters from previous lines
177
size_t shift_left = _beg;
178
::memmove(_buffer, _buffer + shift_left, _content_end - _beg);
182
_content_end -= shift_left;
185
if (end < _buffer_size) {
188
fill_length = _buffer_size - end;
189
return; // use the whole buffer except partial line at the beginning
191
// the whole buffer contains a partial line, which means we must expand
193
size_t new_size = (_buffer_size < BIG_SIZE ? BIG_SIZE
194
: _buffer_size + _buffer_size / 2);
195
assert(new_size > _buffer_size, "");
196
if (expand_buffer(new_size)) {
199
fill_length = _buffer_size - end;
200
return; // use the expanded buffer, except the partial line
202
// no recovery from failed allocation; just set the error state and bail
206
// The only buffer content is between the given offsets.
207
// Set _beg, _end, _next, and _content_end appropriately.
208
void inputStream::set_buffer_content(size_t content_start,
209
size_t content_end) {
210
assert(content_end <= _buffer_size, "");
211
assert(content_start <= content_end + NEXT_PHANTOM, "");
212
if (content_start >= content_end) { // empty content; clear buffer
218
size_t content_len = content_end - content_start;
219
_beg = content_start;
220
_content_end = content_end;
222
// this is where we scan for newlines
223
char* nl = (char*) memchr(&_buffer[content_start], '\n', content_len);
226
_next = _end = content_end;
228
assert(need_to_read(), "");
231
*nl = '\0'; // so that this->current_line() will work
233
size_t end = nl - &_buffer[0];
235
assert(_next != _content_end + NEXT_PHANTOM, "");
236
if (end > content_start && nl[-1] == '\r') { // yuck
237
// again, for this->current_line(), remove '\r' before '\n'
240
// Note: we could treat '\r' alone as a line ending on some
241
// platforms, but that is way too much work. Newline '\n' is
242
// supported everywhere, and some tools insist on accompanying
243
// it with return as well, so we remove that. But return '\r'
244
// by itself is an obsolete format, and also inconsistent with
245
// outputStream, which standarizes on '\n' and never emits '\r'.
246
// Postel's law suggests that we write '\n' only and grudgingly
247
// accept '\r' before '\n'.
249
_end = end; // now this->current_line() points to buf[beg..end]
250
_line_ending = (int)(_next - end);
251
assert(have_current_line(), "");
252
assert(current_line() == &_buffer[_beg], "");
253
assert(current_line_length() == _end - _beg, "");
257
// Return true iff we expanded the buffer to the given length.
258
bool inputStream::expand_buffer(size_t new_length) {
259
assert(new_length > _buffer_size, "");
260
char* new_buf = nullptr;
261
assert(new_length > sizeof(_small_buffer), "");
262
if (_buffer == &_small_buffer[0]) {
263
// fresh alloc from c-heap
265
new_buf = NEW_C_HEAP_ARRAY(char, new_length, mtInternal);
266
assert(new_buf != nullptr, "would have exited VM if OOM");
267
if (_content_end > 0) {
268
assert(_content_end <= _buffer_size, "");
269
::memcpy(new_buf, _buffer, _content_end); // copy only the active content
274
new_buf = REALLOC_C_HEAP_ARRAY(char, _buffer, new_length, mtInternal);
275
assert(new_buf != nullptr, "would have exited VM if OOM");
278
if (new_buf == nullptr) {
279
return false; // do not further update _buffer etc.
282
_buffer_size = new_length;
286
inputStream::~inputStream() {
287
if (has_c_heap_buffer()) {
289
DEBUG_ONLY(_buffer = (char*)((uintptr_t)0xdeadbeef)); // sanity
294
void inputStream::dump(const char* what) {
295
int diff = (int)(_end - _beg);
296
if (!_buffer || _beg > _buffer_size || _end > _buffer_size)
299
bool ntr = (_next == _end),
300
hcl = (_beg < _content_end && _end < _next),
301
ddn = (_beg == _content_end && _next > _content_end);
302
tty->print_cr("%s%sistream %s%s%s%s%s [%d<%.*s>%d/%d..%d] LE=%d,"
303
" B=%llx%s[%d], LN=%d, CH=%d",
304
what ? what : "", what ? ": " : "",
305
_buffer == nullptr ? "U" : "",
309
(_next < _content_end ? "" :
310
_next == _content_end ? "N" : "P"),
312
diff < 0 ? 0 : diff > 10 ? 10 : diff,
313
_buffer ? &_buffer[_beg] : "",
314
(int)_end, (int)_next, (int)_content_end,
316
(unsigned long long)(intptr_t)_buffer,
317
_buffer == _small_buffer ? "(SB)" : "",
320
has_c_heap_buffer());
321
assert(is_sane(), "");
326
// More support for coverage testing.
327
int inputStream::coverage_mode(int start,
328
int& cases, int& total, int& zeroes) {
329
int old_mode = current_coverage_mode;
330
current_coverage_mode = start;
331
int num_cases = 0, zero_count = 0, case_count = 0;
332
#define COUNT_COV_CASE(casename) { \
333
int tem = COV_COUNT(casename); \
335
if (tem == 0) ++zero_count; \
338
DO_COV_CASES(COUNT_COV_CASE)
341
tty->print("istream coverage:");
342
#define PRINT_COV_CASE(casename) \
343
tty->print(" %s:%d", #casename, COV_COUNT(casename));
344
DO_COV_CASES(PRINT_COV_CASE)
346
#undef PRINT_COV_CASE
347
if (zero_count != 0) {
348
case_count = -case_count;
349
#define ZERO_COV_CASE(casename) \
350
if (COV_COUNT(casename) == 0) \
351
tty->print_cr("%s: no coverage for %s", \
352
__FILE__, #casename); \
353
DO_COV_CASES(ZERO_COV_CASE)
357
if (start >= 2 || start < 0) {
358
#define CLEAR_COV_CASE(casename) \
359
COV_COUNT(casename) = 0;
360
DO_COV_CASES(CLEAR_COV_CASE)
361
#undef CLEAR_COV_CASE