brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 78f5030 Raw
89 lines · cpp
1//===- MarkLive.cpp -------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "COFFLinkerContext.h"10#include "Chunks.h"11#include "Symbols.h"12#include "lld/Common/Timer.h"13#include "llvm/Support/TimeProfiler.h"14 15namespace lld::coff {16 17// Set live bit on for each reachable chunk. Unmarked (unreachable)18// COMDAT chunks will be ignored by Writer, so they will be excluded19// from the final output.20void markLive(COFFLinkerContext &ctx) {21  llvm::TimeTraceScope timeScope("Mark live");22  ScopedTimer t(ctx.gcTimer);23 24  // We build up a worklist of sections which have been marked as live. We only25  // push into the worklist when we discover an unmarked section, and we mark26  // as we push, so sections never appear twice in the list.27  SmallVector<SectionChunk *, 256> worklist;28 29  // COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not30  // traverse DWARF sections. They are live, but they should not keep other31  // sections alive.32  for (Chunk *c : ctx.driver.getChunks())33    if (auto *sc = dyn_cast<SectionChunk>(c))34      if (sc->live && !sc->isDWARF())35        worklist.push_back(sc);36 37  auto enqueue = [&](SectionChunk *c) {38    if (c->live)39      return;40    c->live = true;41    worklist.push_back(c);42  };43 44  std::function<void(Symbol *)> addSym;45 46  auto addImportFile = [&](ImportFile *file) {47    file->live = true;48    if (file->impchkThunk && file->impchkThunk->exitThunk)49      addSym(file->impchkThunk->exitThunk);50  };51 52  addSym = [&](Symbol *s) {53    Defined *b = s->getDefined();54    if (!b)55      return;56    if (auto *sym = dyn_cast<DefinedRegular>(b)) {57      enqueue(sym->getChunk());58    } else if (auto *sym = dyn_cast<DefinedImportData>(b)) {59      addImportFile(sym->file);60    } else if (auto *sym = dyn_cast<DefinedImportThunk>(b)) {61      addImportFile(sym->wrappedSym->file);62      sym->getChunk()->live = true;63    }64  };65 66  // Add GC root chunks.67  for (Symbol *b : ctx.config.gcroot)68    addSym(b);69 70  while (!worklist.empty()) {71    SectionChunk *sc = worklist.pop_back_val();72    assert(sc->live && "We mark as live when pushing onto the worklist!");73 74    // Mark all symbols listed in the relocation table for this section.75    for (Symbol *b : sc->symbols())76      if (b)77        addSym(b);78 79    // Mark associative sections if any.80    for (SectionChunk &c : sc->children())81      enqueue(&c);82 83    // Mark EC entry thunks.84    if (Defined *entryThunk = sc->getEntryThunk())85      addSym(entryThunk);86  }87}88}89