Skip to content

Commit 572510c

Browse files
[ClusterLegalizer] Fixed Memory Leak
A memory leak was able to occur if the external pin utilization string was set to an invalid number. This was caught by the CI, which inexplicably came back to life today.
1 parent 09d498f commit 572510c

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

vpr/src/pack/cluster_legalizer.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,19 @@ ClusterLegalizer::ClusterLegalizer(const AtomNetlist& atom_netlist,
16371637
// Verify that the inputs are valid.
16381638
VTR_ASSERT_SAFE(lb_type_rr_graphs != nullptr);
16391639

1640+
// Get the target external pin utilization
1641+
// NOTE: This has to be initialized first due to the fact that VPR_FATA_ERROR
1642+
// may be called within the constructor of t_ext_pin_util_targets. If
1643+
// this occurs, the destructor may or may not be called (honestly I have
1644+
// no idea why it does or does not, but it changes based on how VPR
1645+
// is compiled...). If the destructor is not called, it is important
1646+
// that nothing was allocated before this line is called. If the
1647+
// destructor is called, we just need to be careful of double freeing
1648+
// (check if the allocated member variables are nullptr).
1649+
// FIXME: This can be fixed by removing all allocations from the constructor
1650+
// (see cluster_placement_stats_).
1651+
target_external_pin_util_ = t_ext_pin_util_targets(target_external_pin_util_str);
1652+
16401653
// Resize the atom_cluster lookup to make the accesses much cheaper.
16411654
atom_cluster_.resize(atom_netlist.blocks().size(), LegalizationClusterId::INVALID());
16421655
// Allocate the cluster_placement_stats
@@ -1662,15 +1675,6 @@ ClusterLegalizer::ClusterLegalizer(const AtomNetlist& atom_netlist,
16621675
enable_pin_feasibility_filter_ = enable_pin_feasibility_filter;
16631676
feasible_block_array_size_ = feasible_block_array_size;
16641677
log_verbosity_ = log_verbosity;
1665-
// Get the target external pin utilization
1666-
// NOTE: This has to be initialized last due to the fact that VPR_FATA_ERROR
1667-
// may be called within the constructor of t_ext_pin_util_targets. If
1668-
// this occurs, an excpetion is thrown which will drain the stack. If
1669-
// the cluster legalizer object is stored on the stack, this can call
1670-
// the destructor prematurely (before certain structures are allocated).
1671-
// Therefore, this is created at the end, when the class is in a state
1672-
// where it can be destroyed.
1673-
target_external_pin_util_ = t_ext_pin_util_targets(target_external_pin_util_str);
16741678
}
16751679

16761680
void ClusterLegalizer::reset() {
@@ -1776,6 +1780,7 @@ ClusterLegalizer::~ClusterLegalizer() {
17761780
destroy_cluster(cluster_id);
17771781
}
17781782
// Free the cluster_placement_stats
1779-
free_cluster_placement_stats(cluster_placement_stats_);
1783+
if (cluster_placement_stats_ != nullptr)
1784+
free_cluster_placement_stats(cluster_placement_stats_);
17801785
}
17811786

0 commit comments

Comments
 (0)