36 assert(_pos == 0, "still outstanding bytes in the line buffer");
37 if (_buf != _smallbuf) {
38 os::free(_buf);
39 }
40 }
41
42 // try_ensure_cap tries to enlarge the capacity of the internal buffer
43 // to the given atleast value. May fail if either OOM happens or atleast
44 // is larger than a reasonable max of 1 M. Caller must not assume
45 // capacity without checking.
46 void LogStream::LineBuffer::try_ensure_cap(size_t atleast) {
47 assert(_cap >= sizeof(_smallbuf), "sanity");
48 if (_cap < atleast) {
49 // Cap out at a reasonable max to prevent runaway leaks.
50 const size_t reasonable_max = 1 * M;
51 assert(_cap <= reasonable_max, "sanity");
52 if (_cap == reasonable_max) {
53 return;
54 }
55
56 size_t newcap = align_up(atleast + 64, 64);
57 if (newcap > reasonable_max) {
58 log_info(logging)("Suspiciously long log line: \"%.100s%s",
59 _buf, (_pos >= 100 ? "..." : ""));
60 newcap = reasonable_max;
61 }
62
63 char* const newbuf = (char*) os::malloc(newcap, mtLogging);
64 if (newbuf == NULL) { // OOM. Leave object unchanged.
65 return;
66 }
67 if (_pos > 0) { // preserve old content
68 memcpy(newbuf, _buf, _pos + 1); // ..including trailing zero
69 }
70 if (_buf != _smallbuf) {
71 os::free(_buf);
72 }
73 _buf = newbuf;
74 _cap = newcap;
75 }
76 assert(_cap >= atleast, "sanity");
77 }
78
79 void LogStream::LineBuffer::append(const char* s, size_t len) {
80 assert(_buf[_pos] == '\0', "sanity");
81 assert(_pos < _cap, "sanity");
82 try_ensure_cap(_pos + len + 1);
83 // try_ensure_cap may not have enlarged the capacity to the full requested
84 // extend or may have not worked at all. In that case, just gracefully work
85 // with what we have already; just truncate if necessary.
86 if (_pos + len + 1 > _cap) {
87 len = _cap - _pos - 1;
88 if (len == 0) {
89 return;
90 }
91 }
92 memcpy(_buf + _pos, s, len);
93 _pos += len;
94 _buf[_pos] = '\0';
95 }
96
97 void LogStream::LineBuffer::reset() {
98 _pos = 0;
99 _buf[_pos] = '\0';
100 }
101
102 void LogStream::write(const char* s, size_t len) {
103 if (len > 0 && s[len - 1] == '\n') {
104 _current_line.append(s, len - 1); // omit the newline.
105 _log_handle.print("%s", _current_line.ptr());
106 _current_line.reset();
107 } else {
108 _current_line.append(s, len);
109 }
110 update_position(s, len);
111 }
112
|
36 assert(_pos == 0, "still outstanding bytes in the line buffer");
37 if (_buf != _smallbuf) {
38 os::free(_buf);
39 }
40 }
41
42 // try_ensure_cap tries to enlarge the capacity of the internal buffer
43 // to the given atleast value. May fail if either OOM happens or atleast
44 // is larger than a reasonable max of 1 M. Caller must not assume
45 // capacity without checking.
46 void LogStream::LineBuffer::try_ensure_cap(size_t atleast) {
47 assert(_cap >= sizeof(_smallbuf), "sanity");
48 if (_cap < atleast) {
49 // Cap out at a reasonable max to prevent runaway leaks.
50 const size_t reasonable_max = 1 * M;
51 assert(_cap <= reasonable_max, "sanity");
52 if (_cap == reasonable_max) {
53 return;
54 }
55
56 const size_t additional_expansion = 256;
57 size_t newcap = align_up(atleast + additional_expansion, additional_expansion);
58 if (newcap > reasonable_max) {
59 log_info(logging)("Suspiciously long log line: \"%.100s%s",
60 _buf, (_pos >= 100 ? "..." : ""));
61 newcap = reasonable_max;
62 }
63
64 char* const newbuf = (char*) os::malloc(newcap, mtLogging);
65 if (newbuf == NULL) { // OOM. Leave object unchanged.
66 return;
67 }
68 if (_pos > 0) { // preserve old content
69 memcpy(newbuf, _buf, _pos + 1); // ..including trailing zero
70 }
71 if (_buf != _smallbuf) {
72 os::free(_buf);
73 }
74 _buf = newbuf;
75 _cap = newcap;
76 }
77 assert(_cap >= atleast, "sanity");
78 }
79
80 void LogStream::LineBuffer::append(const char* s, size_t len) {
81 assert(_buf[_pos] == '\0', "sanity");
82 assert(_pos < _cap, "sanity");
83 const size_t minimum_capacity_needed = _pos + len + 1;
84 try_ensure_cap(minimum_capacity_needed);
85 // try_ensure_cap may not have enlarged the capacity to the full requested
86 // extend or may have not worked at all. In that case, just gracefully work
87 // with what we have already; just truncate if necessary.
88 if (_cap < minimum_capacity_needed) {
89 len = _cap - _pos - 1;
90 if (len == 0) {
91 return;
92 }
93 }
94 memcpy(_buf + _pos, s, len);
95 _pos += len;
96 _buf[_pos] = '\0';
97 }
98
99 void LogStream::LineBuffer::reset() {
100 _pos = 0;
101 _buf[_pos] = '\0';
102 }
103
104 void LogStream::write(const char* s, size_t len) {
105 if (len > 0 && s[len - 1] == '\n') {
106 _current_line.append(s, len - 1); // omit the newline.
107 _log_handle.print("%s", _current_line.buffer());
108 _current_line.reset();
109 } else {
110 _current_line.append(s, len);
111 }
112 update_position(s, len);
113 }
114
|