From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) by sourceware.org (Postfix) with ESMTPS id B4FB63858C60; Sun, 19 Dec 2021 21:30:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B4FB63858C60 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nieper-wisskirchen.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-f46.google.com with SMTP id t26so16156672wrb.4; Sun, 19 Dec 2021 13:30:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=XcPcur8foFtJ00NZMMmPyzViEmKIs+K0i4e0NCBVi5E=; b=NA1MslHVxRZ3dp8aCjn/wYEQbUz7qejWF60ZBQjdazu+NwNoekK7DB73Mj+fKjn/1r FrW+wwh5lp/HiXMVS0cFXomXte2KUfmfxYzsGuK8bfU9/VZfW8pXKPS8tcSGAlhwQpgV HFClokoDIaHXY0okmue2cPYGlLElxKpo14uln9tRjAFIRYQSrbuzMRWUxx1jdsCzKULI FSoTft12EDTnsHJ4EKWKVJPCbJ8TqrgUx1un8747Ood1QDqLWDDtrKCA1Av/qAEpfkm6 DGcv5SLOOQPps52FT0v9UfOzjt9oG7uC7R9+Ax6aBivrHDnTr3EwNdF0Ukrmcny6/hmm aU8Q== X-Gm-Message-State: AOAM530u7jQH+Llk7cEtgvtvOM4lj+kfAZhZVBPtAZ/S/nHL4/SrnIRO HKRnSUG7yB7mY0QOqCPCVyAGtQB0fjA= X-Google-Smtp-Source: ABdhPJy6mC8MoS/E72rbum3rDezKr/wwztU1zFdrUSplVPZRTv0n1qZShIlDls3i96RmX0toa10X2A== X-Received: by 2002:a05:6000:10d2:: with SMTP id b18mr9853529wrx.193.1639949439317; Sun, 19 Dec 2021 13:30:39 -0800 (PST) Received: from caesar.localdomain (ipbcc1ad82.dynamic.kabel-deutschland.de. [188.193.173.130]) by smtp.googlemail.com with ESMTPSA id 4sm19978312wrz.90.2021.12.19.13.30.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Dec 2021 13:30:38 -0800 (PST) From: =?UTF-8?q?Marc=20Nieper-Wi=C3=9Fkirchen?= To: gcc-patches@gcc.gnu.org Cc: jit@gcc.gnu.org, dmalcolm@redhat.com, =?UTF-8?q?Marc=20Nieper-Wi=C3=9Fkirchen?= Subject: [PATCH] gcc: pass-manager: Fix memory leak. [PR jit/63854] Date: Sun, 19 Dec 2021 22:30:10 +0100 Message-Id: <20211219213010.17113-1-marc@nieper-wisskirchen.de> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: jit@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Jit mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 19 Dec 2021 21:30:43 -0000 This patch fixes a memory leak in the pass manager. In the existing code, the m_name_to_pass_map is allocated in pass_manager::register_pass_name, but never deallocated. This is fixed by adding a deletion in pass_manager::~pass_manager. Moreover the string keys in m_name_to_pass_map are all dynamically allocated. To free them, this patch adds a new hash trait for string hashes that are to be freed when the corresponding hash entry is removed. This fix is particularly relevant for using GCC as a library through libgccjit. The memory leak also occurs when libgccjit is instructed to use an external driver. Before the patch, compiling the hello world example of libgccjit with the external driver under Valgrind shows a loss of 12,611 (48 direct) bytes. After the patch, no memory leaks are reported anymore. (Memory leaks occurring when using the internal driver are mostly in the driver code in gcc/gcc.c and have to be fixed separately.) The patch has been tested by fully bootstrapping the compiler with the frontends C, C++, Fortran, LTO, ObjC, JIT and running the test suite under a x86_64-pc-linux-gnu host. gcc/ChangeLog: PR jit/63854 * hash-traits.h (struct typed_const_free_remove): New. (struct free_string_hash): New. * pass_manager.h: Use free_string_hash. * passes.c (pass_manager::register_pass_name): Use free_string_hash. (pass_manager::~pass_manager): Delete allocated m_name_to_pass_map. --- gcc/hash-traits.h | 17 +++++++++++++++++ gcc/pass_manager.h | 3 +-- gcc/passes.c | 5 +++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/gcc/hash-traits.h b/gcc/hash-traits.h index 6f0373ec27f..1c08d6874ab 100644 --- a/gcc/hash-traits.h +++ b/gcc/hash-traits.h @@ -28,6 +28,11 @@ struct typed_free_remove static inline void remove (Type *p); }; +template +struct typed_const_free_remove +{ + static inline void remove (const Type *p); +}; /* Remove with free. */ @@ -38,6 +43,13 @@ typed_free_remove ::remove (Type *p) free (p); } +template +inline void +typed_const_free_remove ::remove (const Type *p) +{ + free (const_cast (p)); +} + /* Helpful type for removing with delete. */ template @@ -305,6 +317,11 @@ struct ggc_ptr_hash : pointer_hash , ggc_remove {}; template struct ggc_cache_ptr_hash : pointer_hash , ggc_cache_remove {}; +/* Traits for string elements that should be freed when an element is + deleted. */ + +struct free_string_hash : string_hash, typed_const_free_remove {}; + /* Traits for string elements that should not be freed when an element is deleted. */ diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h index aaf72cf6803..f5615e1fda8 100644 --- a/gcc/pass_manager.h +++ b/gcc/pass_manager.h @@ -106,7 +106,7 @@ private: private: context *m_ctxt; - hash_map *m_name_to_pass_map; + hash_map *m_name_to_pass_map; /* References to all of the individual passes. These fields are generated via macro expansion. @@ -146,4 +146,3 @@ private: } // namespace gcc #endif /* ! GCC_PASS_MANAGER_H */ - diff --git a/gcc/passes.c b/gcc/passes.c index 4bea6ae5b6a..0c70ece5321 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -903,7 +903,7 @@ void pass_manager::register_pass_name (opt_pass *pass, const char *name) { if (!m_name_to_pass_map) - m_name_to_pass_map = new hash_map (256); + m_name_to_pass_map = new hash_map (256); if (m_name_to_pass_map->get (name)) return; /* Ignore plugin passes. */ @@ -1674,6 +1674,7 @@ pass_manager::~pass_manager () GCC_PASS_LISTS #undef DEF_PASS_LIST + delete m_name_to_pass_map; } /* If we are in IPA mode (i.e., current_function_decl is NULL), call @@ -1943,7 +1944,7 @@ pass_manager::dump_profile_report () const " |in count |out prob " "|in count |out prob " "|size |time |\n"); - + for (int i = 1; i < passes_by_id_size; i++) if (profile_record[i].run) { -- 2.32.0