Screenshot instructions:
Windows
Mac
Red Hat Linux
Ubuntu
Click URL instructions:
Right-click on ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(25) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(51) |
Feb
(71) |
Mar
(24) |
Apr
(4) |
May
|
Jun
(5) |
Jul
|
Aug
(25) |
Sep
(15) |
Oct
(13) |
Nov
|
Dec
|
2003 |
Jan
(20) |
Feb
(11) |
Mar
(22) |
Apr
(18) |
May
(25) |
Jun
(13) |
Jul
(4) |
Aug
(17) |
Sep
(34) |
Oct
(4) |
Nov
|
Dec
(2) |
2004 |
Jan
(4) |
Feb
|
Mar
(30) |
Apr
|
May
(3) |
Jun
(3) |
Jul
(7) |
Aug
(19) |
Sep
(2) |
Oct
(12) |
Nov
|
Dec
(60) |
2005 |
Jan
(13) |
Feb
(9) |
Mar
(1) |
Apr
(6) |
May
|
Jun
(4) |
Jul
|
Aug
(1) |
Sep
(7) |
Oct
(4) |
Nov
(9) |
Dec
|
2006 |
Jan
(4) |
Feb
(15) |
Mar
(8) |
Apr
(13) |
May
(28) |
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
(9) |
Nov
(9) |
Dec
(2) |
2007 |
Jan
(3) |
Feb
|
Mar
(1) |
Apr
|
May
(4) |
Jun
(3) |
Jul
|
Aug
(2) |
Sep
(2) |
Oct
|
Nov
|
Dec
(14) |
2008 |
Jan
(3) |
Feb
(4) |
Mar
|
Apr
(4) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
(13) |
Nov
(2) |
Dec
(7) |
2009 |
Jan
(23) |
Feb
(15) |
Mar
(8) |
Apr
|
May
|
Jun
|
Jul
(22) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
(4) |
2010 |
Jan
|
Feb
(17) |
Mar
(2) |
Apr
(7) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
|
|
|
|
1
|
2
(3) |
3
|
4
|
5
(6) |
6
(3) |
7
|
8
(6) |
9
|
10
(3) |
11
(5) |
12
|
13
(1) |
14
|
15
(11) |
16
|
17
|
18
(6) |
19
(4) |
20
|
21
(3) |
22
|
23
|
24
|
25
(3) |
26
(10) |
27
(1) |
28
(6) |
|
|
From: Armin Rigo <arigo@us...> - 2002-02-05 20:08:30
|
Update of /cvsroot/psyco/psyco/c In directory usw-pr-cvs1:/tmp/cvs-serv27600/c Modified Files: Makefile codemanager.c codemanager.h dispatcher.c dispatcher.h encoding.h hack.c mergepoints.c processor.c processor.h psyco.c psyco.h selective.c vcompiler.c vcompiler.h Log Message: major and numerous bug fixes. Psyco will now run most of Python's regresstion tests. Index: Makefile =================================================================== RCS file: /cvsroot/psyco/psyco/c/Makefile,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Makefile 2002/01/11 16:18:02 1.8 --- Makefile 2002/02/05 20:08:23 1.9 *************** *** 3,15 **** ### Fix the Python include path for your system. # - # PY_INCLUDE = /home/arigo/cvs/python/dist/src/Include PY_INCLUDE = /usr/include/python2.2 - # PY_INCLUDE = /users/arigo/include/python2.2 - # PY_INCLUDE = /home/arigo/include/python2.1 # # ! CC = gcc ! C_FLAGS = -g -Wall -Wstrict-prototypes # -O3 -DDISABLE_DEBUG ! LINK_FLAGS = -shared # ############################################################################## --- 3,28 ---- ### Fix the Python include path for your system. # PY_INCLUDE = /usr/include/python2.2 # # ! CC = gcc ! LINK_FLAGS = -shared ! DEBUG_FLAGS = -g -Wall -Wstrict-prototypes ! RELEASE_FLAGS = -O3 -DPSYCO_DEBUG=0 ! # ! # pick one of the following mode or make your own. ! # see psyco.h for the range and meaning of the defines. ! # ! # release mode: ! #C_FLAGS = ${RELEASE_FLAGS} ! # ! # lightweight debugging checks (recommended for now): ! C_FLAGS = ${DEBUG_FLAGS} -DVERBOSE_LEVEL=0 -DCODE_DUMP=1 -DHEAVY_MEM_CHECK=0 ! # ! # usual debugging mode: ! #C_FLAGS = ${DEBUG_FLAGS} -DVERBOSE_LEVEL=1 -DCODE_DUMP=2 -DHEAVY_MEM_CHECK=0 ! # ! # heavy debugging, fully verbose with instruction tracing: ! #C_FLAGS = ${DEBUG_FLAGS} -DVERBOSE_LEVEL=4 -DCODE_DUMP=3 -DHEAVY_MEM_CHECK=1 # ############################################################################## Index: codemanager.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/codemanager.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** codemanager.c 2002/01/17 13:32:57 1.5 --- codemanager.c 2002/02/05 20:08:23 1.6 *************** *** 21,25 **** b->codeptr = (codepointer); \ SET_CODE_END(!setcodelimit); \ ! if (VERBOSE_LEVEL > 1) \ debug_printf(("psyco: %s code buffer %p\n", \ extrasize ? "new" : "proxy", b->codeptr)); \ --- 21,25 ---- b->codeptr = (codepointer); \ SET_CODE_END(!setcodelimit); \ ! if (VERBOSE_LEVEL > 2) \ debug_printf(("psyco: %s code buffer %p\n", \ extrasize ? "new" : "proxy", b->codeptr)); \ *************** *** 69,73 **** b->codeptr = (code_t*) (b + 1); b->po = NULL; ! if (VERBOSE_LEVEL > 1) debug_printf(("psyco: new_code_buffer_size(%d) %p\n", size, b->codeptr)); return b; --- 69,73 ---- b->codeptr = (code_t*) (b + 1); b->po = NULL; ! if (VERBOSE_LEVEL > 2) debug_printf(("psyco: new_code_buffer_size(%d) %p\n", size, b->codeptr)); return b; *************** *** 75,79 **** #endif ! #ifdef CODE_DUMP_FILE DEFINEVAR CodeBufferObject* psyco_codebuf_chained_list = NULL; DEFINEVAR void** psyco_codebuf_spec_dict_list = NULL; --- 75,79 ---- #endif ! #if CODE_DUMP DEFINEVAR CodeBufferObject* psyco_codebuf_chained_list = NULL; DEFINEVAR void** psyco_codebuf_spec_dict_list = NULL; *************** *** 87,94 **** ndata = PyObject_REALLOC(obj, sizeof(CodeBufferObject) + nsize); //printf("psyco: shrink_code_buffer %p to %d\n", obj->codeptr, nsize); ! if (VERBOSE_LEVEL > 1) debug_printf(("psyco: disassemble %p %p (%d bytes)\n", obj->codeptr, obj->codeptr + nsize, nsize)); ! else debug_printf(("[%d]", nsize)); assert(ndata == obj); /* don't know what to do if this is not the case */ --- 87,94 ---- ndata = PyObject_REALLOC(obj, sizeof(CodeBufferObject) + nsize); //printf("psyco: shrink_code_buffer %p to %d\n", obj->codeptr, nsize); ! if (VERBOSE_LEVEL > 2) debug_printf(("psyco: disassemble %p %p (%d bytes)\n", obj->codeptr, obj->codeptr + nsize, nsize)); ! else if (VERBOSE_LEVEL > 1) debug_printf(("[%d]", nsize)); assert(ndata == obj); /* don't know what to do if this is not the case */ *************** *** 98,102 **** obj->codemode = "normal"; #endif ! #ifdef CODE_DUMP_FILE obj->chained_list = psyco_codebuf_chained_list; psyco_codebuf_chained_list = obj; --- 98,102 ---- obj->codemode = "normal"; #endif ! #if CODE_DUMP obj->chained_list = psyco_codebuf_chained_list; psyco_codebuf_chained_list = obj; *************** *** 139,143 **** static void codebuf_dealloc(CodeBufferObject* self) { ! #ifdef CODE_DUMP_FILE CodeBufferObject** ptr = &psyco_codebuf_chained_list; void** chain; --- 139,143 ---- static void codebuf_dealloc(CodeBufferObject* self) { ! #if CODE_DUMP CodeBufferObject** ptr = &psyco_codebuf_chained_list; void** chain; *************** *** 155,159 **** assert(!"releasing a code buffer with a spec_dict"); #endif ! if (VERBOSE_LEVEL > 1) debug_printf(("psyco: releasing code buffer %p at %p\n", self->codeptr, self)); --- 155,159 ---- assert(!"releasing a code buffer with a spec_dict"); #endif ! if (VERBOSE_LEVEL > 2) debug_printf(("psyco: releasing code buffer %p at %p\n", self->codeptr, self)); Index: codemanager.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/codemanager.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** codemanager.h 2002/01/11 16:15:38 1.2 --- codemanager.h 2002/02/05 20:08:23 1.3 *************** *** 14,19 **** /*#undef STORE_CODE_END*/ ! #ifdef CODE_DUMP_FILE ! # define STORE_CODE_END /* always needed by CODE_DUMP_FILE */ #endif --- 14,19 ---- /*#undef STORE_CODE_END*/ ! #if CODE_DUMP ! # define STORE_CODE_END /* always needed by CODE_DUMP */ #endif *************** *** 35,45 **** code_t* codeend; char* codemode; ! #ifdef CODE_DUMP_FILE CodeBufferObject* chained_list; ! #endif #endif }; ! #ifdef CODE_DUMP_FILE EXTERNVAR CodeBufferObject* psyco_codebuf_chained_list; EXTERNVAR void** psyco_codebuf_spec_dict_list; --- 35,45 ---- code_t* codeend; char* codemode; ! # if CODE_DUMP CodeBufferObject* chained_list; ! # endif #endif }; ! #if CODE_DUMP EXTERNVAR CodeBufferObject* psyco_codebuf_chained_list; EXTERNVAR void** psyco_codebuf_spec_dict_list; Index: dispatcher.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/dispatcher.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** dispatcher.c 2002/01/29 15:37:46 1.10 --- dispatcher.c 2002/02/05 20:08:23 1.11 *************** *** 17,23 **** fpo->fz_vlocals = array_new(po->vlocals.count); duplicate_array(fpo->fz_vlocals, &po->vlocals); ! fpo->fz_stuff.as_int = ! (po->stack_depth<<8) | ((int) po->last_used_reg); ! fpo->fz_arguments_count = po->arguments_count; fpo->fz_pyc_data = pyc_data_new(&po->pr); } --- 17,22 ---- fpo->fz_vlocals = array_new(po->vlocals.count); duplicate_array(fpo->fz_vlocals, &po->vlocals); ! fpo->fz_stuff.fz_stack_depth = po->stack_depth; ! fpo->fz_last_used_reg = (int) po->last_used_reg; fpo->fz_pyc_data = pyc_data_new(&po->pr); } *************** *** 56,61 **** PsycoObject* po = PsycoObject_New(fpo->fz_vlocals->count); po->stack_depth = get_stack_depth(fpo); ! po->last_used_reg = (reg_t)(fpo->fz_stuff.as_int & 0xFF); ! po->arguments_count = fpo->fz_arguments_count; assert_cleared_tmp_marks(fpo->fz_vlocals); duplicate_array(&po->vlocals, fpo->fz_vlocals); --- 55,59 ---- PsycoObject* po = PsycoObject_New(fpo->fz_vlocals->count); po->stack_depth = get_stack_depth(fpo); ! po->last_used_reg = (reg_t) fpo->fz_last_used_reg; assert_cleared_tmp_marks(fpo->fz_vlocals); duplicate_array(&po->vlocals, fpo->fz_vlocals); *************** *** 160,164 **** that code now, but any time later is fine: use the trash of codemanager.c */ psyco_trash_object((PyObject*) rs->self); ! psyco_dump_code_buffers(); /* XXX don't know what to do with this reference to codebuf */ return codebuf->codeptr; --- 158,162 ---- that code now, but any time later is fine: use the trash of codemanager.c */ psyco_trash_object((PyObject*) rs->self); ! dump_code_buffers(); /* XXX don't know what to do with this reference to codebuf */ return codebuf->codeptr; *************** *** 248,252 **** FAR_COND_JUMP_TO(codebuf->codeptr, jmpcondition); END_CODE ! psyco_dump_code_buffers(); } else --- 246,250 ---- FAR_COND_JUMP_TO(codebuf->codeptr, jmpcondition); END_CODE ! dump_code_buffers(); } else *************** *** 521,546 **** { vinfo_t* b = bb->items[i]; ! if (b != NULL) { if (is_runtime(b->source)) { char rg, rgb; vinfo_t* overridden; - vinfo_t* a = b->tmp; /* source value */ long dststack = RUNTIME_STACK(b); long srcstack = RUNTIME_STACK(a); ! /* check for values passing from no-reference to reference ! or vice-versa */ ! if (((a->source ^ b->source) & RunTime_NoRef) != 0) ! { ! /* from 'with ref' to 'no ref' is forbidden ! by psyco_compatible() */ ! extra_assert((a->source & RunTime_NoRef) != 0); ! RTVINFO_IN_REG(a); ! rg = RUNTIME_REG(a); ! INC_OB_REFCNT(rg); ! a->source &= ~RunTime_NoRef; ! } rgb = RUNTIME_REG(b); --- 519,562 ---- { vinfo_t* b = bb->items[i]; ! if (b != NULL && b->tmp != NULL) { + vinfo_t* a = b->tmp; /* source value */ + b->tmp = NULL; /* don't consider the same 'b' more than once */ + if (is_runtime(b->source)) { char rg, rgb; vinfo_t* overridden; long dststack = RUNTIME_STACK(b); long srcstack = RUNTIME_STACK(a); ! /* check for values passing from no-reference to reference */ ! if ((b->source & RunTime_NoRef) == 0) { /* destination has ref */ ! if ((a->source & RunTime_NoRef) == 0) /* source has ref too */ ! { ! /* remove the reference from 'a' because it now belongs ! to 'b' ('b->source' itself is in the frozen snapshot ! and must not be modified!) */ ! a->source = remove_rtref(a->source); ! } ! else ! { ! /* create a new reference for 'b'. Note that if the same ! 'a' is copied to several 'b's during data_update_stack() ! as is allowed by graph quotient detection in ! psyco_compatible(), then only the first copy will get ! the original reference owned by 'a' (if any) and for ! the following copies the following increfing code is ! executed as well. */ ! RTVINFO_IN_REG(a); ! rg = RUNTIME_REG(a); ! INC_OB_REFCNT(rg); ! } ! } ! /* 'a' must no longer own a reference at this point. ! The case of 'b' wanting no reference but 'a' having one ! is forbidden by psyco_compatible() because decrefing 'a' ! would potentially leave a freed pointer in 'b'. */ ! extra_assert(!has_rtref(a->source)); rgb = RUNTIME_REG(b); *************** *** 597,604 **** } DEFINEFN code_t* psyco_unify(PsycoObject* po, CodeBufferObject** target) { ! /* Update 'this' to match 'target', then jump to 'target'. */ int i; --- 613,655 ---- } + static code_t* data_free_unused(code_t* code, struct dmove_s* dm, + vinfo_array_t* aa) + { + /* decref any object that would be present in 'po' but not at all in + the snapshot. Note that it is uncommon that this function actually + finds any unused object at all. */ + int i = aa->count; + while (i--) + { + vinfo_t* a = aa->items[i]; + if (a != NULL) + { + if (has_rtref(a->source)) + { + PsycoObject* po = dm->po; + code_t* saved_code; + a->source = remove_rtref(a->source); + + saved_code = po->code; + po->code = code; + psyco_decref_rt(po, a); + code = po->code; + po->code = saved_code; + + if (code > dm->code_limit) + /* oops, buffer overflow. Start a new buffer */ + code = data_new_buffer(code, dm); + } + if (a->array != NullArray) + code = data_free_unused(code, dm, a->array); + } + } + return code; + } + DEFINEFN code_t* psyco_unify(PsycoObject* po, CodeBufferObject** target) { ! /* Update 'po' to match 'target', then jump to 'target'. */ int i; *************** *** 610,620 **** psyco_assert_coherent(po); - if (sdepth > po->stack_depth) - { - /* more items in the target stack (uncommon case). - Let the stack grow. */ - STACK_CORRECTION(sdepth - po->stack_depth); - po->stack_depth = sdepth; - } dm.usages_size = sdepth + sizeof(vinfo_t**); dm.usages = (char*) PyCore_MALLOC(dm.usages_size); --- 661,664 ---- *************** *** 630,636 **** --- 674,693 ---- dm.private_codebuf = NULL; + if (sdepth > po->stack_depth) + { + /* more items in the target stack (uncommon case). + Let the stack grow. */ + STACK_CORRECTION(sdepth - po->stack_depth); + po->stack_depth = sdepth; + } + /* update the stack */ code = data_update_stack(code, &dm, target_codebuf->snapshot.fz_vlocals); + /* decref any object that would be present in 'po' but not at all in + the snapshot (data_update_stack() has removed the 'ref' tag of all + vinfo_ts it actually used from 'po') */ + code = data_free_unused(code, &dm, &po->vlocals); + /* update the registers (1): reg-to-reg moves and exchanges */ memset(pops, -1, sizeof(pops)); *************** *** 655,659 **** LOAD_REG_FROM_REG(i, rg); /* an update is omitted because we are about to ! release 'this' anyway: 'REG_NUMBER(po, i) = a;' */ } dm.copy_regs[i] = NULL; --- 712,716 ---- LOAD_REG_FROM_REG(i, rg); /* an update is omitted because we are about to ! release 'po' anyway: 'REG_NUMBER(po, i) = a;' */ } dm.copy_regs[i] = NULL; *************** *** 690,693 **** --- 747,753 ---- po->stack_depth -= 4; } + if (code > dm.code_limit) /* start a new buffer if we wrote past the end */ + code = data_new_buffer(code, &dm); + /* update the registers (3): stack-to-register loads */ for (i=0; i<REG_TOTAL; i++) *************** *** 710,714 **** PyCore_FREE(dm.usages); - psyco_stabilize(target_codebuf); if (dm.private_codebuf == NULL) Py_INCREF(target_codebuf); /* no new buffer created */ --- 770,773 ---- *************** *** 721,725 **** code = po->code; JUMP_TO(dm.private_codebuf->codeptr); ! psyco_dump_code_buffers(); } PsycoObject_Delete(po); --- 780,784 ---- code = po->code; JUMP_TO(dm.private_codebuf->codeptr); ! dump_code_buffers(); } PsycoObject_Delete(po); *************** *** 838,842 **** #if PROMOTION_TACTIC == 1 typedef struct rt_local_buf_s { ! # ifdef CODE_DUMP_FILE long signature; # endif --- 897,901 ---- #if PROMOTION_TACTIC == 1 typedef struct rt_local_buf_s { ! # if CODE_DUMP long signature; # endif *************** *** 855,859 **** #if PROMOTION_TACTIC == 0 PyObject* spec_dict; /* local cache (promotions to already-seen values) */ ! # ifdef CODE_DUMP_FILE void** chained_list; /* must be last, with spec_dict just before */ # endif --- 914,918 ---- #if PROMOTION_TACTIC == 0 PyObject* spec_dict; /* local cache (promotions to already-seen values) */ ! # if CODE_DUMP void** chained_list; /* must be last, with spec_dict just before */ # endif *************** *** 980,984 **** code_t* codeend; rt_local_buf_t* buf = (rt_local_buf_t*) codebuf->codeptr; ! # ifdef CODE_DUMP_FILE buf->signature = 0x66666666; # endif --- 1039,1043 ---- code_t* codeend; rt_local_buf_t* buf = (rt_local_buf_t*) codebuf->codeptr; ! # if CODE_DUMP buf->signature = 0x66666666; # endif *************** *** 996,1000 **** #endif ! psyco_dump_code_buffers(); return result; } --- 1055,1059 ---- #endif ! dump_code_buffers(); return result; } *************** *** 1064,1067 **** --- 1123,1127 ---- void* do_promotion; + TRACE_EXECUTION("PROMOTION"); BEGIN_CODE #if PROMOTION_FAST_COMMON_CASE *************** *** 1110,1114 **** if (fs->spec_dict == NULL) OUT_OF_MEMORY(); ! # ifdef CODE_DUMP_FILE fs->chained_list = psyco_codebuf_spec_dict_list; psyco_codebuf_spec_dict_list = (void**)&fs->chained_list; --- 1170,1174 ---- if (fs->spec_dict == NULL) OUT_OF_MEMORY(); ! # if CODE_DUMP fs->chained_list = psyco_codebuf_spec_dict_list; psyco_codebuf_spec_dict_list = (void**)&fs->chained_list; *************** *** 1194,1197 **** --- 1254,1258 ---- extra_assert(fix->array->count == 0); /* cannot fix array values, because of known_to_be_default() */ + TRACE_EXECUTION("FIXED_SWITCH"); BEGIN_CODE NEED_CC(); Index: dispatcher.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/dispatcher.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** dispatcher.h 2002/01/11 16:15:47 1.6 --- dispatcher.h 2002/02/05 20:08:23 1.7 *************** *** 28,36 **** struct FrozenPsycoObject_s { union { ! int as_int; /* last_used_reg in bits 0-7 and stack_depth in the rest */ struct respawn_s* respawning; } fz_stuff; vinfo_array_t* fz_vlocals; ! short fz_arguments_count; short fz_respawned_cnt; CodeBufferObject* fz_respawned_from; --- 28,36 ---- struct FrozenPsycoObject_s { union { ! int fz_stack_depth; struct respawn_s* respawning; } fz_stuff; vinfo_array_t* fz_vlocals; ! short fz_last_used_reg; short fz_respawned_cnt; CodeBufferObject* fz_respawned_from; *************** *** 54,58 **** /* inspection */ inline int get_stack_depth(FrozenPsycoObject* fpo) { ! return fpo->fz_stuff.as_int >> 8; } --- 54,58 ---- /* inspection */ inline int get_stack_depth(FrozenPsycoObject* fpo) { ! return fpo->fz_stuff.fz_stack_depth; } Index: encoding.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/encoding.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** encoding.h 2002/02/02 08:23:07 1.6 --- encoding.h 2002/02/05 20:08:23 1.7 *************** *** 861,866 **** #define STACK_CORRECTION(stack_correction) do { \ if ((stack_correction) != 0) { \ ! NEED_CC(); \ ! if (COMPACT_ENCODING && \ -128 <= (stack_correction) && (stack_correction) < 128) { \ code[0] = 0x83; /* SUB */ \ --- 861,865 ---- #define STACK_CORRECTION(stack_correction) do { \ if ((stack_correction) != 0) { \ ! if (COMPACT_ENCODING && po->ccreg == NULL && \ -128 <= (stack_correction) && (stack_correction) < 128) { \ code[0] = 0x83; /* SUB */ \ *************** *** 870,877 **** } \ else { \ ! code[0] = 0x81; /* SUB */ \ ! code[1] = 0xEC; /* ESP, imm32 */ \ ! *(long*)(code+2) = (stack_correction); \ ! code += 6; \ } \ } \ --- 869,877 ---- } \ else { \ ! code[0] = 0x8D; /* LEA */ \ ! code[1] = 0x84 | ((char)REG_386_ESP)<<3; /* ESP, */ \ ! code[2] = 0x24; /* [ESP+imm32] */ \ ! *(long*)(code+3) = -(stack_correction); \ ! code += 7; \ } \ } \ *************** *** 895,898 **** --- 895,907 ---- LOAD_REG_FROM(vi->source, rg); \ } \ + } while (0) + + #define EMIT_TRACE(msg) do { \ + TEMP_SAVE_REGS_FN_CALLS; \ + PUSH_IMMED((long) code); \ + PUSH_IMMED((long) (msg)); \ + CALL_C_FUNCTION(psyco_trace_execution, 2); \ + STACK_CORRECTION(-8); \ + TEMP_RESTORE_REGS_FN_CALLS; \ } while (0) Index: hack.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/hack.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** hack.c 2002/01/08 19:36:55 1.5 --- hack.c 2002/02/05 20:08:23 1.6 *************** *** 8,15 **** /* means that all .c files are meant to be compiler together, with all symbols 'static' */ ! #define ALL_STATIC ! /* disable all debugging code */ ! /*#define DISABLE_DEBUG*/ --- 8,15 ---- /* means that all .c files are meant to be compiler together, with all symbols 'static' */ ! #define ALL_STATIC 1 ! /* you can disable all debugging code by setting PSYCO_DEBUG to 0 */ ! /*#define PSYCO_DEBUG 0*/ *************** *** 45,78 **** #include "selective.c" #include "psyco.c" /* must be the last one for CODE_DUMP_AT_END_ONLY to work */ - - - /***************************************************************/ - /*** Debug dumping of state ***/ - /***************************************************************/ - - /* #ifdef PSYCO_DUMP */ - /* static int psyco_dump() */ - /* { */ - /* int i; */ - /* PyObject* source = psyco_ge_mainloop.fatlist; */ - /* FILE* f = fopen("psyco.dump", "wb"); */ - /* if (f == NULL) */ - /* return -1; */ - - /* for (i=0; i<PyList_Size(source); i++) */ - /* { */ - /* CodeBufferObject* codebuf = (CodeBufferObject*) PyList_GetItem(source, i); */ - /* int size; */ - /* assert(codebuf != NULL && CodeBuffer_Check(codebuf)); */ - /* size = codebuf->codesize; */ - /* if (size == -1) */ - /* size = BIG_BUFFER_SIZE - GUARANTEED_MINIMUM; */ - /* fprintf(f, "CodeBufferObject %p %d %d\n", */ - /* codebuf->codeptr, codebuf->codesize, size); */ - /* fwrite(codebuf->codeptr, 1, size, f); */ - /* } */ - - /* return fclose(f); */ - /* } */ - /* void* psyco_just_a_dummy_pointer = &psyco_dump; */ - /* #endif */ --- 45,46 ---- Index: mergepoints.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/mergepoints.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mergepoints.c 2002/01/11 16:16:24 1.4 --- mergepoints.c 2002/02/05 20:08:23 1.5 *************** *** 131,134 **** --- 131,135 ---- SET_LINENO, CALL_FUNCTION, + MAKE_FUNCTION, 0 }; *************** *** 140,148 **** (oparg) == Py_GT || \ (oparg) == Py_GE || \ ! (oparg) == IS || \ ! (oparg) == IS_NOT || \ ! (oparg) == IN || \ ! (oparg) == NOT_IN || \ ! (oparg) == EXC_MATCH || \ 0) --- 141,149 ---- (oparg) == Py_GT || \ (oparg) == Py_GE || \ ! (oparg) == PyCmp_IS || \ ! (oparg) == PyCmp_IS_NOT || \ ! (oparg) == PyCmp_IN || \ ! (oparg) == PyCmp_NOT_IN || \ ! (oparg) == PyCmp_EXC_MATCH || \ 0) *************** *** 198,202 **** for (i=0; i<length; ) { ! #ifdef VERBOSE int i0 = i; #endif --- 199,203 ---- for (i=0; i<length; ) { ! #if VERBOSE_LEVEL int i0 = i; #endif *************** *** 220,226 **** { /* unsupported instruction */ ! #ifdef VERBOSE ! printf("psyco: unsupported instruction: bytecode %d at %s:%d\n", ! (int) op, PyString_AS_STRING(co->co_name), i0); #endif PyCore_FREE(paths); --- 221,228 ---- { /* unsupported instruction */ ! #if VERBOSE_LEVEL ! debug_printf(("psyco: unsupported instruction: " ! "bytecode %d at %s:%d\n", ! (int) op, PyCodeObject_NAME(co), i0)); #endif PyCore_FREE(paths); Index: processor.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/processor.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** processor.c 2002/01/27 22:42:19 1.5 --- processor.c 2002/02/05 20:08:23 1.6 *************** *** 70,78 **** DEFINEFN PyObject* psyco_processor_run(CodeBufferObject* codebuf, ! long initial_stack[]) { ! return glue_run_code_1(codebuf->codeptr, ! initial_stack + codebuf->snapshot.fz_arguments_count, ! initial_stack); } --- 70,76 ---- DEFINEFN PyObject* psyco_processor_run(CodeBufferObject* codebuf, ! long initial_stack[], int argc) { ! return glue_run_code_1(codebuf->codeptr, initial_stack + argc, initial_stack); } *************** *** 121,130 **** { code_t* code = po->code; if (retval != SOURCE_DUMMY) LOAD_REG_FROM(retval, REG_FUNCTIONS_RETURN); ! STACK_CORRECTION(INITIAL_STACK_DEPTH + 4 + po->arguments_count * 4 ! - po->stack_depth); ! code[0] = 0xC2; // RET ! *(short*)(code+1) = po->arguments_count * 4; PsycoObject_Delete(po); return code+3; --- 119,150 ---- { code_t* code = po->code; + int retpos = getstack(po->vlocals.items[INDEX_LOC_CONTINUATION]->source); + + /* load the return value into EAX */ if (retval != SOURCE_DUMMY) LOAD_REG_FROM(retval, REG_FUNCTIONS_RETURN); ! ! /* 'retpos' is the position in the stack of the return value. */ ! /* clean up the stack up to that position */ ! extra_assert(retpos != RunTime_StackNone); ! STACK_CORRECTION(retpos - po->stack_depth); ! ! /* emit a 'RET xxx' instruction that pops and jumps to the address ! which is now at the top of the stack, and finishes to clean the ! stack by removing everything left past the return address ! (typically the arguments, although it could be anything). */ ! retpos -= INITIAL_STACK_DEPTH+4; ! extra_assert(0<=retpos); ! if (retpos >= 0x8000) ! { ! /* uncommon case: too many stuff left in the stack for the 16-bit ! immediate we can encoding in RET */ ! POP_REG(REG_386_EDX); ! STACK_CORRECTION(-retpos); ! PUSH_REG(REG_386_EDX); ! retpos = 0; ! } ! code[0] = 0xC2; // RET imm16 ! *(short*)(code+1) = retpos; PsycoObject_Delete(po); return code+3; *************** *** 183,187 **** /* make 'fs' point just after the end of the code, aligned */ result = (void*)(((long)code + 3) & ~ 3); ! #ifdef CODE_DUMP_FILE while (code != (char*) result) *code++ = 0xFE; /* fill with invalid instructions */ --- 203,207 ---- /* make 'fs' point just after the end of the code, aligned */ result = (void*)(((long)code + 3) & ~ 3); ! #if CODE_DUMP while (code != (char*) result) *code++ = 0xFE; /* fill with invalid instructions */ *************** *** 1022,1026 **** args[i] = (long)malloc( ((vinfo_array_t*)args[i])->count ); ! #ifdef ALL_CHECKS if (argtags[i] == 'r') Py_FatalError("psyco_generic_call(): arg mode " --- 1042,1046 ---- args[i] = (long)malloc( ((vinfo_array_t*)args[i])->count ); ! #if ALL_CHECKS if (argtags[i] == 'r') Py_FatalError("psyco_generic_call(): arg mode " *************** *** 1151,1155 **** vresult = generic_call_check(po, flags, vresult); vinfo_xdecref(vresult, po); ! #ifdef ALL_CHECKS if (vresult != NULL) vresult = (vinfo_t*) 1; /* anything non-NULL */ --- 1171,1175 ---- vresult = generic_call_check(po, flags, vresult); vinfo_xdecref(vresult, po); ! #if ALL_CHECKS if (vresult != NULL) vresult = (vinfo_t*) 1; /* anything non-NULL */ *************** *** 1166,1170 **** DEFINEFN vinfo_t* psyco_call_psyco(PsycoObject* po, CodeBufferObject* codebuf, ! Source argsources[]) { /* this is a simplified version of psyco_generic_call() which --- 1186,1190 ---- DEFINEFN vinfo_t* psyco_call_psyco(PsycoObject* po, CodeBufferObject* codebuf, ! Source argsources[], int argcount) { /* this is a simplified version of psyco_generic_call() which *************** *** 1178,1184 **** initial_depth = po->stack_depth; p = argsources; ! for (i=codebuf->snapshot.fz_arguments_count; i--; p++) ! CALL_SET_ARG_FROM_RT(*p, i,codebuf->snapshot.fz_arguments_count); ! CALL_C_FUNCTION(codebuf->codeptr, codebuf->snapshot.fz_arguments_count); po->stack_depth = initial_depth; /* callee removes arguments */ END_CODE --- 1198,1204 ---- initial_depth = po->stack_depth; p = argsources; ! for (i=argcount; i--; p++) ! CALL_SET_ARG_FROM_RT(*p, i, argcount); ! CALL_C_FUNCTION(codebuf->codeptr, argcount); po->stack_depth = initial_depth; /* callee removes arguments */ END_CODE *************** *** 1229,1238 **** vinfo_decref() will not emit a Py_DECREF() that would clobber the condition code. We check all this. */ ! #ifdef ALL_CHECKS assert(!has_rtref(vi->source)); { code_t* code1 = po->code; #endif vinfo_decref(vi, po); ! #ifdef ALL_CHECKS assert(po->code == code1); } #endif --- 1249,1258 ---- vinfo_decref() will not emit a Py_DECREF() that would clobber the condition code. We check all this. */ ! #if ALL_CHECKS assert(!has_rtref(vi->source)); { code_t* code1 = po->code; #endif vinfo_decref(vi, po); ! #if ALL_CHECKS assert(po->code == code1); } #endif *************** *** 1624,1633 **** DEFINEFN vinfo_t* integer_not(PsycoObject* po, vinfo_t* v1) ! GENERIC_UNARY_INSTR(UNARY_INSTR_ON_REG(3, rg), ~a, false, false, CC_ALWAYS_FALSE) DEFINEFN vinfo_t* integer_neg(PsycoObject* po, vinfo_t* v1, bool ovf) ! GENERIC_UNARY_INSTR(UNARY_INSTR_ON_REG(2, rg), -a, ovf, c == (-LONG_MAX-1), CC_O) --- 1644,1653 ---- DEFINEFN vinfo_t* integer_not(PsycoObject* po, vinfo_t* v1) ! GENERIC_UNARY_INSTR(UNARY_INSTR_ON_REG(2, rg), ~a, false, false, CC_ALWAYS_FALSE) DEFINEFN vinfo_t* integer_neg(PsycoObject* po, vinfo_t* v1, bool ovf) ! GENERIC_UNARY_INSTR(UNARY_INSTR_ON_REG(3, rg), -a, ovf, c == (-LONG_MAX-1), CC_O) Index: processor.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/processor.h,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** processor.h 2002/01/27 22:42:19 1.5 --- processor.h 2002/02/05 20:08:23 1.6 *************** *** 30,34 **** */ EXTERNFN PyObject* psyco_processor_run(CodeBufferObject* codebuf, ! long initial_stack[]); /* return a new vinfo_t* meaning `in the processor flags, true if <cc>', --- 30,34 ---- */ EXTERNFN PyObject* psyco_processor_run(CodeBufferObject* codebuf, ! long initial_stack[], int argc); /* return a new vinfo_t* meaning `in the processor flags, true if <cc>', *************** *** 240,244 **** psyco_build_frame(). */ EXTERNFN vinfo_t* psyco_call_psyco(PsycoObject* po, CodeBufferObject* codebuf, ! Source argsources[]); /*****************************************************************/ --- 240,251 ---- psyco_build_frame(). */ EXTERNFN vinfo_t* psyco_call_psyco(PsycoObject* po, CodeBufferObject* codebuf, ! Source argsources[], int argcount); ! ! inline int get_arguments_count(vinfo_array_t* vlocals) { ! int retpos = getstack(vlocals->items[INDEX_LOC_CONTINUATION]->source); ! extra_assert(retpos != RunTime_StackNone); ! return (retpos - (INITIAL_STACK_DEPTH+4)) / 4; ! } ! /*****************************************************************/ Index: psyco.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/psyco.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** psyco.c 2002/01/15 12:41:10 1.15 --- psyco.c 2002/02/05 20:08:23 1.16 *************** *** 10,18 **** - #if defined(CODE_DUMP_FILE) && defined(CODE_DUMP_AT_END_ONLY) - # undef psyco_dump_code_buffers - EXTERNFN void psyco_dump_code_buffers(void); - #endif - /***************************************************************/ /*** Frame and arguments building ***/ --- 10,13 ---- *************** *** 36,42 **** if (target->items[i] == NULL) continue; /* item was removed by psyco_simplify_array() */ ! if (sources != NULL) ! sources[po->arguments_count] = a->source; ! po->arguments_count++; po->stack_depth += sizeof(long); /* arguments get borrowed references */ --- 31,38 ---- if (target->items[i] == NULL) continue; /* item was removed by psyco_simplify_array() */ ! if (sources != NULL) { ! int argc = (po->stack_depth-INITIAL_STACK_DEPTH) / sizeof(long); ! sources[argc] = a->source; ! } po->stack_depth += sizeof(long); /* arguments get borrowed references */ *************** *** 94,98 **** PyErr_Format(PyExc_TypeError, "%.200s() takes %s %d %sargument%s (%d given)", ! PyString_AsString(co->co_name), minargcnt == co->co_argcount ? "exactly" : (inputargs < n ? "at least" : "at most"), --- 90,94 ---- PyErr_Format(PyExc_TypeError, "%.200s() takes %s %d %sargument%s (%d given)", ! PyCodeObject_NAME(co), minargcnt == co->co_argcount ? "exactly" : (inputargs < n ? "at least" : "at most"), *************** *** 170,175 **** Py_INCREF(co); /* XXX never freed */ pyc_data_build(po, merge_points); ! ! po->stack_depth += sizeof(long); /* count the CALL return address */ psyco_assert_coherent(po); return po; --- 166,174 ---- Py_INCREF(co); /* XXX never freed */ pyc_data_build(po, merge_points); ! ! /* set up the CALL return address */ ! po->stack_depth += sizeof(long); ! LOC_CONTINUATION = vinfo_new(RunTime_NewStack(po->stack_depth, REG_NONE, ! false)); psyco_assert_coherent(po); return po; *************** *** 193,197 **** Source* sources; vinfo_t* result; ! int i; int tuple_size = PsycoTuple_Load(arg_tuple); --- 192,196 ---- Source* sources; vinfo_t* result; ! int i, argcount; int tuple_size = PsycoTuple_Load(arg_tuple); *************** *** 201,204 **** --- 200,208 ---- is not implemented, revert to the default behaviour */ + /* the processor condition codes will be messed up soon */ + BEGIN_CODE + NEED_CC(); + END_CODE + /* prepare a frame */ arginfo = array_new(tuple_size); *************** *** 217,220 **** --- 221,225 ---- return NULL; } + argcount = get_arguments_count(&mypo->vlocals); /* compile the function (this frees mypo) */ *************** *** 224,228 **** /* get the run-time argument sources and push them on the stack and write the actual CALL */ ! result = psyco_call_psyco(po, codebuf, sources); PyCore_FREE(sources); return result; --- 229,233 ---- /* get the run-time argument sources and push them on the stack and write the actual CALL */ ! result = psyco_call_psyco(po, codebuf, sources, argcount); PyCore_FREE(sources); return result; *************** *** 307,320 **** /* get the actual arguments */ ! assert(codebuf->snapshot.fz_arguments_count == PyTuple_GET_SIZE(arg)); initial_stack = (long*) (&PyTuple_GET_ITEM(arg, 0)); /* run! */ ! result = psyco_processor_run(codebuf, initial_stack); Py_DECREF(codebuf); psyco_trash_object(NULL); /* free any trashed object now */ ! #ifdef CODE_DUMP_FILE psyco_dump_code_buffers(); #endif --- 312,328 ---- /* get the actual arguments */ ! /*extra_assert(get_arguments_count(codebuf->snapshot.fz_vlocals) == ! PyTuple_GET_SIZE(arg)); ! --- crashed if the codebuf has no snapshot, e.g. unify code bufs */ initial_stack = (long*) (&PyTuple_GET_ITEM(arg, 0)); /* run! */ ! result = psyco_processor_run(codebuf, initial_stack, ! PyTuple_GET_SIZE(arg)); Py_DECREF(codebuf); psyco_trash_object(NULL); /* free any trashed object now */ ! #if CODE_DUMP >= 2 psyco_dump_code_buffers(); #endif *************** *** 407,411 **** } ! #ifdef CODE_DUMP_FILE static void vinfo_array_dump(vinfo_array_t* array, FILE* f, PyObject* d) { --- 415,419 ---- } ! #if CODE_DUMP static void vinfo_array_dump(vinfo_array_t* array, FILE* f, PyObject* d) { *************** *** 472,476 **** obj->codeptr, nsize, get_stack_depth(&obj->snapshot), co?PyString_AsString(co->co_filename):"", ! co?PyString_AsString(co->co_name):"", co?obj->snapshot.fz_pyc_data->next_instr:-1, obj->codemode); --- 480,484 ---- obj->codeptr, nsize, get_stack_depth(&obj->snapshot), co?PyString_AsString(co->co_filename):"", ! co?PyCodeObject_NAME(co):"", co?obj->snapshot.fz_pyc_data->next_instr:-1, obj->codemode); *************** *** 549,554 **** --- 557,570 ---- } } + #endif /* CODE_DUMP */ + + #if VERBOSE_LEVEL >= 4 + DEFINEFN void psyco_trace_execution(char* msg, void* code_position) + { + debug_printf(("psyco: trace %p for %s\n", code_position, msg)); + } #endif + /*****************************************************************/ *************** *** 608,613 **** (PyObject*) &PsycoFunction_Type)) return; ! #ifdef ALL_CHECKS ! if (PyModule_AddIntConstant(CPsycoModule, "ALL_CHECKS", 1)) return; #endif --- 624,633 ---- (PyObject*) &PsycoFunction_Type)) return; ! #if ALL_CHECKS ! if (PyModule_AddIntConstant(CPsycoModule, "ALL_CHECKS", ALL_CHECKS)) ! return; ! #endif ! #if VERBOSE_LEVEL ! if (PyModule_AddIntConstant(CPsycoModule, "VERBOSE_LEVEL", VERBOSE_LEVEL)) return; #endif Index: psyco.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/psyco.h,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** psyco.h 2002/01/11 16:16:10 1.9 --- psyco.h 2002/02/05 20:08:23 1.10 *************** *** 11,47 **** #include <compile.h> /* for PyCodeObject */ - #ifndef DISABLE_DEBUG - /* define for extra assert()'s */ - # define ALL_CHECKS ! /* level of debugging outputs: 0 = none, 1 = a few, 2 = a lot */ ! # ifndef VERBOSE_LEVEL ! # define VERBOSE_LEVEL 1 /* 0, 1 or 2 */ # endif - #ifndef MS_WIN32 ! /* define for *heavy* memory checking: 0 = off, 1 = reasonably heavy, ! 2 = unreasonably heaving */ ! # ifndef HEAVY_MEM_CHECK ! # define HEAVY_MEM_CHECK 0 ! # endif #endif ! /* define to write produced blocks of code into a file ! See 'xam.py' */ ! # ifndef NO_CODE_DUMP ! # define CODE_DUMP_FILE "psyco.dump" ! # endif ! # define CODE_DUMP_AT_END_ONLY ! #endif /* !DISABLE_DEBUG */ /* define to inline the most common functions in the produced code (should be enabled unless you want to trade code size for speed) */ ! #define INLINE_COMMON_FUNCTIONS ! #if defined(CODE_DUMP_FILE) && defined(HAVE_DLFCN_H) /* define to locate shared symbols and write them in CODE_DUMP_FILE requires the GNU extension dladdr() in <dlfcn.h> --- 11,69 ---- #include <compile.h> /* for PyCodeObject */ ! /*****************************************************************/ ! /*** Various customizable parameters (use your compilers' ***/ ! /*** option to override them, e.g. -DXXX=value in gcc) ***/ ! ! /* set to 0 to disable all debugging checks and output */ ! #ifndef PSYCO_DEBUG ! # ifdef NDEBUG ! # define PSYCO_DEBUG 0 ! # else ! # define PSYCO_DEBUG 1 # endif + #endif ! /* define to 1 for extra assert()'s */ ! #ifndef ALL_CHECKS ! # define ALL_CHECKS (PSYCO_DEBUG ? 1 : 0) ! #endif + /* level of debugging outputs: 0 = none, 1 = a few, 2 = more, + 3 = detailled, 4 = full execution trace */ + #ifndef VERBOSE_LEVEL + # define VERBOSE_LEVEL (PSYCO_DEBUG ? 0 : 0) #endif ! /* define for *heavy* memory checking: 0 = off, 1 = reasonably heavy, ! 2 = unreasonably heavy */ ! #ifndef HEAVY_MEM_CHECK ! # define HEAVY_MEM_CHECK (PSYCO_DEBUG ? 0 : 0) ! #endif ! #ifdef MS_WIN32 ! # undef HEAVY_MEM_CHECK ! # define HEAVY_MEM_CHECK 0 /* not supported on Windows */ ! #endif ! /* define to write produced blocks of code into a file; see 'xam.py' ! 0 = off, 1 = only manually (from a debugger), ! 2 = only when returning from Psyco, ! 3 = every time a new code block is built */ ! #ifndef CODE_DUMP ! # define CODE_DUMP (PSYCO_DEBUG ? 1 : 0) ! #endif ! ! #if CODE_DUMP && !defined(CODE_DUMP_FILE) ! # define CODE_DUMP_FILE "psyco.dump" ! #endif /* define to inline the most common functions in the produced code (should be enabled unless you want to trade code size for speed) */ ! #ifndef INLINE_COMMON_FUNCTIONS ! # define INLINE_COMMON_FUNCTIONS 1 ! #endif ! #if CODE_DUMP && defined(HAVE_DLFCN_H) /* define to locate shared symbols and write them in CODE_DUMP_FILE requires the GNU extension dladdr() in <dlfcn.h> *************** *** 58,66 **** routines (like mmap) are invoked. We rely on the fact that PyObject_REALLOC will not move the memory around when shrinking ! a block of BIG_BUFFER_SIZE+sizeof(CodeBufferObject) bytes. */ ! #ifdef DISABLE_DEBUG ! # define BIG_BUFFER_SIZE 0x7F00 ! #else ! # define BIG_BUFFER_SIZE 0x7F0 #endif --- 80,89 ---- routines (like mmap) are invoked. We rely on the fact that PyObject_REALLOC will not move the memory around when shrinking ! a block of BIG_BUFFER_SIZE+sizeof(CodeBufferObject) bytes. ! Numbers too large might cause serious fragmentation of the heap. ! In debugging mode, we use a small size to stress the buffer- ! continuation coding routines. */ ! #ifndef BIG_BUFFER_SIZE ! # define BIG_BUFFER_SIZE (PSYCO_DEBUG ? 0x100+BUFFER_MARGIN : 0x3F00) #endif *************** *** 69,74 **** XXX carefully check that it is impossible to overflow by more We need more than 128 bytes because of the way conditional jumps ! are emitted; see pycompiler.c */ ! #define BUFFER_MARGIN (192 + GUARANTEED_MINIMUM) /* When emitting code, all called functions can assume that they --- 92,104 ---- XXX carefully check that it is impossible to overflow by more We need more than 128 bytes because of the way conditional jumps ! are emitted; see pycompiler.c. ! XXX actually there are too many places that might emit an ! unbounded size of code. This is a Big Bug. I won't attempt to ! fix it now because it should be done together with Psyco's rewrite ! towards flexible code-emitting back-ends. For now just pretent that ! a quite large value will be OK. */ ! #ifndef BUFFER_MARGIN ! # define BUFFER_MARGIN (1920 + GUARANTEED_MINIMUM) ! #endif /* When emitting code, all called functions can assume that they *************** *** 77,84 **** jump to these from the original code (jumps can be done in less than GUARANTEED_MINIMUM bytes). */ ! #define GUARANTEED_MINIMUM 32 ! #ifdef ALL_CHECKS # define MALLOC_CHECK_ 2 /* GCC malloc() checks */ # undef NDEBUG --- 107,132 ---- jump to these from the original code (jumps can be done in less than GUARANTEED_MINIMUM bytes). */ ! #ifndef GUARANTEED_MINIMUM ! # define GUARANTEED_MINIMUM 64 ! #endif ! #ifndef ALL_STATIC ! # define ALL_STATIC 0 /* make all functions static; set to 1 by hack.c */ ! #endif ! ! #if ALL_STATIC ! # define EXTERNVAR staticforward ! # define EXTERNFN static ! # define DEFINEVAR statichere ! # define DEFINEFN static ! #else ! # define EXTERNVAR ! # define EXTERNFN ! # define DEFINEVAR ! # define DEFINEFN ! #endif ! ! #if ALL_CHECKS # define MALLOC_CHECK_ 2 /* GCC malloc() checks */ # undef NDEBUG *************** *** 89,129 **** #endif ! #ifndef VERBOSE_LEVEL ! # define VERBOSE_LEVEL 0 ! #else ! # define VERBOSE ! #endif ! ! #ifdef VERBOSE # define debug_printf(args) (printf args, fflush(stdout)) #else # define debug_printf(args) (void)0 /* nothing */ #endif ! ! #ifdef ALL_STATIC ! # define EXTERNVAR staticforward ! # define EXTERNFN static ! # define DEFINEVAR statichere ! # define DEFINEFN static #else ! # define EXTERNVAR ! # define EXTERNFN ! # define DEFINEVAR ! # define DEFINEFN #endif ! #ifdef INLINE_COMMON_FUNCTIONS ! # ifdef MS_WIN32 ! # define inline __inline static ! # else ! # define inline __inline__ static /* is this GCC-specific? */ ! # endif #else # define inline static #endif - #ifndef HEAVY_MEM_CHECK - # define HEAVY_MEM_CHECK 0 - #endif #if HEAVY_MEM_CHECK # include "linuxmemchk.h" --- 137,160 ---- #endif ! #if VERBOSE_LEVEL # define debug_printf(args) (printf args, fflush(stdout)) #else # define debug_printf(args) (void)0 /* nothing */ #endif ! #if VERBOSE_LEVEL >= 4 ! # define TRACE_EXECUTION(msg) do { \ ! BEGIN_CODE EMIT_TRACE(msg); END_CODE } while (0) ! EXTERNFN void psyco_trace_execution(char* msg, void* code_position); #else ! # define TRACE_EXECUTION(msg) do { } while (0) /* nothing */ #endif ! ! #if INLINE_COMMON_FUNCTIONS ! # define inline __inline static #else # define inline static #endif #if HEAVY_MEM_CHECK # include "linuxmemchk.h" *************** *** 204,212 **** ! #if defined(CODE_DUMP_FILE) && !defined(CODE_DUMP_AT_END_ONLY) EXTERNFN void psyco_dump_code_buffers(void); #else ! # define psyco_dump_code_buffers() do { } while (0) /* nothing */ #endif --- 235,250 ---- ! #if CODE_DUMP EXTERNFN void psyco_dump_code_buffers(void); + #endif + #if CODE_DUMP >= 3 + # define dump_code_buffers() psyco_dump_code_buffers() #else ! # define dump_code_buffers() do { } while (0) /* nothing */ #endif + + /* to display code object names */ + #define PyCodeObject_NAME(co) (co->co_name ? PyString_AS_STRING(co->co_name) \ + : "<anonymous code object>") Index: selective.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/selective.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** selective.c 2002/01/04 18:00:00 1.4 --- selective.c 2002/02/05 20:08:23 1.5 *************** *** 15,18 **** --- 15,20 ---- code = frame->f_code->co_code; name = frame->f_code->co_name; + if (name == NULL) + return 0; g = frame->f_globals; *************** *** 36,42 **** if (value++ >= ticks) { tmp = PyDict_GetItem(g, name); ! if (tmp != NULL) { /* Rebind function to a proxy */ ! debug_printf(("psyco: compiling function %s\n", PyString_AS_STRING(name))); value = FUN_BOUND; tmp = (PyObject*)psyco_PsycoFunction_New((PyFunctionObject*)tmp, MAX_RECURSION); --- 38,51 ---- if (value++ >= ticks) { tmp = PyDict_GetItem(g, name); ! if (tmp != NULL && PyFunction_Check(tmp)) { /* Rebind function to a proxy */ ! #if VERBOSE_LEVEL ! PyObject* modulename = PyDict_GetItemString(g, "__name__"); ! debug_printf(("psyco: rebinding function %s.%s\n", ! (modulename && PyString_Check(modulename)) ! ? PyString_AS_STRING(modulename) : "<anonymous>", ! PyString_Check(name) ! ? PyString_AS_STRING(name) : "<anonymous>")); ! #endif value = FUN_BOUND; tmp = (PyObject*)psyco_PsycoFunction_New((PyFunctionObject*)tmp, MAX_RECURSION); Index: vcompiler.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/vcompiler.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** vcompiler.c 2002/01/17 13:32:57 1.9 --- vcompiler.c 2002/02/05 20:08:23 1.10 *************** *** 194,198 **** } ! #ifdef ALL_CHECKS DEFINEFN void assert_cleared_tmp_marks(vinfo_array_t* array) --- 194,198 ---- } ! #if ALL_CHECKS DEFINEFN void assert_cleared_tmp_marks(vinfo_array_t* array) *************** *** 226,230 **** } ! #ifdef ALL_CHECKS static void coherent_array(vinfo_array_t* source, PsycoObject* po, int found[]) { --- 226,230 ---- } ! #if ALL_CHECKS static void coherent_array(vinfo_array_t* source, PsycoObject* po, int found[]) { *************** *** 379,383 **** result->stack_depth = po->stack_depth; result->last_used_reg = po->last_used_reg; - result->arguments_count = po->arguments_count; result->respawn_cnt = po->respawn_cnt; result->respawn_proxy = po->respawn_proxy; --- 379,382 ---- *************** *** 427,431 **** /* cannot Py_DECREF(cp->self) because the current function is returning into that code now, but any time later is fine: use the trash of codemanager.c */ ! psyco_dump_code_buffers(); psyco_trash_object((PyObject*) cp->self); return target; --- 426,430 ---- /* cannot Py_DECREF(cp->self) because the current function is returning into that code now, but any time later is fine: use the trash of codemanager.c */ ! dump_code_buffers(); psyco_trash_object((PyObject*) cp->self); return target; *************** *** 480,484 **** FAR_COND_JUMP_TO(codebuf->codeptr, jmpcondition); END_CODE ! psyco_dump_code_buffers(); } --- 479,483 ---- FAR_COND_JUMP_TO(codebuf->codeptr, jmpcondition); END_CODE ! dump_code_buffers(); } *************** *** 538,542 **** if (codebuf == NULL) OUT_OF_MEMORY(); ! #ifdef CODE_DUMP_FILE codebuf->chained_list = psyco_codebuf_chained_list; psyco_codebuf_chained_list = codebuf; --- 537,541 ---- if (codebuf == NULL) OUT_OF_MEMORY(); ! #if CODE_DUMP codebuf->chained_list = psyco_codebuf_chained_list; psyco_codebuf_chained_list = codebuf; *************** *** 569,575 **** { CodeBufferObject* oldcodebuf; - vinfo_array_t* diff = mp==NULL ? NULL : - psyco_compatible(po, &mp->entries, &oldcodebuf); PsycoObject* po2 = PsycoObject_Duplicate(po); extra_assert(condition < CC_TOTAL); --- 568,574 ---- { CodeBufferObject* oldcodebuf; PsycoObject* po2 = PsycoObject_Duplicate(po); + vinfo_array_t* diff = mp==NULL ? NULL : + psyco_compatible(po2, &mp->entries, &oldcodebuf); extra_assert(condition < CC_TOTAL); *************** *** 657,661 **** its actual size */ psyco_shrink_code_buffer(codebuf, code1 - codebuf->codeptr); ! psyco_dump_code_buffers(); return codebuf; } --- 656,660 ---- its actual size */ psyco_shrink_code_buffer(codebuf, code1 - codebuf->codeptr); ! dump_code_buffers(); return codebuf; } Index: vcompiler.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/vcompiler.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** vcompiler.h 2001/12/24 17:01:18 1.3 --- vcompiler.h 2002/02/05 20:08:23 1.4 *************** *** 327,331 **** /* array management */ EXTERNFN void clear_tmp_marks(vinfo_array_t* array); ! #ifdef ALL_CHECKS EXTERNFN void assert_cleared_tmp_marks(vinfo_array_t* array); #else --- 327,331 ---- /* array management */ EXTERNFN void clear_tmp_marks(vinfo_array_t* array); ! #if ALL_CHECKS EXTERNFN void assert_cleared_tmp_marks(vinfo_array_t* array); #else *************** *** 362,366 **** /* compiler private variables for producing and optimizing code */ reg_t last_used_reg; /* the most recently used register */ - int arguments_count; /* # run-time arguments given to the function */ int respawn_cnt; /* see psyco_prepare_respawn() */ CodeBufferObject* respawn_proxy; /* see psyco_prepare_respawn() */ --- 362,365 ---- *************** *** 446,450 **** /* management functions; see comments in compiler.c */ ! #ifdef ALL_CHECKS EXTERNFN void psyco_assert_coherent(PsycoObject* po); #else --- 445,449 ---- /* management functions; see comments in compiler.c */ ! #if ALL_CHECKS EXTERNFN void psyco_assert_coherent(PsycoObject* po); #else |
From: Armin Rigo <arigo@us...> - 2002-02-05 20:08:30
|
Update of /cvsroot/psyco/psyco/test In directory usw-pr-cvs1:/tmp/cvs-serv27600/test Modified Files: psyco.py test.py Log Message: major and numerous bug fixes. Psyco will now run most of Python's regresstion tests. Index: psyco.py =================================================================== RCS file: /cvsroot/psyco/psyco/test/psyco.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** psyco.py 2002/01/03 11:50:13 1.5 --- psyco.py 2002/02/05 20:08:23 1.6 *************** *** 2,5 **** --- 2,40 ---- _psyco.selective(1) # Argument is number of invocations before rebinding + + ########################################################################### + # Support for Python's warnings is not complete, because it + # uses sys._getframe() which will give strange results on a mixed Psyco- + # and Python-style stack frame. + # We work around this by having sys._getframe() always raise ValueError. + # The warning subsystem will then apply the filters globally instead of + # on a per-module basis. + + import sys + + def disabled_getframe(n=0): + global _erronce + if not _erronce: + # cannot use Warnings, I guess it would cause an endless loop + print >> sys.stderr, 'psyco: sys._getframe() not supported; support for warnings is only partial' + _erronce = 1 + raise ValueError, 'sys._getframe() disabled for Psyco' + + sys_getframe = sys._getframe # old value + sys._getframe = disabled_getframe + _erronce = 0 + + + ########################################################################### + # The code produced by Psyco is not nice with threads; it does not + # include all the checks the Python interpreter does regularly. + + + + ########################################################################### + # Python-based rebinding code, now moved in selective.c. This code + # should probably be partially moved back here, leaving only the detection + # of the most used functions to C code, not the rebinding. + # import sys Index: test.py =================================================================== RCS file: /cvsroot/psyco/psyco/test/test.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test.py 2002/01/29 15:37:46 1.5 --- test.py 2002/02/05 20:08:23 1.6 *************** *** 122,127 **** v2, t2 = time(f, *args) if v1 == v2: ! print 'Python got the same result in %s seconds, Psyco is %.2f times faster' %\ ! (t2, (t2/float(t1))) else: print v2 --- 122,130 ---- v2, t2 = time(f, *args) if v1 == v2: ! if t1 and t2: ! s = ', Psyco is %.2f times faster' % (t2/float(t1)) ! else: ! s = '' ! print 'Python got the same result in %s seconds%s' % (t2, s) else: print v2 |
From: Armin Rigo <arigo@us...> - 2002-02-05 20:08:29
|
Update of /cvsroot/psyco/psyco/c/Python In directory usw-pr-cvs1:/tmp/cvs-serv27600/c/Python Modified Files: pbltinmodule.c pycheader.h pycompiler.c pycompiler.h Log Message: major and numerous bug fixes. Psyco will now run most of Python's regresstion tests. Index: pbltinmodule.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Python/pbltinmodule.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pbltinmodule.c 2002/01/29 15:37:46 1.4 --- pbltinmodule.c 2002/02/05 20:08:23 1.5 *************** *** 261,265 **** case 3: kwdict = PsycoTuple_GET_ITEM(vargs, 2); ! if (Psyco_TypeSwitch(po, alist, &psyfs_dict) != 0) { /* 'kwdict' is not a dictionary */ break; --- 261,265 ---- case 3: kwdict = PsycoTuple_GET_ITEM(vargs, 2); ! if (Psyco_TypeSwitch(po, kwdict, &psyfs_dict) != 0) { /* 'kwdict' is not a dictionary */ break; *************** *** 281,285 **** } ! if (PsycoErr_Occurred(po)) return NULL; return psyco_generic_call(po, cd_apply.cd_function, --- 281,285 ---- } ! if (PycException_Occurred(po)) return NULL; return psyco_generic_call(po, cd_apply.cd_function, *************** *** 297,303 **** PsycoTuple_GET_ITEM(vargs, 1)); } - - if (PsycoErr_Occurred(po)) - return NULL; return psyco_generic_call(po, cd_divmod.cd_function, CfReturnRef|CfPyErrIfNull, --- 297,300 ---- Index: pycheader.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Python/pycheader.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pycheader.h 2002/01/11 16:16:58 1.4 --- pycheader.h 2002/02/05 20:08:23 1.5 *************** *** 37,43 **** */ ! #define INDEX_LOC_GLOBALS 0 /* globals() dict object */ ! #define INDEX_LOC_LOCALS_PLUS 1 /* start of local variables + stack */ #define LOC_GLOBALS (po->vlocals.items[INDEX_LOC_GLOBALS]) #define LOC_LOCALS_PLUS (po->vlocals.items + INDEX_LOC_LOCALS_PLUS) --- 37,45 ---- */ ! #define INDEX_LOC_CONTINUATION 0 /* return address in the stack */ ! #define INDEX_LOC_GLOBALS 1 /* globals() dict object */ ! #define INDEX_LOC_LOCALS_PLUS 2 /* start of local variables + stack */ + #define LOC_CONTINUATION (po->vlocals.items[INDEX_LOC_CONTINUATION]) #define LOC_GLOBALS (po->vlocals.items[INDEX_LOC_GLOBALS]) #define LOC_LOCALS_PLUS (po->vlocals.items + INDEX_LOC_LOCALS_PLUS) Index: pycompiler.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Python/pycompiler.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pycompiler.c 2002/01/11 16:17:18 1.9 --- pycompiler.c 2002/02/05 20:08:23 1.10 *************** *** 146,150 **** case CfPyErrCheck: /* always check with PyErr_Occurred() */ ! cc = integer_NON_NULL(po, PsycoErr_Occurred(po)); break; --- 146,150 ---- case CfPyErrCheck: /* always check with PyErr_Occurred() */ ! cc = integer_NON_NULL(po, psyco_PyErr_Occurred(po)); break; *************** *** 155,159 **** if (runtime_condition_t(po, cc)) return vi; /* result is not -1, ok */ ! cc = integer_NON_NULL(po, PsycoErr_Occurred(po)); break; --- 155,159 ---- if (runtime_condition_t(po, cc)) return vi; /* result is not -1, ok */ ! cc = integer_NON_NULL(po, psyco_PyErr_Occurred(po)); break; *************** *** 164,168 **** if (runtime_condition_t(po, cc)) return vi; /* result is >= 0, ok */ ! cc = integer_NON_NULL(po, PsycoErr_Occurred(po)); break; --- 164,168 ---- if (runtime_condition_t(po, cc)) return vi; /* result is >= 0, ok */ ! cc = integer_NON_NULL(po, psyco_PyErr_Occurred(po)); break; *************** *** 188,192 **** FORGET_REF; /* NULL result */ vinfo_decref(vi, po); ! cc = integer_NON_NULL(po, PsycoErr_Occurred(po)); if (cc == CC_ERROR || runtime_condition_f(po, cc)) goto PythonError; /* PyErr_Occurred() returns true */ --- 188,192 ---- FORGET_REF; /* NULL result */ vinfo_decref(vi, po); ! cc = integer_NON_NULL(po, psyco_PyErr_Occurred(po)); if (cc == CC_ERROR || runtime_condition_f(po, cc)) goto PythonError; /* PyErr_Occurred() returns true */ *************** *** 444,447 **** --- 444,448 ---- { PyObject* tb; + extra_assert(PyErr_Occurred()); PyErr_Fetch(target+0, target+1, &tb); Py_XDECREF(tb); /* XXX implement tracebacks */ *************** *** 460,463 **** --- 461,465 ---- { PyObject* tb; + extra_assert(PyErr_Occurred()); PyErr_Fetch(target+0, target+1, &tb); PyErr_NormalizeException(target+0, target+1, &tb); *************** *** 466,469 **** --- 468,481 ---- } + static void cimpl_pyerr_normalize(PyObject* exc, PyObject* val, + PyObject* target[]) + { + PyObject* tb = NULL; + target[0] = exc; Py_INCREF(exc); + target[1] = val; Py_INCREF(val); + PyErr_NormalizeException(target+0, target+1, &tb); + Py_XDECREF(tb); /* XXX implement tracebacks */ + } + DEFINEFN void PycException_Fetch(PsycoObject* po) *************** *** 487,519 **** inline bool PycException_FetchNormalize(PsycoObject* po) { if (PycException_Is(po, &ERtPython)) { ! vinfo_array_t* array = array_new(2); ! if (psyco_generic_call(po, cimpl_pyerr_fetch_and_normalize, ! CfNoReturnValue, "A", array) == NULL) ! return false; ! clear_pseudo_exception(po); ! PycException_Raise(po, array->items[0], array->items[1]); ! array_release(array); } else { ! /* normalize the exception */ ! vinfo_t* exc; ! vinfo_t* val; ! vinfo_t* tb; ! vinfo_t* zero; ! exc = make_runtime_copy(po, po->pr.exc); ! if (exc == NULL) return false; ! val = make_runtime_copy(po, po->pr.val); ! if (val == NULL) return false; ! zero = psyco_vi_Zero(); ! tb = make_runtime_copy(po, zero); ! vinfo_decref(zero, po); ! if (tb == NULL) return false; ! if (psyco_generic_call(po, PyErr_NormalizeException, ! CfNoReturnValue, "rrr", exc, val, tb) == NULL) ! return false; ! vinfo_decref(tb, po); ! PycException_Raise(po, exc, val); } return true; } --- 499,522 ---- inline bool PycException_FetchNormalize(PsycoObject* po) { + vinfo_t* result; + vinfo_array_t* array = array_new(2); if (PycException_Is(po, &ERtPython)) { ! /* fetch and normalize the exception */ ! result = psyco_generic_call(po, cimpl_pyerr_fetch_and_normalize, ! CfNoReturnValue, "A", array); } else { ! /* normalize the already-given exception */ ! result = psyco_generic_call(po, cimpl_pyerr_normalize, ! CfNoReturnValue, "vvA", ! po->pr.exc, po->pr.val, array); } + if (result == NULL) { + array_delete(array, po); + return false; + } + clear_pseudo_exception(po); + PycException_Raise(po, array->items[0], array->items[1]); + array_release(array); return true; } *************** *** 826,830 **** onchangebuf->codeptr); po->code = code; ! psyco_dump_code_buffers(); Py_INCREF(result); --- 829,833 ---- onchangebuf->codeptr); po->code = code; ! dump_code_buffers(); Py_INCREF(result); *************** *** 1344,1347 **** --- 1347,1353 ---- next_instr+1); + /* trace each code block entry point */ + TRACE_EXECUTION("ENTER_MAINLOOP"); + /* main loop */ while (1) { *************** *** 2039,2059 **** switch (oparg) { ! case IS: /* pointer comparison */ cc = integer_cmp(po, v, w, Py_EQ); break; ! case IS_NOT: /* pointer comparison */ cc = integer_cmp(po, v, w, Py_NE); break; ! case IN: ! case NOT_IN: x = PsycoSequence_Contains(po, w, v); cc = integer_NON_NULL(po, x); ! if (oparg == NOT_IN && cc != CC_ERROR) cc = INVERT_CC(cc); break; ! case EXC_MATCH: x = psyco_generic_call(po, PyErr_GivenExceptionMatches, CfPure|CfReturnNormal, --- 2045,2065 ---- switch (oparg) { ! case PyCmp_IS: /* pointer comparison */ cc = integer_cmp(po, v, w, Py_EQ); break; ! case PyCmp_IS_NOT: /* pointer comparison */ cc = integer_cmp(po, v, w, Py_NE); break; ! case PyCmp_IN: ! case PyCmp_NOT_IN: x = PsycoSequence_Contains(po, w, v); cc = integer_NON_NULL(po, x); ! if (oparg == PyCmp_NOT_IN && cc != CC_ERROR) cc = INVERT_CC(cc); break; ! case PyCmp_EXC_MATCH: x = psyco_generic_call(po, PyErr_GivenExceptionMatches, CfPure|CfReturnNormal, *************** *** 2171,2175 **** case SET_LINENO: ! /* nothing */ goto fine; --- 2177,2182 ---- case SET_LINENO: ! /* trace execution at each SET_LINENO opcode */ ! TRACE_EXECUTION("SET_LINENO"); goto fine; *************** *** 2222,2229 **** MISSING_OPCODE(CALL_FUNCTION_KW); MISSING_OPCODE(CALL_FUNCTION_VAR_KW); - MISSING_OPCODE(MAKE_FUNCTION); MISSING_OPCODE(MAKE_CLOSURE); MISSING_OPCODE(BUILD_SLICE);*/ case EXTENDED_ARG: opcode = NEXTOP(); --- 2229,2251 ---- MISSING_OPCODE(CALL_FUNCTION_KW); MISSING_OPCODE(CALL_FUNCTION_VAR_KW); MISSING_OPCODE(MAKE_CLOSURE); MISSING_OPCODE(BUILD_SLICE);*/ + case MAKE_FUNCTION: + if (oparg > 0) + v = PsycoTuple_New(oparg, STACK_POINTER() - oparg - 1); + else + v = NULL; + x = PsycoFunction_New(po, TOP(), LOC_GLOBALS, v); + vinfo_xdecref(v, po); + if (x == NULL) + break; + + /* clean up the stack (remove args and func) */ + while (oparg-- >= 0) + POP_DECREF(); + PUSH(x); + goto fine; + case EXTENDED_ARG: opcode = NEXTOP(); *************** *** 2266,2269 **** --- 2288,2294 ---- goto finished; mp++; + /* trace execution at each of the <snapshot>s the execution + goes through */ + TRACE_EXECUTION("SNAPSHOT"); } } /* end of the main loop, exit if exception */ *************** *** 2391,2395 **** finished: ! #ifdef ALL_CHECKS if (PyErr_Occurred()) { fprintf(stderr, "psyco: unexpected Python exception during compilation:\n"); --- 2416,2420 ---- finished: ! #if ALL_CHECKS if (PyErr_Occurred()) { fprintf(stderr, "psyco: unexpected Python exception during compilation:\n"); Index: pycompiler.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Python/pycompiler.h,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pycompiler.h 2002/01/11 16:16:58 1.5 --- pycompiler.h 2002/02/05 20:08:23 1.6 *************** *** 30,33 **** --- 30,36 ---- + #define MAX3(a,b,c) ((a)>(b)?((a)>(c)?(a):(c)):(b)>(c)?(b):(c)) + + /*****************************************************************/ /*** Common constants ***/ *************** *** 219,224 **** /*** Exception utilities ***/ ! /* Psyco equivalent of PyErr_Occurred() */ ! inline vinfo_t* PsycoErr_Occurred(PsycoObject* po) { if (PycException_Occurred(po) && PycException_IsPython(po)) { return psyco_vi_One(); --- 222,229 ---- /*** Exception utilities ***/ ! /* Psyco meta-equivalent of PyErr_Occurred(). Not to be confused with ! PycException_Occurred(), which tells whether a Psyco-level exception ! is currently set. */ ! inline vinfo_t* psyco_PyErr_Occurred(PsycoObject* po) { if (PycException_Occurred(po) && PycException_IsPython(po)) { return psyco_vi_One(); |
From: Armin Rigo <arigo@us...> - 2002-02-05 20:08:29
|
Update of /cvsroot/psyco/psyco/py-utils In directory usw-pr-cvs1:/tmp/cvs-serv27600/py-utils Modified Files: xam.py Added Files: symbols.py Log Message: major and numerous bug fixes. Psyco will now run most of Python's regresstion tests. --- NEW FILE: symbols.py --- import sys, os import xam """ This script loads a psyco.dump file (like httpxam.py) and reads on its standard input a list of addresses. For each address that it recognizes it prints the name of the corresponding symbol or the address of the code buffer that contains the address. Use this on debugger memory dumps. This could be enhanced by detecting the addresses of vinfo_t's as well. """ def main(codebufs, f): while 1: line = f.readline() if not line: break for addr in xam.lineaddresses(line): sym = xam.symbols.get(addr) if sym: print '0x%x\tis\t' % addr, xam.symtext(sym, addr) break if __name__ == '__main__': if len(sys.argv) <= 1: print "Usage: python symbols.py <directory>" print " psyco.dump is loaded from the <directory>." sys.exit(1) DIRECTORY = sys.argv[1] del sys.argv[1] codebufs = xam.readdump(os.path.join(DIRECTORY, 'psyco.dump')) print >> sys.stderr, "Reading for addresses from stdin..." main(codebufs, sys.stdin) Index: xam.py =================================================================== RCS file: /cvsroot/psyco/psyco/py-utils/xam.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** xam.py 2002/01/15 12:42:09 1.4 --- xam.py 2002/02/05 20:08:23 1.5 *************** *** 67,73 **** return ''.join([revmap.get(c,c) for c in text]) - LOC_LOCALS_PLUS = 1 class CodeBuf: --- 67,85 ---- return ''.join([revmap.get(c,c) for c in text]) + def lineaddresses(line): + result = [] + i = 0 + while 1: + match = re_addr.search(line, i) + if not match: + break + i = match.end() + addr = long(match.group(1), 16) + result.append(addr) + return result + LOC_LOCALS_PLUS = 2 + class CodeBuf: *************** *** 139,143 **** for codebuf in maybe.keys(): for line in codebuf.disass_text: ! for addr in codebuf.addresses(line): if start <= addr < end: self.reverse_lookup.append((addr-start, codebuf)) --- 151,155 ---- for codebuf in maybe.keys(): for line in codebuf.disass_text: ! for addr in lineaddresses(line): if start <= addr < end: self.reverse_lookup.append((addr-start, codebuf)) *************** *** 160,179 **** except: pass - - def addresses(self, line): - result = [] - i = 0 - while 1: - match = re_addr.search(line, i) - if not match: - break - i = match.end() - addr = long(match.group(1), 16) - result.append(addr) - return result ## def build_reverse_lookup(self): ## for line in self.disass_text: ! ## for addr in self.addresses(line): ## sym = symbols.get(addr) ## if isinstance(sym, CodeBuf): --- 172,179 ---- except: pass ## def build_reverse_lookup(self): ## for line in self.disass_text: ! ## for addr in lineaddresses(line): ## sym = symbols.get(addr) ## if isinstance(sym, CodeBuf): *************** *** 200,204 **** if sources != [self]*len(sources): data.append('\n') ! for addr in self.addresses(line): sym = symbols.get(addr) if sym: --- 200,204 ---- if sources != [self]*len(sources): data.append('\n') ! for addr in lineaddresses(line): sym = symbols.get(addr) if sym: |
From: Armin Rigo <arigo@us...> - 2002-02-05 20:08:28
|
Update of /cvsroot/psyco/psyco/c/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27600/c/Objects Modified Files: pabstract.c pdictobject.c pfuncobject.c pfuncobject.h piterobject.c ptupleobject.h Log Message: major and numerous bug fixes. Psyco will now run most of Python's regresstion tests. Index: pabstract.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pabstract.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pabstract.c 2002/01/17 13:32:57 1.4 --- pabstract.c 2002/02/05 20:08:23 1.5 *************** *** 70,74 **** use_proxy: ! if (PsycoErr_Occurred(po)) return NULL; return psyco_generic_call(po, PyEval_CallObjectWithKeywords, --- 70,74 ---- use_proxy: ! if (PycException_Occurred(po)) return NULL; return psyco_generic_call(po, PyEval_CallObjectWithKeywords, Index: pdictobject.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pdictobject.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pdictobject.c 2001/12/04 16:12:07 1.1 --- pdictobject.c 2002/02/05 20:08:23 1.2 *************** *** 2,5 **** --- 2,9 ---- + #if NEW_STYLE_TYPES + # define DICT_MA_USED QUARTER(offsetof(PyDictObject, ma_used)) + #endif + DEFINEFN vinfo_t* PsycoDict_New(PsycoObject* po) *************** *** 17,20 **** --- 21,29 ---- } + static vinfo_t* psyco_dict_length(PsycoObject* po, vinfo_t* vi) + { + return read_array_item(po, vi, DICT_MA_USED); + } + DEFINEFN *************** *** 22,25 **** { PyMappingMethods *m = PyDict_Type.tp_as_mapping; ! Psyco_DefineMeta(m->mp_length, psyco_generic_mut_ob_size); } --- 31,34 ---- { PyMappingMethods *m = PyDict_Type.tp_as_mapping; ! Psyco_DefineMeta(m->mp_length, psyco_dict_length); } Index: pfuncobject.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pfuncobject.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pfuncobject.c 2001/12/28 12:35:37 1.3 --- pfuncobject.c 2002/02/05 20:08:23 1.4 *************** *** 3,6 **** --- 3,77 ---- + /***************************************************************/ + /*** Virtual functions ***/ + + #define FUNC_CODE QUARTER(offsetof(PyFunctionObject, func_code)) + #define FUNC_GLOBALS QUARTER(offsetof(PyFunctionObject, func_globals)) + #define FUNC_DEFAULTS QUARTER(offsetof(PyFunctionObject, func_defaults)) + + static source_virtual_t psyco_computed_function; + + static bool compute_function(PsycoObject* po, vinfo_t* v) + { + vinfo_t* newobj; + vinfo_t* fcode; + vinfo_t* fglobals; + vinfo_t* fdefaults; + + fcode = get_array_item(po, v, FUNC_CODE); + if (fcode == NULL) + return false; + + fglobals = get_array_item(po, v, FUNC_GLOBALS); + if (fglobals == NULL) + return false; + + fdefaults = get_array_item(po, v, FUNC_DEFAULTS); + if (fdefaults == NULL) + return false; + + newobj = psyco_generic_call(po, PyFunction_New, + CfReturnRef|CfPyErrIfNull, + "vv", fcode, fglobals); + if (newobj == NULL) + return false; + + if (!psyco_knowntobe(fdefaults, (long) NULL)) { + if (!psyco_generic_call(po, PyFunction_SetDefaults, + CfNoReturnValue|CfPyErrIfNonNull, + "vv", newobj, fdefaults)) + return false; + } + + /* move the resulting non-virtual Python object back into 'v' */ + vinfo_move(po, v, newobj); + return true; + } + + + DEFINEFN + vinfo_t* PsycoFunction_New(PsycoObject* po, vinfo_t* fcode, + vinfo_t* fglobals, vinfo_t* fdefaults) + { + vinfo_t* r = vinfo_new(VirtualTime_New(&psyco_computed_function)); + r->array = array_new(MAX3(FUNC_CODE, FUNC_GLOBALS, FUNC_DEFAULTS)+1); + r->array->items[OB_TYPE] = + vinfo_new(CompileTime_New((long)(&PyFunction_Type))); + vinfo_incref(fcode); + r->array->items[FUNC_CODE] = fcode; + vinfo_incref(fglobals); + r->array->items[FUNC_GLOBALS] = fglobals; + if (fdefaults == NULL) + fdefaults = psyco_vi_Zero(); + else + vinfo_incref(fdefaults); + r->array->items[FUNC_DEFAULTS] = fdefaults; + return r; + } + + + /***************************************************************/ + /*** function objects meta-implementation ***/ + static vinfo_t* pfunction_call(PsycoObject* po, vinfo_t* func, vinfo_t* arg, vinfo_t* kw) *************** *** 9,12 **** --- 80,88 ---- auto_recursion > 0. We promote the Python function to compile-time if it is not known yet. */ + + /* XXX this is not how it should be done! We must read the + function's func_code, func_globals and func_defaults + and pass them further. The code below forces all functions + out of virtual-time. */ if (po->pr.auto_recursion > 0 && psyco_knowntobe(kw, (long) NULL)) { PyObject* pyfunc = psyco_pyobj_atcompiletime(po, func); *************** *** 40,42 **** --- 116,119 ---- Psyco_DefineMeta(PyFunction_Type.tp_call, pfunction_call); Psyco_DefineMeta(PyFunction_Type.tp_descr_get, pfunc_descr_get); + psyco_computed_function.compute_fn = &compute_function; } Index: pfuncobject.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pfuncobject.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pfuncobject.h 2001/12/06 15:48:25 1.2 --- pfuncobject.h 2002/02/05 20:08:23 1.3 *************** *** 11,14 **** --- 11,21 ---- + /***************************************************************/ + /* virtual functions. */ + /* 'fdefaults' may be NULL. */ + EXTERNFN vinfo_t* PsycoFunction_New(PsycoObject* po, vinfo_t* fcode, + vinfo_t* fglobals, vinfo_t* fdefaults); + + EXTERNFN void psy_funcobject_init(void); Index: piterobject.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/piterobject.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** piterobject.c 2002/01/11 16:17:28 1.2 --- piterobject.c 2002/02/05 20:08:23 1.3 *************** *** 13,17 **** vinfo_t* index; vinfo_t* result; - vinfo_t* index_plus_1; seq = get_array_item(po, v, SEQITER_IT_SEQ); --- 13,16 ---- *************** *** 19,33 **** return NULL; ! index = get_array_item(po, v, SEQITER_IT_INDEX); if (index == NULL) return NULL; - index_plus_1 = integer_add_i(po, index, 1); - if (index_plus_1 == NULL) - return NULL; result = PsycoSequence_GetItem(po, seq, index); - - set_array_item(po, v, SEQITER_IT_INDEX, index_plus_1); - if (result == NULL) { vinfo_t* matches = PycException_Matches(po, PyExc_IndexError); --- 18,26 ---- return NULL; ! index = read_array_item(po, v, SEQITER_IT_INDEX); if (index == NULL) return NULL; result = PsycoSequence_GetItem(po, seq, index); if (result == NULL) { vinfo_t* matches = PycException_Matches(po, PyExc_IndexError); *************** *** 37,40 **** --- 30,52 ---- } } + else { + /* very remotely potential incompatibility: when exhausted, + the internal iterator index is not incremented. Python + is not consistent in this respect. This could be an + issue if an iterator of a mutable object is not + immediately deleted when exhausted. Well, I guess that + muting an object we iterate over is generally considered + as DDIWWY (Don't Do It -- We Warned You.) */ + vinfo_t* index_plus_1 = integer_add_i(po, index, 1); + if (index_plus_1 == NULL) { + vinfo_decref(result, po); + result = NULL; + } + else { + write_array_item(po, v, SEQITER_IT_INDEX, index_plus_1); + vinfo_decref(index_plus_1, po); + } + } + vinfo_decref(index, po); return result; } Index: ptupleobject.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/ptupleobject.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ptupleobject.h 2001/12/06 15:48:25 1.2 --- ptupleobject.h 2002/02/05 20:08:23 1.3 *************** *** 29,33 **** /* get the (possibly virtual) array of items in the tuple, returning the length of the tuple or -1 if it fails (items not known). ! The items are then found in tuple->array->items[TUPLE_OB_ITEM+i]. */ EXTERNFN int PsycoTuple_Load(vinfo_t* tuple); --- 29,34 ---- /* get the (possibly virtual) array of items in the tuple, returning the length of the tuple or -1 if it fails (items not known). ! The items are then found in tuple->array->items[TUPLE_OB_ITEM+i]. ! Never sets a PycException. */ EXTERNFN int PsycoTuple_Load(vinfo_t* tuple); |
From: Armin Rigo <arigo@us...> - 2002-02-05 20:05:54
|
Update of /cvsroot/psyco/psyco/test In directory usw-pr-cvs1:/tmp/cvs-serv27008 Added Files: classicregrtest.py Log Message: Python's regression tests can be run by Psyco with this script. --- NEW FILE: classicregrtest.py --- import sys, os, StringIO NO_SYS_GETFRAME = """using sys._getframe() fails with Psyco""" NO_THREAD = """XXX not reliable, check if Psyco is generally unreliable with threads or if there is another problem""" NO_PICKLE = """pickles function objects that Psyco rebinds""" SKIP = {'test_gc': NO_SYS_GETFRAME, 'test_thread': NO_THREAD, 'test_asynchat': NO_THREAD, 'test_extcall': 'prints to stdout a function object that Psyco rebinds', 'test_descr': NO_PICKLE, 'test_pickle': NO_PICKLE, 'test_cpickle': NO_PICKLE, 'test_re': NO_PICKLE, 'test_sre': 'Psyco does not set sys.exc_xxx upon exception', 'test_inspect': 'gets confused with Psyco rebinding functions', 'test_profilehooks': NO_SYS_GETFRAME, 'test_profile': 'profiling does not see all functions run by Psyco', } # Per-module user-filtered warnings don't work correctly # because sys._getframe() cannot see the Psyco frames. # Some tests expect an OverflowError to be raised when # an overflow is detected. To work around this, we # globally force these to raise an error. import warnings warnings.filterwarnings("error", "", OverflowWarning, "") for dir in sys.path: file = os.path.join(dir, "string.py") if os.path.isfile(file): test = os.path.join(dir, "test") if os.path.isdir(test): # Add the "test" directory to PYTHONPATH. sys.path = sys.path + [test] import regrtest, test_support repeat_counter = 4 def alltests(): import random # randomize the list of tests, but try to ensure that we start with # not-already-seen tests and only after go on with the rest filename = "tmp_tests_passed" try: f = open(filename) tests_passed = eval(f.read()) f.close() except IOError: tests_passed = {} testlist = regrtest.findtests() testlist = [test for test in testlist if test not in tests_passed] random.shuffle(testlist) testlist1 = tests_passed.keys() random.shuffle(testlist1) print '\t'.join(['Scheduled tests:']+testlist) if testlist1: print '%d more tests were already passed and are scheduled to run thereafter.' % len(testlist1) testlist += testlist1 for test in testlist: print '='*40 err = os.system('"%s" "%s" "%s"' % (sys.executable, sys.argv[0], test)) if err: print '*** exited with error code', err return err tests_passed[test] = 1 f = open(filename, 'w') f.write(repr(tests_passed)) f.close() print "="*60 print print "Classic Regression Tests with Psyco successfully completed." print "All tests that succeeded twice in the same Python process" print "also succeeded %d more times with Psyco activated." % repeat_counter print try: os.unlink(filename) except: pass import _psyco print "Psyco compilation flags:", d = _psyco.__dict__ if 'ALL_CHECKS' not in d: print "Release mode", for key in d: if key == key.upper() and isinstance(d[key], int): print "%s=%d" % (key, d[key]), print def python_check(test): if test in SKIP: print '%s skipped -- %s' % (test, SKIP[test]) return 0 for i in range(min(repeat_counter, 2)): print '%s, Python iteration %d' % (test, i+1) ok = regrtest.runtest(test, 0, 0, 0) special_cleanup() if ok <= 0: return 0 # skipped or failed -- don't test with Psyco return 1 def main(testlist, verbose=0, use_resources=None): if use_resources is None: use_resources = [] test_support.verbose = verbose # Tell tests to be moderately quiet test_support.use_resources = use_resources if isinstance(testlist, str): testlist = [testlist] testlist = filter(python_check, testlist) # Psyco selective compilation is only activated here import psyco #print "sleeping, time for a Ctrl-C !..." #import time; time.sleep(1.5) for test in testlist: for i in range(repeat_counter): print '%s, Psyco iteration %d' % (test, i+1) ok = regrtest.runtest(test, 0, 0, 0) special_cleanup() if ok == 0: return 0 elif ok < 0: break return 1 def special_cleanup(): try: dircache = sys.modules['dircache'] except KeyError: pass else: for key in dircache.cache.keys(): del dircache.cache[key] if __name__ == '__main__': if len(sys.argv) <= 1: sys.exit(alltests() or 0) else: if not main(sys.argv[1:]): sys.exit(2) |