static void radix_tree_dump_node(const struct radix_tree *t, void *vp, uint64_t offset, unsigned int height) { struct radix_tree_node *n; unsigned int i; for (i = 0; i < t->t_height - height; i++) { printf(" "); } if (entry_tagmask(vp) == 0) { printf("[%" PRIu64 "] %p", offset, entry_ptr(vp)); } else { printf("[%" PRIu64 "] %p (tagmask=0x%x)", offset, entry_ptr(vp), entry_tagmask(vp)); } if (height == 0) { printf(" (leaf)\n"); return; } n = entry_ptr(vp); assert(any_children_tagmask(n) == entry_tagmask(vp)); printf(" (%u children)\n", n->n_nptrs); for (i = 0; i < __arraycount(n->n_ptrs); i++) { void *c; c = n->n_ptrs[i]; if (c == NULL) { continue; } radix_tree_dump_node(t, c, offset + i * (UINT64_C(1) << (RADIX_TREE_BITS_PER_HEIGHT * (height - 1))), height - 1); } }
static inline struct radix_tree_node * path_node(const struct radix_tree * t, const struct radix_tree_path *p, unsigned int height) { KASSERT(height <= t->t_height); return entry_ptr(*path_pptr(t, p, height)); }
void Execution_Tracer::copy_elements(int src_offset, void* dst, int dst_offset, int num_elems, Object_p dst_obj) { lprintf( "copy_elements src_offset %d, buffer 0x%x, dst 0x%x, dst_offset %d, num_elems %d, dst_obj 0x%x, next %d\n", src_offset, buffer, dst, dst_offset, num_elems, (Object*)dst_obj, next); Oop* dst_oop = (Oop*)dst + dst_offset * e_N; // zero-fill for GC sake for (int i = 0; i < num_elems; ++i) for (int j = 0; j < e_N; ++j) dst_oop[i * e_N + j] = Oop::from_int(0); for (int i = 0; i < num_elems; ++i, dst_oop += e_N) { bc* bcp = (bc*)entry_ptr(i); gc* gcp = (gc*)bcp; proc* procp = (proc*)bcp; rcved_interp* rip = (rcved_interp*)bcp; aux* auxp = (aux*)bcp; dst_oop[e_kind] = Oop::from_int(bcp->kind); switch (bcp->kind) { default: fatal(); break; case k_aux: { dst_oop[e_id ] = Oop::from_int(auxp->id); dst_oop[e_aux1 ] = Oop::from_int(auxp->aux1); dst_oop[e_aux2 ] = Oop::from_int(auxp->aux2); dst_oop[e_rank ] = Oop::from_int(auxp->rank); } break; case k_bc: { dst_oop[e_method ] = bcp->method; Object_p mo = dst_oop[e_method].as_object(); dst_oop[e_rcvr ] = bcp->rcvr; dst_oop[e_rank ] = Oop::from_int(bcp->rank); dst_oop[e_bcCount ] = Oop::from_int(bcp->bcCount); dst_oop[e_pc ] = Oop::from_int(bcp->pc - (mo->first_byte_address() - mo->as_char_p())); dst_oop[e_aux1 ] = Oop::from_int(bcp->aux1); dst_oop[e_aux2 ] = Oop::from_int(bcp->aux2); dst_oop[e_is_block] = bcp->is_block ? The_Squeak_Interpreter()->roots.trueObj : The_Squeak_Interpreter()->roots.falseObj; assert_always(dst_oop[e_method ].is_mem()); assert_always(dst_oop[e_pc ].is_int()); assert_always(dst_oop[e_rank].is_int()); assert_always(dst_oop[e_is_block] == The_Squeak_Interpreter()->roots.trueObj || dst_oop[e_is_block] == The_Squeak_Interpreter()->roots.falseObj); assert_always( (int(dst_oop) - int(dst_obj) - Object::BaseHeaderSize) % e_N == 0 ); } break; case k_gc: dst_oop[e_gc ] = Oop::from_int(gcp->gc); dst_oop[e_rank] = Oop::from_int(gcp->rank); break; case k_proc: dst_oop[e_rank] = Oop::from_int(procp->rank); dst_oop[e_process ] = procp->process; break; case k_rcved_interp: dst_oop[e_rank] = Oop::from_int(rip->to_rank); break; } } dst_obj->my_heap()->check_multiple_stores_for_generations_only(dst_oop, num_elems * e_N); }
void * radix_tree_lookup_node(struct radix_tree *t, uint64_t idx) { void **vpp; vpp = radix_tree_lookup_ptr(t, idx, NULL, false, 0); if (vpp == NULL) { return NULL; } return entry_ptr(*vpp); }
static inline bool entry_match_p(void *p, unsigned int tagmask) { KASSERT(entry_ptr(p) != NULL || entry_tagmask(p) == 0); if (p == NULL) { return false; } if (tagmask == 0) { return true; } return (entry_tagmask(p) & tagmask) != 0; }
void * radix_tree_replace_node(struct radix_tree *t, uint64_t idx, void *p) { void **vpp; void *oldp; KASSERT(p != NULL); KASSERT(entry_compose(p, 0) == p); vpp = radix_tree_lookup_ptr(t, idx, NULL, false, 0); KASSERT(vpp != NULL); oldp = *vpp; KASSERT(oldp != NULL); *vpp = entry_compose(p, entry_tagmask(*vpp)); return entry_ptr(oldp); }
void radix_tree_clear_tag(struct radix_tree *t, uint64_t idx, radix_tree_tagid_t tagid) { struct radix_tree_path path; const unsigned int tagmask = tagid_to_mask(tagid); void **vpp; int i; vpp = radix_tree_lookup_ptr(t, idx, &path, false, 0); KASSERT(vpp != NULL); KASSERT(*vpp != NULL); KASSERT(path.p_lastidx == t->t_height); KASSERT(vpp == path_pptr(t, &path, path.p_lastidx)); /* * if already cleared, nothing to do */ if ((entry_tagmask(*vpp) & tagmask) == 0) { return; } /* * clear the tag only if no children have the tag. */ for (i = t->t_height; i >= 0; i--) { void ** const pptr = (void **)path_pptr(t, &path, i); void *entry; KASSERT(pptr != NULL); entry = *pptr; KASSERT((entry_tagmask(entry) & tagmask) != 0); *pptr = entry_compose(entry_ptr(entry), entry_tagmask(entry) & ~tagmask); /* * check if we should proceed to process the next level. */ if (0 < i) { struct radix_tree_node *n = path_node(t, &path, i - 1); if ((any_children_tagmask(n) & tagmask) != 0) { break; } } } }
void Execution_Tracer::do_all_roots(Oop_Closure* oc) { oc->value(&ctx, (Object_p)NULL); for (int i = 0; i < end_of_live_data(); ++i) { bc* bcp = (bc*)entry_ptr(i); proc* procp = (proc*)bcp; switch (bcp->kind) { default: fatal(); break; case k_bc: oc->value(&bcp->method, (Object_p)NULL); oc->value(&bcp->rcvr, (Object_p)NULL); break; case k_gc: case k_rcved_interp: case k_aux: break; case k_proc: oc->value(&procp->process, (Object_p)NULL); break; } } }
/** * Handle an incoming Update() signal from DBus */ void LauncherEntryRemoteModel::HandleUpdateRequest(std::string const& sender_name, GVariant* parameters) { if (!parameters) return; if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sa{sv})"))) { LOG_ERROR(logger) << "Received 'com.canonical.Unity.LauncherEntry.Update' with" " illegal payload signature '" << g_variant_get_type_string(parameters) << "'. Expected '(sa{sv})'."; return; } glib::String app_uri; GVariantIter* prop_iter; g_variant_get(parameters, "(sa{sv})", &app_uri, &prop_iter); auto entry = LookupByUri(app_uri.Str()); if (entry) { /* It's important that we update the DBus name first since it might * unset the quicklist if it changes */ entry->SetDBusName(sender_name); entry->Update(prop_iter); } else { LauncherEntryRemote::Ptr entry_ptr(new LauncherEntryRemote(sender_name, parameters)); AddEntry(entry_ptr); } g_variant_iter_free(prop_iter); }
gang_lookup_scan(struct radix_tree *t, struct radix_tree_path *path, void **results, unsigned int maxresults, const unsigned int tagmask, bool reverse) { /* * we keep the path updated only for lastidx-1. * vpp is what path_pptr(t, path, lastidx) would be. */ void **vpp; unsigned int nfound; unsigned int lastidx; /* * set up scan direction dependant constants so that we can iterate * n_ptrs as the following. * * for (i = first; i != guard; i += step) * visit n->n_ptrs[i]; */ const int step = reverse ? -1 : 1; const unsigned int first = reverse ? RADIX_TREE_PTR_PER_NODE - 1 : 0; const unsigned int last = reverse ? 0 : RADIX_TREE_PTR_PER_NODE - 1; const unsigned int guard = last + step; KASSERT(maxresults > 0); KASSERT(&t->t_root == path_pptr(t, path, 0)); lastidx = path->p_lastidx; KASSERT(lastidx == RADIX_TREE_INVALID_HEIGHT || lastidx == t->t_height || !entry_match_p(*path_pptr(t, path, lastidx), tagmask)); nfound = 0; if (lastidx == RADIX_TREE_INVALID_HEIGHT) { if (reverse) { lastidx = 0; vpp = path_pptr(t, path, lastidx); goto descend; } return 0; } vpp = path_pptr(t, path, lastidx); while (/*CONSTCOND*/true) { struct radix_tree_node *n; unsigned int i; if (entry_match_p(*vpp, tagmask)) { KASSERT(lastidx == t->t_height); /* * record the matching non-NULL leaf. */ results[nfound] = entry_ptr(*vpp); nfound++; if (nfound == maxresults) { return nfound; } } scan_siblings: /* * try to find the next matching non-NULL sibling. */ if (lastidx == 0) { /* * the root has no siblings. * we've done. */ KASSERT(vpp == &t->t_root); break; } n = path_node(t, path, lastidx - 1); if (*vpp != NULL && n->n_nptrs == 1) { /* * optimization; if the node has only a single pointer * and we've already visited it, there's no point to * keep scanning in this node. */ goto no_siblings; } for (i = vpp - n->n_ptrs + step; i != guard; i += step) { KASSERT(i < RADIX_TREE_PTR_PER_NODE); if (entry_match_p(n->n_ptrs[i], tagmask)) { vpp = &n->n_ptrs[i]; break; } } if (i == guard) { no_siblings: /* * not found. go to parent. */ lastidx--; vpp = path_pptr(t, path, lastidx); goto scan_siblings; } descend: /* * following the left-most (or right-most in the case of * reverse scan) child node, decend until reaching the leaf or * an non-matching entry. */ while (entry_match_p(*vpp, tagmask) && lastidx < t->t_height) { /* * save vpp in the path so that we can come back to this * node after finishing visiting children. */ path->p_refs[lastidx].pptr = vpp; n = entry_ptr(*vpp); vpp = &n->n_ptrs[first]; lastidx++; } } return nfound; }
void * radix_tree_remove_node(struct radix_tree *t, uint64_t idx) { struct radix_tree_path path; void **vpp; void *oldp; int i; vpp = radix_tree_lookup_ptr(t, idx, &path, false, 0); KASSERT(vpp != NULL); oldp = *vpp; KASSERT(oldp != NULL); KASSERT(path.p_lastidx == t->t_height); KASSERT(vpp == path_pptr(t, &path, path.p_lastidx)); *vpp = NULL; for (i = t->t_height - 1; i >= 0; i--) { void *entry; struct radix_tree_node ** const pptr = (struct radix_tree_node **)path_pptr(t, &path, i); struct radix_tree_node *n; KASSERT(pptr != NULL); entry = *pptr; n = entry_ptr(entry); KASSERT(n != NULL); KASSERT(n->n_nptrs > 0); n->n_nptrs--; if (n->n_nptrs > 0) { break; } radix_tree_free_node(n); *pptr = NULL; } /* * fix up height */ if (i < 0) { KASSERT(t->t_root == NULL); t->t_height = 0; } /* * update tags */ for (; i >= 0; i--) { void *entry; struct radix_tree_node ** const pptr = (struct radix_tree_node **)path_pptr(t, &path, i); struct radix_tree_node *n; unsigned int newmask; KASSERT(pptr != NULL); entry = *pptr; n = entry_ptr(entry); KASSERT(n != NULL); KASSERT(n->n_nptrs > 0); newmask = any_children_tagmask(n); if (newmask == entry_tagmask(entry)) { break; } *pptr = entry_compose(n, newmask); } /* * XXX is it worth to try to reduce height? * if we do that, make radix_tree_grow rollback its change as well. */ return entry_ptr(oldp); }