Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8259710: Inlining trace leaks memory
Reviewed-by: thartmann, neliasso
  • Loading branch information
tstuefe committed Jan 25, 2021
1 parent 09489e2 commit ca20c63c04dc4890e93bb2ee1cf534188f73756f
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 29 deletions.
@@ -4184,12 +4184,7 @@ void Compile::print_inlining_init() {
// print_inlining_init is actually called several times.
print_inlining_stream_free();
_print_inlining_stream = new stringStream();
// Watch out: The memory initialized by the constructor call 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());
_print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer*>(comp_arena(), 1, 1, new PrintInliningBuffer());
}
}

@@ -4209,32 +4204,32 @@ void Compile::print_inlining_commit() {
assert(print_inlining() || print_intrinsics(), "PrintInlining off?");
// Transfer the message from _print_inlining_stream to the current
// _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();
}

void Compile::print_inlining_push() {
// Add new buffer to the _print_inlining_list at current position
_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);
}

void Compile::print_inlining_update(CallGenerator* cg) {
if (print_inlining() || print_intrinsics()) {
if (cg->is_late_inline()) {
if (print_inlining_current().cg() != cg &&
(print_inlining_current().cg() != NULL ||
print_inlining_current().ss()->size() != 0)) {
if (print_inlining_current()->cg() != cg &&
(print_inlining_current()->cg() != NULL ||
print_inlining_current()->ss()->size() != 0)) {
print_inlining_push();
}
print_inlining_commit();
print_inlining_current().set_cg(cg);
print_inlining_current()->set_cg(cg);
} else {
if (print_inlining_current().cg() != NULL) {
if (print_inlining_current()->cg() != NULL) {
print_inlining_push();
}
print_inlining_commit();
@@ -4247,7 +4242,7 @@ void Compile::print_inlining_move_to(CallGenerator* cg) {
// corresponding inlining buffer so that we can update it.
if (print_inlining() || print_intrinsics()) {
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;
return;
}
@@ -4259,11 +4254,11 @@ void Compile::print_inlining_move_to(CallGenerator* cg) {
void Compile::print_inlining_update_delayed(CallGenerator* cg) {
if (print_inlining() || print_intrinsics()) {
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
_print_inlining_list->at_put(_print_inlining_idx, PrintInliningBuffer());
_print_inlining_list->at_put(_print_inlining_idx, new PrintInliningBuffer());
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;
assert(_print_inlining_list != NULL, "process_print_inlining should be called only once.");
for (int i = 0; i < _print_inlining_list->length(); i++) {
ss.print("%s", _print_inlining_list->adr_at(i)->ss()->as_string());
_print_inlining_list->at(i).freeStream();
PrintInliningBuffer* pib = _print_inlining_list->at(i);
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.
// It is on the arena, so it will be freed when the arena is reset.
@@ -392,24 +392,23 @@ class Compile : public Phase {
// Inlining may not happen in parse order which would make
// PrintInlining output confusing. Keep track of PrintInlining
// pieces in order.
class PrintInliningBuffer : public ResourceObj {
class PrintInliningBuffer : public CHeapObj<mtCompiler> {
private:
CallGenerator* _cg;
stringStream* _ss;
stringStream _ss;
static const size_t default_stream_buffer_size = 128;

public:
PrintInliningBuffer()
: _cg(NULL) { _ss = new stringStream(); }
: _cg(NULL), _ss(default_stream_buffer_size) {}

void freeStream() { _ss->~stringStream(); _ss = NULL; }

stringStream* ss() const { return _ss; }
CallGenerator* cg() const { return _cg; }
stringStream* ss() { return &_ss; }
CallGenerator* cg() { return _cg; }
void set_cg(CallGenerator* cg) { _cg = cg; }
};

stringStream* _print_inlining_stream;
GrowableArray<PrintInliningBuffer>* _print_inlining_list;
GrowableArray<PrintInliningBuffer*>* _print_inlining_list;
int _print_inlining_idx;
char* _print_inlining_output;

@@ -429,7 +428,7 @@ class Compile : public Phase {
void print_inlining_reinit();
void print_inlining_commit();
void print_inlining_push();
PrintInliningBuffer& print_inlining_current();
PrintInliningBuffer* print_inlining_current();

void log_late_inline_failure(CallGenerator* cg, const char* msg);
DEBUG_ONLY(bool _exception_backedge;)

0 comments on commit ca20c63

Please sign in to comment.