Skip to content

Commit fb9b2bf

Browse files
author
Joel Dice
committed
avoid creating garbage when iterating over hashmaps
1 parent 4392b04 commit fb9b2bf

File tree

4 files changed

+52
-49
lines changed

4 files changed

+52
-49
lines changed

src/machine.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -770,12 +770,8 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool)
770770
PROTECT(t, interfaceTable);
771771

772772
unsigned i = 0;
773-
object it = hashMapIterator(t, map);
774-
PROTECT(t, it);
775-
776-
for (; it; it = hashMapIteratorNext(t, it)) {
777-
object interface = resolveClass
778-
(t, tripleFirst(t, hashMapIteratorNode(t, it)));
773+
for (HashMapIterator it(t, map); it.hasMore();) {
774+
object interface = resolveClass(t, tripleFirst(t, it.next()));
779775
if (UNLIKELY(t->exception)) return;
780776

781777
set(t, interfaceTable, ArrayBody + (i * BytesPerWord), interface);
@@ -1243,10 +1239,8 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
12431239
if (classFlags(t, class_) & ACC_INTERFACE) {
12441240
PROTECT(t, vtable);
12451241

1246-
for (object it = hashMapIterator(t, virtualMap); it;
1247-
it = hashMapIteratorNext(t, it))
1248-
{
1249-
object method = tripleFirst(t, hashMapIteratorNode(t, it));
1242+
for (HashMapIterator it(t, virtualMap); it.hasMore();) {
1243+
object method = tripleFirst(t, it.next());
12501244
assert(t, arrayBody(t, vtable, methodOffset(t, method)) == 0);
12511245
set(t, vtable, ArrayBody + (methodOffset(t, method) * BytesPerWord),
12521246
method);

src/types.def

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,6 @@
7373
(type weakHashMap
7474
(extends hashMap))
7575

76-
(type hashMapIterator
77-
(object map)
78-
(object node)
79-
(unsigned index))
80-
8176
(type list
8277
(uint32_t size)
8378
(object front)

src/util.cpp

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -482,40 +482,6 @@ hashMapRemove(Thread* t, object map, object key,
482482
return o;
483483
}
484484

485-
object
486-
hashMapIterator(Thread* t, object map)
487-
{
488-
object array = hashMapArray(t, map);
489-
if (array) {
490-
for (unsigned i = 0; i < arrayLength(t, array); ++i) {
491-
if (arrayBody(t, array, i)) {
492-
return makeHashMapIterator(t, map, arrayBody(t, array, i), i + 1);
493-
}
494-
}
495-
}
496-
return 0;
497-
}
498-
499-
object
500-
hashMapIteratorNext(Thread* t, object it)
501-
{
502-
object map = hashMapIteratorMap(t, it);
503-
object node = hashMapIteratorNode(t, it);
504-
unsigned index = hashMapIteratorIndex(t, it);
505-
506-
if (tripleThird(t, node)) {
507-
return makeHashMapIterator(t, map, tripleThird(t, node), index);
508-
} else {
509-
object array = hashMapArray(t, map);
510-
for (unsigned i = index; i < arrayLength(t, array); ++i) {
511-
if (arrayBody(t, array, i)) {
512-
return makeHashMapIterator(t, map, arrayBody(t, array, i), i + 1);
513-
}
514-
}
515-
return 0;
516-
}
517-
}
518-
519485
void
520486
listAppend(Thread* t, object list, object value)
521487
{

src/util.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,54 @@ treeInsertNode(Thread* t, Zone* zone, object tree, intptr_t key, object node,
9393
object sentinal,
9494
intptr_t (*compare)(Thread* t, intptr_t key, object b));
9595

96+
class HashMapIterator: public Thread::Protector {
97+
public:
98+
HashMapIterator(Thread* t, object map):
99+
Protector(t), map(map), node(0), index(0)
100+
{
101+
find();
102+
}
103+
104+
void find() {
105+
object array = hashMapArray(t, map);
106+
for (unsigned i = index; i < arrayLength(t, array); ++i) {
107+
if (arrayBody(t, array, i)) {
108+
node = arrayBody(t, array, i);
109+
index = i + 1;
110+
return;
111+
}
112+
}
113+
node = 0;
114+
}
115+
116+
bool hasMore() {
117+
return node != 0;
118+
}
119+
120+
object next() {
121+
if (node) {
122+
object n = node;
123+
if (tripleThird(t, node)) {
124+
node = tripleThird(t, node);
125+
} else {
126+
find();
127+
}
128+
return n;
129+
} else {
130+
return 0;
131+
}
132+
}
133+
134+
virtual void visit(Heap::Visitor* v) {
135+
v->visit(&map);
136+
v->visit(&node);
137+
}
138+
139+
object map;
140+
object node;
141+
unsigned index;
142+
};
143+
96144
} // vm
97145

98146
#endif//UTIL_H

0 commit comments

Comments
 (0)