Esempio n. 1
0
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);
	}
}
Esempio n. 2
0
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));
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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;
}
Esempio n. 6
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);
}
Esempio n. 7
0
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;
			}
		}
	}
}
Esempio n. 8
0
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);
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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);
}