1 /*
2 * Copyright 2014 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define IN_FRUIT_CPP_FILE 1
18
19 #include <algorithm>
20 #include <cstdlib>
21 #include <fruit/impl/util/type_info.h>
22 #include <iostream>
23 #include <memory>
24 #include <vector>
25
26 #include <fruit/impl/normalized_component_storage/normalized_component_storage.h>
27
28 #include <fruit/impl/component_storage/component_storage.h>
29 #include <fruit/impl/data_structures/semistatic_graph.templates.h>
30 #include <fruit/impl/data_structures/semistatic_map.templates.h>
31 #include <fruit/impl/injector/injector_storage.h>
32 #include <fruit/impl/normalized_component_storage/binding_normalization.h>
33
34 using std::cout;
35 using std::endl;
36
37 using namespace fruit;
38 using namespace fruit::impl;
39
40 namespace fruit {
41 namespace impl {
42
NormalizedComponentStorage(ComponentStorage && component,const std::vector<TypeId,ArenaAllocator<TypeId>> & exposed_types,MemoryPool & memory_pool,WithPermanentCompression)43 NormalizedComponentStorage::NormalizedComponentStorage(ComponentStorage&& component,
44 const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
45 MemoryPool& memory_pool, WithPermanentCompression)
46 : normalized_component_memory_pool(),
47 binding_compression_info_map(createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
48 0 /* capacity */, normalized_component_memory_pool)),
49 fully_expanded_components_with_no_args(
50 createLazyComponentWithNoArgsSet(0 /* capacity */, normalized_component_memory_pool)),
51 fully_expanded_components_with_args(
52 createLazyComponentWithArgsSet(0 /* capacity */, normalized_component_memory_pool)),
53 component_with_no_args_replacements(
54 createLazyComponentWithNoArgsReplacementMap(0 /* capacity */, normalized_component_memory_pool)),
55 component_with_args_replacements(
56 createLazyComponentWithArgsReplacementMap(0 /* capacity */, normalized_component_memory_pool)) {
57
58 using bindings_vector_t = std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>;
59 bindings_vector_t bindings_vector = bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
60 BindingNormalization::normalizeBindingsWithPermanentBindingCompression(std::move(component).release(),
61 fixed_size_allocator_data, memory_pool,
62 exposed_types, bindings_vector, multibindings);
63
64 bindings = SemistaticGraph<TypeId, NormalizedBinding>(InjectorStorage::BindingDataNodeIter{bindings_vector.begin()},
65 InjectorStorage::BindingDataNodeIter{bindings_vector.end()},
66 memory_pool);
67 }
68
NormalizedComponentStorage(ComponentStorage && component,const std::vector<TypeId,ArenaAllocator<TypeId>> & exposed_types,MemoryPool & memory_pool,WithUndoableCompression)69 NormalizedComponentStorage::NormalizedComponentStorage(ComponentStorage&& component,
70 const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
71 MemoryPool& memory_pool, WithUndoableCompression)
72 : normalized_component_memory_pool(),
73 binding_compression_info_map(createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
74 20 /* capacity */, normalized_component_memory_pool)),
75 fully_expanded_components_with_no_args(
76 createLazyComponentWithNoArgsSet(20 /* capacity */, normalized_component_memory_pool)),
77 fully_expanded_components_with_args(
78 createLazyComponentWithArgsSet(20 /* capacity */, normalized_component_memory_pool)),
79 component_with_no_args_replacements(
80 createLazyComponentWithNoArgsReplacementMap(20 /* capacity */, normalized_component_memory_pool)),
81 component_with_args_replacements(
82 createLazyComponentWithArgsReplacementMap(20 /* capacity */, normalized_component_memory_pool)) {
83
84 using bindings_vector_t = std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>;
85 bindings_vector_t bindings_vector = bindings_vector_t(ArenaAllocator<ComponentStorageEntry>(memory_pool));
86 BindingNormalization::normalizeBindingsWithUndoableBindingCompression(
87 std::move(component).release(), fixed_size_allocator_data, memory_pool, normalized_component_memory_pool,
88 normalized_component_memory_pool, exposed_types, bindings_vector, multibindings, binding_compression_info_map,
89 fully_expanded_components_with_no_args, fully_expanded_components_with_args, component_with_no_args_replacements,
90 component_with_args_replacements);
91
92 bindings = SemistaticGraph<TypeId, NormalizedBinding>(InjectorStorage::BindingDataNodeIter{bindings_vector.begin()},
93 InjectorStorage::BindingDataNodeIter{bindings_vector.end()},
94 memory_pool);
95 }
96
~NormalizedComponentStorage()97 NormalizedComponentStorage::~NormalizedComponentStorage() {
98 for (auto& x : fully_expanded_components_with_args) {
99 x.destroy();
100 }
101
102 for (const auto& pair : component_with_args_replacements) {
103 const LazyComponentWithArgs& replaced_component = pair.first;
104 const ComponentStorageEntry& replacement_component = pair.second;
105 replaced_component.destroy();
106 replacement_component.destroy();
107 }
108
109 for (const auto& pair : component_with_no_args_replacements) {
110 const ComponentStorageEntry& replacement_component = pair.second;
111 replacement_component.destroy();
112 }
113
114 // We must free all the memory in these before the normalized_component_memory_pool is destroyed.
115 binding_compression_info_map = createHashMapWithArenaAllocator<TypeId, CompressedBindingUndoInfo>(
116 0 /* capacity */, normalized_component_memory_pool);
117 fully_expanded_components_with_no_args =
118 createLazyComponentWithNoArgsSet(0 /* capacity */, normalized_component_memory_pool);
119 fully_expanded_components_with_args =
120 createLazyComponentWithArgsSet(0 /* capacity */, normalized_component_memory_pool);
121 component_with_no_args_replacements =
122 createLazyComponentWithNoArgsReplacementMap(0 /* capacity */, normalized_component_memory_pool);
123 component_with_args_replacements =
124 createLazyComponentWithArgsReplacementMap(0 /* capacity */, normalized_component_memory_pool);
125 }
126
127 } // namespace impl
128 // We need a LCOV_EXCL_BR_LINE below because for some reason gcov/lcov think there's a branch there.
129 } // namespace fruit LCOV_EXCL_BR_LINE
130