diff options
Diffstat (limited to 'xdelta3')
-rw-r--r-- | xdelta3/Makefile | 9 | ||||
-rw-r--r-- | xdelta3/xdelta3-main.h | 27 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 49 |
3 files changed, 69 insertions, 16 deletions
diff --git a/xdelta3/Makefile b/xdelta3/Makefile index 19afc42..9c8b79e 100644 --- a/xdelta3/Makefile +++ b/xdelta3/Makefile | |||
@@ -218,8 +218,13 @@ xdelta3-everything: $(SOURCES) | |||
218 | -DXD3_DEBUG=1 -lm | 218 | -DXD3_DEBUG=1 -lm |
219 | 219 | ||
220 | xdelta3-Opg: $(SOURCES) | 220 | xdelta3-Opg: $(SOURCES) |
221 | $(CC) -pg -g -O -Wall -Wshadow xdelta3.c -o xdelta3-Opg -DXD3_MAIN=1 \ | 221 | $(CC) -pg -g -O3 -fno-builtin -Wall -Wshadow xdelta3.c -o xdelta3-Opg \ |
222 | -DSECONDARY_DJW=1 -DSECONDARY_FGK=1 -DXD3_POSIX=1 -DXD3_USE_LARGEFILE64=1 -DREGRESSION_TEST=1 | 222 | -DXD3_MAIN=1 \ |
223 | -DSECONDARY_DJW=1 \ | ||
224 | -DSECONDARY_FGK=1 \ | ||
225 | -DXD3_POSIX=1 \ | ||
226 | -DXD3_USE_LARGEFILE64=1 \ | ||
227 | -DREGRESSION_TEST=1 | ||
223 | 228 | ||
224 | xdelta3-nosec.o: $(SOURCES) | 229 | xdelta3-nosec.o: $(SOURCES) |
225 | $(CC) -O2 -Wall -Wshadow -c xdelta3.c -DSECONDARY_FGK=0 -DSECONDARY_DJW=0 -o xdelta3-nosec.o | 230 | $(CC) -O2 -Wall -Wshadow -c xdelta3.c -DSECONDARY_FGK=0 -DSECONDARY_DJW=0 -o xdelta3-nosec.o |
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h index 6be82dc..23133a3 100644 --- a/xdelta3/xdelta3-main.h +++ b/xdelta3/xdelta3-main.h | |||
@@ -1138,7 +1138,12 @@ main_print_window (xd3_stream* stream, main_file *xfile) | |||
1138 | 1138 | ||
1139 | while (stream->inst_sect.buf < stream->inst_sect.buf_max) | 1139 | while (stream->inst_sect.buf < stream->inst_sect.buf_max) |
1140 | { | 1140 | { |
1141 | uint code = stream->inst_sect.buf[0]; | 1141 | uint code = stream->inst_sect.buf[0]; |
1142 | const uint8_t *addr_before = stream->addr_sect.buf; | ||
1143 | const uint8_t *inst_before = stream->inst_sect.buf; | ||
1144 | usize_t addr_bytes; | ||
1145 | usize_t inst_bytes; | ||
1146 | usize_t size_before = size; | ||
1142 | 1147 | ||
1143 | if ((ret = xd3_decode_instruction (stream))) | 1148 | if ((ret = xd3_decode_instruction (stream))) |
1144 | { | 1149 | { |
@@ -1147,13 +1152,15 @@ main_print_window (xd3_stream* stream, main_file *xfile) | |||
1147 | return ret; | 1152 | return ret; |
1148 | } | 1153 | } |
1149 | 1154 | ||
1155 | addr_bytes = stream->addr_sect.buf - addr_before; | ||
1156 | inst_bytes = stream->inst_sect.buf - inst_before; | ||
1157 | |||
1150 | VC(UT " %06"Q"u %03u %s %3u", stream->dec_winstart + size, code, | 1158 | VC(UT " %06"Q"u %03u %s %3u", stream->dec_winstart + size, code, |
1151 | xd3_rtype_to_string (stream->dec_current1.type, option_print_cpymode), | 1159 | xd3_rtype_to_string (stream->dec_current1.type, option_print_cpymode), |
1152 | (usize_t) stream->dec_current1.size)VE; | 1160 | (usize_t) stream->dec_current1.size)VE; |
1153 | 1161 | ||
1154 | if (stream->dec_current1.type != XD3_NOOP) | 1162 | if (stream->dec_current1.type != XD3_NOOP) |
1155 | { | 1163 | { |
1156 | size += stream->dec_current1.size; | ||
1157 | if (stream->dec_current1.type >= XD3_CPY) | 1164 | if (stream->dec_current1.type >= XD3_CPY) |
1158 | { | 1165 | { |
1159 | VC(UT " @%-6u", (usize_t)stream->dec_current1.addr)VE; | 1166 | VC(UT " @%-6u", (usize_t)stream->dec_current1.addr)VE; |
@@ -1162,11 +1169,12 @@ main_print_window (xd3_stream* stream, main_file *xfile) | |||
1162 | { | 1169 | { |
1163 | VC(UT " ")VE; | 1170 | VC(UT " ")VE; |
1164 | } | 1171 | } |
1172 | |||
1173 | size += stream->dec_current1.size; | ||
1165 | } | 1174 | } |
1166 | 1175 | ||
1167 | if (stream->dec_current2.type != XD3_NOOP) | 1176 | if (stream->dec_current2.type != XD3_NOOP) |
1168 | { | 1177 | { |
1169 | size += stream->dec_current2.size; | ||
1170 | VC(UT " %s %3u", | 1178 | VC(UT " %s %3u", |
1171 | xd3_rtype_to_string (stream->dec_current2.type, | 1179 | xd3_rtype_to_string (stream->dec_current2.type, |
1172 | option_print_cpymode), | 1180 | option_print_cpymode), |
@@ -1176,9 +1184,22 @@ main_print_window (xd3_stream* stream, main_file *xfile) | |||
1176 | { | 1184 | { |
1177 | VC(UT " @%-6u", (usize_t)stream->dec_current2.addr)VE; | 1185 | VC(UT " @%-6u", (usize_t)stream->dec_current2.addr)VE; |
1178 | } | 1186 | } |
1187 | |||
1188 | size += stream->dec_current2.size; | ||
1179 | } | 1189 | } |
1180 | 1190 | ||
1181 | VC(UT "\n")VE; | 1191 | VC(UT "\n")VE; |
1192 | |||
1193 | if (option_verbose && | ||
1194 | addr_bytes + inst_bytes >= (size - size_before) && | ||
1195 | (stream->dec_current1.type >= XD3_CPY || | ||
1196 | stream->dec_current2.type >= XD3_CPY)) | ||
1197 | { | ||
1198 | VC(UT " %06"Q"u (inefficiency) %u encoded as %u bytes\n", | ||
1199 | stream->dec_winstart + size_before, | ||
1200 | size - size_before, | ||
1201 | addr_bytes + inst_bytes)VE; | ||
1202 | } | ||
1182 | } | 1203 | } |
1183 | 1204 | ||
1184 | if (stream->dec_tgtlen != size && (stream->flags & XD3_SKIP_WINDOW) == 0) | 1205 | if (stream->dec_tgtlen != size && (stream->flags & XD3_SKIP_WINDOW) == 0) |
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 197c7ed..cf2d224 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -968,7 +968,9 @@ xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl) | |||
968 | { | 968 | { |
969 | for (size1 = 1; size1 <= desc->addcopy_add_max; size1 += 1) | 969 | for (size1 = 1; size1 <= desc->addcopy_add_max; size1 += 1) |
970 | { | 970 | { |
971 | int max = (mode < 2 + desc->near_modes) ? desc->addcopy_near_cpy_max : desc->addcopy_same_cpy_max; | 971 | int max = (mode < 2 + desc->near_modes) ? |
972 | desc->addcopy_near_cpy_max : | ||
973 | desc->addcopy_same_cpy_max; | ||
972 | 974 | ||
973 | for (size2 = MIN_MATCH; size2 <= max; size2 += 1, d += 1) | 975 | for (size2 = MIN_MATCH; size2 <= max; size2 += 1, d += 1) |
974 | { | 976 | { |
@@ -982,7 +984,9 @@ xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl) | |||
982 | 984 | ||
983 | for (mode = 0; mode < cpy_modes; mode += 1) | 985 | for (mode = 0; mode < cpy_modes; mode += 1) |
984 | { | 986 | { |
985 | int max = (mode < 2 + desc->near_modes) ? desc->copyadd_near_cpy_max : desc->copyadd_same_cpy_max; | 987 | int max = (mode < 2 + desc->near_modes) ? |
988 | desc->copyadd_near_cpy_max : | ||
989 | desc->copyadd_same_cpy_max; | ||
986 | 990 | ||
987 | for (size1 = MIN_MATCH; size1 <= max; size1 += 1) | 991 | for (size1 = MIN_MATCH; size1 <= max; size1 += 1) |
988 | { | 992 | { |
@@ -1073,7 +1077,9 @@ xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_ri | |||
1073 | { | 1077 | { |
1074 | /* The second and third exprs are 0 in the | 1078 | /* The second and third exprs are 0 in the |
1075 | default table. */ | 1079 | default table. */ |
1076 | prev->code2 = sizes->offset + (sizes->mult * (prev->size - MIN_MATCH)) + (inst->size - MIN_ADD); | 1080 | prev->code2 = sizes->offset + |
1081 | (sizes->mult * (prev->size - MIN_MATCH)) + | ||
1082 | (inst->size - MIN_ADD); | ||
1077 | } | 1083 | } |
1078 | } | 1084 | } |
1079 | } | 1085 | } |
@@ -1105,7 +1111,9 @@ xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_ri | |||
1105 | 1111 | ||
1106 | if (inst->size <= sizes->cpy_max) | 1112 | if (inst->size <= sizes->cpy_max) |
1107 | { | 1113 | { |
1108 | prev->code2 = sizes->offset + (sizes->mult * (prev->size - MIN_ADD)) + (inst->size - MIN_MATCH); | 1114 | prev->code2 = sizes->offset + |
1115 | (sizes->mult * (prev->size - MIN_ADD)) + | ||
1116 | (inst->size - MIN_MATCH); | ||
1109 | } | 1117 | } |
1110 | } | 1118 | } |
1111 | } | 1119 | } |
@@ -1116,7 +1124,7 @@ xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_ri | |||
1116 | 1124 | ||
1117 | /* This version of xd3_choose_instruction is hard-coded for the default table. */ | 1125 | /* This version of xd3_choose_instruction is hard-coded for the default table. */ |
1118 | static void | 1126 | static void |
1119 | xd3_choose_instruction (/* const xd3_code_table_desc *desc,*/ xd3_rinst *prev, xd3_rinst *inst) | 1127 | xd3_choose_instruction (xd3_rinst *prev, xd3_rinst *inst) |
1120 | { | 1128 | { |
1121 | switch (inst->type) | 1129 | switch (inst->type) |
1122 | { | 1130 | { |
@@ -3121,9 +3129,12 @@ xd3_iopt_flush_instructions (xd3_stream *stream, int force) | |||
3121 | r2moff = r2end - r1end; | 3129 | r2moff = r2end - r1end; |
3122 | gap = r2end - r1->pos; | 3130 | gap = r2end - r1->pos; |
3123 | 3131 | ||
3124 | /* If the two matches overlap almost entirely, choose the better | 3132 | /* If the two matches overlap almost entirely, choose the better match |
3125 | * match and discard the other. This heuristic is BLACK MAGIC. | 3133 | * and discard the other. The else branch can still create inefficient |
3126 | * Havesomething better? */ | 3134 | * copies, e.g., a 4-byte copy that takes 4 bytes to encode, which |
3135 | * xd3_smatch() wouldn't allow by its crude efficiency check. However, | ||
3136 | * in this case there are adjacent copies which mean the add would cost | ||
3137 | * one extra byte. Allow the inefficiency here. */ | ||
3127 | if (gap < 2*MIN_MATCH || r2moff <= 2 || r2off <= 2) | 3138 | if (gap < 2*MIN_MATCH || r2moff <= 2 || r2off <= 2) |
3128 | { | 3139 | { |
3129 | /* Only one match should be used, choose the longer one. */ | 3140 | /* Only one match should be used, choose the longer one. */ |
@@ -4783,9 +4794,6 @@ xd3_check_smatch (const uint8_t *ref0, const uint8_t *inp0, | |||
4783 | * linked lists are in use (because stream->smatcher.small_chain > 1), | 4794 | * linked lists are in use (because stream->smatcher.small_chain > 1), |
4784 | * previous matches are tested searching for the longest match. If | 4795 | * previous matches are tested searching for the longest match. If |
4785 | * (stream->min_match > MIN_MATCH) then a lazy match is in effect. | 4796 | * (stream->min_match > MIN_MATCH) then a lazy match is in effect. |
4786 | * | ||
4787 | * TODO: This is the second most-expensive function, after | ||
4788 | * xd3_srcwin_move_point(). | ||
4789 | */ | 4797 | */ |
4790 | static usize_t | 4798 | static usize_t |
4791 | xd3_smatch (xd3_stream *stream, | 4799 | xd3_smatch (xd3_stream *stream, |
@@ -4872,6 +4880,25 @@ xd3_smatch (xd3_stream *stream, | |||
4872 | } | 4880 | } |
4873 | 4881 | ||
4874 | done: | 4882 | done: |
4883 | /* Crude efficiency test: if the match is very short and very far back, it's | ||
4884 | * unlikely to help, but the exact calculation requires knowing the state of | ||
4885 | * the address cache and adjacent instructions, which we can't do here. | ||
4886 | * Rather than encode a probably inefficient copy here and check it later | ||
4887 | * (which complicates the code a lot), do this: | ||
4888 | */ | ||
4889 | if (match_length == 4 && stream->input_position - (*match_offset) >= 1<<14) | ||
4890 | { | ||
4891 | /* It probably takes >2 bytes to encode an address >= 2^14 from here */ | ||
4892 | return 0; | ||
4893 | } | ||
4894 | if (match_length == 5 && stream->input_position - (*match_offset) >= 1<<21) | ||
4895 | { | ||
4896 | /* It probably takes >3 bytes to encode an address >= 2^21 from here */ | ||
4897 | return 0; | ||
4898 | } | ||
4899 | |||
4900 | /* It's unlikely that a window is large enough for the (match_length == 6 && | ||
4901 | * address >= 2^28) check */ | ||
4875 | return match_length; | 4902 | return match_length; |
4876 | } | 4903 | } |
4877 | 4904 | ||