annotate lld/COFF/MarkLive.cpp @ 213:25ca0248ac32

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 11 Jul 2021 17:05:31 +0900
parents 0572611fdcc8
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- MarkLive.cpp -------------------------------------------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "Chunks.h"
anatofuz
parents:
diff changeset
10 #include "Symbols.h"
anatofuz
parents:
diff changeset
11 #include "lld/Common/Timer.h"
anatofuz
parents:
diff changeset
12 #include "llvm/ADT/STLExtras.h"
anatofuz
parents:
diff changeset
13 #include <vector>
anatofuz
parents:
diff changeset
14
anatofuz
parents:
diff changeset
15 namespace lld {
anatofuz
parents:
diff changeset
16 namespace coff {
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 static Timer gctimer("GC", Timer::root());
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 // Set live bit on for each reachable chunk. Unmarked (unreachable)
anatofuz
parents:
diff changeset
21 // COMDAT chunks will be ignored by Writer, so they will be excluded
anatofuz
parents:
diff changeset
22 // from the final output.
anatofuz
parents:
diff changeset
23 void markLive(ArrayRef<Chunk *> chunks) {
anatofuz
parents:
diff changeset
24 ScopedTimer t(gctimer);
anatofuz
parents:
diff changeset
25
anatofuz
parents:
diff changeset
26 // We build up a worklist of sections which have been marked as live. We only
anatofuz
parents:
diff changeset
27 // push into the worklist when we discover an unmarked section, and we mark
anatofuz
parents:
diff changeset
28 // as we push, so sections never appear twice in the list.
anatofuz
parents:
diff changeset
29 SmallVector<SectionChunk *, 256> worklist;
anatofuz
parents:
diff changeset
30
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
31 // COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
32 // traverse DWARF sections. They are live, but they should not keep other
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
33 // sections alive.
150
anatofuz
parents:
diff changeset
34 for (Chunk *c : chunks)
anatofuz
parents:
diff changeset
35 if (auto *sc = dyn_cast<SectionChunk>(c))
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
36 if (sc->live && !sc->isDWARF())
150
anatofuz
parents:
diff changeset
37 worklist.push_back(sc);
anatofuz
parents:
diff changeset
38
anatofuz
parents:
diff changeset
39 auto enqueue = [&](SectionChunk *c) {
anatofuz
parents:
diff changeset
40 if (c->live)
anatofuz
parents:
diff changeset
41 return;
anatofuz
parents:
diff changeset
42 c->live = true;
anatofuz
parents:
diff changeset
43 worklist.push_back(c);
anatofuz
parents:
diff changeset
44 };
anatofuz
parents:
diff changeset
45
anatofuz
parents:
diff changeset
46 auto addSym = [&](Symbol *b) {
anatofuz
parents:
diff changeset
47 if (auto *sym = dyn_cast<DefinedRegular>(b))
anatofuz
parents:
diff changeset
48 enqueue(sym->getChunk());
anatofuz
parents:
diff changeset
49 else if (auto *sym = dyn_cast<DefinedImportData>(b))
anatofuz
parents:
diff changeset
50 sym->file->live = true;
anatofuz
parents:
diff changeset
51 else if (auto *sym = dyn_cast<DefinedImportThunk>(b))
anatofuz
parents:
diff changeset
52 sym->wrappedSym->file->live = sym->wrappedSym->file->thunkLive = true;
anatofuz
parents:
diff changeset
53 };
anatofuz
parents:
diff changeset
54
anatofuz
parents:
diff changeset
55 // Add GC root chunks.
anatofuz
parents:
diff changeset
56 for (Symbol *b : config->gcroot)
anatofuz
parents:
diff changeset
57 addSym(b);
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 while (!worklist.empty()) {
anatofuz
parents:
diff changeset
60 SectionChunk *sc = worklist.pop_back_val();
anatofuz
parents:
diff changeset
61 assert(sc->live && "We mark as live when pushing onto the worklist!");
anatofuz
parents:
diff changeset
62
anatofuz
parents:
diff changeset
63 // Mark all symbols listed in the relocation table for this section.
anatofuz
parents:
diff changeset
64 for (Symbol *b : sc->symbols())
anatofuz
parents:
diff changeset
65 if (b)
anatofuz
parents:
diff changeset
66 addSym(b);
anatofuz
parents:
diff changeset
67
anatofuz
parents:
diff changeset
68 // Mark associative sections if any.
anatofuz
parents:
diff changeset
69 for (SectionChunk &c : sc->children())
anatofuz
parents:
diff changeset
70 enqueue(&c);
anatofuz
parents:
diff changeset
71 }
anatofuz
parents:
diff changeset
72 }
anatofuz
parents:
diff changeset
73
anatofuz
parents:
diff changeset
74 }
anatofuz
parents:
diff changeset
75 }