1fe6060f1SDimitry Andric //===- GCStrategy.cpp - Garbage Collector Description ---------------------===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric // 9fe6060f1SDimitry Andric // This file implements the policy object GCStrategy which describes the 10fe6060f1SDimitry Andric // behavior of a given garbage collector. 11fe6060f1SDimitry Andric // 12fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 13fe6060f1SDimitry Andric 14fe6060f1SDimitry Andric #include "llvm/IR/GCStrategy.h" 15fcaf7f86SDimitry Andric #include "llvm/ADT/Twine.h" 16*bdd1243dSDimitry Andric #include "llvm/IR/BuiltinGCs.h" 17fe6060f1SDimitry Andric 18fe6060f1SDimitry Andric using namespace llvm; 19fe6060f1SDimitry Andric 20fe6060f1SDimitry Andric LLVM_INSTANTIATE_REGISTRY(GCRegistry) 21fe6060f1SDimitry Andric 22fe6060f1SDimitry Andric GCStrategy::GCStrategy() = default; 23349cc55cSDimitry Andric getGCStrategy(const StringRef Name)24349cc55cSDimitry Andricstd::unique_ptr<GCStrategy> llvm::getGCStrategy(const StringRef Name) { 25349cc55cSDimitry Andric for (auto &S : GCRegistry::entries()) 26349cc55cSDimitry Andric if (S.getName() == Name) 27349cc55cSDimitry Andric return S.instantiate(); 28349cc55cSDimitry Andric 29*bdd1243dSDimitry Andric // We need to link all the builtin GCs when LLVM is used as a static library. 30*bdd1243dSDimitry Andric // The linker will quite happily remove the static constructors that register 31*bdd1243dSDimitry Andric // the builtin GCs if we don't use a function from that object. This function 32*bdd1243dSDimitry Andric // does nothing but we need to make sure it is (or at least could be, even 33*bdd1243dSDimitry Andric // with all optimisations enabled) called *somewhere*, and this is a good 34*bdd1243dSDimitry Andric // place to do that: if the GC strategies are being used then this function 35*bdd1243dSDimitry Andric // obviously can't be removed by the linker, and here it won't affect 36*bdd1243dSDimitry Andric // performance, since there's about to be a fatal error anyway. 37*bdd1243dSDimitry Andric llvm::linkAllBuiltinGCs(); 38*bdd1243dSDimitry Andric 39349cc55cSDimitry Andric if (GCRegistry::begin() == GCRegistry::end()) { 40349cc55cSDimitry Andric // In normal operation, the registry should not be empty. There should 41349cc55cSDimitry Andric // be the builtin GCs if nothing else. The most likely scenario here is 42349cc55cSDimitry Andric // that we got here without running the initializers used by the Registry 43349cc55cSDimitry Andric // itself and it's registration mechanism. 44349cc55cSDimitry Andric const std::string error = 45349cc55cSDimitry Andric std::string("unsupported GC: ") + Name.str() + 46349cc55cSDimitry Andric " (did you remember to link and initialize the library?)"; 47fcaf7f86SDimitry Andric report_fatal_error(Twine(error)); 48349cc55cSDimitry Andric } else 49fcaf7f86SDimitry Andric report_fatal_error(Twine(std::string("unsupported GC: ") + Name.str())); 50349cc55cSDimitry Andric } 51