rybakit / msgpack.php

A pure PHP implementation of the MessagePack serialization format / msgpack.org[PHP]
MIT License
388 stars 18 forks source link

Try unpacking without recursion #35

Closed rybakit closed 3 years ago

rybakit commented 3 years ago

This is an attempt to speed up unpacking by inlining the recursive unpack() calls. Unfortunately, it seems that this change makes unpacking not faster, but slower:

Opcache disabled:

MP_BENCH_TESTS='complex map' MP_BENCH_TARGETS=pure_bu php -n -dpcre.jit=1 tests/bench.php
master no_recursion
0.3763 0.5335

Opcache enabled:

MP_BENCH_TESTS='complex map' MP_BENCH_TARGETS=pure_bu php -n -dpcre.jit=1 -dzend_extension=opcache.so -dopcache.enable=1 -dopcache.enable_cli=1 tests/bench.php
master no_recursion
0.3193 0.4729

JIT enabled (tracing):

MP_BENCH_TESTS='complex map' MP_BENCH_TARGETS=pure_bu php -n -dpcre.jit=1 -dzend_extension=opcache.so -dopcache.jit_buffer_size=64M -dopcache.jit=tracing -dopcache.enable=1 -dopcache.enable_cli=1 tests/bench.php
master no_recursion
0.1133 0.2019

Opcodes:

 php -d opcache.opt_debug_level=0x20000 -dopcache.enable_cli=1 unpack.php
master ``` MessagePack\BufferUnpacker::unpack: ; (lines=530, args=0, vars=1, tmps=112) ; (after optimizer) ; .../msgpack.php/src/BufferUnpacker.php:181-280 0000 EXT_STMT 0001 T2 = FETCH_OBJ_R THIS string("offset") 0002 T1 = FETCH_OBJ_IS THIS string("buffer") 0003 T3 = ISSET_ISEMPTY_DIM_OBJ (isset) T1 T2 0004 T4 = BOOL_NOT T3 0005 JMPZ T4 0010 0006 EXT_STMT 0007 V5 = NEW 0 string("MessagePack\Exception\InsufficientDataException") 0008 DO_FCALL 0009 THROW V5 0010 EXT_STMT 0011 INIT_FCALL 1 96 string("ord") 0012 T8 = FETCH_OBJ_R THIS string("offset") 0013 T7 = FETCH_OBJ_R THIS string("buffer") 0014 T9 = FETCH_DIM_R T7 T8 0015 SEND_VAL T9 1 0016 V10 = DO_FCALL 0017 ASSIGN CV0($c) V10 0018 EXT_STMT 0019 PRE_INC_OBJ THIS string("offset") 0020 EXT_STMT 0021 T13 = IS_SMALLER_OR_EQUAL CV0($c) int(127) 0022 JMPZ T13 0025 0023 EXT_STMT 0024 RETURN CV0($c) 0025 EXT_STMT 0026 T14 = IS_SMALLER_OR_EQUAL int(160) CV0($c) 0027 T14 = JMPZ_EX T14 0030 0028 T15 = IS_SMALLER_OR_EQUAL CV0($c) int(191) 0029 T14 = BOOL T15 0030 JMPZ T14 0042 0031 EXT_STMT 0032 T16 = BW_AND CV0($c) int(31) 0033 JMPZ T16 0040 0034 INIT_METHOD_CALL 1 THIS string("read") 0035 T17 = BW_AND CV0($c) int(31) 0036 SEND_VAL_EX T17 1 0037 V18 = DO_FCALL 0038 T19 = QM_ASSIGN V18 0039 JMP 0041 0040 T19 = QM_ASSIGN string("") 0041 RETURN T19 0042 EXT_STMT 0043 T20 = IS_SMALLER_OR_EQUAL int(224) CV0($c) 0044 JMPZ T20 0048 0045 EXT_STMT 0046 T21 = SUB CV0($c) int(256) 0047 RETURN T21 0048 EXT_STMT 0049 SWITCH_LONG CV0($c) 192: 0177, 194: 0179, 195: 0181, 128: 0183, 129: 0185, 130: 0192, 131: 0204, 132: 0221, 133: 0226, 134: 0231, 135: 0236, 136: 0241, 137: 0246, 138: 0251, 139: 0256, 140: 0261, 141: 0266, 142: 0271, 143: 0276, 144: 0281, 145: 0283, 146: 0288, 147: 0296, 148: 0307, 149: 0312, 150: 0317, 151: 0322, 152: 0327, 153: 0332, 154: 0337, 155: 0342, 156: 0347, 157: 0352, 158: 0357, 159: 0362, 196: 0367, 197: 0374, 198: 0381, 202: 0388, 203: 0392, 204: 0396, 205: 0400, 206: 0404, 207: 0408, 208: 0412, 209: 0416, 210: 0420, 211: 0424, 217: 0428, 218: 0435, 219: 0442, 220: 0449, 221: 0456, 222: 0463, 223: 0470, 212: 0477, 213: 0482, 214: 0487, 215: 0492, 216: 0497, 199: 0502, 200: 0509, 201: 0516, default: 0523 0050 T22 = IS_EQUAL CV0($c) int(192) 0051 JMPNZ T22 0177 0052 T22 = IS_EQUAL CV0($c) int(194) 0053 JMPNZ T22 0179 0054 T22 = IS_EQUAL CV0($c) int(195) 0055 JMPNZ T22 0181 0056 T22 = IS_EQUAL CV0($c) int(128) 0057 JMPNZ T22 0183 0058 T22 = IS_EQUAL CV0($c) int(129) 0059 JMPNZ T22 0185 0060 T22 = IS_EQUAL CV0($c) int(130) 0061 JMPNZ T22 0192 0062 T22 = IS_EQUAL CV0($c) int(131) 0063 JMPNZ T22 0204 0064 T22 = IS_EQUAL CV0($c) int(132) 0065 JMPNZ T22 0221 0066 T22 = IS_EQUAL CV0($c) int(133) 0067 JMPNZ T22 0226 0068 T22 = IS_EQUAL CV0($c) int(134) 0069 JMPNZ T22 0231 0070 T22 = IS_EQUAL CV0($c) int(135) 0071 JMPNZ T22 0236 0072 T22 = IS_EQUAL CV0($c) int(136) 0073 JMPNZ T22 0241 0074 T22 = IS_EQUAL CV0($c) int(137) 0075 JMPNZ T22 0246 0076 T22 = IS_EQUAL CV0($c) int(138) 0077 JMPNZ T22 0251 0078 T22 = IS_EQUAL CV0($c) int(139) 0079 JMPNZ T22 0256 0080 T22 = IS_EQUAL CV0($c) int(140) 0081 JMPNZ T22 0261 0082 T22 = IS_EQUAL CV0($c) int(141) 0083 JMPNZ T22 0266 0084 T22 = IS_EQUAL CV0($c) int(142) 0085 JMPNZ T22 0271 0086 T22 = IS_EQUAL CV0($c) int(143) 0087 JMPNZ T22 0276 0088 T22 = IS_EQUAL CV0($c) int(144) 0089 JMPNZ T22 0281 0090 T22 = IS_EQUAL CV0($c) int(145) 0091 JMPNZ T22 0283 0092 T22 = IS_EQUAL CV0($c) int(146) 0093 JMPNZ T22 0288 0094 T22 = IS_EQUAL CV0($c) int(147) 0095 JMPNZ T22 0296 0096 T22 = IS_EQUAL CV0($c) int(148) 0097 JMPNZ T22 0307 0098 T22 = IS_EQUAL CV0($c) int(149) 0099 JMPNZ T22 0312 0100 T22 = IS_EQUAL CV0($c) int(150) 0101 JMPNZ T22 0317 0102 T22 = IS_EQUAL CV0($c) int(151) 0103 JMPNZ T22 0322 0104 T22 = IS_EQUAL CV0($c) int(152) 0105 JMPNZ T22 0327 0106 T22 = IS_EQUAL CV0($c) int(153) 0107 JMPNZ T22 0332 0108 T22 = IS_EQUAL CV0($c) int(154) 0109 JMPNZ T22 0337 0110 T22 = IS_EQUAL CV0($c) int(155) 0111 JMPNZ T22 0342 0112 T22 = IS_EQUAL CV0($c) int(156) 0113 JMPNZ T22 0347 0114 T22 = IS_EQUAL CV0($c) int(157) 0115 JMPNZ T22 0352 0116 T22 = IS_EQUAL CV0($c) int(158) 0117 JMPNZ T22 0357 0118 T22 = IS_EQUAL CV0($c) int(159) 0119 JMPNZ T22 0362 0120 T22 = IS_EQUAL CV0($c) int(196) 0121 JMPNZ T22 0367 0122 T22 = IS_EQUAL CV0($c) int(197) 0123 JMPNZ T22 0374 0124 T22 = IS_EQUAL CV0($c) int(198) 0125 JMPNZ T22 0381 0126 T22 = IS_EQUAL CV0($c) int(202) 0127 JMPNZ T22 0388 0128 T22 = IS_EQUAL CV0($c) int(203) 0129 JMPNZ T22 0392 0130 T22 = IS_EQUAL CV0($c) int(204) 0131 JMPNZ T22 0396 0132 T22 = IS_EQUAL CV0($c) int(205) 0133 JMPNZ T22 0400 0134 T22 = IS_EQUAL CV0($c) int(206) 0135 JMPNZ T22 0404 0136 T22 = IS_EQUAL CV0($c) int(207) 0137 JMPNZ T22 0408 0138 T22 = IS_EQUAL CV0($c) int(208) 0139 JMPNZ T22 0412 0140 T22 = IS_EQUAL CV0($c) int(209) 0141 JMPNZ T22 0416 0142 T22 = IS_EQUAL CV0($c) int(210) 0143 JMPNZ T22 0420 0144 T22 = IS_EQUAL CV0($c) int(211) 0145 JMPNZ T22 0424 0146 T22 = IS_EQUAL CV0($c) int(217) 0147 JMPNZ T22 0428 0148 T22 = IS_EQUAL CV0($c) int(218) 0149 JMPNZ T22 0435 0150 T22 = IS_EQUAL CV0($c) int(219) 0151 JMPNZ T22 0442 0152 T22 = IS_EQUAL CV0($c) int(220) 0153 JMPNZ T22 0449 0154 T22 = IS_EQUAL CV0($c) int(221) 0155 JMPNZ T22 0456 0156 T22 = IS_EQUAL CV0($c) int(222) 0157 JMPNZ T22 0463 0158 T22 = IS_EQUAL CV0($c) int(223) 0159 JMPNZ T22 0470 0160 T22 = IS_EQUAL CV0($c) int(212) 0161 JMPNZ T22 0477 0162 T22 = IS_EQUAL CV0($c) int(213) 0163 JMPNZ T22 0482 0164 T22 = IS_EQUAL CV0($c) int(214) 0165 JMPNZ T22 0487 0166 T22 = IS_EQUAL CV0($c) int(215) 0167 JMPNZ T22 0492 0168 T22 = IS_EQUAL CV0($c) int(216) 0169 JMPNZ T22 0497 0170 T22 = IS_EQUAL CV0($c) int(199) 0171 JMPNZ T22 0502 0172 T22 = IS_EQUAL CV0($c) int(200) 0173 JMPNZ T22 0509 0174 T22 = IS_EQUAL CV0($c) int(201) 0175 JMPNZ T22 0516 0176 JMP 0523 0177 EXT_STMT 0178 RETURN null 0179 EXT_STMT 0180 RETURN bool(false) 0181 EXT_STMT 0182 RETURN bool(true) 0183 EXT_STMT 0184 RETURN array(...) 0185 EXT_STMT 0186 INIT_METHOD_CALL 0 THIS string("unpackMapKey") 0187 V23 = DO_FCALL 0188 INIT_METHOD_CALL 0 THIS string("unpack") 0189 V24 = DO_FCALL 0190 T25 = INIT_ARRAY 1 (packed) V24 V23 0191 RETURN T25 0192 EXT_STMT 0193 INIT_METHOD_CALL 0 THIS string("unpackMapKey") 0194 V26 = DO_FCALL 0195 INIT_METHOD_CALL 0 THIS string("unpack") 0196 V27 = DO_FCALL 0197 T28 = INIT_ARRAY 2 (packed) V27 V26 0198 INIT_METHOD_CALL 0 THIS string("unpackMapKey") 0199 V29 = DO_FCALL 0200 INIT_METHOD_CALL 0 THIS string("unpack") 0201 V30 = DO_FCALL 0202 T28 = ADD_ARRAY_ELEMENT V30 V29 0203 RETURN T28 0204 EXT_STMT 0205 INIT_METHOD_CALL 0 THIS string("unpackMapKey") 0206 V31 = DO_FCALL 0207 INIT_METHOD_CALL 0 THIS string("unpack") 0208 V32 = DO_FCALL 0209 T33 = INIT_ARRAY 3 (packed) V32 V31 0210 INIT_METHOD_CALL 0 THIS string("unpackMapKey") 0211 V34 = DO_FCALL 0212 INIT_METHOD_CALL 0 THIS string("unpack") 0213 V35 = DO_FCALL 0214 T33 = ADD_ARRAY_ELEMENT V35 V34 0215 INIT_METHOD_CALL 0 THIS string("unpackMapKey") 0216 V36 = DO_FCALL 0217 INIT_METHOD_CALL 0 THIS string("unpack") 0218 V37 = DO_FCALL 0219 T33 = ADD_ARRAY_ELEMENT V37 V36 0220 RETURN T33 0221 EXT_STMT 0222 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0223 SEND_VAL_EX int(4) 1 0224 V38 = DO_FCALL 0225 RETURN V38 0226 EXT_STMT 0227 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0228 SEND_VAL_EX int(5) 1 0229 V39 = DO_FCALL 0230 RETURN V39 0231 EXT_STMT 0232 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0233 SEND_VAL_EX int(6) 1 0234 V40 = DO_FCALL 0235 RETURN V40 0236 EXT_STMT 0237 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0238 SEND_VAL_EX int(7) 1 0239 V41 = DO_FCALL 0240 RETURN V41 0241 EXT_STMT 0242 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0243 SEND_VAL_EX int(8) 1 0244 V42 = DO_FCALL 0245 RETURN V42 0246 EXT_STMT 0247 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0248 SEND_VAL_EX int(9) 1 0249 V43 = DO_FCALL 0250 RETURN V43 0251 EXT_STMT 0252 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0253 SEND_VAL_EX int(10) 1 0254 V44 = DO_FCALL 0255 RETURN V44 0256 EXT_STMT 0257 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0258 SEND_VAL_EX int(11) 1 0259 V45 = DO_FCALL 0260 RETURN V45 0261 EXT_STMT 0262 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0263 SEND_VAL_EX int(12) 1 0264 V46 = DO_FCALL 0265 RETURN V46 0266 EXT_STMT 0267 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0268 SEND_VAL_EX int(13) 1 0269 V47 = DO_FCALL 0270 RETURN V47 0271 EXT_STMT 0272 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0273 SEND_VAL_EX int(14) 1 0274 V48 = DO_FCALL 0275 RETURN V48 0276 EXT_STMT 0277 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0278 SEND_VAL_EX int(15) 1 0279 V49 = DO_FCALL 0280 RETURN V49 0281 EXT_STMT 0282 RETURN array(...) 0283 EXT_STMT 0284 INIT_METHOD_CALL 0 THIS string("unpack") 0285 V50 = DO_FCALL 0286 T51 = INIT_ARRAY 1 (packed) V50 NEXT 0287 RETURN T51 0288 EXT_STMT 0289 INIT_METHOD_CALL 0 THIS string("unpack") 0290 V52 = DO_FCALL 0291 T53 = INIT_ARRAY 2 (packed) V52 NEXT 0292 INIT_METHOD_CALL 0 THIS string("unpack") 0293 V54 = DO_FCALL 0294 T53 = ADD_ARRAY_ELEMENT V54 NEXT 0295 RETURN T53 0296 EXT_STMT 0297 INIT_METHOD_CALL 0 THIS string("unpack") 0298 V55 = DO_FCALL 0299 T56 = INIT_ARRAY 3 (packed) V55 NEXT 0300 INIT_METHOD_CALL 0 THIS string("unpack") 0301 V57 = DO_FCALL 0302 T56 = ADD_ARRAY_ELEMENT V57 NEXT 0303 INIT_METHOD_CALL 0 THIS string("unpack") 0304 V58 = DO_FCALL 0305 T56 = ADD_ARRAY_ELEMENT V58 NEXT 0306 RETURN T56 0307 EXT_STMT 0308 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0309 SEND_VAL_EX int(4) 1 0310 V59 = DO_FCALL 0311 RETURN V59 0312 EXT_STMT 0313 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0314 SEND_VAL_EX int(5) 1 0315 V60 = DO_FCALL 0316 RETURN V60 0317 EXT_STMT 0318 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0319 SEND_VAL_EX int(6) 1 0320 V61 = DO_FCALL 0321 RETURN V61 0322 EXT_STMT 0323 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0324 SEND_VAL_EX int(7) 1 0325 V62 = DO_FCALL 0326 RETURN V62 0327 EXT_STMT 0328 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0329 SEND_VAL_EX int(8) 1 0330 V63 = DO_FCALL 0331 RETURN V63 0332 EXT_STMT 0333 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0334 SEND_VAL_EX int(9) 1 0335 V64 = DO_FCALL 0336 RETURN V64 0337 EXT_STMT 0338 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0339 SEND_VAL_EX int(10) 1 0340 V65 = DO_FCALL 0341 RETURN V65 0342 EXT_STMT 0343 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0344 SEND_VAL_EX int(11) 1 0345 V66 = DO_FCALL 0346 RETURN V66 0347 EXT_STMT 0348 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0349 SEND_VAL_EX int(12) 1 0350 V67 = DO_FCALL 0351 RETURN V67 0352 EXT_STMT 0353 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0354 SEND_VAL_EX int(13) 1 0355 V68 = DO_FCALL 0356 RETURN V68 0357 EXT_STMT 0358 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0359 SEND_VAL_EX int(14) 1 0360 V69 = DO_FCALL 0361 RETURN V69 0362 EXT_STMT 0363 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0364 SEND_VAL_EX int(15) 1 0365 V70 = DO_FCALL 0366 RETURN V70 0367 EXT_STMT 0368 INIT_METHOD_CALL 1 THIS string("read") 0369 INIT_METHOD_CALL 0 THIS string("unpackUint8") 0370 V71 = DO_FCALL 0371 SEND_VAR_NO_REF_EX V71 1 0372 V72 = DO_FCALL 0373 RETURN V72 0374 EXT_STMT 0375 INIT_METHOD_CALL 1 THIS string("read") 0376 INIT_METHOD_CALL 0 THIS string("unpackUint16") 0377 V73 = DO_FCALL 0378 SEND_VAR_NO_REF_EX V73 1 0379 V74 = DO_FCALL 0380 RETURN V74 0381 EXT_STMT 0382 INIT_METHOD_CALL 1 THIS string("read") 0383 INIT_METHOD_CALL 0 THIS string("unpackUint32") 0384 V75 = DO_FCALL 0385 SEND_VAR_NO_REF_EX V75 1 0386 V76 = DO_FCALL 0387 RETURN V76 0388 EXT_STMT 0389 INIT_METHOD_CALL 0 THIS string("unpackFloat32") 0390 V77 = DO_FCALL 0391 RETURN V77 0392 EXT_STMT 0393 INIT_METHOD_CALL 0 THIS string("unpackFloat64") 0394 V78 = DO_FCALL 0395 RETURN V78 0396 EXT_STMT 0397 INIT_METHOD_CALL 0 THIS string("unpackUint8") 0398 V79 = DO_FCALL 0399 RETURN V79 0400 EXT_STMT 0401 INIT_METHOD_CALL 0 THIS string("unpackUint16") 0402 V80 = DO_FCALL 0403 RETURN V80 0404 EXT_STMT 0405 INIT_METHOD_CALL 0 THIS string("unpackUint32") 0406 V81 = DO_FCALL 0407 RETURN V81 0408 EXT_STMT 0409 INIT_METHOD_CALL 0 THIS string("unpackUint64") 0410 V82 = DO_FCALL 0411 RETURN V82 0412 EXT_STMT 0413 INIT_METHOD_CALL 0 THIS string("unpackInt8") 0414 V83 = DO_FCALL 0415 RETURN V83 0416 EXT_STMT 0417 INIT_METHOD_CALL 0 THIS string("unpackInt16") 0418 V84 = DO_FCALL 0419 RETURN V84 0420 EXT_STMT 0421 INIT_METHOD_CALL 0 THIS string("unpackInt32") 0422 V85 = DO_FCALL 0423 RETURN V85 0424 EXT_STMT 0425 INIT_METHOD_CALL 0 THIS string("unpackInt64") 0426 V86 = DO_FCALL 0427 RETURN V86 0428 EXT_STMT 0429 INIT_METHOD_CALL 1 THIS string("read") 0430 INIT_METHOD_CALL 0 THIS string("unpackUint8") 0431 V87 = DO_FCALL 0432 SEND_VAR_NO_REF_EX V87 1 0433 V88 = DO_FCALL 0434 RETURN V88 0435 EXT_STMT 0436 INIT_METHOD_CALL 1 THIS string("read") 0437 INIT_METHOD_CALL 0 THIS string("unpackUint16") 0438 V89 = DO_FCALL 0439 SEND_VAR_NO_REF_EX V89 1 0440 V90 = DO_FCALL 0441 RETURN V90 0442 EXT_STMT 0443 INIT_METHOD_CALL 1 THIS string("read") 0444 INIT_METHOD_CALL 0 THIS string("unpackUint32") 0445 V91 = DO_FCALL 0446 SEND_VAR_NO_REF_EX V91 1 0447 V92 = DO_FCALL 0448 RETURN V92 0449 EXT_STMT 0450 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0451 INIT_METHOD_CALL 0 THIS string("unpackUint16") 0452 V93 = DO_FCALL 0453 SEND_VAR_NO_REF_EX V93 1 0454 V94 = DO_FCALL 0455 RETURN V94 0456 EXT_STMT 0457 INIT_METHOD_CALL 1 THIS string("unpackArrayData") 0458 INIT_METHOD_CALL 0 THIS string("unpackUint32") 0459 V95 = DO_FCALL 0460 SEND_VAR_NO_REF_EX V95 1 0461 V96 = DO_FCALL 0462 RETURN V96 0463 EXT_STMT 0464 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0465 INIT_METHOD_CALL 0 THIS string("unpackUint16") 0466 V97 = DO_FCALL 0467 SEND_VAR_NO_REF_EX V97 1 0468 V98 = DO_FCALL 0469 RETURN V98 0470 EXT_STMT 0471 INIT_METHOD_CALL 1 THIS string("unpackMapData") 0472 INIT_METHOD_CALL 0 THIS string("unpackUint32") 0473 V99 = DO_FCALL 0474 SEND_VAR_NO_REF_EX V99 1 0475 V100 = DO_FCALL 0476 RETURN V100 0477 EXT_STMT 0478 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0479 SEND_VAL_EX int(1) 1 0480 V101 = DO_FCALL 0481 RETURN V101 0482 EXT_STMT 0483 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0484 SEND_VAL_EX int(2) 1 0485 V102 = DO_FCALL 0486 RETURN V102 0487 EXT_STMT 0488 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0489 SEND_VAL_EX int(4) 1 0490 V103 = DO_FCALL 0491 RETURN V103 0492 EXT_STMT 0493 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0494 SEND_VAL_EX int(8) 1 0495 V104 = DO_FCALL 0496 RETURN V104 0497 EXT_STMT 0498 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0499 SEND_VAL_EX int(16) 1 0500 V105 = DO_FCALL 0501 RETURN V105 0502 EXT_STMT 0503 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0504 INIT_METHOD_CALL 0 THIS string("unpackUint8") 0505 V106 = DO_FCALL 0506 SEND_VAR_NO_REF_EX V106 1 0507 V107 = DO_FCALL 0508 RETURN V107 0509 EXT_STMT 0510 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0511 INIT_METHOD_CALL 0 THIS string("unpackUint16") 0512 V108 = DO_FCALL 0513 SEND_VAR_NO_REF_EX V108 1 0514 V109 = DO_FCALL 0515 RETURN V109 0516 EXT_STMT 0517 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0518 INIT_METHOD_CALL 0 THIS string("unpackUint32") 0519 V110 = DO_FCALL 0520 SEND_VAR_NO_REF_EX V110 1 0521 V111 = DO_FCALL 0522 RETURN V111 0523 EXT_STMT 0524 INIT_STATIC_METHOD_CALL 1 string("MessagePack\Exception\UnpackingFailedException") string("unknownCode") 0525 SEND_VAR_EX CV0($c) 1 0526 V112 = DO_FCALL 0527 THROW V112 0528 EXT_STMT 0529 RETURN null ```
no_recursion ``` MessagePack\BufferUnpacker4::unpack: ; (lines=844, args=0, vars=8, tmps=256) ; (after optimizer) ; .../msgpack.php/src/BufferUnpacker.php:182-342 0000 EXT_STMT 0001 V8 = FETCH_OBJ_W (ref) THIS string("buffer") 0002 ASSIGN_REF CV0($buffer) V8 0003 EXT_STMT 0004 V10 = FETCH_OBJ_W (ref) THIS string("offset") 0005 ASSIGN_REF CV1($offset) V10 0006 EXT_STMT 0007 ASSIGN CV2($stack) array(...) 0008 EXT_STMT 0009 ASSIGN CV3($top) int(0) 0010 EXT_STMT 0011 T14 = ISSET_ISEMPTY_DIM_OBJ (isset) CV0($buffer) CV1($offset) 0012 T15 = BOOL_NOT T14 0013 JMPZ T15 0018 0014 EXT_STMT 0015 V16 = NEW 0 string("MessagePack\Exception\InsufficientDataException") 0016 DO_FCALL 0017 THROW V16 0018 EXT_STMT 0019 INIT_FCALL 1 96 string("ord") 0020 T18 = FETCH_DIM_R CV0($buffer) CV1($offset) 0021 SEND_VAL T18 1 0022 V19 = DO_FCALL 0023 ASSIGN CV4($c) V19 0024 EXT_STMT 0025 PRE_INC CV1($offset) 0026 EXT_STMT 0027 T22 = IS_SMALLER_OR_EQUAL CV4($c) int(127) 0028 JMPZ T22 0033 0029 EXT_STMT 0030 ASSIGN CV5($value) CV4($c) 0031 EXT_STMT 0032 JMP 0782 0033 EXT_STMT 0034 T24 = IS_SMALLER_OR_EQUAL int(160) CV4($c) 0035 T24 = JMPZ_EX T24 0038 0036 T25 = IS_SMALLER_OR_EQUAL CV4($c) int(191) 0037 T24 = BOOL T25 0038 JMPZ T24 0051 0039 EXT_STMT 0040 T26 = BW_AND CV4($c) int(31) 0041 JMPZ T26 0047 0042 EXT_STMT 0043 T27 = BW_AND CV4($c) int(31) 0044 ASSIGN CV6($length) T27 0045 EXT_STMT 0046 JMP 0763 0047 EXT_STMT 0048 ASSIGN CV5($value) string("") 0049 EXT_STMT 0050 JMP 0782 0051 EXT_STMT 0052 T30 = IS_SMALLER_OR_EQUAL int(224) CV4($c) 0053 JMPZ T30 0059 0054 EXT_STMT 0055 T31 = SUB CV4($c) int(256) 0056 ASSIGN CV5($value) T31 0057 EXT_STMT 0058 JMP 0782 0059 EXT_STMT 0060 SWITCH_LONG CV4($c) 192: 0188, 194: 0192, 195: 0196, 128: 0200, 129: 0204, 130: 0214, 131: 0224, 132: 0234, 133: 0244, 134: 0254, 135: 0264, 136: 0274, 137: 0284, 138: 0294, 139: 0304, 140: 0314, 141: 0324, 142: 0334, 143: 0344, 144: 0354, 145: 0358, 146: 0368, 147: 0378, 148: 0388, 149: 0398, 150: 0408, 151: 0418, 152: 0428, 153: 0438, 154: 0448, 155: 0458, 156: 0468, 157: 0478, 158: 0488, 159: 0498, 196: 0508, 197: 0516, 198: 0524, 202: 0532, 203: 0540, 204: 0548, 205: 0556, 206: 0564, 207: 0572, 208: 0578, 209: 0586, 210: 0594, 211: 0602, 217: 0610, 218: 0618, 219: 0626, 220: 0634, 221: 0648, 222: 0662, 223: 0676, 212: 0690, 213: 0697, 214: 0704, 215: 0711, 216: 0718, 199: 0725, 200: 0736, 201: 0747, default: 0758 0061 T33 = IS_EQUAL CV4($c) int(192) 0062 JMPNZ T33 0188 0063 T33 = IS_EQUAL CV4($c) int(194) 0064 JMPNZ T33 0192 0065 T33 = IS_EQUAL CV4($c) int(195) 0066 JMPNZ T33 0196 0067 T33 = IS_EQUAL CV4($c) int(128) 0068 JMPNZ T33 0200 0069 T33 = IS_EQUAL CV4($c) int(129) 0070 JMPNZ T33 0204 0071 T33 = IS_EQUAL CV4($c) int(130) 0072 JMPNZ T33 0214 0073 T33 = IS_EQUAL CV4($c) int(131) 0074 JMPNZ T33 0224 0075 T33 = IS_EQUAL CV4($c) int(132) 0076 JMPNZ T33 0234 0077 T33 = IS_EQUAL CV4($c) int(133) 0078 JMPNZ T33 0244 0079 T33 = IS_EQUAL CV4($c) int(134) 0080 JMPNZ T33 0254 0081 T33 = IS_EQUAL CV4($c) int(135) 0082 JMPNZ T33 0264 0083 T33 = IS_EQUAL CV4($c) int(136) 0084 JMPNZ T33 0274 0085 T33 = IS_EQUAL CV4($c) int(137) 0086 JMPNZ T33 0284 0087 T33 = IS_EQUAL CV4($c) int(138) 0088 JMPNZ T33 0294 0089 T33 = IS_EQUAL CV4($c) int(139) 0090 JMPNZ T33 0304 0091 T33 = IS_EQUAL CV4($c) int(140) 0092 JMPNZ T33 0314 0093 T33 = IS_EQUAL CV4($c) int(141) 0094 JMPNZ T33 0324 0095 T33 = IS_EQUAL CV4($c) int(142) 0096 JMPNZ T33 0334 0097 T33 = IS_EQUAL CV4($c) int(143) 0098 JMPNZ T33 0344 0099 T33 = IS_EQUAL CV4($c) int(144) 0100 JMPNZ T33 0354 0101 T33 = IS_EQUAL CV4($c) int(145) 0102 JMPNZ T33 0358 0103 T33 = IS_EQUAL CV4($c) int(146) 0104 JMPNZ T33 0368 0105 T33 = IS_EQUAL CV4($c) int(147) 0106 JMPNZ T33 0378 0107 T33 = IS_EQUAL CV4($c) int(148) 0108 JMPNZ T33 0388 0109 T33 = IS_EQUAL CV4($c) int(149) 0110 JMPNZ T33 0398 0111 T33 = IS_EQUAL CV4($c) int(150) 0112 JMPNZ T33 0408 0113 T33 = IS_EQUAL CV4($c) int(151) 0114 JMPNZ T33 0418 0115 T33 = IS_EQUAL CV4($c) int(152) 0116 JMPNZ T33 0428 0117 T33 = IS_EQUAL CV4($c) int(153) 0118 JMPNZ T33 0438 0119 T33 = IS_EQUAL CV4($c) int(154) 0120 JMPNZ T33 0448 0121 T33 = IS_EQUAL CV4($c) int(155) 0122 JMPNZ T33 0458 0123 T33 = IS_EQUAL CV4($c) int(156) 0124 JMPNZ T33 0468 0125 T33 = IS_EQUAL CV4($c) int(157) 0126 JMPNZ T33 0478 0127 T33 = IS_EQUAL CV4($c) int(158) 0128 JMPNZ T33 0488 0129 T33 = IS_EQUAL CV4($c) int(159) 0130 JMPNZ T33 0498 0131 T33 = IS_EQUAL CV4($c) int(196) 0132 JMPNZ T33 0508 0133 T33 = IS_EQUAL CV4($c) int(197) 0134 JMPNZ T33 0516 0135 T33 = IS_EQUAL CV4($c) int(198) 0136 JMPNZ T33 0524 0137 T33 = IS_EQUAL CV4($c) int(202) 0138 JMPNZ T33 0532 0139 T33 = IS_EQUAL CV4($c) int(203) 0140 JMPNZ T33 0540 0141 T33 = IS_EQUAL CV4($c) int(204) 0142 JMPNZ T33 0548 0143 T33 = IS_EQUAL CV4($c) int(205) 0144 JMPNZ T33 0556 0145 T33 = IS_EQUAL CV4($c) int(206) 0146 JMPNZ T33 0564 0147 T33 = IS_EQUAL CV4($c) int(207) 0148 JMPNZ T33 0572 0149 T33 = IS_EQUAL CV4($c) int(208) 0150 JMPNZ T33 0578 0151 T33 = IS_EQUAL CV4($c) int(209) 0152 JMPNZ T33 0586 0153 T33 = IS_EQUAL CV4($c) int(210) 0154 JMPNZ T33 0594 0155 T33 = IS_EQUAL CV4($c) int(211) 0156 JMPNZ T33 0602 0157 T33 = IS_EQUAL CV4($c) int(217) 0158 JMPNZ T33 0610 0159 T33 = IS_EQUAL CV4($c) int(218) 0160 JMPNZ T33 0618 0161 T33 = IS_EQUAL CV4($c) int(219) 0162 JMPNZ T33 0626 0163 T33 = IS_EQUAL CV4($c) int(220) 0164 JMPNZ T33 0634 0165 T33 = IS_EQUAL CV4($c) int(221) 0166 JMPNZ T33 0648 0167 T33 = IS_EQUAL CV4($c) int(222) 0168 JMPNZ T33 0662 0169 T33 = IS_EQUAL CV4($c) int(223) 0170 JMPNZ T33 0676 0171 T33 = IS_EQUAL CV4($c) int(212) 0172 JMPNZ T33 0690 0173 T33 = IS_EQUAL CV4($c) int(213) 0174 JMPNZ T33 0697 0175 T33 = IS_EQUAL CV4($c) int(214) 0176 JMPNZ T33 0704 0177 T33 = IS_EQUAL CV4($c) int(215) 0178 JMPNZ T33 0711 0179 T33 = IS_EQUAL CV4($c) int(216) 0180 JMPNZ T33 0718 0181 T33 = IS_EQUAL CV4($c) int(199) 0182 JMPNZ T33 0725 0183 T33 = IS_EQUAL CV4($c) int(200) 0184 JMPNZ T33 0736 0185 T33 = IS_EQUAL CV4($c) int(201) 0186 JMPNZ T33 0747 0187 JMP 0758 0188 EXT_STMT 0189 ASSIGN CV5($value) null 0190 EXT_STMT 0191 JMP 0782 0192 EXT_STMT 0193 ASSIGN CV5($value) bool(false) 0194 EXT_STMT 0195 JMP 0782 0196 EXT_STMT 0197 ASSIGN CV5($value) bool(true) 0198 EXT_STMT 0199 JMP 0782 0200 EXT_STMT 0201 ASSIGN CV5($value) array(...) 0202 EXT_STMT 0203 JMP 0782 0204 EXT_STMT 0205 T38 = PRE_INC CV3($top) 0206 V40 = NEW 2 string("MessagePack\State") 0207 SEND_VAL_EX int(2) 1 0208 SEND_VAL_EX int(1) 2 0209 DO_FCALL 0210 ASSIGN_DIM CV2($stack) T38 0211 OP_DATA V40 0212 EXT_STMT 0213 JMP 0010 0214 EXT_STMT 0215 T42 = PRE_INC CV3($top) 0216 V44 = NEW 2 string("MessagePack\State") 0217 SEND_VAL_EX int(2) 1 0218 SEND_VAL_EX int(2) 2 0219 DO_FCALL 0220 ASSIGN_DIM CV2($stack) T42 0221 OP_DATA V44 0222 EXT_STMT 0223 JMP 0010 0224 EXT_STMT 0225 T46 = PRE_INC CV3($top) 0226 V48 = NEW 2 string("MessagePack\State") 0227 SEND_VAL_EX int(2) 1 0228 SEND_VAL_EX int(3) 2 0229 DO_FCALL 0230 ASSIGN_DIM CV2($stack) T46 0231 OP_DATA V48 0232 EXT_STMT 0233 JMP 0010 0234 EXT_STMT 0235 T50 = PRE_INC CV3($top) 0236 V52 = NEW 2 string("MessagePack\State") 0237 SEND_VAL_EX int(2) 1 0238 SEND_VAL_EX int(4) 2 0239 DO_FCALL 0240 ASSIGN_DIM CV2($stack) T50 0241 OP_DATA V52 0242 EXT_STMT 0243 JMP 0010 0244 EXT_STMT 0245 T54 = PRE_INC CV3($top) 0246 V56 = NEW 2 string("MessagePack\State") 0247 SEND_VAL_EX int(2) 1 0248 SEND_VAL_EX int(5) 2 0249 DO_FCALL 0250 ASSIGN_DIM CV2($stack) T54 0251 OP_DATA V56 0252 EXT_STMT 0253 JMP 0010 0254 EXT_STMT 0255 T58 = PRE_INC CV3($top) 0256 V60 = NEW 2 string("MessagePack\State") 0257 SEND_VAL_EX int(2) 1 0258 SEND_VAL_EX int(6) 2 0259 DO_FCALL 0260 ASSIGN_DIM CV2($stack) T58 0261 OP_DATA V60 0262 EXT_STMT 0263 JMP 0010 0264 EXT_STMT 0265 T62 = PRE_INC CV3($top) 0266 V64 = NEW 2 string("MessagePack\State") 0267 SEND_VAL_EX int(2) 1 0268 SEND_VAL_EX int(7) 2 0269 DO_FCALL 0270 ASSIGN_DIM CV2($stack) T62 0271 OP_DATA V64 0272 EXT_STMT 0273 JMP 0010 0274 EXT_STMT 0275 T66 = PRE_INC CV3($top) 0276 V68 = NEW 2 string("MessagePack\State") 0277 SEND_VAL_EX int(2) 1 0278 SEND_VAL_EX int(8) 2 0279 DO_FCALL 0280 ASSIGN_DIM CV2($stack) T66 0281 OP_DATA V68 0282 EXT_STMT 0283 JMP 0010 0284 EXT_STMT 0285 T70 = PRE_INC CV3($top) 0286 V72 = NEW 2 string("MessagePack\State") 0287 SEND_VAL_EX int(2) 1 0288 SEND_VAL_EX int(9) 2 0289 DO_FCALL 0290 ASSIGN_DIM CV2($stack) T70 0291 OP_DATA V72 0292 EXT_STMT 0293 JMP 0010 0294 EXT_STMT 0295 T74 = PRE_INC CV3($top) 0296 V76 = NEW 2 string("MessagePack\State") 0297 SEND_VAL_EX int(2) 1 0298 SEND_VAL_EX int(10) 2 0299 DO_FCALL 0300 ASSIGN_DIM CV2($stack) T74 0301 OP_DATA V76 0302 EXT_STMT 0303 JMP 0010 0304 EXT_STMT 0305 T78 = PRE_INC CV3($top) 0306 V80 = NEW 2 string("MessagePack\State") 0307 SEND_VAL_EX int(2) 1 0308 SEND_VAL_EX int(11) 2 0309 DO_FCALL 0310 ASSIGN_DIM CV2($stack) T78 0311 OP_DATA V80 0312 EXT_STMT 0313 JMP 0010 0314 EXT_STMT 0315 T82 = PRE_INC CV3($top) 0316 V84 = NEW 2 string("MessagePack\State") 0317 SEND_VAL_EX int(2) 1 0318 SEND_VAL_EX int(12) 2 0319 DO_FCALL 0320 ASSIGN_DIM CV2($stack) T82 0321 OP_DATA V84 0322 EXT_STMT 0323 JMP 0010 0324 EXT_STMT 0325 T86 = PRE_INC CV3($top) 0326 V88 = NEW 2 string("MessagePack\State") 0327 SEND_VAL_EX int(2) 1 0328 SEND_VAL_EX int(13) 2 0329 DO_FCALL 0330 ASSIGN_DIM CV2($stack) T86 0331 OP_DATA V88 0332 EXT_STMT 0333 JMP 0010 0334 EXT_STMT 0335 T90 = PRE_INC CV3($top) 0336 V92 = NEW 2 string("MessagePack\State") 0337 SEND_VAL_EX int(2) 1 0338 SEND_VAL_EX int(14) 2 0339 DO_FCALL 0340 ASSIGN_DIM CV2($stack) T90 0341 OP_DATA V92 0342 EXT_STMT 0343 JMP 0010 0344 EXT_STMT 0345 T94 = PRE_INC CV3($top) 0346 V96 = NEW 2 string("MessagePack\State") 0347 SEND_VAL_EX int(2) 1 0348 SEND_VAL_EX int(15) 2 0349 DO_FCALL 0350 ASSIGN_DIM CV2($stack) T94 0351 OP_DATA V96 0352 EXT_STMT 0353 JMP 0010 0354 EXT_STMT 0355 ASSIGN CV5($value) array(...) 0356 EXT_STMT 0357 JMP 0782 0358 EXT_STMT 0359 T99 = PRE_INC CV3($top) 0360 V101 = NEW 2 string("MessagePack\State") 0361 SEND_VAL_EX int(1) 1 0362 SEND_VAL_EX int(1) 2 0363 DO_FCALL 0364 ASSIGN_DIM CV2($stack) T99 0365 OP_DATA V101 0366 EXT_STMT 0367 JMP 0010 0368 EXT_STMT 0369 T103 = PRE_INC CV3($top) 0370 V105 = NEW 2 string("MessagePack\State") 0371 SEND_VAL_EX int(1) 1 0372 SEND_VAL_EX int(2) 2 0373 DO_FCALL 0374 ASSIGN_DIM CV2($stack) T103 0375 OP_DATA V105 0376 EXT_STMT 0377 JMP 0010 0378 EXT_STMT 0379 T107 = PRE_INC CV3($top) 0380 V109 = NEW 2 string("MessagePack\State") 0381 SEND_VAL_EX int(1) 1 0382 SEND_VAL_EX int(3) 2 0383 DO_FCALL 0384 ASSIGN_DIM CV2($stack) T107 0385 OP_DATA V109 0386 EXT_STMT 0387 JMP 0010 0388 EXT_STMT 0389 T111 = PRE_INC CV3($top) 0390 V113 = NEW 2 string("MessagePack\State") 0391 SEND_VAL_EX int(1) 1 0392 SEND_VAL_EX int(4) 2 0393 DO_FCALL 0394 ASSIGN_DIM CV2($stack) T111 0395 OP_DATA V113 0396 EXT_STMT 0397 JMP 0010 0398 EXT_STMT 0399 T115 = PRE_INC CV3($top) 0400 V117 = NEW 2 string("MessagePack\State") 0401 SEND_VAL_EX int(1) 1 0402 SEND_VAL_EX int(5) 2 0403 DO_FCALL 0404 ASSIGN_DIM CV2($stack) T115 0405 OP_DATA V117 0406 EXT_STMT 0407 JMP 0010 0408 EXT_STMT 0409 T119 = PRE_INC CV3($top) 0410 V121 = NEW 2 string("MessagePack\State") 0411 SEND_VAL_EX int(1) 1 0412 SEND_VAL_EX int(6) 2 0413 DO_FCALL 0414 ASSIGN_DIM CV2($stack) T119 0415 OP_DATA V121 0416 EXT_STMT 0417 JMP 0010 0418 EXT_STMT 0419 T123 = PRE_INC CV3($top) 0420 V125 = NEW 2 string("MessagePack\State") 0421 SEND_VAL_EX int(1) 1 0422 SEND_VAL_EX int(7) 2 0423 DO_FCALL 0424 ASSIGN_DIM CV2($stack) T123 0425 OP_DATA V125 0426 EXT_STMT 0427 JMP 0010 0428 EXT_STMT 0429 T127 = PRE_INC CV3($top) 0430 V129 = NEW 2 string("MessagePack\State") 0431 SEND_VAL_EX int(1) 1 0432 SEND_VAL_EX int(8) 2 0433 DO_FCALL 0434 ASSIGN_DIM CV2($stack) T127 0435 OP_DATA V129 0436 EXT_STMT 0437 JMP 0010 0438 EXT_STMT 0439 T131 = PRE_INC CV3($top) 0440 V133 = NEW 2 string("MessagePack\State") 0441 SEND_VAL_EX int(1) 1 0442 SEND_VAL_EX int(9) 2 0443 DO_FCALL 0444 ASSIGN_DIM CV2($stack) T131 0445 OP_DATA V133 0446 EXT_STMT 0447 JMP 0010 0448 EXT_STMT 0449 T135 = PRE_INC CV3($top) 0450 V137 = NEW 2 string("MessagePack\State") 0451 SEND_VAL_EX int(1) 1 0452 SEND_VAL_EX int(10) 2 0453 DO_FCALL 0454 ASSIGN_DIM CV2($stack) T135 0455 OP_DATA V137 0456 EXT_STMT 0457 JMP 0010 0458 EXT_STMT 0459 T139 = PRE_INC CV3($top) 0460 V141 = NEW 2 string("MessagePack\State") 0461 SEND_VAL_EX int(1) 1 0462 SEND_VAL_EX int(11) 2 0463 DO_FCALL 0464 ASSIGN_DIM CV2($stack) T139 0465 OP_DATA V141 0466 EXT_STMT 0467 JMP 0010 0468 EXT_STMT 0469 T143 = PRE_INC CV3($top) 0470 V145 = NEW 2 string("MessagePack\State") 0471 SEND_VAL_EX int(1) 1 0472 SEND_VAL_EX int(12) 2 0473 DO_FCALL 0474 ASSIGN_DIM CV2($stack) T143 0475 OP_DATA V145 0476 EXT_STMT 0477 JMP 0010 0478 EXT_STMT 0479 T147 = PRE_INC CV3($top) 0480 V149 = NEW 2 string("MessagePack\State") 0481 SEND_VAL_EX int(1) 1 0482 SEND_VAL_EX int(13) 2 0483 DO_FCALL 0484 ASSIGN_DIM CV2($stack) T147 0485 OP_DATA V149 0486 EXT_STMT 0487 JMP 0010 0488 EXT_STMT 0489 T151 = PRE_INC CV3($top) 0490 V153 = NEW 2 string("MessagePack\State") 0491 SEND_VAL_EX int(1) 1 0492 SEND_VAL_EX int(14) 2 0493 DO_FCALL 0494 ASSIGN_DIM CV2($stack) T151 0495 OP_DATA V153 0496 EXT_STMT 0497 JMP 0010 0498 EXT_STMT 0499 T155 = PRE_INC CV3($top) 0500 V157 = NEW 2 string("MessagePack\State") 0501 SEND_VAL_EX int(1) 1 0502 SEND_VAL_EX int(15) 2 0503 DO_FCALL 0504 ASSIGN_DIM CV2($stack) T155 0505 OP_DATA V157 0506 EXT_STMT 0507 JMP 0010 0508 EXT_STMT 0509 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint8") 0510 SEND_VAR_EX CV0($buffer) 1 0511 SEND_VAR_EX CV1($offset) 2 0512 V159 = DO_FCALL 0513 ASSIGN CV6($length) V159 0514 EXT_STMT 0515 JMP 0763 0516 EXT_STMT 0517 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint16") 0518 SEND_VAR_EX CV0($buffer) 1 0519 SEND_VAR_EX CV1($offset) 2 0520 V161 = DO_FCALL 0521 ASSIGN CV6($length) V161 0522 EXT_STMT 0523 JMP 0763 0524 EXT_STMT 0525 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint32") 0526 SEND_VAR_EX CV0($buffer) 1 0527 SEND_VAR_EX CV1($offset) 2 0528 V163 = DO_FCALL 0529 ASSIGN CV6($length) V163 0530 EXT_STMT 0531 JMP 0763 0532 EXT_STMT 0533 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackFloat32") 0534 SEND_VAR_EX CV0($buffer) 1 0535 SEND_VAR_EX CV1($offset) 2 0536 V165 = DO_FCALL 0537 ASSIGN CV5($value) V165 0538 EXT_STMT 0539 JMP 0782 0540 EXT_STMT 0541 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackFloat64") 0542 SEND_VAR_EX CV0($buffer) 1 0543 SEND_VAR_EX CV1($offset) 2 0544 V167 = DO_FCALL 0545 ASSIGN CV5($value) V167 0546 EXT_STMT 0547 JMP 0782 0548 EXT_STMT 0549 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint8") 0550 SEND_VAR_EX CV0($buffer) 1 0551 SEND_VAR_EX CV1($offset) 2 0552 V169 = DO_FCALL 0553 ASSIGN CV5($value) V169 0554 EXT_STMT 0555 JMP 0782 0556 EXT_STMT 0557 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint16") 0558 SEND_VAR_EX CV0($buffer) 1 0559 SEND_VAR_EX CV1($offset) 2 0560 V171 = DO_FCALL 0561 ASSIGN CV5($value) V171 0562 EXT_STMT 0563 JMP 0782 0564 EXT_STMT 0565 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint32") 0566 SEND_VAR_EX CV0($buffer) 1 0567 SEND_VAR_EX CV1($offset) 2 0568 V173 = DO_FCALL 0569 ASSIGN CV5($value) V173 0570 EXT_STMT 0571 JMP 0782 0572 EXT_STMT 0573 INIT_METHOD_CALL 0 THIS string("unpackUint64") 0574 V175 = DO_FCALL 0575 ASSIGN CV5($value) V175 0576 EXT_STMT 0577 JMP 0782 0578 EXT_STMT 0579 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackInt8") 0580 SEND_VAR_EX CV0($buffer) 1 0581 SEND_VAR_EX CV1($offset) 2 0582 V177 = DO_FCALL 0583 ASSIGN CV5($value) V177 0584 EXT_STMT 0585 JMP 0782 0586 EXT_STMT 0587 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackInt16") 0588 SEND_VAR_EX CV0($buffer) 1 0589 SEND_VAR_EX CV1($offset) 2 0590 V179 = DO_FCALL 0591 ASSIGN CV5($value) V179 0592 EXT_STMT 0593 JMP 0782 0594 EXT_STMT 0595 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackInt32") 0596 SEND_VAR_EX CV0($buffer) 1 0597 SEND_VAR_EX CV1($offset) 2 0598 V181 = DO_FCALL 0599 ASSIGN CV5($value) V181 0600 EXT_STMT 0601 JMP 0782 0602 EXT_STMT 0603 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackInt64") 0604 SEND_VAR_EX CV0($buffer) 1 0605 SEND_VAR_EX CV1($offset) 2 0606 V183 = DO_FCALL 0607 ASSIGN CV5($value) V183 0608 EXT_STMT 0609 JMP 0782 0610 EXT_STMT 0611 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint8") 0612 SEND_VAR_EX CV0($buffer) 1 0613 SEND_VAR_EX CV1($offset) 2 0614 V185 = DO_FCALL 0615 ASSIGN CV6($length) V185 0616 EXT_STMT 0617 JMP 0763 0618 EXT_STMT 0619 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint16") 0620 SEND_VAR_EX CV0($buffer) 1 0621 SEND_VAR_EX CV1($offset) 2 0622 V187 = DO_FCALL 0623 ASSIGN CV6($length) V187 0624 EXT_STMT 0625 JMP 0763 0626 EXT_STMT 0627 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint32") 0628 SEND_VAR_EX CV0($buffer) 1 0629 SEND_VAR_EX CV1($offset) 2 0630 V189 = DO_FCALL 0631 ASSIGN CV6($length) V189 0632 EXT_STMT 0633 JMP 0763 0634 EXT_STMT 0635 T191 = PRE_INC CV3($top) 0636 V193 = NEW 2 string("MessagePack\State") 0637 SEND_VAL_EX int(1) 1 0638 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint16") 0639 SEND_VAR_EX CV0($buffer) 1 0640 SEND_VAR_EX CV1($offset) 2 0641 V194 = DO_FCALL 0642 SEND_VAR_NO_REF_EX V194 2 0643 DO_FCALL 0644 ASSIGN_DIM CV2($stack) T191 0645 OP_DATA V193 0646 EXT_STMT 0647 JMP 0010 0648 EXT_STMT 0649 T196 = PRE_INC CV3($top) 0650 V198 = NEW 2 string("MessagePack\State") 0651 SEND_VAL_EX int(1) 1 0652 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint32") 0653 SEND_VAR_EX CV0($buffer) 1 0654 SEND_VAR_EX CV1($offset) 2 0655 V199 = DO_FCALL 0656 SEND_VAR_NO_REF_EX V199 2 0657 DO_FCALL 0658 ASSIGN_DIM CV2($stack) T196 0659 OP_DATA V198 0660 EXT_STMT 0661 JMP 0010 0662 EXT_STMT 0663 T201 = PRE_INC CV3($top) 0664 V203 = NEW 2 string("MessagePack\State") 0665 SEND_VAL_EX int(2) 1 0666 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint16") 0667 SEND_VAR_EX CV0($buffer) 1 0668 SEND_VAR_EX CV1($offset) 2 0669 V204 = DO_FCALL 0670 SEND_VAR_NO_REF_EX V204 2 0671 DO_FCALL 0672 ASSIGN_DIM CV2($stack) T201 0673 OP_DATA V203 0674 EXT_STMT 0675 JMP 0010 0676 EXT_STMT 0677 T206 = PRE_INC CV3($top) 0678 V208 = NEW 2 string("MessagePack\State") 0679 SEND_VAL_EX int(2) 1 0680 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint32") 0681 SEND_VAR_EX CV0($buffer) 1 0682 SEND_VAR_EX CV1($offset) 2 0683 V209 = DO_FCALL 0684 SEND_VAR_NO_REF_EX V209 2 0685 DO_FCALL 0686 ASSIGN_DIM CV2($stack) T206 0687 OP_DATA V208 0688 EXT_STMT 0689 JMP 0010 0690 EXT_STMT 0691 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0692 SEND_VAL_EX int(1) 1 0693 V211 = DO_FCALL 0694 ASSIGN CV5($value) V211 0695 EXT_STMT 0696 JMP 0782 0697 EXT_STMT 0698 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0699 SEND_VAL_EX int(2) 1 0700 V213 = DO_FCALL 0701 ASSIGN CV5($value) V213 0702 EXT_STMT 0703 JMP 0782 0704 EXT_STMT 0705 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0706 SEND_VAL_EX int(4) 1 0707 V215 = DO_FCALL 0708 ASSIGN CV5($value) V215 0709 EXT_STMT 0710 JMP 0782 0711 EXT_STMT 0712 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0713 SEND_VAL_EX int(8) 1 0714 V217 = DO_FCALL 0715 ASSIGN CV5($value) V217 0716 EXT_STMT 0717 JMP 0782 0718 EXT_STMT 0719 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0720 SEND_VAL_EX int(16) 1 0721 V219 = DO_FCALL 0722 ASSIGN CV5($value) V219 0723 EXT_STMT 0724 JMP 0782 0725 EXT_STMT 0726 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0727 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint8") 0728 SEND_VAR_EX CV0($buffer) 1 0729 SEND_VAR_EX CV1($offset) 2 0730 V221 = DO_FCALL 0731 SEND_VAR_NO_REF_EX V221 1 0732 V222 = DO_FCALL 0733 ASSIGN CV5($value) V222 0734 EXT_STMT 0735 JMP 0782 0736 EXT_STMT 0737 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0738 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint16") 0739 SEND_VAR_EX CV0($buffer) 1 0740 SEND_VAR_EX CV1($offset) 2 0741 V224 = DO_FCALL 0742 SEND_VAR_NO_REF_EX V224 1 0743 V225 = DO_FCALL 0744 ASSIGN CV5($value) V225 0745 EXT_STMT 0746 JMP 0782 0747 EXT_STMT 0748 INIT_METHOD_CALL 1 THIS string("unpackExtData") 0749 INIT_STATIC_METHOD_CALL 2 (self) (exception) string("unpackUint32") 0750 SEND_VAR_EX CV0($buffer) 1 0751 SEND_VAR_EX CV1($offset) 2 0752 V227 = DO_FCALL 0753 SEND_VAR_NO_REF_EX V227 1 0754 V228 = DO_FCALL 0755 ASSIGN CV5($value) V228 0756 EXT_STMT 0757 JMP 0782 0758 EXT_STMT 0759 INIT_STATIC_METHOD_CALL 1 string("MessagePack\Exception\UnpackingFailedException") string("unknownCode") 0760 SEND_VAR_EX CV4($c) 1 0761 V230 = DO_FCALL 0762 THROW V230 0763 EXT_STMT 0764 T231 = ADD CV1($offset) CV6($length) 0765 T232 = SUB T231 int(1) 0766 T233 = ISSET_ISEMPTY_DIM_OBJ (isset) CV0($buffer) T232 0767 T234 = BOOL_NOT T233 0768 JMPZ T234 0773 0769 EXT_STMT 0770 V235 = NEW 0 string("MessagePack\Exception\InsufficientDataException") 0771 DO_FCALL 0772 THROW V235 0773 EXT_STMT 0774 INIT_FCALL 3 128 string("substr") 0775 SEND_VAR CV0($buffer) 1 0776 SEND_VAR CV1($offset) 2 0777 SEND_VAR CV6($length) 3 0778 V237 = DO_FCALL 0779 ASSIGN CV5($value) V237 0780 EXT_STMT 0781 ASSIGN_OP (ADD) CV1($offset) CV6($length) 0782 EXT_STMT 0783 JMP 0839 0784 EXT_STMT 0785 T240 = FETCH_DIM_R CV2($stack) CV3($top) 0786 ASSIGN CV7($state) T240 0787 EXT_STMT 0788 T242 = FETCH_OBJ_R CV7($state) string("type") 0789 T243 = IS_IDENTICAL T242 int(1) 0790 JMPZ T243 0798 0791 EXT_STMT 0792 V244 = FETCH_OBJ_W (dim write) CV7($state) string("value") 0793 ASSIGN_DIM V244 NEXT 0794 OP_DATA CV5($value) 0795 EXT_STMT 0796 PRE_INC_OBJ CV7($state) string("count") 0797 JMP 0825 0798 EXT_STMT 0799 T247 = FETCH_OBJ_R CV7($state) string("type") 0800 T248 = IS_IDENTICAL T247 int(2) 0801 JMPZ T248 0811 0802 EXT_STMT 0803 ASSIGN_OBJ CV7($state) string("type") 0804 OP_DATA int(3) 0805 EXT_STMT 0806 ASSIGN_OBJ CV7($state) string("key") 0807 OP_DATA CV5($value) 0808 EXT_STMT 0809 JMP 0010 0810 JMP 0825 0811 EXT_STMT 0812 T251 = FETCH_OBJ_R CV7($state) string("type") 0813 T252 = IS_IDENTICAL T251 int(3) 0814 JMPZ T252 0825 0815 EXT_STMT 0816 ASSIGN_OBJ CV7($state) string("type") 0817 OP_DATA int(2) 0818 EXT_STMT 0819 T255 = FETCH_OBJ_R CV7($state) string("key") 0820 V254 = FETCH_OBJ_W (dim write) CV7($state) string("value") 0821 ASSIGN_DIM V254 T255 0822 OP_DATA CV5($value) 0823 EXT_STMT 0824 PRE_INC_OBJ CV7($state) string("count") 0825 EXT_STMT 0826 T258 = FETCH_OBJ_R CV7($state) string("size") 0827 T259 = FETCH_OBJ_R CV7($state) string("count") 0828 T260 = IS_NOT_IDENTICAL T258 T259 0829 JMPZ T260 0832 0830 EXT_STMT 0831 JMP 0010 0832 EXT_STMT 0833 UNSET_DIM CV2($stack) CV3($top) 0834 EXT_STMT 0835 PRE_DEC CV3($top) 0836 EXT_STMT 0837 T262 = FETCH_OBJ_R CV7($state) string("value") 0838 ASSIGN CV5($value) T262 0839 JMPNZ CV2($stack) 0784 0840 EXT_STMT 0841 RETURN CV5($value) 0842 EXT_STMT 0843 RETURN null ```
rybakit commented 3 years ago

Funny thing is that @blackfireio shows that "no_recursion" is faster than "master", which is the opposite of the benchmark results shown above :scream::

Opcache disabled:

MP_BENCH_TESTS='complex map' MP_BENCH_TARGETS=pure_bu blackfire run php -n -dextension=blackfire.so -dpcre.jit=1 tests/bench.php
master no_recursion
1m 1s 38.3

Opcache enabled:

MP_BENCH_TESTS='complex map' MP_BENCH_TARGETS=pure_bu blackfire run php -n -dextension=blackfire.so -dpcre.jit=1 -dzend_extension=opcache.so -dopcache.enable=1 -dopcache.enable_cli=1 tests/bench.php
master no_recursion
53.6 37.9
beberlei commented 3 years ago

You need to do -dopcache.enable_cli=1 on the CLi otherwise it will not be enabled.

In addition it might be that Blackfire cauess the JIT to be never be enabled, unless it already implements the Zend Observer API that is new in PHP 8, see https://github.com/php/php-src/commit/d5a82e2c4eebe8337ff7790db46d812af2fbcec9

beberlei commented 3 years ago

Oh sorry, i see that you pass opcache.enable_cli=1, my first skim i thought it wasnt passed.

rybakit commented 3 years ago

In addition it might be that Blackfire cauess the JIT to be never be enabled,

@beberlei As you may see above, I ran Blackfire with JIT and Opcache disabled, so AFAIU the issue you referenced should be irrelevant to my case (in both runs Blackfire incorrectly reports that "no_recursion" is faster than "master").

beberlei commented 3 years ago

Right, i should read more before writing :-)

In that case its probably related to profiling skew/overhead, timing a function takes significant time itself, so every code calling a lot of functions (especially if they are fast) vs code that is calling a lot less functions will be relatively slower, even if its faster without profiling. The only way to compare that code fairly with a Profiler is using a sampling profiler, so that both code variants are under roughly the same profiling overhead. See https://www.mediawiki.org/wiki/Excimer

rybakit commented 3 years ago

That's what I thought too. Another thing that I find strange in Blackfare reports is that 25% of the time is spent on ord(), however, I don't even expect to see it with Opcache enabled, because it is a "compiled" function. So Opcache seems to be ignored?

See https://www.mediawiki.org/wiki/Excimer

Thanks for the link, I will study it!

beberlei commented 3 years ago

Not necessarily, extensions can disable the special compilation of functions by setting the compiler_options to not compile special builtins: https://github.com/php/php-src/blob/PHP-8.0/Zend/zend_compile.c#L4207

rybakit commented 3 years ago

Here are the Excimer reports:

MP_BENCH_ITERATIONS=500000 MP_BENCH_TESTS='complex map' MP_BENCH_TARGETS=pure_bu php -n -dpcre.jit=1 -dzend_extension=opcache.so -dopcache.enable=1 -dopcache.enable_cli=1 -dextension=excimer.so tests/exbench.php

master msgpack_master

Function                                                                                  Self      Inclusive
MessagePack\Tests\Perf\Runner::run                                                           0          57327
/home/gen/develop/msgpack.php/tests/exbench.php                                              0          57327
MessagePack\Tests\Perf\Benchmark\FilterableBenchmark::benchmark                              0          57318
MessagePack\Tests\Perf\Benchmark\PausableBenchmark::benchmark                                0          57308
MessagePack\Tests\Perf\Benchmark\IterationBenchmark::benchmark                               0          57308
MessagePack\Tests\Perf\Benchmark\AverageableBenchmark::benchmark                             0          57308
MessagePack\Tests\Perf\Benchmark\IterationBenchmark::measurePerform                       1924          56494
MessagePack\Tests\Perf\Target\BufferUnpackerTarget::perform                                329          54570
MessagePack\BufferUnpacker::unpack                                                       25547          53205
MessagePack\BufferUnpacker::unpackMapData                                                 5925          50670
MessagePack\BufferUnpacker::unpackMapKey                                                 11016          17906
MessagePack\BufferUnpacker::read                                                          3827           3827
MessagePack\BufferUnpacker::unpackUint32                                                  3671           3671
MessagePack\BufferUnpacker::unpackUint64                                                  3219           3219
MessagePack\Tests\Perf\Test::getPacked                                                    1054           1054
MessagePack\Tests\Perf\Benchmark\IterationBenchmark::measureOverhead                       369            814
MessagePack\Tests\Perf\Target\BufferUnpackerTarget::calibrate                              209            445
MessagePack\BufferUnpacker::reset                                                          218            218
MessagePack\Tests\Perf\Filter\ListFilter::isAccepted                                        10             10
MessagePack\Tests\Perf\Writer\TableWriter::write                                             9              9

no_recursion

msgpack_unpack_wo_recursion

Function                                                                                  Self      Inclusive
MessagePack\Tests\Perf\Runner::run                                                           0          94064
/home/gen/develop/msgpack.php/tests/exbench.php                                              0          94064
MessagePack\Tests\Perf\Benchmark\FilterableBenchmark::benchmark                              0          94044
MessagePack\Tests\Perf\Benchmark\AverageableBenchmark::benchmark                             0          94042
MessagePack\Tests\Perf\Benchmark\IterationBenchmark::benchmark                               0          94042
MessagePack\Tests\Perf\Benchmark\PausableBenchmark::benchmark                                0          94042
MessagePack\Tests\Perf\Benchmark\IterationBenchmark::measurePerform                       3283          93227
MessagePack\Tests\Perf\Target\BufferUnpackerTarget::perform                                220          89944
MessagePack\BufferUnpacker::unpack                                                       73468          88288
MessagePack\BufferUnpacker::unpackUint64                                                  5453           5453
MessagePack\Container::__construct                                                        4712           4712
MessagePack\BufferUnpacker::unpackUint32                                                  4655           4655
MessagePack\Tests\Perf\Test::getPacked                                                    1166           1166
MessagePack\Tests\Perf\Benchmark\IterationBenchmark::measureOverhead                       405            815
MessagePack\BufferUnpacker::reset                                                          520            520
MessagePack\Tests\Perf\Target\BufferUnpackerTarget::calibrate                              160            410
MessagePack\Tests\Perf\Writer\TableWriter::writeSummary                                     10             10
MessagePack\Tests\Perf\Writer\TableWriter::close                                             0             10
MessagePack\Tests\Perf\Writer\TableWriter::writeRow                                         10             10
MessagePack\Tests\Perf\Writer\TableWriter::write                                             0             10
Composer\Autoload\includeFile                                                                0              2
Composer\Autoload\ClassLoader::loadClass                                                     0              2
/home/gen/develop/msgpack.php/tests/Perf/TestSkippedException.php                            2              2

Unfortunately, they are not low-level enough to judge why one implementation is faster than another. My understanding is that master is faster because the overhead of extra jumps and additional object creation is higher than several recursive calls.

rybakit commented 3 years ago

I'm closing this because I don't see how I can make it faster. I tried several other tweaks, but they are all slower than the master implementation. I also compared performance with PECL's msgpack, and with JIT enabled this library is just as fast as the C extension (and even outperforms it on some datasets). Considering that this library is more feature-rich, I'm very happy with the results.