static LIST_HEAD(unix_unvisited_vertices);
 
 enum unix_vertex_index {
-       UNIX_VERTEX_INDEX_UNVISITED,
+       UNIX_VERTEX_INDEX_MARK1,
+       UNIX_VERTEX_INDEX_MARK2,
        UNIX_VERTEX_INDEX_START,
 };
 
+static unsigned long unix_vertex_unvisited_index = UNIX_VERTEX_INDEX_MARK1;
+
 static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)
 {
        struct unix_vertex *vertex = edge->predecessor->vertex;
 
        if (!vertex) {
                vertex = list_first_entry(&fpl->vertices, typeof(*vertex), entry);
+               vertex->index = unix_vertex_unvisited_index;
                vertex->out_degree = 0;
                INIT_LIST_HEAD(&vertex->edges);
 
 }
 
 static LIST_HEAD(unix_visited_vertices);
+static unsigned long unix_vertex_grouped_index = UNIX_VERTEX_INDEX_MARK2;
 
 static void __unix_walk_scc(struct unix_vertex *vertex)
 {
        LIST_HEAD(edge_stack);
 
 next_vertex:
-       /* Push vertex to vertex_stack.
+       /* Push vertex to vertex_stack and mark it as on-stack
+        * (index >= UNIX_VERTEX_INDEX_START).
         * The vertex will be popped when finalising SCC later.
         */
-       vertex->on_stack = true;
        list_add(&vertex->scc_entry, &vertex_stack);
 
        vertex->index = index;
                if (!next_vertex)
                        continue;
 
-               if (next_vertex->index == UNIX_VERTEX_INDEX_UNVISITED) {
+               if (next_vertex->index == unix_vertex_unvisited_index) {
                        /* Iterative deepening depth first search
                         *
                         *   1. Push a forward edge to edge_stack and set
                         * to skip SCC finalisation.
                         */
                        vertex->lowlink = min(vertex->lowlink, next_vertex->lowlink);
-               } else if (next_vertex->on_stack) {
+               } else if (next_vertex->index != unix_vertex_grouped_index) {
                        /* Loop detected by a back/cross edge.
                         *
                         * The successor is on vertex_stack, so two vertices are
                        /* Don't restart DFS from this vertex in unix_walk_scc(). */
                        list_move_tail(&vertex->entry, &unix_visited_vertices);
 
-                       vertex->on_stack = false;
+                       /* Mark vertex as off-stack. */
+                       vertex->index = unix_vertex_grouped_index;
                }
 
                list_del(&scc);
 
 static void unix_walk_scc(void)
 {
-       struct unix_vertex *vertex;
-
-       list_for_each_entry(vertex, &unix_unvisited_vertices, entry)
-               vertex->index = UNIX_VERTEX_INDEX_UNVISITED;
-
        /* Visit every vertex exactly once.
         * __unix_walk_scc() moves visited vertices to unix_visited_vertices.
         */
        while (!list_empty(&unix_unvisited_vertices)) {
+               struct unix_vertex *vertex;
+
                vertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry);
                __unix_walk_scc(vertex);
        }
 
        list_replace_init(&unix_visited_vertices, &unix_unvisited_vertices);
+       swap(unix_vertex_unvisited_index, unix_vertex_grouped_index);
 }
 
 static LIST_HEAD(gc_candidates);