8259710: Inlining trace leaks memory

Reviewed-by: thartmann, neliasso
This commit is contained in:
Thomas Stuefe 2021-01-25 10:50:39 +00:00
parent 09489e28bd
commit ca20c63c04
2 changed files with 25 additions and 29 deletions

View file

@ -4184,12 +4184,7 @@ void Compile::print_inlining_init() {
// print_inlining_init is actually called several times. // print_inlining_init is actually called several times.
print_inlining_stream_free(); print_inlining_stream_free();
_print_inlining_stream = new stringStream(); _print_inlining_stream = new stringStream();
// Watch out: The memory initialized by the constructor call PrintInliningBuffer() _print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer*>(comp_arena(), 1, 1, new PrintInliningBuffer());
// will be copied into the only initial element. The default destructor of
// PrintInliningBuffer will be called when leaving the scope here. If it
// would destuct the enclosed stringStream _print_inlining_list[0]->_ss
// would be destructed, too!
_print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
} }
} }
@ -4209,32 +4204,32 @@ void Compile::print_inlining_commit() {
assert(print_inlining() || print_intrinsics(), "PrintInlining off?"); assert(print_inlining() || print_intrinsics(), "PrintInlining off?");
// Transfer the message from _print_inlining_stream to the current // Transfer the message from _print_inlining_stream to the current
// _print_inlining_list buffer and clear _print_inlining_stream. // _print_inlining_list buffer and clear _print_inlining_stream.
_print_inlining_list->at(_print_inlining_idx).ss()->write(_print_inlining_stream->base(), _print_inlining_stream->size()); _print_inlining_list->at(_print_inlining_idx)->ss()->write(_print_inlining_stream->base(), _print_inlining_stream->size());
print_inlining_reset(); print_inlining_reset();
} }
void Compile::print_inlining_push() { void Compile::print_inlining_push() {
// Add new buffer to the _print_inlining_list at current position // Add new buffer to the _print_inlining_list at current position
_print_inlining_idx++; _print_inlining_idx++;
_print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer()); _print_inlining_list->insert_before(_print_inlining_idx, new PrintInliningBuffer());
} }
Compile::PrintInliningBuffer& Compile::print_inlining_current() { Compile::PrintInliningBuffer* Compile::print_inlining_current() {
return _print_inlining_list->at(_print_inlining_idx); return _print_inlining_list->at(_print_inlining_idx);
} }
void Compile::print_inlining_update(CallGenerator* cg) { void Compile::print_inlining_update(CallGenerator* cg) {
if (print_inlining() || print_intrinsics()) { if (print_inlining() || print_intrinsics()) {
if (cg->is_late_inline()) { if (cg->is_late_inline()) {
if (print_inlining_current().cg() != cg && if (print_inlining_current()->cg() != cg &&
(print_inlining_current().cg() != NULL || (print_inlining_current()->cg() != NULL ||
print_inlining_current().ss()->size() != 0)) { print_inlining_current()->ss()->size() != 0)) {
print_inlining_push(); print_inlining_push();
} }
print_inlining_commit(); print_inlining_commit();
print_inlining_current().set_cg(cg); print_inlining_current()->set_cg(cg);
} else { } else {
if (print_inlining_current().cg() != NULL) { if (print_inlining_current()->cg() != NULL) {
print_inlining_push(); print_inlining_push();
} }
print_inlining_commit(); print_inlining_commit();
@ -4247,7 +4242,7 @@ void Compile::print_inlining_move_to(CallGenerator* cg) {
// corresponding inlining buffer so that we can update it. // corresponding inlining buffer so that we can update it.
if (print_inlining() || print_intrinsics()) { if (print_inlining() || print_intrinsics()) {
for (int i = 0; i < _print_inlining_list->length(); i++) { for (int i = 0; i < _print_inlining_list->length(); i++) {
if (_print_inlining_list->adr_at(i)->cg() == cg) { if (_print_inlining_list->at(i)->cg() == cg) {
_print_inlining_idx = i; _print_inlining_idx = i;
return; return;
} }
@ -4259,11 +4254,11 @@ void Compile::print_inlining_move_to(CallGenerator* cg) {
void Compile::print_inlining_update_delayed(CallGenerator* cg) { void Compile::print_inlining_update_delayed(CallGenerator* cg) {
if (print_inlining() || print_intrinsics()) { if (print_inlining() || print_intrinsics()) {
assert(_print_inlining_stream->size() > 0, "missing inlining msg"); assert(_print_inlining_stream->size() > 0, "missing inlining msg");
assert(print_inlining_current().cg() == cg, "wrong entry"); assert(print_inlining_current()->cg() == cg, "wrong entry");
// replace message with new message // replace message with new message
_print_inlining_list->at_put(_print_inlining_idx, PrintInliningBuffer()); _print_inlining_list->at_put(_print_inlining_idx, new PrintInliningBuffer());
print_inlining_commit(); print_inlining_commit();
print_inlining_current().set_cg(cg); print_inlining_current()->set_cg(cg);
} }
} }
@ -4278,8 +4273,10 @@ void Compile::process_print_inlining() {
stringStream ss; stringStream ss;
assert(_print_inlining_list != NULL, "process_print_inlining should be called only once."); assert(_print_inlining_list != NULL, "process_print_inlining should be called only once.");
for (int i = 0; i < _print_inlining_list->length(); i++) { for (int i = 0; i < _print_inlining_list->length(); i++) {
ss.print("%s", _print_inlining_list->adr_at(i)->ss()->as_string()); PrintInliningBuffer* pib = _print_inlining_list->at(i);
_print_inlining_list->at(i).freeStream(); ss.print("%s", pib->ss()->as_string());
delete pib;
DEBUG_ONLY(_print_inlining_list->at_put(i, NULL));
} }
// Reset _print_inlining_list, it only contains destructed objects. // Reset _print_inlining_list, it only contains destructed objects.
// It is on the arena, so it will be freed when the arena is reset. // It is on the arena, so it will be freed when the arena is reset.

View file

@ -392,24 +392,23 @@ class Compile : public Phase {
// Inlining may not happen in parse order which would make // Inlining may not happen in parse order which would make
// PrintInlining output confusing. Keep track of PrintInlining // PrintInlining output confusing. Keep track of PrintInlining
// pieces in order. // pieces in order.
class PrintInliningBuffer : public ResourceObj { class PrintInliningBuffer : public CHeapObj<mtCompiler> {
private: private:
CallGenerator* _cg; CallGenerator* _cg;
stringStream* _ss; stringStream _ss;
static const size_t default_stream_buffer_size = 128;
public: public:
PrintInliningBuffer() PrintInliningBuffer()
: _cg(NULL) { _ss = new stringStream(); } : _cg(NULL), _ss(default_stream_buffer_size) {}
void freeStream() { _ss->~stringStream(); _ss = NULL; } stringStream* ss() { return &_ss; }
CallGenerator* cg() { return _cg; }
stringStream* ss() const { return _ss; }
CallGenerator* cg() const { return _cg; }
void set_cg(CallGenerator* cg) { _cg = cg; } void set_cg(CallGenerator* cg) { _cg = cg; }
}; };
stringStream* _print_inlining_stream; stringStream* _print_inlining_stream;
GrowableArray<PrintInliningBuffer>* _print_inlining_list; GrowableArray<PrintInliningBuffer*>* _print_inlining_list;
int _print_inlining_idx; int _print_inlining_idx;
char* _print_inlining_output; char* _print_inlining_output;
@ -429,7 +428,7 @@ class Compile : public Phase {
void print_inlining_reinit(); void print_inlining_reinit();
void print_inlining_commit(); void print_inlining_commit();
void print_inlining_push(); void print_inlining_push();
PrintInliningBuffer& print_inlining_current(); PrintInliningBuffer* print_inlining_current();
void log_late_inline_failure(CallGenerator* cg, const char* msg); void log_late_inline_failure(CallGenerator* cg, const char* msg);
DEBUG_ONLY(bool _exception_backedge;) DEBUG_ONLY(bool _exception_backedge;)