Skip to content

Commit 4392b04

Browse files
author
Joel Dice
committed
avoid creating unecessary garbage in treeInsertNode and friends
1 parent fccf906 commit 4392b04

File tree

4 files changed

+122
-85
lines changed

4 files changed

+122
-85
lines changed

src/compile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5205,7 +5205,7 @@ compile(MyThread* t, object method)
52055205
PROTECT(t, node);
52065206

52075207
methodTree(t) = treeInsertNode
5208-
(t, methodTree(t), reinterpret_cast<intptr_t>
5208+
(t, &(context.zone), methodTree(t), reinterpret_cast<intptr_t>
52095209
(&singletonValue(t, compiled, 0)), node, methodTreeSentinal(t),
52105210
compareIpToMethodBounds);
52115211
}

src/types.def

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,6 @@
9595
(object value)
9696
(object left)
9797
(object right))
98-
99-
(type treePath
100-
(uintptr_t fresh)
101-
(object node)
102-
(object root)
103-
(object ancestors))
10498

10599
(type callNode
106100
(intptr_t address)

src/util.cpp

Lines changed: 119 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,54 @@ using namespace vm;
1414

1515
namespace {
1616

17+
class TreeContext {
18+
public:
19+
class Path {
20+
public:
21+
Path(object node, Path* next): node(node), next(next) { }
22+
23+
object node;
24+
Path* next;
25+
};
26+
27+
class MyProtector: public Thread::Protector {
28+
public:
29+
MyProtector(Thread* thread, TreeContext* context):
30+
Protector(thread), context(context)
31+
{ }
32+
33+
virtual void visit(Heap::Visitor* v) {
34+
v->visit(&(context->root));
35+
v->visit(&(context->node));
36+
37+
for (Path* p = context->ancestors; p; p = p->next) {
38+
v->visit(&(p->node));
39+
}
40+
}
41+
42+
TreeContext* context;
43+
};
44+
45+
TreeContext(Thread* thread, Zone* zone):
46+
zone(zone), root(0), node(0), ancestors(0), protector(thread, this),
47+
fresh(false)
48+
{ }
49+
50+
Zone* zone;
51+
object root;
52+
object node;
53+
Path* ancestors;
54+
MyProtector protector;
55+
bool fresh;
56+
};
57+
58+
TreeContext::Path*
59+
path(TreeContext* c, object node, TreeContext::Path* next)
60+
{
61+
return new (c->zone->allocate(sizeof(TreeContext::Path)))
62+
TreeContext::Path(node, next);
63+
}
64+
1765
inline object
1866
getTreeNodeValue(Thread*, object n)
1967
{
@@ -58,8 +106,9 @@ cloneTreeNode(Thread* t, object n)
58106
return newNode;
59107
}
60108

61-
object
62-
treeFind(Thread* t, object old, intptr_t key, object node, object sentinal,
109+
void
110+
treeFind(Thread* t, TreeContext* c, object old, intptr_t key, object node,
111+
object sentinal,
63112
intptr_t (*compare)(Thread* t, intptr_t key, object b))
64113
{
65114
PROTECT(t, old);
@@ -72,11 +121,8 @@ treeFind(Thread* t, object old, intptr_t key, object node, object sentinal,
72121
object new_ = newRoot;
73122
PROTECT(t, new_);
74123

75-
object ancestors = 0;
76-
PROTECT(t, ancestors);
77-
78124
while (old != sentinal) {
79-
ancestors = makePair(t, new_, ancestors);
125+
c->ancestors = path(c, new_, c->ancestors);
80126

81127
intptr_t difference = compare(t, key, getTreeNodeValue(t, old));
82128

@@ -91,13 +137,20 @@ treeFind(Thread* t, object old, intptr_t key, object node, object sentinal,
91137
set(t, new_, TreeNodeRight, n);
92138
new_ = n;
93139
} else {
94-
return makeTreePath(t, false, new_, newRoot, pairSecond(t, ancestors));
140+
c->fresh = false;
141+
c->root = newRoot;
142+
c->node = new_;
143+
c->ancestors = c->ancestors->next;
144+
return;
95145
}
96146
}
97147

98148
setTreeNodeValue(t, new_, getTreeNodeValue(t, node));
99149

100-
return makeTreePath(t, true, new_, newRoot, ancestors);
150+
c->fresh = true;
151+
c->root = newRoot;
152+
c->node = new_;
153+
c->ancestors = c->ancestors;
101154
}
102155

103156
object
@@ -123,122 +176,109 @@ rightRotate(Thread* t, object n)
123176
}
124177

125178
object
126-
treeAdd(Thread* t, object path)
179+
treeAdd(Thread* t, TreeContext* c)
127180
{
128-
object new_ = treePathNode(t, path);
181+
object new_ = c->node;
129182
PROTECT(t, new_);
130183

131-
object newRoot = treePathRoot(t, path);
184+
object newRoot = c->root;
132185
PROTECT(t, newRoot);
133186

134-
object ancestors = treePathAncestors(t, path);
135-
PROTECT(t, ancestors);
136-
137187
// rebalance
138188
setTreeNodeRed(t, new_, true);
139-
while (ancestors != 0 and treeNodeRed(t, pairFirst(t, ancestors))) {
140-
if (pairFirst(t, ancestors)
141-
== treeNodeLeft(t, pairFirst(t, pairSecond(t, ancestors))))
189+
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->node)) {
190+
if (c->ancestors->node
191+
== treeNodeLeft(t, c->ancestors->next->node))
142192
{
143193
if (treeNodeRed
144-
(t, treeNodeRight(t, pairFirst(t, pairSecond(t, ancestors)))))
194+
(t, treeNodeRight(t, c->ancestors->next->node)))
145195
{
146-
setTreeNodeRed(t, pairFirst(t, ancestors), false);
196+
setTreeNodeRed(t, c->ancestors->node, false);
147197

148198
object n = cloneTreeNode
149-
(t, treeNodeRight(t, pairFirst(t, pairSecond(t, ancestors))));
199+
(t, treeNodeRight(t, c->ancestors->next->node));
150200

151-
set(t, pairFirst(t, pairSecond(t, ancestors)), TreeNodeRight, n);
201+
set(t, c->ancestors->next->node, TreeNodeRight, n);
152202

153-
setTreeNodeRed
154-
(t, treeNodeRight
155-
(t, pairFirst(t, pairSecond(t, ancestors))), false);
203+
setTreeNodeRed(t, treeNodeRight(t, c->ancestors->next->node), false);
156204

157-
setTreeNodeRed(t, pairFirst(t, pairSecond(t, ancestors)), true);
205+
setTreeNodeRed(t, c->ancestors->next->node, true);
158206

159-
new_ = pairFirst(t, pairSecond(t, ancestors));
160-
ancestors = pairSecond(t, pairSecond(t, ancestors));
207+
new_ = c->ancestors->next->node;
208+
c->ancestors = c->ancestors->next->next;
161209
} else {
162-
if (new_ == treeNodeRight(t, pairFirst(t, ancestors))) {
163-
new_ = pairFirst(t, ancestors);
164-
ancestors = pairSecond(t, ancestors);
210+
if (new_ == treeNodeRight(t, c->ancestors->node)) {
211+
new_ = c->ancestors->node;
212+
c->ancestors = c->ancestors->next;
165213

166214
object n = leftRotate(t, new_);
167215

168-
if (new_ == treeNodeRight(t, pairFirst(t, ancestors))) {
169-
set(t, pairFirst(t, ancestors), TreeNodeRight, n);
216+
if (new_ == treeNodeRight(t, c->ancestors->node)) {
217+
set(t, c->ancestors->node, TreeNodeRight, n);
170218
} else {
171-
set(t, pairFirst(t, ancestors), TreeNodeLeft, n);
219+
set(t, c->ancestors->node, TreeNodeLeft, n);
172220
}
173-
ancestors = makePair(t, n, ancestors);
221+
c->ancestors = path(c, n, c->ancestors);
174222
}
175-
setTreeNodeRed(t, pairFirst(t, ancestors), false);
176-
setTreeNodeRed(t, pairFirst(t, pairSecond(t, ancestors)), true);
223+
setTreeNodeRed(t, c->ancestors->node, false);
224+
setTreeNodeRed(t, c->ancestors->next->node, true);
177225

178-
object n = rightRotate(t, pairFirst(t, pairSecond(t, ancestors)));
179-
if (pairSecond(t, pairSecond(t, ancestors)) == 0) {
226+
object n = rightRotate(t, c->ancestors->next->node);
227+
if (c->ancestors->next->next == 0) {
180228
newRoot = n;
181-
} else if (treeNodeRight
182-
(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))))
183-
== pairFirst(t, pairSecond(t, ancestors)))
229+
} else if (treeNodeRight(t, c->ancestors->next->next->node)
230+
== c->ancestors->next->node)
184231
{
185-
set(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))),
186-
TreeNodeRight, n);
232+
set(t, c->ancestors->next->next->node, TreeNodeRight, n);
187233
} else {
188-
set(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))),
189-
TreeNodeLeft, n);
234+
set(t, c->ancestors->next->next->node, TreeNodeLeft, n);
190235
}
191236
// done
192237
}
193238
} else { // this is just the reverse of the code above (right and
194239
// left swapped):
195240
if (treeNodeRed
196-
(t, treeNodeLeft(t, pairFirst(t, pairSecond(t, ancestors)))))
241+
(t, treeNodeLeft(t, c->ancestors->next->node)))
197242
{
198-
setTreeNodeRed(t, pairFirst(t, ancestors), false);
243+
setTreeNodeRed(t, c->ancestors->node, false);
199244

200245
object n = cloneTreeNode
201-
(t, treeNodeLeft(t, pairFirst(t, pairSecond(t, ancestors))));
246+
(t, treeNodeLeft(t, c->ancestors->next->node));
202247

203-
set(t, pairFirst(t, pairSecond(t, ancestors)), TreeNodeLeft, n);
248+
set(t, c->ancestors->next->node, TreeNodeLeft, n);
204249

205-
setTreeNodeRed
206-
(t, treeNodeLeft
207-
(t, pairFirst(t, pairSecond(t, ancestors))), false);
250+
setTreeNodeRed(t, treeNodeLeft(t, c->ancestors->next->node), false);
208251

209-
setTreeNodeRed(t, pairFirst(t, pairSecond(t, ancestors)), true);
252+
setTreeNodeRed(t, c->ancestors->next->node, true);
210253

211-
new_ = pairFirst(t, pairSecond(t, ancestors));
212-
ancestors = pairSecond(t, pairSecond(t, ancestors));
254+
new_ = c->ancestors->next->node;
255+
c->ancestors = c->ancestors->next->next;
213256
} else {
214-
if (new_ == treeNodeLeft(t, pairFirst(t, ancestors))) {
215-
new_ = pairFirst(t, ancestors);
216-
ancestors = pairSecond(t, ancestors);
257+
if (new_ == treeNodeLeft(t, c->ancestors->node)) {
258+
new_ = c->ancestors->node;
259+
c->ancestors = c->ancestors->next;
217260

218261
object n = rightRotate(t, new_);
219262

220-
if (new_ == treeNodeLeft(t, pairFirst(t, ancestors))) {
221-
set(t, pairFirst(t, ancestors), TreeNodeLeft, n);
263+
if (new_ == treeNodeLeft(t, c->ancestors->node)) {
264+
set(t, c->ancestors->node, TreeNodeLeft, n);
222265
} else {
223-
set(t, pairFirst(t, ancestors), TreeNodeRight, n);
266+
set(t, c->ancestors->node, TreeNodeRight, n);
224267
}
225-
ancestors = makePair(t, n, ancestors);
268+
c->ancestors = path(c, n, c->ancestors);
226269
}
227-
setTreeNodeRed(t, pairFirst(t, ancestors), false);
228-
setTreeNodeRed(t, pairFirst(t, pairSecond(t, ancestors)), true);
270+
setTreeNodeRed(t, c->ancestors->node, false);
271+
setTreeNodeRed(t, c->ancestors->next->node, true);
229272

230-
object n = leftRotate(t, pairFirst(t, pairSecond(t, ancestors)));
231-
if (pairSecond(t, pairSecond(t, ancestors)) == 0) {
273+
object n = leftRotate(t, c->ancestors->next->node);
274+
if (c->ancestors->next->next == 0) {
232275
newRoot = n;
233-
} else if (treeNodeLeft
234-
(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))))
235-
== pairFirst(t, pairSecond(t, ancestors)))
276+
} else if (treeNodeLeft(t, c->ancestors->next->next->node)
277+
== c->ancestors->next->node)
236278
{
237-
set(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))),
238-
TreeNodeLeft, n);
279+
set(t, c->ancestors->next->next->node, TreeNodeLeft, n);
239280
} else {
240-
set(t, pairFirst(t, pairSecond(t, pairSecond(t, ancestors))),
241-
TreeNodeRight, n);
281+
set(t, c->ancestors->next->next->node, TreeNodeRight, n);
242282
}
243283
// done
244284
}
@@ -541,16 +581,18 @@ treeQuery(Thread* t, object tree, intptr_t key, object sentinal,
541581
}
542582

543583
object
544-
treeInsertNode(Thread* t, object tree, intptr_t key, object node,
584+
treeInsertNode(Thread* t, Zone* zone, object tree, intptr_t key, object node,
545585
object sentinal,
546586
intptr_t (*compare)(Thread* t, intptr_t key, object b))
547587
{
548588
PROTECT(t, tree);
549589
PROTECT(t, sentinal);
550590

551-
object path = treeFind(t, tree, key, node, sentinal, compare);
552-
expect(t, treePathFresh(t, path));
553-
return treeAdd(t, path);
591+
TreeContext c(t, zone);
592+
treeFind(t, &c, tree, key, node, sentinal, compare);
593+
expect(t, c.fresh);
594+
595+
return treeAdd(t, &c);
554596
}
555597

556598
} // namespace vm

src/util.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#define UTIL_H
1313

1414
#include "machine.h"
15+
#include "zone.h"
1516

1617
namespace vm {
1718

@@ -88,7 +89,7 @@ treeQuery(Thread* t, object tree, intptr_t key, object sentinal,
8889
intptr_t (*compare)(Thread* t, intptr_t key, object b));
8990

9091
object
91-
treeInsertNode(Thread* t, object tree, intptr_t key, object node,
92+
treeInsertNode(Thread* t, Zone* zone, object tree, intptr_t key, object node,
9293
object sentinal,
9394
intptr_t (*compare)(Thread* t, intptr_t key, object b));
9495

0 commit comments

Comments
 (0)