xref: /aosp_15_r20/external/google-fruit/src/injector_storage.cpp (revision a65addddcf69f38db5b288d787b6b7571a57bb8f)
1*a65addddSAndroid Build Coastguard Worker /*
2*a65addddSAndroid Build Coastguard Worker  * Copyright 2014 Google Inc. All rights reserved.
3*a65addddSAndroid Build Coastguard Worker  *
4*a65addddSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*a65addddSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*a65addddSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*a65addddSAndroid Build Coastguard Worker  *
8*a65addddSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*a65addddSAndroid Build Coastguard Worker  *
10*a65addddSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*a65addddSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*a65addddSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*a65addddSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*a65addddSAndroid Build Coastguard Worker  * limitations under the License.
15*a65addddSAndroid Build Coastguard Worker  */
16*a65addddSAndroid Build Coastguard Worker 
17*a65addddSAndroid Build Coastguard Worker #define IN_FRUIT_CPP_FILE 1
18*a65addddSAndroid Build Coastguard Worker 
19*a65addddSAndroid Build Coastguard Worker #include <algorithm>
20*a65addddSAndroid Build Coastguard Worker #include <cstdlib>
21*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/util/type_info.h>
22*a65addddSAndroid Build Coastguard Worker #include <iostream>
23*a65addddSAndroid Build Coastguard Worker #include <memory>
24*a65addddSAndroid Build Coastguard Worker #include <vector>
25*a65addddSAndroid Build Coastguard Worker 
26*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/component_storage/component_storage.h>
27*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/data_structures/semistatic_graph.templates.h>
28*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/injector/injector_storage.h>
29*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/normalized_component_storage/binding_normalization.h>
30*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/normalized_component_storage/binding_normalization.templates.h>
31*a65addddSAndroid Build Coastguard Worker 
32*a65addddSAndroid Build Coastguard Worker using std::cout;
33*a65addddSAndroid Build Coastguard Worker using std::endl;
34*a65addddSAndroid Build Coastguard Worker 
35*a65addddSAndroid Build Coastguard Worker namespace fruit {
36*a65addddSAndroid Build Coastguard Worker namespace impl {
37*a65addddSAndroid Build Coastguard Worker 
fatal(const std::string & error)38*a65addddSAndroid Build Coastguard Worker void InjectorStorage::fatal(const std::string& error) {
39*a65addddSAndroid Build Coastguard Worker   std::cerr << "Fatal injection error: " << error << std::endl;
40*a65addddSAndroid Build Coastguard Worker   exit(1);
41*a65addddSAndroid Build Coastguard Worker }
42*a65addddSAndroid Build Coastguard Worker 
43*a65addddSAndroid Build Coastguard Worker // LCOV_EXCL_START
44*a65addddSAndroid Build Coastguard Worker namespace {
45*a65addddSAndroid Build Coastguard Worker template <typename Id, typename Value>
46*a65addddSAndroid Build Coastguard Worker struct DummyNode {
getIdfruit::impl::__anon3388e2e40111::DummyNode47*a65addddSAndroid Build Coastguard Worker   Id getId() {
48*a65addddSAndroid Build Coastguard Worker     return Id();
49*a65addddSAndroid Build Coastguard Worker   }
isTerminalfruit::impl::__anon3388e2e40111::DummyNode50*a65addddSAndroid Build Coastguard Worker   bool isTerminal() {
51*a65addddSAndroid Build Coastguard Worker     return false;
52*a65addddSAndroid Build Coastguard Worker   }
getEdgesBeginfruit::impl::__anon3388e2e40111::DummyNode53*a65addddSAndroid Build Coastguard Worker   Id* getEdgesBegin() {
54*a65addddSAndroid Build Coastguard Worker     return nullptr;
55*a65addddSAndroid Build Coastguard Worker   }
getEdgesEndfruit::impl::__anon3388e2e40111::DummyNode56*a65addddSAndroid Build Coastguard Worker   Id* getEdgesEnd() {
57*a65addddSAndroid Build Coastguard Worker     return nullptr;
58*a65addddSAndroid Build Coastguard Worker   }
getValuefruit::impl::__anon3388e2e40111::DummyNode59*a65addddSAndroid Build Coastguard Worker   Value getValue() {
60*a65addddSAndroid Build Coastguard Worker     return Value();
61*a65addddSAndroid Build Coastguard Worker   }
62*a65addddSAndroid Build Coastguard Worker };
63*a65addddSAndroid Build Coastguard Worker }
64*a65addddSAndroid Build Coastguard Worker // LCOV_EXCL_STOP
65*a65addddSAndroid Build Coastguard Worker 
InjectorStorage(ComponentStorage && component,const std::vector<TypeId,ArenaAllocator<TypeId>> & exposed_types,MemoryPool & memory_pool)66*a65addddSAndroid Build Coastguard Worker InjectorStorage::InjectorStorage(ComponentStorage&& component,
67*a65addddSAndroid Build Coastguard Worker                                  const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
68*a65addddSAndroid Build Coastguard Worker                                  MemoryPool& memory_pool)
69*a65addddSAndroid Build Coastguard Worker     : normalized_component_storage_ptr(new NormalizedComponentStorage(
70*a65addddSAndroid Build Coastguard Worker           std::move(component), exposed_types, memory_pool, NormalizedComponentStorage::WithPermanentCompression())),
71*a65addddSAndroid Build Coastguard Worker       allocator(normalized_component_storage_ptr->fixed_size_allocator_data),
72*a65addddSAndroid Build Coastguard Worker       bindings(normalized_component_storage_ptr->bindings, (DummyNode<TypeId, NormalizedBinding>*)nullptr,
73*a65addddSAndroid Build Coastguard Worker                (DummyNode<TypeId, NormalizedBinding>*)nullptr, memory_pool),
74*a65addddSAndroid Build Coastguard Worker       multibindings(std::move(normalized_component_storage_ptr->multibindings)) {
75*a65addddSAndroid Build Coastguard Worker 
76*a65addddSAndroid Build Coastguard Worker #if FRUIT_EXTRA_DEBUG
77*a65addddSAndroid Build Coastguard Worker   bindings.checkFullyConstructed();
78*a65addddSAndroid Build Coastguard Worker #endif
79*a65addddSAndroid Build Coastguard Worker }
80*a65addddSAndroid Build Coastguard Worker 
InjectorStorage(const NormalizedComponentStorage & normalized_component,ComponentStorage && component,MemoryPool & memory_pool)81*a65addddSAndroid Build Coastguard Worker InjectorStorage::InjectorStorage(const NormalizedComponentStorage& normalized_component, ComponentStorage&& component,
82*a65addddSAndroid Build Coastguard Worker                                  MemoryPool& memory_pool) {
83*a65addddSAndroid Build Coastguard Worker 
84*a65addddSAndroid Build Coastguard Worker   FixedSizeAllocator::FixedSizeAllocatorData fixed_size_allocator_data;
85*a65addddSAndroid Build Coastguard Worker   using new_bindings_vector_t = std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>;
86*a65addddSAndroid Build Coastguard Worker   new_bindings_vector_t new_bindings_vector = new_bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
87*a65addddSAndroid Build Coastguard Worker 
88*a65addddSAndroid Build Coastguard Worker   BindingNormalization::normalizeBindingsAndAddTo(std::move(component).release(), memory_pool, normalized_component,
89*a65addddSAndroid Build Coastguard Worker                                                   fixed_size_allocator_data, new_bindings_vector, multibindings);
90*a65addddSAndroid Build Coastguard Worker 
91*a65addddSAndroid Build Coastguard Worker   allocator = FixedSizeAllocator(fixed_size_allocator_data);
92*a65addddSAndroid Build Coastguard Worker 
93*a65addddSAndroid Build Coastguard Worker   bindings = Graph(normalized_component.bindings, BindingDataNodeIter{new_bindings_vector.begin()},
94*a65addddSAndroid Build Coastguard Worker                    BindingDataNodeIter{new_bindings_vector.end()}, memory_pool);
95*a65addddSAndroid Build Coastguard Worker #if FRUIT_EXTRA_DEBUG
96*a65addddSAndroid Build Coastguard Worker   bindings.checkFullyConstructed();
97*a65addddSAndroid Build Coastguard Worker #endif
98*a65addddSAndroid Build Coastguard Worker }
99*a65addddSAndroid Build Coastguard Worker 
~InjectorStorage()100*a65addddSAndroid Build Coastguard Worker InjectorStorage::~InjectorStorage() {}
101*a65addddSAndroid Build Coastguard Worker 
ensureConstructedMultibinding(NormalizedMultibindingSet & multibinding_set)102*a65addddSAndroid Build Coastguard Worker void InjectorStorage::ensureConstructedMultibinding(NormalizedMultibindingSet& multibinding_set) {
103*a65addddSAndroid Build Coastguard Worker   for (NormalizedMultibinding& multibinding : multibinding_set.elems) {
104*a65addddSAndroid Build Coastguard Worker     if (!multibinding.is_constructed) {
105*a65addddSAndroid Build Coastguard Worker       multibinding.object = multibinding.create(*this);
106*a65addddSAndroid Build Coastguard Worker       multibinding.is_constructed = true;
107*a65addddSAndroid Build Coastguard Worker     }
108*a65addddSAndroid Build Coastguard Worker   }
109*a65addddSAndroid Build Coastguard Worker }
110*a65addddSAndroid Build Coastguard Worker 
getMultibindings(TypeId typeInfo)111*a65addddSAndroid Build Coastguard Worker void* InjectorStorage::getMultibindings(TypeId typeInfo) {
112*a65addddSAndroid Build Coastguard Worker   NormalizedMultibindingSet* multibinding_set = getNormalizedMultibindingSet(typeInfo);
113*a65addddSAndroid Build Coastguard Worker   if (multibinding_set == nullptr) {
114*a65addddSAndroid Build Coastguard Worker     // Not registered.
115*a65addddSAndroid Build Coastguard Worker     return nullptr;
116*a65addddSAndroid Build Coastguard Worker   }
117*a65addddSAndroid Build Coastguard Worker   return multibinding_set->get_multibindings_vector(*this).get();
118*a65addddSAndroid Build Coastguard Worker }
119*a65addddSAndroid Build Coastguard Worker 
eagerlyInjectMultibindings()120*a65addddSAndroid Build Coastguard Worker void InjectorStorage::eagerlyInjectMultibindings() {
121*a65addddSAndroid Build Coastguard Worker   std::lock_guard<std::recursive_mutex> lock(mutex);
122*a65addddSAndroid Build Coastguard Worker   for (auto& typeInfoInfoPair : multibindings) {
123*a65addddSAndroid Build Coastguard Worker     typeInfoInfoPair.second.get_multibindings_vector(*this);
124*a65addddSAndroid Build Coastguard Worker   }
125*a65addddSAndroid Build Coastguard Worker }
126*a65addddSAndroid Build Coastguard Worker 
127*a65addddSAndroid Build Coastguard Worker } // namespace impl
128*a65addddSAndroid Build Coastguard Worker // We need a LCOV_EXCL_BR_LINE below because for some reason gcov/lcov think there's a branch there.
129*a65addddSAndroid Build Coastguard Worker } // namespace fruit LCOV_EXCL_BR_LINE
130