📄 _hotshot.c
字号:
err = unpack_packed_int(self, &lineno, 2);
if (self->linetimings && !err)
err = unpack_packed_int(self, &tdelta, 0);
break;
case WHAT_ADD_INFO:
err = unpack_add_info(self);
break;
case WHAT_DEFINE_FILE:
err = unpack_packed_int(self, &fileno, 0);
if (!err) {
err = unpack_string(self, &s1);
if (!err) {
Py_INCREF(Py_None);
s2 = Py_None;
}
}
break;
case WHAT_DEFINE_FUNC:
err = unpack_packed_int(self, &fileno, 0);
if (!err) {
err = unpack_packed_int(self, &lineno, 0);
if (!err)
err = unpack_string(self, &s1);
}
break;
case WHAT_LINE_TIMES:
if ((c = fgetc(self->logfp)) == EOF)
err = ERR_EOF;
else {
self->linetimings = c ? 1 : 0;
goto restart;
}
break;
case WHAT_FRAME_TIMES:
if ((c = fgetc(self->logfp)) == EOF)
err = ERR_EOF;
else {
self->frametimings = c ? 1 : 0;
goto restart;
}
break;
default:
err = ERR_BAD_RECTYPE;
}
if (err == ERR_BAD_RECTYPE) {
PyErr_SetString(PyExc_ValueError,
"unknown record type in log file");
}
else if (err == ERR_EOF) {
eof_error();
}
else if (!err) {
result = PyTuple_New(4);
PyTuple_SET_ITEM(result, 0, PyInt_FromLong(what));
PyTuple_SET_ITEM(result, 2, PyInt_FromLong(fileno));
if (s1 == NULL)
PyTuple_SET_ITEM(result, 1, PyInt_FromLong(tdelta));
else
PyTuple_SET_ITEM(result, 1, s1);
if (s2 == NULL)
PyTuple_SET_ITEM(result, 3, PyInt_FromLong(lineno));
else
PyTuple_SET_ITEM(result, 3, s2);
}
/* The only other case is err == ERR_EXCEPTION, in which case the
* exception is already set.
*/
#if 0
b0 = self->buffer[self->index];
b1 = self->buffer[self->index + 1];
if (b0 & 1) {
/* This is a line-number event. */
what = PyTrace_LINE;
lineno = ((b0 & ~1) << 7) + b1;
self->index += 2;
}
else {
what = (b0 & 0x0E) >> 1;
tdelta = ((b0 & 0xF0) << 4) + b1;
if (what == PyTrace_CALL) {
/* we know there's a 2-byte file ID & 2-byte line number */
fileno = ((self->buffer[self->index + 2] << 8)
+ self->buffer[self->index + 3]);
lineno = ((self->buffer[self->index + 4] << 8)
+ self->buffer[self->index + 5]);
self->index += 6;
}
else
self->index += 2;
}
#endif
return result;
}
static void
logreader_dealloc(LogReaderObject *self)
{
if (self->logfp != NULL) {
fclose(self->logfp);
self->logfp = NULL;
}
PyObject_Del(self);
}
static PyObject *
logreader_sq_item(LogReaderObject *self, int index)
{
PyObject *result = logreader_tp_iternext(self);
if (result == NULL && !PyErr_Occurred()) {
PyErr_SetString(PyExc_IndexError, "no more events in log");
return NULL;
}
return result;
}
static char next__doc__[] =
"next() -> event-info\n"
"Return the next event record from the log file.";
static PyObject *
logreader_next(LogReaderObject *self, PyObject *args)
{
PyObject *result = NULL;
if (PyArg_ParseTuple(args, ":next")) {
result = logreader_tp_iternext(self);
/* XXX return None if there's nothing left */
/* tp_iternext does the right thing, though */
if (result == NULL && !PyErr_Occurred()) {
result = Py_None;
Py_INCREF(result);
}
}
return result;
}
static void
do_stop(ProfilerObject *self);
static int
flush_data(ProfilerObject *self)
{
/* Need to dump data to the log file... */
size_t written = fwrite(self->buffer, 1, self->index, self->logfp);
if (written == (size_t)self->index)
self->index = 0;
else {
memmove(self->buffer, &self->buffer[written],
self->index - written);
self->index -= written;
if (written == 0) {
char *s = PyString_AsString(self->logfilename);
PyErr_SetFromErrnoWithFilename(PyExc_IOError, s);
do_stop(self);
return -1;
}
}
if (written > 0) {
if (fflush(self->logfp)) {
char *s = PyString_AsString(self->logfilename);
PyErr_SetFromErrnoWithFilename(PyExc_IOError, s);
do_stop(self);
return -1;
}
}
return 0;
}
static inline int
pack_packed_int(ProfilerObject *self, int value)
{
unsigned char partial;
do {
partial = value & 0x7F;
value >>= 7;
if (value)
partial |= 0x80;
self->buffer[self->index] = partial;
self->index++;
} while (value);
return 0;
}
/* Encode a modified packed integer, with a subfield of modsize bits
* containing the value "subfield". The value of subfield is not
* checked to ensure it actually fits in modsize bits.
*/
static inline int
pack_modified_packed_int(ProfilerObject *self, int value,
int modsize, int subfield)
{
const int maxvalues[] = {-1, 1, 3, 7, 15, 31, 63, 127};
int bits = 7 - modsize;
int partial = value & maxvalues[bits];
unsigned char b = subfield | (partial << modsize);
if (partial != value) {
b |= 0x80;
self->buffer[self->index] = b;
self->index++;
return pack_packed_int(self, value >> bits);
}
self->buffer[self->index] = b;
self->index++;
return 0;
}
static int
pack_string(ProfilerObject *self, const char *s, int len)
{
if (len + PISIZE + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
if (pack_packed_int(self, len) < 0)
return -1;
memcpy(self->buffer + self->index, s, len);
self->index += len;
return 0;
}
static int
pack_add_info(ProfilerObject *self, const char *s1, const char *s2)
{
int len1 = strlen(s1);
int len2 = strlen(s2);
if (len1 + len2 + PISIZE*2 + 1 + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_ADD_INFO;
self->index++;
if (pack_string(self, s1, len1) < 0)
return -1;
return pack_string(self, s2, len2);
}
static int
pack_define_file(ProfilerObject *self, int fileno, const char *filename)
{
int len = strlen(filename);
if (len + PISIZE*2 + 1 + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_DEFINE_FILE;
self->index++;
if (pack_packed_int(self, fileno) < 0)
return -1;
return pack_string(self, filename, len);
}
static int
pack_define_func(ProfilerObject *self, int fileno, int lineno,
const char *funcname)
{
int len = strlen(funcname);
if (len + PISIZE*3 + 1 + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_DEFINE_FUNC;
self->index++;
if (pack_packed_int(self, fileno) < 0)
return -1;
if (pack_packed_int(self, lineno) < 0)
return -1;
return pack_string(self, funcname, len);
}
static int
pack_line_times(ProfilerObject *self)
{
if (2 + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_LINE_TIMES;
self->buffer[self->index + 1] = self->linetimings ? 1 : 0;
self->index += 2;
return 0;
}
static int
pack_frame_times(ProfilerObject *self)
{
if (2 + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
self->buffer[self->index] = WHAT_FRAME_TIMES;
self->buffer[self->index + 1] = self->frametimings ? 1 : 0;
self->index += 2;
return 0;
}
static inline int
pack_enter(ProfilerObject *self, int fileno, int tdelta, int lineno)
{
if (MPISIZE + PISIZE*2 + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
pack_modified_packed_int(self, fileno, 2, WHAT_ENTER);
pack_packed_int(self, lineno);
if (self->frametimings)
return pack_packed_int(self, tdelta);
else
return 0;
}
static inline int
pack_exit(ProfilerObject *self, int tdelta)
{
if (MPISIZE + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
if (self->frametimings)
return pack_modified_packed_int(self, tdelta, 2, WHAT_EXIT);
self->buffer[self->index] = WHAT_EXIT;
self->index++;
return 0;
}
static inline int
pack_lineno(ProfilerObject *self, int lineno)
{
if (MPISIZE + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return -1;
}
return pack_modified_packed_int(self, lineno, 2, WHAT_LINENO);
}
static inline int
pack_lineno_tdelta(ProfilerObject *self, int lineno, int tdelta)
{
if (MPISIZE + PISIZE + self->index >= BUFFERSIZE) {
if (flush_data(self) < 0)
return 0;
}
if (pack_modified_packed_int(self, lineno, 2, WHAT_LINENO) < 0)
return -1;
return pack_packed_int(self, tdelta);
}
static inline int
get_fileno(ProfilerObject *self, PyCodeObject *fcode)
{
/* This is only used for ENTER events. */
PyObject *obj;
PyObject *dict;
int fileno;
obj = PyDict_GetItem(self->filemap, fcode->co_filename);
if (obj == NULL) {
/* first sighting of this file */
dict = PyDict_New();
if (dict == NULL) {
return -1;
}
fileno = self->next_fileno;
obj = Py_BuildValue("iN", fileno, dict);
if (obj == NULL) {
return -1;
}
if (PyDict_SetItem(self->filemap, fcode->co_filename, obj)) {
Py_DECREF(obj);
return -1;
}
self->next_fileno++;
Py_DECREF(obj);
if (pack_define_file(self, fileno,
PyString_AS_STRING(fcode->co_filename)) < 0)
return -1;
}
else {
/* already know this ID */
fileno = PyInt_AS_LONG(PyTuple_GET_ITEM(obj, 0));
dict = PyTuple_GET_ITEM(obj, 1);
}
/* make sure we save a function name for this (fileno, lineno) */
obj = PyInt_FromLong(fcode->co_firstlineno);
if (obj == NULL) {
/* We just won't have it saved; too bad. */
PyErr_Clear();
}
else {
PyObject *name = PyDict_GetItem(dict, obj);
if (name == NULL) {
if (pack_define_func(self, fileno, fcode->co_firstlineno,
PyString_AS_STRING(fcode->co_name)) < 0)
return -1;
if (PyDict_SetItem(dict, obj, fcode->co_name))
return -1;
}
}
return fileno;
}
static inline int
get_tdelta(ProfilerObject *self)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -