Ticket #1341: diff
File diff, 4.3 KB (added by plobsing, 12 years ago) |
---|
-
src/pmc_freeze.c
264 264 /* preallocate freeze image for aggregates with this estimation */ 265 265 #define FREEZE_BYTES_PER_ITEM 9 266 266 267 /* macros/constants to handle packing/unpacking of PMC IDs and flags 268 * the 2 LSBs are used for flags, all other bits are used for PMC ID 269 */ 270 #define PackID_new(id, flags) (((UINTVAL)(id) * 4) | ((UINTVAL)(flags) & 3)) 271 #define PackID_get_PMCID(id) ((UINTVAL)(id) / 4) 272 #define PackID_set_PMCID(lv, id) (lv) = PackID_new((id), PackID_get_FLAGS(lv)) 273 #define PackID_get_FLAGS(id) ((UINTVAL)(id) & 3) 274 #define PackID_set_FLAGS(lv, flags) (lv) = PackID_new(PackID_get_PMCID(lv), (flags)) 275 276 enum { 277 enum_PackID_normal = 0, 278 enum_PackID_seen = 1, 279 enum_PackID_prev_type = 2, 280 enum_PackID_extra_info = 3 281 }; 282 267 283 /* 268 284 269 285 =head2 C<opcode_t> IO Functions … … 666 682 667 683 if (PMC_IS_NULL(pmc)) { 668 684 /* NULL + seen bit */ 669 VTABLE_push_pmc(interp, io, (PMC*) 1);685 VTABLE_push_pmc(interp, io, (PMC*)PackID_new(NULL, enum_PackID_seen)); 670 686 return; 671 687 } 672 688 … … 675 691 if (PObj_is_object_TEST(pmc)) 676 692 type = enum_class_Object; 677 693 678 /* TODO: get rid of these magic numbers; they look like pointer tags */679 694 if (seen) { 680 695 if (info->extra_flags) { 681 id |= 3;696 PackID_set_FLAGS(id, enum_PackID_extra_info); 682 697 VTABLE_push_pmc(interp, io, (PMC *)id); 683 698 VTABLE_push_integer(interp, io, info->extra_flags); 684 699 return; 685 700 } 686 701 687 id |= 1; /* mark bit 0 if this PMC is known */702 PackID_set_FLAGS(id, enum_PackID_seen); 688 703 } 689 704 else if (type == info->last_type) 690 id |= 2; /* mark bit 1 and don't write type */705 PackID_set_FLAGS(id, enum_PackID_prev_type); 691 706 692 707 VTABLE_push_pmc(interp, io, (PMC*)id); 693 708 694 if (! (id & 3)) { /* else write type */ 709 if (PackID_get_FLAGS(id) == enum_PackID_normal) { 710 /* write type */ 695 711 VTABLE_push_integer(interp, io, type); 696 712 info->last_type = type; 697 713 } … … 733 749 734 750 info->extra_flags = EXTRA_IS_NULL; 735 751 736 /* pmc has extra data */ 737 if (((UINTVAL) n & 3) == 3) { 752 switch (PackID_get_FLAGS(n)) { 753 case enum_PackID_extra_info: 754 /* pmc has extra data */ 738 755 info->extra_flags = VTABLE_shift_integer(interp, io); 739 } 740 741 /* seen PMCs have bit 0 set */ 742 else if ((UINTVAL) n & 1) { 756 break; 757 case enum_PackID_seen: 743 758 seen = 1; 744 } 745 746 /* prev PMC was same type */ 747 else if ((UINTVAL) n & 2) { 759 break; 760 case enum_PackID_prev_type: 761 /* prev PMC was same type */ 748 762 *type = info->last_type; 749 } 763 break; 764 default: 765 /* type follows */ 766 { 767 *type = VTABLE_shift_integer(interp, io); 768 info->last_type = *type; 750 769 751 /* type follows */ 752 else { 753 *type = VTABLE_shift_integer(interp, io); 754 info->last_type = *type; 770 if (*type <= 0) 771 Parrot_ex_throw_from_c_args(interp, NULL, 1, 772 "Unknown PMC type to thaw %d", (int) *type); 755 773 756 if (*type <= 0) 757 Parrot_ex_throw_from_c_args(interp, NULL, 1, 758 "Unknown PMC type to thaw %d", (int) *type); 759 760 /* that ought to be a class */ 761 if (*type >= interp->n_vtable_max || !interp->vtables[*type]) 762 *type = enum_class_Class; 774 /* that ought to be a class */ 775 if (*type >= interp->n_vtable_max || !interp->vtables[*type]) 776 *type = enum_class_Class; 777 } 778 break; 763 779 } 764 780 765 781 *id = (UINTVAL)n; … … 861 877 INTVAL type = 0; 862 878 int must_have_seen = thaw_pmc(interp, info, &id, &type); 863 879 864 id >>= 2;880 id = PackID_get_PMCID(id); 865 881 866 882 if (!id) { 867 883 /* got a NULL PMC */ … … 950 966 } 951 967 952 968 /* next id to freeze */ 953 info->id += 4; 969 info->id++; 970 *id = PackID_new(info->id, enum_PackID_normal); 954 971 955 *id = info->id;956 957 972 parrot_hash_put(interp, 958 973 (Hash *)VTABLE_get_pointer(interp, info->seen), pmc, (void *)*id); 959 974