Exemple #1
0
static PyObject* do_fullcompile(PyFrameObject* frame, PyObject* arg)
{
	PyCodeStats* cs;
	cs = PyCodeStats_Get(frame->f_code);
	if (cs->st_codebuf == NULL) {
		/* not already compiled, compile it now */
		PyObject* g = frame->f_globals;
		int rec, module;
		stats_printf(("stats: full compile code:  %s\n",
			      PyCodeObject_NAME(frame->f_code)));
		if (cs->st_globals && PyInt_Check(cs->st_globals))
			rec = PyInt_AS_LONG(cs->st_globals);
		else
			rec = DEFAULT_RECURSION;
                module = frame->f_globals == frame->f_locals;
		cs->st_codebuf = PsycoCode_CompileCode(frame->f_code,
						       g, rec, module);
		if (cs->st_codebuf == Py_None)
			g = NULL;  /* failed */
		else {
			Py_INCREF(g);
			extra_assert(CodeBuffer_Check(cs->st_codebuf));
		}
		Py_XDECREF(cs->st_globals);
		cs->st_globals = g;
	}
	/* already compiled a Psyco version, run it if the globals match */
	extra_assert(frame->f_globals != NULL);
	if (cs->st_globals == frame->f_globals) {
		Py_INCREF(cs->st_codebuf);
		return cs->st_codebuf;
	}
	return NULL;
}
Exemple #2
0
static void stats_dump(void)
{
	float top[STATLINES];
	char* top_names[STATLINES];
	int i, j, k=0;
	PyObject *key, *value;
	for (i=0; i<STATLINES; i++)
		top[i] = -1.0f;
	
	while (PyDict_Next(codestats_dict, &k, &key, &value)) {
		PyCodeStats* cs = (PyCodeStats*) key;
		PyCodeObject* co;
		extra_assert(PyCStruct_Check(key));
		extra_assert(PyCode_Check(cs->cs_key));
		co = (PyCodeObject*) cs->cs_key;
		for (i=0; i<STATLINES; i++) {
			if (cs->st_charge > top[i]) {
				for (j=STATLINES-1; j>i; j--) {
					top      [j] = top      [j-1];
					top_names[j] = top_names[j-1];
				}
				top      [i] = cs->st_charge;
				top_names[i] = PyCodeObject_NAME(co);
				break;
			}
		}
	}
	for (i=0; i<STATLINES; i++) {
		if (top[i] < 0.0f)
			break;
		stats_printf(("stats:  #%d %18g   %s\n",
			      i, top[i], top_names[i]));
	}
}
Exemple #3
0
DEFINEFN
PyObject* psyco_stats_top(int n)
{
	PyObject* l;
	PyObject* l2 = NULL;
	int i, k=0, full=0;
	PyObject *key, *value;
	float charge_min = (float)(charge_total * 0.001);

	extra_assert(n>0);
	l = PyList_New(n);
	if (l == NULL)
		goto fail;
	
	while (PyDict_Next(codestats_dict, &k, &key, &value)) {
		PyCodeStats* cs = (PyCodeStats*) key;
		extra_assert(PyCStruct_Check(key));
		extra_assert(PyCode_Check(cs->cs_key));
		if (cs->st_charge <= charge_min)
			continue;
		if (full < n)
			full++;
		i = full;
		while (--i > 0) {
			PyObject* o = PyList_GetItem(l, i-1);
			PyCodeStats* current = (PyCodeStats*) o;
			if (cs->st_charge <= current->st_charge)
				break;
                        Py_INCREF(o);
			if (PyList_SetItem(l, i, o))
				goto fail;
		}
		Py_INCREF(cs);
		if (PyList_SetItem(l, i, (PyObject*) cs))
			goto fail;
		cs = (PyCodeStats*) PyList_GetItem(l, full-1);
		charge_min = cs->st_charge;
	}

	l2 = PyList_New(full);
	if (l2 == NULL)
		goto fail;

	for (i=0; i<full; i++) {
		PyCodeStats* cs = (PyCodeStats*) PyList_GetItem(l, i);
                PyObject* x = Py_BuildValue("Od", cs->cs_key,
					(double)(cs->st_charge / charge_total));
		if (!x || PyList_SetItem(l2, i, x))
			goto fail;
	}
	Py_DECREF(l);
	return l2;

 fail:
	Py_XDECREF(l2);
	Py_XDECREF(l);
	return NULL;
}
Exemple #4
0
static PyObject* profile_call(PyFrameObject* frame, PyObject* arg)
{
	PyCodeStats* cs;
	psyco_stats_append(frame->f_tstate, frame->f_back);

	cs = PyCodeStats_Get(frame->f_code);
	if (cs->st_globals != NULL) {
		/* we want to accelerate this code object */
		if (cs->st_codebuf == NULL) {
			/* not already compiled, compile it now */
			PyObject* codebuf;
			PyObject* g = frame->f_globals;
			int rec, module;
			stats_printf(("stats: compile code:  %s\n",
				      PyCodeObject_NAME(frame->f_code)));
			if (PyInt_Check(cs->st_globals))
				rec = PyInt_AS_LONG(cs->st_globals);
			else
				rec = DEFAULT_RECURSION;
			module = frame->f_globals == frame->f_locals;
			codebuf = PsycoCode_CompileCode(frame->f_code,
							g, rec, module);
			/* rare race condition: 'cs' might have been mutated
			   during the call to PsycoCode_CompileCode(), so
			   cs->st_codebuf might no longer be NULL, or
			   cs->st_globals might be NULL again */
			Py_XDECREF(cs->st_codebuf);
			cs->st_codebuf = codebuf;
			if (cs->st_codebuf == Py_None)
				g = NULL;  /* failed */
			else {
				Py_INCREF(g);
				extra_assert
					(CodeBuffer_Check(cs->st_codebuf));
			}
			Py_XDECREF(cs->st_globals);
			cs->st_globals = g;
		}
		/* already compiled a Psyco version, run it
		   if the globals match */
		extra_assert(frame->f_globals != NULL);
		if (cs->st_globals == frame->f_globals) {
			Py_INCREF(cs->st_codebuf);
			return cs->st_codebuf;
		}
	}
	return NULL;
}
Exemple #5
0
PSY_INLINE bool call_ceval_hooks(ceval_events_t* cev, int what, PyFrameObject* f)
{
	bool r = true;
	int n;
	struct cevents_s* events;
	PyObject* codebuf;
	PyObject* obj;
	extra_assert(what >= 0);
	if (what >= PyTrace_TOTAL)
		return true;   /* Python >= 2.4 defines PyTrace_C_xxx */
#if VERBOSE_LEVEL >= 3
        stats_printf(("hook: %d %s\n", what, PyCodeObject_NAME(f->f_code)));
#endif
	events = cev->events + what;
	n = events->count;
	do {
		if (n == 0)
			return true;  /* done */
		n--;
		extra_assert(n < events->count);
		codebuf = events->items[n].fn(f, events->items[n].arg);
		if (events->items[n].fn == &deleted_ceval_hook) {
			events->items[n] = events->items[--events->count];
		}
	} while (codebuf == NULL);

	/* call the other hooks, if any */
	while (n != 0) {
		n--;
		extra_assert(n < events->count);
		obj = events->items[n].fn(f, events->items[n].arg);
		Py_XDECREF(obj);
		if (events->items[n].fn == &deleted_ceval_hook) {
			events->items[n] = events->items[--events->count];
		}
	}
	/* enable recursive calls to call_ceval_hooks() */
	f->f_tstate->use_tracing = 1;
	f->f_tstate->tracing--;
	/* run the compiled code */
	r = PsycoCode_Run(codebuf, f, what == PyTrace_CALL);
	f->f_tstate->tracing++;
	Py_DECREF(codebuf);
#if (PY_VERSION_HEX >= 0x02030000) && (PY_VERSION_HEX < 0x020300f0)
	if (!r) f->f_stacktop = NULL;  /* work around a bug in Python 2.3b1 */
#endif
	return r;
}
Exemple #6
0
static void set_ceval_hook(ceval_events_t* cev, int when,
			   ceval_event_fn fn, PyObject* arg)
{
	int n, i, allow;
	struct cevents_s* events;
	extra_assert(0 <= when && when < PyTrace_TOTAL);
	events = cev->events + when;
	n = events->count++;
	PyMem_RESIZE(events->items, struct cevent_s, events->count);
	if (events->items == NULL)
		OUT_OF_MEMORY();
	events->items[n].fn = fn;
	events->items[n].arg = arg;
	cev->events_total++;
	if (arg != NULL) {
		/* bound the total number of hooks by checking if there are
		   too many other hooks with the same 'fn' */
		allow = 8;
		for (i=n; --i >= 0; ) {
			if (events->items[i].fn == fn && !--allow) {
				/* too many! remove an arbitrary one */
				events->items[i].fn = &deleted_ceval_hook;
				cev->events_total--;
				break;
			}
		}
	}
}
Exemple #7
0
DEFINEFN
void psyco_flog(char* msg, ...)
{
  va_list vargs;
  PyObject* s;
  PyObject* r;
  PyObject *etype, *evalue, *etb;
  extra_assert(psyco_logger != NULL);

  PyErr_Fetch(&etype, &evalue, &etb);
  
#ifdef HAVE_STDARG_PROTOTYPES
  va_start(vargs, msg);
#else
  va_start(vargs);
#endif
  s = PyString_FromFormatV(msg, vargs);
  va_end(vargs);

  if (s == NULL)
    OUT_OF_MEMORY();
  r = PyObject_CallFunction(psyco_logger, "O", s);
  if (r == NULL)
    PyErr_WriteUnraisable(psyco_logger);
  else
    Py_DECREF(r);
  Py_DECREF(s);

  PyErr_Restore(etype, evalue, etb);
}
Exemple #8
0
PSY_INLINE ceval_events_t* get_cevents(PyThreadState* tstate)
{
	PyObject* dict = tstate->dict;
	if (dict != NULL) {
		PyObject* o = PyDict_GetItem(dict, ceval_events_key);
		if (o != NULL) {
			extra_assert(PyCStruct_Check(o));
			return (ceval_events_t*) o;
		}
	}
	return new_cevents(tstate);
}
Exemple #9
0
DEFINEFN
PyObject* psyco_stats_dump(void)
{
	PyObject* d = PyDict_New();
	int i = 0;
	PyObject *key, *value;
	if (d == NULL)
		return NULL;
	
	while (PyDict_Next(codestats_dict, &i, &key, &value)) {
		PyCodeStats* cs = (PyCodeStats*) key;
		PyObject* o = PyFloat_FromDouble(cs->st_charge);
		extra_assert(PyCStruct_Check(key));
		extra_assert(PyCode_Check(cs->cs_key));
		if (o == NULL || PyDict_SetItem(d, cs->cs_key, o)) {
			Py_DECREF(d);
			return NULL;
		}
	}
	stats_dump();
	return d;
}
Exemple #10
0
static PyObject* do_nocompile(PyFrameObject* frame, PyObject* arg)
{
	PyCodeStats* cs;
	cs = PyCodeStats_MaybeGet(frame->f_code);
	/* if already compiled a Psyco version, run it if the globals match */
	if (cs != NULL && cs->st_codebuf != NULL &&
	    cs->st_globals == frame->f_globals) {
		extra_assert(frame->f_globals != NULL);
		Py_INCREF(cs->st_codebuf);
		return cs->st_codebuf;
	}
	return NULL;
}
Exemple #11
0
DEFINEFN
bool psyco_generic_ass_subscript(PsycoObject* po, vinfo_t* o,
				 vinfo_t* key, vinfo_t* value)
{
	/* see psyco_generic_subscript() for comments */
	
	/* TypeSwitch */
	PyTypeObject* ktp = Psyco_NeedType(po, key);
	if (ktp == NULL)
		return false;

	if (PyType_TypeCheck(ktp, &PyInt_Type)) {
		return PsycoSequence_SetItem(po, o,
					     PsycoInt_AS_LONG(po, key),
					     value);
	}
	else if (PyType_TypeCheck(ktp, &PyLong_Type)) {
		bool result;
		vinfo_t* key_value = PsycoLong_AsLong(po, key);
		if (key_value == NULL)
			return false;
		result = PsycoSequence_SetItem(po, o, key_value, value);
		vinfo_decref(key_value, po);
		return result;
	}
	else {
		char* vargs = (value!=NULL) ? "vvv" : "vvl";
		PyTypeObject* tp = Psyco_NeedType(po, o);
		if (tp == NULL)
			return false;
		extra_assert(tp->tp_as_mapping != NULL);
		extra_assert(tp->tp_as_mapping->mp_ass_subscript != NULL);
		return psyco_generic_call(po,
					  tp->tp_as_mapping->mp_ass_subscript,
					  CfNoReturnValue|CfPyErrIfNonNull,
					  vargs, o, key, value) != NULL;
	}
}
Exemple #12
0
DEFINEFN
vinfo_t* psyco_generic_subscript(PsycoObject* po, vinfo_t* o, vinfo_t* key)
{
	/* This is the meta-implementation of the mapping item assignment
	   for sequences in Python >= 2.3, which is called for any
	   expression of the form a[n]. It expects n to be an integer
	   or an extended slice object. Regular slicing a[n:m] does not
	   come here. */

	/* TypeSwitch */
	PyTypeObject* ktp = Psyco_NeedType(po, key);
	if (ktp == NULL)
		return NULL;

	if (PyType_TypeCheck(ktp, &PyInt_Type)) {
		return PsycoSequence_GetItem(po, o,
					     PsycoInt_AS_LONG(po, key));
	}
	else if (PyType_TypeCheck(ktp, &PyLong_Type)) {
		vinfo_t* result;
		vinfo_t* key_value = PsycoLong_AsLong(po, key);
		if (key_value == NULL)
			return NULL;
		result = PsycoSequence_GetItem(po, o, key_value);
		vinfo_decref(key_value, po);
		return result;
	}
	else {
		PyTypeObject* tp = Psyco_NeedType(po, o);
		if (tp == NULL)
			return NULL;
		extra_assert(tp->tp_as_mapping != NULL);
		extra_assert(tp->tp_as_mapping->mp_subscript != NULL);
		return psyco_generic_call(po, tp->tp_as_mapping->mp_subscript,
					  CfReturnRef|CfPyErrIfNull,
					  "vv", o, key);
	}
}
Exemple #13
0
DEFINEFN
vinfo_array_t* array_grow1(vinfo_array_t* array, int ncount)
{
  int i = array->count;
  extra_assert(ncount > i);
  if (i == 0)
    array = PyMem_MALLOC(sizeof(int) + ncount * sizeof(vinfo_t*));
  else
    array = PyMem_REALLOC(array, sizeof(int) + ncount * sizeof(vinfo_t*));
  if (array == NULL)
    OUT_OF_MEMORY();
  array->count = ncount;
  while (i<ncount)
    array->items[i++] = NULL;
  return array;
}
Exemple #14
0
static void unset_ceval_hook(ceval_events_t* cev, int when,
			     ceval_event_fn fn, PyObject* arg)
{
	/* warning: do not shuffle values in the events->items array to
	   compact it, because this might be called while the array is 
	   being enumerated by call_ceval_hooks() */
	int n;
	struct cevents_s* events;
	extra_assert(0 <= when && when < PyTrace_TOTAL);
	events = cev->events + when;
	n = events->count;
	while (n--) {
		if (events->items[n].fn == fn && events->items[n].arg == arg) {
			events->items[n].fn = &deleted_ceval_hook;
			cev->events_total--;
		}
	}
}