diff --git a/src/code/amd64.c b/src/code/amd64.c index 0b961143eaf7877f9d8064928122509130ed1ca9..1077f9b6eb2b90420da3198dc3167cc3518a1207 100644 --- a/src/code/amd64.c +++ b/src/code/amd64.c @@ -1034,8 +1034,8 @@ static void amd64_push_svaluep_to(int reg, int spoff) mov_reg_mem(REG_RAX, sp_reg, spoff*sizeof(struct svalue)+OFFSETOF(svalue, type)); and_reg_imm(REG_RAX, 0x1f); mov_reg_mem(REG_RCX, sp_reg, spoff*sizeof(struct svalue)+OFFSETOF(svalue, u.refs)); - cmp_reg32_imm(REG_RAX, MAX_REF_TYPE); - jg(&label_A); + cmp_reg32_imm(REG_RAX, MIN_REF_TYPE); + jl(&label_A); add_imm_mem( 1, REG_RCX, OFFSETOF(pike_string, refs)); LABEL_A; } @@ -1096,9 +1096,9 @@ static void amd64_free_svalue(enum amd64_reg src, int guaranteed_ref ) /* load type -> RAX */ mov_sval_type( src, REG_RAX ); - /* if RAX > MAX_REF_TYPE+1 */ - cmp_reg32_imm( REG_RAX,MAX_REF_TYPE); - jg( &label_A ); + /* if RAX < MIN_REF_TYPE+1 */ + cmp_reg32_imm( REG_RAX,MIN_REF_TYPE); + jl( &label_A ); /* Load pointer to refs -> RAX */ mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX); @@ -1121,12 +1121,12 @@ static void amd64_free_svalue_type(enum amd64_reg src, enum amd64_reg type, int guaranteed_ref ) { LABELS(); - /* if type > MAX_REF_TYPE+1 */ + /* if type < MIN_REF_TYPE+1 */ if( src == REG_RAX ) Pike_fatal("Clobbering RAX for free-svalue\n"); - cmp_reg32_imm(type,MAX_REF_TYPE); - jg( &label_A ); + cmp_reg32_imm(type,MIN_REF_TYPE); + jl( &label_A ); /* Load pointer to refs -> RAX */ mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX); @@ -1153,9 +1153,9 @@ void amd64_ref_svalue( enum amd64_reg src, int already_have_type ) else and_reg_imm( REG_RAX, 0x1f ); - /* if RAX > MAX_REF_TYPE+1 */ - cmp_reg32_imm(REG_RAX, MAX_REF_TYPE ); - jg( &label_A ); + /* if RAX > MIN_REF_TYPE+1 */ + cmp_reg32_imm(REG_RAX, MIN_REF_TYPE ); + jl( &label_A ); /* Load pointer to refs -> RAX */ mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX); /* *RAX++ */ @@ -2121,8 +2121,8 @@ int amd64_ins_f_jump(unsigned int op, int backward_jump) /* inc refs? */ and_reg_imm( REG_RAX, 0x1f ); - cmp_reg32_imm(REG_RAX, MAX_REF_TYPE); - jg( &label_B ); + cmp_reg32_imm(REG_RAX, MIN_REF_TYPE); + jl( &label_B ); add_imm_mem( 1, REG_RCX, OFFSETOF(pike_string, refs)); jmp( &label_B ); @@ -2206,8 +2206,8 @@ int amd64_ins_f_jump(unsigned int op, int backward_jump) /* Optimization: The types are equal, pop_stack can be greatly * simplified if they are <= max_ref_type */ - cmp_reg32_imm( REG_RCX,MAX_REF_TYPE+1); - jl( &label_B ); + cmp_reg32_imm( REG_RCX,MIN_REF_TYPE); + jge( &label_B ); /* cheap pop. We know that both are > max_ref_type */ amd64_add_sp( -2 ); jmp( &label_D ); diff --git a/src/code/ia32.c b/src/code/ia32.c index 860ca516c31e77763fd748993ee1ddabd208e779..f97956aeed0faf154ff8a2ccd00942dee0fb805b 100644 --- a/src/code/ia32.c +++ b/src/code/ia32.c @@ -584,10 +584,10 @@ static void ia32_push_svalue (enum ia32_reg svalue_ptr_reg) add_to_program(0x66); /* Switch to 16 bit operand mode. */ add_to_program(0x83); /* cmp $xx,svalue_ptr_reg */ add_to_program(0xf8 | svalue_ptr_reg); - add_to_program(MAX_REF_TYPE); + add_to_program(MIN_REF_TYPE); DEALLOC_REG (svalue_ptr_reg); - add_to_program(0x77); /* ja bork */ + add_to_program(0x7c); /* jl bork */ add_to_program(0x02); CHECK_VALID_REG (tmp_reg); diff --git a/src/encode.c b/src/encode.c index 48c9212540469a0a552fa5bc247c321fdf4505d3..e49514878c6c01e4d5a71b07b3563d3f676b78c4 100644 --- a/src/encode.c +++ b/src/encode.c @@ -74,21 +74,27 @@ /* Tags used by encode value. - * Currently they only differ from the PIKE_T variants by - * TAG_FLOAT == PIKE_T_TYPE == 7 + * + * Currently they differ from the old PIKE_T variants by + * TAG_FLOAT == OLD_PIKE_T_TYPE == 7 * and - * TAG_TYPE == PIKE_T_FLOAT == 9 + * TAG_TYPE == OLD_PIKE_T_FLOAT == 9 + * + * The old PIKE_T variants in turn differ from the current for values + * less than 16 (aka MAX_TYPE) by bit 3 (mask 0x0008 (aka MIN_REF_TYPE)) + * being inverted. + * * These are NOT to be renumbered unless the file-format version is changed! */ /* Current encoding: �ke0 * * +---+-+-+-------+ - * |s z|s|n|t y p e| + * |s z|s|n| t a g | * +---+-+-+-------+ * sz size/small int * s small int indicator * n negative (or rather inverted) - * type TAG_type + * tag TAG_type (4 bits) */ #define TAG_ARRAY 0 #define TAG_MAPPING 1 @@ -235,9 +241,16 @@ static int type_to_tag(int type) { if (type == T_FLOAT) return TAG_FLOAT; if (type == T_TYPE) return TAG_TYPE; + if (type <= MAX_TYPE) return type ^ MIN_REF_TYPE; return type; } -static int (*tag_to_type)(int) = type_to_tag; +static int tag_to_type(int tag) +{ + if (tag == TAG_FLOAT) return T_FLOAT; + if (tag == TAG_TYPE) return T_TYPE; + if (tag <= MAX_TYPE) return tag ^ MIN_REF_TYPE; + return tag; +} /* Let's cram those bits... */ static void code_entry(int tag, INT64 num, struct encode_data *data) @@ -313,17 +326,19 @@ static void encode_type(struct pike_type *t, struct encode_data *data) { one_more_type: if (t->type == T_MANY) { - addchar(T_FUNCTION); + addchar(T_FUNCTION ^ MIN_REF_TYPE); addchar(T_MANY); } else if (t->type == T_STRING) { if (t->car == int_type_string) { - addchar(T_STRING); + addchar(T_STRING ^ MIN_REF_TYPE); } else { /* Narrow string */ addchar(PIKE_T_NSTRING); encode_type(t->car, data); } return; + } else if (t->type <= MAX_TYPE) { + addchar(t->type ^ MIN_REF_TYPE); } else { addchar(t->type); } @@ -2323,6 +2338,7 @@ static void low_decode_type(struct decode_data *data) SET_ONERROR(err2, restore_type_mark, Pike_compiler->pike_type_mark_stackp); tmp = GETC(); + if (tmp <= MAX_TYPE) tmp ^= MIN_REF_TYPE; switch(tmp) { default: diff --git a/src/gc.c b/src/gc.c index 80127be575eb40b52767b09582f22086135cc95d..d8cc7c206749d73a4def428bb36440cf2a85268d 100644 --- a/src/gc.c +++ b/src/gc.c @@ -4355,7 +4355,15 @@ PMOD_EXPORT visit_ref_cb *visit_ref = NULL; /* Be careful if extending this with internal types like * T_MAPPING_DATA and T_MULTISET_DATA; there's code that assumes * type_from_visit_fn only returns types that fit in a TYPE_FIELD. */ -PMOD_EXPORT visit_thing_fn *const visit_fn_from_type[MAX_REF_TYPE + 1] = { +PMOD_EXPORT visit_thing_fn *const visit_fn_from_type[MAX_TYPE + 1] = { + (visit_thing_fn *) (ptrdiff_t) -1, + (visit_thing_fn *) (ptrdiff_t) -1, + (visit_thing_fn *) (ptrdiff_t) -1, + (visit_thing_fn *) (ptrdiff_t) -1, + (visit_thing_fn *) (ptrdiff_t) -1, + (visit_thing_fn *) (ptrdiff_t) -1, + (visit_thing_fn *) (ptrdiff_t) -1, + (visit_thing_fn *) (ptrdiff_t) -1, (visit_thing_fn *) &visit_array, (visit_thing_fn *) &visit_mapping, (visit_thing_fn *) &visit_multiset, diff --git a/src/gc.h b/src/gc.h index 9695e63304306e14f190d23e38bf4909c582470d..99873d228453d59824121b7c7833e901df58d4fe 100644 --- a/src/gc.h +++ b/src/gc.h @@ -659,7 +659,7 @@ PMOD_EXPORT extern visit_ref_cb *visit_ref; * VISIT_COMPLEX_ONLY. */ /* Map between type and visit function for the standard ref types. */ -PMOD_EXPORT extern visit_thing_fn *const visit_fn_from_type[MAX_REF_TYPE + 1]; +PMOD_EXPORT extern visit_thing_fn *const visit_fn_from_type[MAX_TYPE + 1]; PMOD_EXPORT TYPE_T type_from_visit_fn (visit_thing_fn *fn); PMOD_EXPORT TYPE_FIELD real_visit_svalues (struct svalue *s, size_t num, diff --git a/src/pike_types.c b/src/pike_types.c index e06090385daa4f5d8f700ee96802c92705124a53..67d24d33d65079c74882ef852d11d3b9d1f4a8c1 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -8137,9 +8137,16 @@ static void low_make_function_type(unsigned char *type_string, static void low_make_pike_type(unsigned char *type_string, unsigned char **cont) { - unsigned INT32 type; + unsigned INT32 type = *type_string; - switch(type = *type_string) { + if (type <= MAX_TYPE) { + /* Remap from old type enumeration to + * keep compat with output from __parse_pike_type(). + */ + type ^= MIN_REF_TYPE; + } + + switch(type) { #ifdef PIKE_DEBUG case T_SCOPE: Pike_fatal("Not supported yet.\n"); @@ -8410,16 +8417,24 @@ static void low_type_to_string(struct pike_type *t) case T_ARRAY: case T_MULTISET: case T_TYPE: - case T_NOT: case T_PROGRAM: + my_putchar(t->type ^ MIN_REF_TYPE); + t = t->car; + goto recurse; + + case T_NOT: my_putchar(t->type); - /* FALL_THROUGH */ t = t->car; goto recurse; + case T_MAPPING: + my_putchar(t->type ^ MIN_REF_TYPE); + low_type_to_string(t->car); + t = t->cdr; + goto recurse; + case PIKE_T_RING: case T_TUPLE: - case T_MAPPING: case T_OR: case T_AND: my_putchar(t->type); @@ -8427,6 +8442,11 @@ static void low_type_to_string(struct pike_type *t) t = t->cdr; goto recurse; + case T_FLOAT: + case T_ZERO: + my_putchar(t->type ^ MIN_REF_TYPE); + break; + case '0': case '1': case '2': @@ -8437,8 +8457,6 @@ static void low_type_to_string(struct pike_type *t) case '7': case '8': case '9': - case T_FLOAT: - case T_ZERO: case T_VOID: case T_MIXED: my_putchar(t->type); @@ -8447,7 +8465,7 @@ static void low_type_to_string(struct pike_type *t) case T_OBJECT: { INT32 i; - my_putchar(T_OBJECT); + my_putchar(T_OBJECT ^ MIN_REF_TYPE); i = (INT32)CAR_TO_INT(t); my_putchar( i ); i = (INT32)CDR_TO_INT(t); @@ -8464,7 +8482,7 @@ static void low_type_to_string(struct pike_type *t) case T_STRING: { if (t->car == int_type_string) { - my_putchar(T_STRING); + my_putchar(T_STRING ^ MIN_REF_TYPE); } else { my_putchar(PIKE_T_NSTRING); low_type_to_string(t->car); @@ -8475,7 +8493,7 @@ static void low_type_to_string(struct pike_type *t) case T_INT: { INT32 i; - my_putchar(T_INT); + my_putchar(T_INT ^ MIN_REF_TYPE); i = (INT32)CAR_TO_INT(t); my_putchar((i >> 24) & 0xff); my_putchar((i >> 16) & 0xff); @@ -8491,7 +8509,7 @@ static void low_type_to_string(struct pike_type *t) case T_FUNCTION: case T_MANY: - my_putchar(T_FUNCTION); + my_putchar(T_FUNCTION ^ MIN_REF_TYPE); while(t->type == T_FUNCTION) { low_type_to_string(t->car); t = t->cdr; diff --git a/src/svalue.c b/src/svalue.c index 9e2fcf228555e2ba8ef8c3e3034b69159f49af72..39b1a8cc8f15452e3bd2b95c2eff60af74ef9c79 100644 --- a/src/svalue.c +++ b/src/svalue.c @@ -137,10 +137,13 @@ PMOD_EXPORT void really_free_svalue(struct svalue *s) case T_STRING: really_free_string(tmp.u.string); break; + + case PIKE_T_FREE: + break; #ifdef PIKE_DEBUG default: - Pike_fatal("Bad type in really_free_svalue.\n"); + Pike_fatal("Bad type in really_free_svalue: %d.\n", TYPEOF(tmp)); #endif } @@ -181,56 +184,6 @@ PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hin DOTYPE(BIT_OBJECT, free_object, object); DOTYPE(BIT_PROGRAM, free_program, program); - case 3: case 5: case 6: case 7: case 9: case 10: case 11: - case 12: case 13: case 14: case 15: case 17: case 18: case 19: - case 20: case 21: case 22: case 23: case 24: case 25: case 26: - case 27: case 28: case 29: case 30: case 31: case 33: case 34: - case 35: case 36: case 37: case 38: case 39: case 40: case 41: - case 42: case 43: case 44: case 45: case 46: case 47: case 48: - case 49: case 50: case 51: case 52: case 53: case 54: case 55: - case 56: case 57: case 58: case 59: case 60: case 61: case 62: - case 63: case 65: case 66: case 67: case 68: case 69: case 70: - case 71: case 72: case 73: case 74: case 75: case 76: case 77: - case 78: case 79: case 80: case 81: case 82: case 83: case 84: - case 85: case 86: case 87: case 88: case 89: case 90: case 91: - case 92: case 93: case 94: case 95: case 96: case 97: case 98: - case 99: case 100: case 101: case 102: case 103: case 104: case 105: - case 106: case 107: case 108: case 109: case 110: case 111: case 112: - case 113: case 114: case 115: case 116: case 117: case 118: case 119: - case 120: case 121: case 122: case 123: case 124: case 125: case 126: - case 127: case 129: case 130: case 131: case 132: case 133: case 134: - case 135: case 136: case 137: case 138: case 139: case 140: case 141: - case 142: case 143: case 144: case 145: case 146: case 147: case 148: - case 149: case 150: case 151: case 152: case 153: case 154: case 155: - case 156: case 157: case 158: case 159: case 160: case 161: case 162: - case 163: case 164: case 165: case 166: case 167: case 168: case 169: - case 170: case 171: case 172: case 173: case 174: case 175: case 176: - case 177: case 178: case 179: case 180: case 181: case 182: case 183: - case 184: case 185: case 186: case 187: case 188: case 189: case 190: - case 191: case 192: case 193: case 194: case 195: case 196: case 197: - case 198: case 199: case 200: case 201: case 202: case 203: case 204: - case 205: case 206: case 207: case 208: case 209: case 210: case 211: - case 212: case 213: case 214: case 215: case 216: case 217: case 218: - case 219: case 220: case 221: case 222: case 223: case 224: case 225: - case 226: case 227: case 228: case 229: case 230: case 231: case 232: - case 233: case 234: case 235: case 236: case 237: case 238: case 239: - case 240: case 241: case 242: case 243: case 244: case 245: case 246: - case 247: case 248: case 249: case 250: case 251: case 252: case 253: - case 254: case 255: - - while(num--) - { -#ifdef DEBUG_MALLOC - debug_malloc_update_location(s->u.refs DMALLOC_PROXY_ARGS); -#endif - if(!sub_ref(s->u.dummy)) - { - really_free_svalue(s); - } - s++; - } - break; - case BIT_FUNCTION: while(num--) { @@ -251,7 +204,8 @@ PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hin #undef DOTYPE default: - while(num--) + if (type_hint & (BIT_FLOAT | BIT_INT)) { + while(num--) { #ifdef DEBUG_MALLOC if(REFCOUNTED_TYPE(TYPEOF(*s))) @@ -259,6 +213,20 @@ PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hin #endif free_svalue(s++); } + } else { + while(num--) + { +#ifdef DEBUG_MALLOC + debug_malloc_update_location(s->u.refs DMALLOC_PROXY_ARGS); +#endif + if(!sub_ref(s->u.dummy)) + { + really_free_svalue(s); + } + s++; + } + } + break; } } @@ -2528,7 +2496,8 @@ void real_gc_free_svalue(struct svalue *s) Pike_in_gc != GC_PASS_ZAP_WEAK) Pike_fatal("gc_free_svalue() called in invalid gc pass.\n"); #endif - if (TYPEOF(*s) <= MAX_COMPLEX && *(s->u.refs) == 1) + if (REFCOUNTED_TYPE(TYPEOF(*s)) && TYPEOF(*s) <= MAX_COMPLEX && + *(s->u.refs) == 1) gc_delayed_free(s->u.refs, TYPEOF(*s)); } free_svalue(s); @@ -2542,7 +2511,7 @@ void real_gc_free_short_svalue(union anything *u, TYPE_T type) Pike_in_gc != GC_PASS_ZAP_WEAK) Pike_fatal("gc_free_short_svalue() called in invalid gc pass.\n"); #endif - if (type <= MAX_COMPLEX && *u->refs == 1) + if (REFCOUNTED_TYPE(type) && type <= MAX_COMPLEX && *u->refs == 1) gc_delayed_free(u->refs, type); } free_short_svalue(u, type); diff --git a/src/svalue.h b/src/svalue.h index 3a64a0e2702f47e9d24e6458cd017b861e5fe44e..b704b3860bf515c24ed6102f464c7baf70c47197 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -116,25 +116,33 @@ struct svalue */ #define INVALIDATE_SVAL(SVAL) SET_SVAL_TYPE(SVAL, 99) /* an invalid type */ -#define PIKE_T_ARRAY 0 -#define PIKE_T_MAPPING 1 -#define PIKE_T_MULTISET 2 -#define PIKE_T_OBJECT 3 -#define PIKE_T_FUNCTION 4 -#define PIKE_T_PROGRAM 5 -#define PIKE_T_STRING 6 -#define PIKE_T_TYPE 7 -#define PIKE_T_INT 8 -#define PIKE_T_FLOAT 9 +/* The native types. + * + * Note that PIKE_T_INT is zero so that cleared memory + * is filled with zeroes. + */ +#define PIKE_T_INT 0 +#define PIKE_T_FLOAT 1 + +/* NB: The reference counted types all have bit 4 set. */ +#define PIKE_T_ARRAY 8 +#define PIKE_T_MAPPING 9 +#define PIKE_T_MULTISET 10 +#define PIKE_T_OBJECT 11 +#define PIKE_T_FUNCTION 12 +#define PIKE_T_PROGRAM 13 +#define PIKE_T_STRING 14 +#define PIKE_T_TYPE 15 /* The types above are valid types in svalues. * The following are only used by the internal systems. */ -#define PIKE_T_ZERO 14 /**< Can return 0, but nothing else */ +/* NB: 6 & 7 below are selected for easy backward compat with Pike 7.8. */ +#define PIKE_T_ZERO 6 /**< Can return 0, but nothing else */ -#define T_UNFINISHED 15 +#define T_UNFINISHED 7 #define T_VOID 16 /**< Can't return any value. Also used on stack to fill out the second * svalue on an lvalue when it isn't used. */ @@ -200,6 +208,10 @@ struct svalue #define T_MULTISET_DATA 10003 #define T_STRUCT_CALLABLE 10004 +/* NOTE: The t* macros below currently use the old type encoding + * to be compatible with __parse_pike_type() in older + * versions of Pike. + */ #define tArr(VAL) "\000" VAL #define tArray tArr(tMix) #define tMap(IND,VAL) "\001" IND VAL @@ -325,7 +337,7 @@ struct svalue #define BIT_VOID (1 << T_VOID) /** This is used in typechecking to signify that the rest of the - * arguments has to be of this type. + * arguments have to be of this type. */ #define BIT_MANY (1 << T_MANY) @@ -338,12 +350,12 @@ struct svalue /* Max type which contains svalues */ #define MAX_COMPLEX PIKE_T_PROGRAM -/* Max type with ref count */ -#define MAX_REF_TYPE PIKE_T_TYPE +/* Min type with ref count */ +#define MIN_REF_TYPE PIKE_T_ARRAY /* Max type handled by svalue primitives */ -#define MAX_TYPE PIKE_T_FLOAT +#define MAX_TYPE PIKE_T_TYPE -#define REFCOUNTED_TYPE(T) ((T) <= MAX_REF_TYPE) +#define REFCOUNTED_TYPE(T) (((T) & ~(MIN_REF_TYPE - 1)) == MIN_REF_TYPE) #define NUMBER_NUMBER 0 #define NUMBER_UNDEFINED 1