Fix a clang memory leak
authorYonghong Song <yhs@fb.com>
Tue, 18 Jul 2017 06:20:17 +0000 (23:20 -0700)
committerYonghong Song <yhs@fb.com>
Tue, 18 Jul 2017 06:20:17 +0000 (23:20 -0700)
In clang frontend actions, several compiler invocations are called
for rewriter and transforming source code to IR. During the invocation
to transform source code to IR, CodeGenOpts.DisableFree is used
to control whether the top target machine structure should be
freed or not for a particular clang invocation,
and its default value is TRUE.

See clang:lib/CodeGen/BackendUtil.cpp:
  ~EmitAssemblyHelper() {
    if (CodeGenOpts.DisableFree)
      BuryPointer(std::move(TM));
  }

So by default, the memory held by TM will not freed, even if
BPF module itself is freed. This is even more problematic
when continuous building/loading/unloading happens for long
live service.

This patch explicitly sets CodeGenOpts.DisableFree to FALSE
so memory can be properly freed. I did a simple experiment
to compile/load/unload an empty BPF program and the saving
is roughly 0.5MB.

Signed-off-by: Yonghong Song <yhs@fb.com>
src/cc/frontends/clang/loader.cc

index e16ce02..5c1f8be 100644 (file)
@@ -296,6 +296,7 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, TableStorage &ts, const st
   invocation2.getFrontendOpts().Inputs.push_back(FrontendInputFile(
       main_path, FrontendOptions::getInputKindForExtension("c")));
   invocation2.getFrontendOpts().DisableFree = false;
+  invocation2.getCodeGenOpts().DisableFree = false;
   // Resort to normal inlining. In -O0 the default is OnlyAlwaysInlining and
   // clang might add noinline attribute even for functions with inline hint.
   invocation2.getCodeGenOpts().setInlining(CodeGenOptions::NormalInlining);