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
DEFINEFN
void psyco_turbo_code(PyCodeObject* code, int recursion)
{
	PyCodeStats* cs = PyCodeStats_Get(code);
	if (cs->st_codebuf == NULL && cs->st_globals == NULL) {
		/* trigger compilation at the next occasion
		   by storing something non-NULL in st_globals */
		cs->st_globals = PyInt_FromLong(recursion);
		if (cs->st_globals == NULL)
			OUT_OF_MEMORY();
        }
}
Exemple #3
0
DEFINEFN
void psyco_stats_append(PyThreadState* tstate, PyFrameObject* f)
{
	double charge;
	float cs_charge;
	int bits;
	time_measure_t numticks;

	if (!measuring_state(tstate))
		return;
	numticks = get_measure(tstate);
	if (measure_is_zero(numticks) || f == NULL)
		return;  /* f==NULL must still make a get_measure() call */
	charge = ((double) charge_unit) * numticks;
	
	bits = c_random();
	while (1) {
		PyCodeStats* cs = PyCodeStats_Get(f->f_code);
		cs_charge = (float)(cs->st_charge + charge);
		cs->st_charge = cs_charge;
		charge_total += charge;
		if (cs_charge > charge_prelimit && charge_callback) {
			/* update charge_prelimit */
			charge_prelimit = (float)(charge_total * charge_watermark);
			if (cs_charge > charge_prelimit) {
				/* still over the up-to-date limit */
				cs->st_charge = 0.0f;
				break;
			}
		}
		if (bits >= 0)
			return;  /* triggers in about 50% of the cases */
		bits <<= 1;
		f = f->f_back;
		if (!f)
			return;
		charge *= charge_parent2;
	}

	/* charge limit reached, invoke callback */
	{
		PyObject* r;
		r = PyObject_CallFunction(charge_callback, "Of", f, cs_charge);
		if (r == NULL) {
			PyErr_WriteUnraisable((PyObject*) f);
		}
		else {
			Py_DECREF(r);
		}
	}
}
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;
}