Skip to content

Commit 8cc1848

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#1860 from tautschnig/restore-irept-sharing
Revert irept change that stopped sharing and add unit test
2 parents fea5db0 + cbce4bc commit 8cc1848

File tree

5 files changed

+373
-46
lines changed

5 files changed

+373
-46
lines changed

src/util/fresh_symbol.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Chris Smowton, [email protected]
1111

1212
#include "fresh_symbol.h"
1313

14+
#include "invariant.h"
1415
#include "namespace.h"
1516
#include "rename.h"
1617
#include "symbol.h"

src/util/irep.cpp

+144-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ Author: Daniel Kroening, [email protected]
2626
#include <iostream>
2727
#endif
2828

29+
irept nil_rep_storage;
30+
31+
#ifdef SHARING
32+
irept::dt irept::empty_d;
33+
#endif
34+
2935
#ifdef SUB_IS_LIST
3036
static inline bool named_subt_order(
3137
const std::pair<irep_namet, irept> &a,
@@ -49,20 +55,157 @@ static inline irept::named_subt::iterator named_subt_lower_bound(
4955

5056
const irept &get_nil_irep()
5157
{
52-
static irept nil_rep_storage;
5358
if(nil_rep_storage.id().empty()) // initialized?
5459
nil_rep_storage.id(ID_nil);
5560
return nil_rep_storage;
5661
}
5762

63+
#ifdef SHARING
64+
void irept::detach()
65+
{
66+
#ifdef IREP_DEBUG
67+
std::cout << "DETACH1: " << data << '\n';
68+
#endif
69+
70+
if(data==&empty_d)
71+
{
72+
data=new dt;
73+
74+
#ifdef IREP_DEBUG
75+
std::cout << "ALLOCATED " << data << '\n';
76+
#endif
77+
}
78+
else if(data->ref_count>1)
79+
{
80+
dt *old_data(data);
81+
data=new dt(*old_data);
82+
83+
#ifdef IREP_DEBUG
84+
std::cout << "ALLOCATED " << data << '\n';
85+
#endif
86+
87+
data->ref_count=1;
88+
remove_ref(old_data);
89+
}
90+
91+
POSTCONDITION(data->ref_count==1);
92+
93+
#ifdef IREP_DEBUG
94+
std::cout << "DETACH2: " << data << '\n';
95+
#endif
96+
}
97+
#endif
98+
99+
#ifdef SHARING
100+
void irept::remove_ref(dt *old_data)
101+
{
102+
if(old_data==&empty_d)
103+
return;
104+
105+
#if 0
106+
nonrecursive_destructor(old_data);
107+
#else
108+
109+
PRECONDITION(old_data->ref_count!=0);
110+
111+
#ifdef IREP_DEBUG
112+
std::cout << "R: " << old_data << " " << old_data->ref_count << '\n';
113+
#endif
114+
115+
old_data->ref_count--;
116+
if(old_data->ref_count==0)
117+
{
118+
#ifdef IREP_DEBUG
119+
std::cout << "D: " << pretty() << '\n';
120+
std::cout << "DELETING " << old_data->data
121+
<< " " << old_data << '\n';
122+
old_data->clear();
123+
std::cout << "DEALLOCATING " << old_data << "\n";
124+
#endif
125+
126+
// may cause recursive call
127+
delete old_data;
128+
129+
#ifdef IREP_DEBUG
130+
std::cout << "DONE\n";
131+
#endif
132+
}
133+
#endif
134+
}
135+
#endif
136+
137+
/// Does the same as remove_ref, but using an explicit stack instead of
138+
/// recursion.
139+
#ifdef SHARING
140+
void irept::nonrecursive_destructor(dt *old_data)
141+
{
142+
std::vector<dt *> stack(1, old_data);
143+
144+
while(!stack.empty())
145+
{
146+
dt *d=stack.back();
147+
stack.erase(--stack.end());
148+
if(d==&empty_d)
149+
continue;
150+
151+
INVARIANT(d->ref_count!=0, "All contents of the stack must be in use");
152+
d->ref_count--;
153+
154+
if(d->ref_count==0)
155+
{
156+
stack.reserve(stack.size()+
157+
d->named_sub.size()+
158+
d->comments.size()+
159+
d->sub.size());
160+
161+
for(named_subt::iterator
162+
it=d->named_sub.begin();
163+
it!=d->named_sub.end();
164+
it++)
165+
{
166+
stack.push_back(it->second.data);
167+
it->second.data=&empty_d;
168+
}
169+
170+
for(named_subt::iterator
171+
it=d->comments.begin();
172+
it!=d->comments.end();
173+
it++)
174+
{
175+
stack.push_back(it->second.data);
176+
it->second.data=&empty_d;
177+
}
178+
179+
for(subt::iterator
180+
it=d->sub.begin();
181+
it!=d->sub.end();
182+
it++)
183+
{
184+
stack.push_back(it->data);
185+
it->data=&empty_d;
186+
}
187+
188+
// now delete, won't do recursion
189+
delete d;
190+
}
191+
}
192+
}
193+
#endif
194+
58195
void irept::move_to_named_sub(const irep_namet &name, irept &irep)
59196
{
197+
#ifdef SHARING
198+
detach();
199+
#endif
60200
add(name).swap(irep);
61201
irep.clear();
62202
}
63203

64204
void irept::move_to_sub(irept &irep)
65205
{
206+
#ifdef SHARING
207+
detach();
208+
#endif
66209
get_sub().push_back(get_nil_irep());
67210
get_sub().back().swap(irep);
68211
}

0 commit comments

Comments
 (0)