From: Armin R. <ar...@us...> - 2001-12-30 23:42:28
|
Update of /cvsroot/psyco/psyco/c In directory usw-pr-cvs1:/tmp/cvs-serv14155/c Modified Files: dispatcher.c dispatcher.h vcompiler.c Log Message: un-promoting several values at once Index: dispatcher.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/dispatcher.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** dispatcher.c 2001/12/28 12:36:48 1.4 --- dispatcher.c 2001/12/30 23:42:24 1.5 *************** *** 259,263 **** /*****************************************************************/ ! static vinfo_t* compatible_array(vinfo_array_t* aa, vinfo_array_t* bb) { /* 'aa' is the array from the live PsycoObject. 'bb' is from the snapshop. --- 259,264 ---- /*****************************************************************/ ! static bool compatible_array(vinfo_array_t* aa, vinfo_array_t* bb, ! vinfo_array_t** result) { /* 'aa' is the array from the live PsycoObject. 'bb' is from the snapshop. *************** *** 275,281 **** process. ! Return value of compatible_array(): as in psyco_compatible(). */ - vinfo_t* result = COMPATIBLE; int i; int count = bb->count; --- 276,282 ---- process. ! Return value of compatible_array(): false if incompatible, otherwise ! fills the 'result' array with the variables to un-promote. */ int i; int count = bb->count; *************** *** 286,290 **** for (i=aa->count; i<count; i++) if (bb->items[i] != NULL) ! return INCOMPATIBLE; /* differs */ count = aa->count; } --- 287,291 ---- for (i=aa->count; i<count; i++) if (bb->items[i] != NULL) ! return false; /* differs */ count = aa->count; } *************** *** 293,297 **** for (i=aa->count; i>count; ) if (aa->items[--i] != NULL) ! return INCOMPATIBLE; /* differs */ } } --- 294,298 ---- for (i=aa->count; i>count; ) if (aa->items[--i] != NULL) ! return false; /* differs */ } } *************** *** 351,359 **** SkFlagFixed) != 0) goto incompatible; /* b's value is fixed */ ! /* approximative match, might un-promote 'a' from ! compile-time to run-time. */ ! //fprintf(stderr, "psyco: compatible_array() with vinfo_t* a=%p, b=%p\n", a, b); ! if (result == COMPATIBLE) ! result = a; } } --- 352,370 ---- SkFlagFixed) != 0) goto incompatible; /* b's value is fixed */ ! else { ! /* approximative match, might un-promote 'a' from ! compile-time to run-time. */ ! //fprintf(stderr, "psyco: compatible_array() with vinfo_t* a=%p, b=%p\n", a, b); ! int i, ocount = (*result)->count; ! /* do not add several time the same value to the array */ ! for (i=0; i<ocount; i++) ! if ((*result)->items[i] == a) ! break; ! if (i==ocount) ! { ! *result = array_grow1(*result, ocount+1); ! (*result)->items[ocount] = a; ! } ! } } } *************** *** 361,373 **** if (a->array != b->array) { /* can only be equal if both ==NullArray */ ! vinfo_t* subresult = compatible_array(a->array, b->array); ! if (subresult == INCOMPATIBLE) goto incompatible; - if (result == COMPATIBLE) - result = subresult; } } } ! return result; incompatible: /* we have to reset the 'tmp' fields to NULL, --- 372,381 ---- if (a->array != b->array) { /* can only be equal if both ==NullArray */ ! if (!compatible_array(a->array, b->array, result)) goto incompatible; } } } ! return true; incompatible: /* we have to reset the 'tmp' fields to NULL, *************** *** 380,392 **** clear_tmp_marks(bb->items[i]->array); } ! return INCOMPATIBLE; } DEFINEFN ! vinfo_t* psyco_compatible(PsycoObject* po, global_entries_t* patterns, ! CodeBufferObject** matching) { int i; ! vinfo_t* result = INCOMPATIBLE; PyObject* plist = patterns->fatlist; extra_assert(PyList_Check(plist)); --- 388,400 ---- clear_tmp_marks(bb->items[i]->array); } ! return false; } DEFINEFN ! vinfo_array_t* psyco_compatible(PsycoObject* po, global_entries_t* patterns, ! CodeBufferObject** matching) { int i; ! vinfo_array_t* bestresult = NULL; PyObject* plist = patterns->fatlist; extra_assert(PyList_Check(plist)); *************** *** 394,398 **** while (i--) /* the most dummy algorithm: step by step in the list, */ { /* checking for a match at each step. */ ! vinfo_t* diff; CodeBufferObject* codebuf = (CodeBufferObject*) PyList_GET_ITEM(plist, i); extra_assert(CodeBuffer_Check(codebuf)); --- 402,406 ---- while (i--) /* the most dummy algorithm: step by step in the list, */ { /* checking for a match at each step. */ ! vinfo_array_t* differences = NullArray; CodeBufferObject* codebuf = (CodeBufferObject*) PyList_GET_ITEM(plist, i); extra_assert(CodeBuffer_Check(codebuf)); *************** *** 400,414 **** all their 'tmp' fields set to NULL. */ assert_cleared_tmp_marks(codebuf->snapshot.fz_vlocals); ! diff = compatible_array(&po->vlocals, codebuf->snapshot.fz_vlocals); ! if (diff != INCOMPATIBLE) { /* compatible_array() leaves data in the 'tmp' fields. It must be cleared unless it is the final result of psyco_compatible() itself. */ ! if (diff == COMPATIBLE) { /* Total match */ *matching = codebuf; ! return COMPATIBLE; } else --- 408,422 ---- all their 'tmp' fields set to NULL. */ assert_cleared_tmp_marks(codebuf->snapshot.fz_vlocals); ! if (compatible_array(&po->vlocals, codebuf->snapshot.fz_vlocals, ! &differences)) { /* compatible_array() leaves data in the 'tmp' fields. It must be cleared unless it is the final result of psyco_compatible() itself. */ ! if (differences == NullArray) { /* Total match */ *matching = codebuf; ! return NullArray; } else *************** *** 416,425 **** /* Partial match, clear 'tmp' fields */ clear_tmp_marks(codebuf->snapshot.fz_vlocals); ! if (result == INCOMPATIBLE) { ! /* Record the first partial match we find */ ! *matching = codebuf; ! result = diff; } } } --- 424,436 ---- /* Partial match, clear 'tmp' fields */ clear_tmp_marks(codebuf->snapshot.fz_vlocals); ! if (bestresult != NULL) { ! if (bestresult->count <= differences->count) ! continue; /* not better than the previous partial match */ ! array_release(bestresult); } + /* Record the first partial match we found */ + bestresult = differences; + *matching = codebuf; } } *************** *** 427,431 **** assert_cleared_tmp_marks(codebuf->snapshot.fz_vlocals); } ! return result; } --- 438,442 ---- assert_cleared_tmp_marks(codebuf->snapshot.fz_vlocals); } ! return bestresult; } Index: dispatcher.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/dispatcher.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** dispatcher.h 2001/12/24 17:01:18 1.4 --- dispatcher.h 2001/12/30 23:42:24 1.5 *************** *** 59,76 **** /* psyco_compatible(): ! search in the given global_entries_t for a match to the living PsycoObject. ! Return the best match in *matching. The result is either COMPATIBLE, ! INCOMPATIBLE (no match), or an actual vinfo_t* of 'po' which is a compile- ! time value that should be un-promoted to run-time. ! If the result is COMPATIBLE, this call leaves the dispatcher in a unstable state; it must be fixed by calling one of the psyco_unify() functions below, or by psyco_stabilize(). */ ! #define COMPATIBLE NULL ! #define INCOMPATIBLE ((vinfo_t*) 1) ! ! EXTERNFN vinfo_t* psyco_compatible(PsycoObject* po, global_entries_t* pattern, ! CodeBufferObject** matching); EXTERNFN void psyco_stabilize(CodeBufferObject* lastmatch); --- 59,76 ---- /* psyco_compatible(): ! search in the given global_entries_t for a match to the live PsycoObject. ! The best match is returned in *matching. The function result is NULL if no ! match is found; otherwise, it is an array of the 'vinfo_t*' of 'po' which ! are compile-time but should be un-promoted to run-time. In particular, the ! array is empty (==NullArray) if an exact match is found. A non-empty ! returned array must be released by 'array_release()'. ! If the result is NullArray, this call leaves the dispatcher in a unstable state; it must be fixed by calling one of the psyco_unify() functions below, or by psyco_stabilize(). */ ! EXTERNFN vinfo_array_t* psyco_compatible(PsycoObject* po, ! global_entries_t* pattern, ! CodeBufferObject** matching); EXTERNFN void psyco_stabilize(CodeBufferObject* lastmatch); Index: vcompiler.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/vcompiler.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** vcompiler.c 2001/12/24 17:01:18 1.4 --- vcompiler.c 2001/12/30 23:42:24 1.5 *************** *** 508,517 **** { CodeBufferObject* oldcodebuf; ! vinfo_t* diff = mp==NULL ? INCOMPATIBLE : psyco_compatible(po, &mp->entries, &oldcodebuf); /*psyco_assert_cleared_tmp_marks(&po->vlocals); -- not needed -- */ ! if (diff == COMPATIBLE) { code_t* code2 = psyco_unify(po, &oldcodebuf); --- 508,517 ---- { CodeBufferObject* oldcodebuf; ! vinfo_array_t* diff = mp==NULL ? NULL : psyco_compatible(po, &mp->entries, &oldcodebuf); /*psyco_assert_cleared_tmp_marks(&po->vlocals); -- not needed -- */ ! if (diff == NullArray) /* exact match, jump there */ { code_t* code2 = psyco_unify(po, &oldcodebuf); *************** *** 521,525 **** else { ! if (po->codelimit - po->code <= BUFFER_MARGIN && diff == INCOMPATIBLE) { /* Running out of space in this buffer. */ --- 521,525 ---- else { ! if (po->codelimit - po->code <= BUFFER_MARGIN && diff == NULL) { /* Running out of space in this buffer. */ *************** *** 550,557 **** } ! if (diff != INCOMPATIBLE) { ! /* diff points to a vinfo_t: make it run-time */ ! psyco_unfix(po, diff); /* start over (maybe we have already seen this new state) */ return psyco_compile(po, mp, continue_compilation); --- 550,560 ---- } ! if (diff != NULL) /* partial match */ { ! /* diff points to an array of vinfo_ts: make them run-time */ ! int i; ! for (i=diff->count; i--; ) ! psyco_unfix(po, diff->items[i]); ! array_release(diff); /* start over (maybe we have already seen this new state) */ return psyco_compile(po, mp, continue_compilation); *************** *** 571,575 **** { CodeBufferObject* oldcodebuf; ! vinfo_t* diff = mp==NULL ? INCOMPATIBLE : psyco_compatible(po, &mp->entries, &oldcodebuf); PsycoObject* po2 = PsycoObject_Duplicate(po); --- 574,578 ---- { CodeBufferObject* oldcodebuf; ! vinfo_array_t* diff = mp==NULL ? NULL : psyco_compatible(po, &mp->entries, &oldcodebuf); PsycoObject* po2 = PsycoObject_Duplicate(po); *************** *** 577,581 **** extra_assert(condition < CC_TOTAL); ! if (diff == COMPATIBLE) { /* try to emit: --- 580,584 ---- extra_assert(condition < CC_TOTAL); ! if (diff == NullArray) /* exact match */ { /* try to emit: *************** *** 611,614 **** --- 614,618 ---- which will perform the actual compilation later. */ + array_release(diff); psyco_coding_pause(po2, condition, &psyco_resume_compile, NULL, 0); po->code = po2->code; *************** *** 624,633 **** CodeBufferObject* codebuf; CodeBufferObject* oldcodebuf; ! vinfo_t* diff = mp==NULL ? INCOMPATIBLE : psyco_compatible(po, &mp->entries, &oldcodebuf); /*psyco_assert_cleared_tmp_marks(&po->vlocals); -- not needed -- */ ! if (diff == COMPATIBLE) return psyco_unify_code(po, oldcodebuf); --- 628,637 ---- CodeBufferObject* codebuf; CodeBufferObject* oldcodebuf; ! vinfo_array_t* diff = mp==NULL ? NULL : psyco_compatible(po, &mp->entries, &oldcodebuf); /*psyco_assert_cleared_tmp_marks(&po->vlocals); -- not needed -- */ ! if (diff == NullArray) /* exact match */ return psyco_unify_code(po, oldcodebuf); *************** *** 638,644 **** po->code = codebuf->codeptr; ! if (diff != INCOMPATIBLE) { ! psyco_unfix(po, diff); /* start over (maybe we have already seen this new state) */ code1 = psyco_compile(po, mp, false); --- 642,651 ---- po->code = codebuf->codeptr; ! if (diff != NULL) /* partial match */ { ! int i; ! for (i=diff->count; i--; ) ! psyco_unfix(po, diff->items[i]); ! array_release(diff); /* start over (maybe we have already seen this new state) */ code1 = psyco_compile(po, mp, false); |