/***************************************************************/ /*** Support to manage the emitted code chunks ***/ /***************************************************************/ #ifndef _CODEMANAGER_H #define _CODEMANAGER_H #include "psyco.h" #include "dispatcher.h" #define WARN_TOO_MANY_BUFFERS 6 /* to detect missing buffer unlocks */ /* a CodeBufferObject is a pointer to emitted code. The 'state' PsycoObject records the state of the compiler at the start of the emission of code. Consider this field as private. Future versions of the code manager will probably encode the recorded states in a more sophisticated form than just a dump copy. (There are usually a lot of small CodeBufferObjects, so if each one has a full copy of the state big projects will explode the memory.) */ struct CodeBufferObject_s { PyObject_HEAD void* codestart; int idno; FrozenPsycoObject snapshot; #if CODE_DUMP char* codemode; CodeBufferObject* chained_list; #endif }; #if CODE_DUMP extern CodeBufferObject* psyco_codebuf_chained_list; extern void** psyco_codebuf_spec_dict_list; void psyco_dump_bigbuffers(FILE* f); # define SET_CODEMODE(b, mode) ((b)->codemode = (mode)) #else # define SET_CODEMODE(b, mode) do { } while (0) /* nothing */ #endif #define CodeBuffer_Check(v) ((v)->ob_type == &CodeBuffer_Type) extern PyTypeObject CodeBuffer_Type; /* starts a new code buffer. The limit is returned in the optional last argument. 'po' is the state of the compiler at this point, of which a frozen copy will be made. It can be NULL. If not, set 'ge' as in psyco_compile(). */ CodeBufferObject* psyco_new_code_buffer(PsycoObject *po, global_entries_t* ge, code_t** plimit); /* creates a CodeBufferObject pointing to an already existing code target */ CodeBufferObject* psyco_proxy_code_buffer(PsycoObject *po, global_entries_t* ge); #if 0 /* creates a minimal CodeBufferObject with only a code pointer */ CodeBufferObject* psyco_minimal_code_buffer(code_t* code); #endif /* shrink a buffer returned by new_code_buffer() */ void psyco_shrink_code_buffer(CodeBufferObject* obj, code_t* codeend); /* emergency enlarge a buffer (by coding a jump to a new buffer) */ void psyco_emergency_enlarge_buffer(code_t** pcode, code_t** pcodelimit); int psyco_locked_buffers(void); #define SHRINK_CODE_BUFFER(obj, nend, mode) do { \ psyco_shrink_code_buffer(obj, nend); \ SET_CODEMODE(obj, mode); \ } while (0) /* a replacement for Py_XDECREF(obj) which does not release the object immediately, but only at the next call to psyco_trash_object() */ void psyco_trash_object(PyObject* obj); #endif /* _CODEMANAGER_H */