MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dry up jit fallback

+66 -91
+66 -91
src/silver/engine.c
··· 248 248 return result; 249 249 } 250 250 251 + #ifdef ANT_JIT 252 + static inline ant_value_t sv_try_direct_closure_jit( 253 + sv_vm_t *vm, ant_t *js, sv_func_t *caller_func, uint8_t *caller_ip, sv_frame_t *caller_frame, 254 + sv_closure_t *closure, ant_value_t jit_this, ant_value_t *call_args, int call_argc 255 + ) { 256 + sv_func_t *callee = closure->func; 257 + if (!callee) return SV_JIT_RETRY_INTERP; 258 + 259 + if (caller_func && caller_func->type_feedback && caller_ip) 260 + sv_tfb_record_call_target(caller_func, (int)(caller_ip - caller_func->code), callee); 261 + 262 + if (callee->jit_code) { 263 + if (caller_frame && caller_ip) caller_frame->ip = caller_ip + 3; 264 + sv_jit_enter(js); 265 + ant_value_t jit_result = ((sv_jit_func_t)callee->jit_code)( 266 + vm, jit_this, call_args, call_argc, closure); 267 + sv_jit_leave(js); 268 + if (sv_is_jit_bailout(jit_result)) { 269 + sv_jit_on_bailout(callee); 270 + return SV_JIT_RETRY_INTERP; 271 + } 272 + return jit_result; 273 + } 274 + 275 + if (callee->is_generator) return SV_JIT_RETRY_INTERP; 276 + 277 + uint32_t cc = ++callee->call_count; 278 + if (__builtin_expect(cc == SV_TFB_ALLOC_THRESHOLD, 0)) 279 + sv_tfb_ensure(callee); 280 + if (cc <= SV_JIT_THRESHOLD) return SV_JIT_RETRY_INTERP; 281 + 282 + sv_jit_func_t jit_fn = sv_jit_compile(js, callee, closure); 283 + if (!jit_fn) { 284 + callee->call_count = 0; 285 + callee->back_edge_count = 0; 286 + return SV_JIT_RETRY_INTERP; 287 + } 288 + 289 + callee->jit_code = (void *)jit_fn; 290 + if (caller_frame && caller_ip) caller_frame->ip = caller_ip + 3; 291 + sv_jit_enter(js); 292 + ant_value_t jit_result = jit_fn(vm, jit_this, call_args, call_argc, closure); 293 + sv_jit_leave(js); 294 + if (sv_is_jit_bailout(jit_result)) { 295 + sv_jit_on_bailout(callee); 296 + return SV_JIT_RETRY_INTERP; 297 + } 298 + return jit_result; 299 + } 300 + #endif 301 + 251 302 ant_value_t sv_execute_entry( 252 303 sv_vm_t *vm, sv_func_t *func, ant_value_t this_val, ant_value_t *args, int argc 253 304 ) { ··· 716 767 DISPATCH(); 717 768 } 718 769 719 - // TODO: make the methods below DRY 720 770 L_CALL: { 721 771 uint16_t call_argc = sv_get_u16(ip + 1); 722 772 ant_value_t *call_args = &vm->stack[vm->sp - call_argc]; ··· 734 784 if (closure->func->is_async) goto call_fallback; 735 785 #ifdef ANT_JIT 736 786 { 737 - sv_func_t *callee = closure->func; 738 - if (func->type_feedback) 739 - sv_tfb_record_call_target(func, (int)(ip - func->code), callee); 740 - if (callee->jit_code) { 741 - ant_value_t jit_this = ( 742 - callee->is_arrow || vtype(closure->bound_this) != T_UNDEF) 743 - ? closure->bound_this : js_mkundef(); 744 - frame->ip = ip + 3; 745 - sv_jit_enter(js); 746 - ant_value_t jit_result = ((sv_jit_func_t)callee->jit_code)( 747 - vm, jit_this, call_args, (int)call_argc, closure); 748 - sv_jit_leave(js); 749 - if (sv_is_jit_bailout(jit_result)) { 750 - sv_jit_on_bailout(callee); 751 - goto call_fallback; 752 - } 787 + ant_value_t jit_this = ( 788 + closure->func->is_arrow || vtype(closure->bound_this) != T_UNDEF) 789 + ? closure->bound_this : js_mkundef(); 790 + ant_value_t jit_result = sv_try_direct_closure_jit( 791 + vm, js, func, ip, frame, closure, jit_this, call_args, (int)call_argc); 792 + if (jit_result != SV_JIT_RETRY_INTERP) { 753 793 vm->sp -= call_argc + 1; 754 794 if (is_err(jit_result)) { sv_err = jit_result; goto sv_throw; } 755 795 vm->stack[vm->sp++] = jit_result; 756 796 ip = frame->ip; 757 797 DISPATCH(); 758 798 } 759 - if (!callee->is_generator) { 760 - uint32_t cc = ++callee->call_count; 761 - if (__builtin_expect(cc == SV_TFB_ALLOC_THRESHOLD, 0)) 762 - sv_tfb_ensure(callee); 763 - if (cc > SV_JIT_THRESHOLD) { 764 - sv_jit_func_t jit_fn = sv_jit_compile(js, callee, closure); 765 - if (jit_fn) { 766 - callee->jit_code = (void *)jit_fn; 767 - ant_value_t jit_this = ( 768 - callee->is_arrow || vtype(closure->bound_this) != T_UNDEF) 769 - ? closure->bound_this : js_mkundef(); 770 - frame->ip = ip + 3; 771 - sv_jit_enter(js); 772 - ant_value_t jit_result = jit_fn(vm, jit_this, call_args, (int)call_argc, closure); 773 - sv_jit_leave(js); 774 - if (sv_is_jit_bailout(jit_result)) { 775 - sv_jit_on_bailout(callee); 776 - goto call_fallback; 777 - } 778 - vm->sp -= call_argc + 1; 779 - if (is_err(jit_result)) { sv_err = jit_result; goto sv_throw; } 780 - vm->stack[vm->sp++] = jit_result; 781 - ip = frame->ip; 782 - DISPATCH(); 783 - } else { 784 - callee->call_count = 0; 785 - callee->back_edge_count = 0; 786 - }} 787 - } 788 799 } 789 800 #endif 790 801 if (vm->fp + 1 >= vm->max_frames && !sv_vm_grow_frames(vm)) { ··· 861 872 if (closure->func->is_async) goto call_method_fallback; 862 873 #ifdef ANT_JIT 863 874 { 864 - sv_func_t *callee = closure->func; 865 - if (callee->jit_code) { 866 - ant_value_t jit_this = ( 867 - callee->is_arrow || vtype(closure->bound_this) != T_UNDEF) 868 - ? closure->bound_this : call_this; 869 - frame->ip = ip + 3; 870 - sv_jit_enter(js); 871 - ant_value_t jit_result = ((sv_jit_func_t)callee->jit_code)( 872 - vm, jit_this, call_args, (int)call_argc, closure); 873 - sv_jit_leave(js); 874 - if (sv_is_jit_bailout(jit_result)) { 875 - sv_jit_on_bailout(callee); 876 - goto call_method_fallback; 877 - } 875 + ant_value_t jit_this = ( 876 + closure->func->is_arrow || vtype(closure->bound_this) != T_UNDEF) 877 + ? closure->bound_this : call_this; 878 + ant_value_t jit_result = sv_try_direct_closure_jit( 879 + vm, js, func, ip, frame, closure, jit_this, call_args, (int)call_argc); 880 + if (jit_result != SV_JIT_RETRY_INTERP) { 878 881 vm->sp -= call_argc + 2; 879 882 if (is_err(jit_result)) { sv_err = jit_result; goto sv_throw; } 880 883 vm->stack[vm->sp++] = jit_result; 881 884 ip = frame->ip; 882 885 DISPATCH(); 883 - } 884 - if (!callee->is_generator) { 885 - uint32_t cc = ++callee->call_count; 886 - if (__builtin_expect(cc == SV_TFB_ALLOC_THRESHOLD, 0)) 887 - sv_tfb_ensure(callee); 888 - if (cc > SV_JIT_THRESHOLD) { 889 - sv_jit_func_t jit_fn = sv_jit_compile(js, callee, closure); 890 - if (jit_fn) { 891 - callee->jit_code = (void *)jit_fn; 892 - ant_value_t jit_this = ( 893 - callee->is_arrow || vtype(closure->bound_this) != T_UNDEF) 894 - ? closure->bound_this : call_this; 895 - frame->ip = ip + 3; 896 - sv_jit_enter(js); 897 - ant_value_t jit_result = jit_fn(vm, jit_this, call_args, (int)call_argc, closure); 898 - sv_jit_leave(js); 899 - if (sv_is_jit_bailout(jit_result)) { 900 - sv_jit_on_bailout(callee); 901 - goto call_method_fallback; 902 - } 903 - vm->sp -= call_argc + 2; 904 - if (is_err(jit_result)) { sv_err = jit_result; goto sv_throw; } 905 - vm->stack[vm->sp++] = jit_result; 906 - ip = frame->ip; 907 - DISPATCH(); 908 - } else { 909 - callee->call_count = 0; 910 - callee->back_edge_count = 0; 911 - }} 912 886 } 913 887 } 914 888 #endif ··· 1052 1026 ant_value_t *call_args = &vm->stack[vm->sp - call_argc]; 1053 1027 ant_value_t call_func = vm->stack[vm->sp - call_argc - 1]; 1054 1028 sv_closure_t *closure = js_func_closure(call_func); 1055 - if (frame->bp) sv_close_upvalues_from_slot(vm, frame->bp); 1029 + if (frame->bp && vm->open_upvalues) sv_close_upvalues_from_slot(vm, frame->bp); 1056 1030 vm->sp = frame->prev_sp; 1057 1031 int arg_slots = ( 1058 1032 (int)call_argc > closure->func->param_count) ··· 1329 1303 if (js->vm_exec_depth > 0) js->vm_exec_depth--; 1330 1304 return vm_result; 1331 1305 } 1306 + if (vm->open_upvalues) { 1332 1307 for (int f = vm->fp; f >= entry_fp; f--) { 1333 1308 ant_value_t *drop_bp = vm->frames[f].bp; 1334 1309 if (drop_bp) sv_close_upvalues_from_slot(vm, drop_bp); 1335 - } 1310 + }} 1336 1311 vm->fp = entry_fp; 1337 1312 vm->sp = vm->frames[entry_fp].prev_sp; 1338 1313 vm->handler_depth = vm->frames[entry_fp].handler_base;