diff options
Diffstat (limited to 'byterun')
-rw-r--r-- | byterun/Makefile | 1 | ||||
-rw-r--r-- | byterun/Makefile.nt | 6 | ||||
-rw-r--r-- | byterun/callback.c | 32 | ||||
-rw-r--r-- | byterun/compatibility.h | 392 | ||||
-rw-r--r-- | byterun/config.h | 2 | ||||
-rw-r--r-- | byterun/exec.h | 2 | ||||
-rw-r--r-- | byterun/extern.c | 44 | ||||
-rw-r--r-- | byterun/fail.c | 3 | ||||
-rw-r--r-- | byterun/finalise.c | 120 | ||||
-rw-r--r-- | byterun/fix_code.c | 2 | ||||
-rw-r--r-- | byterun/gc_ctrl.c | 1 | ||||
-rw-r--r-- | byterun/instrtrace.c | 196 | ||||
-rw-r--r-- | byterun/instrtrace.h | 4 | ||||
-rw-r--r-- | byterun/instruct.h | 1 | ||||
-rw-r--r-- | byterun/intern.c | 6 | ||||
-rw-r--r-- | byterun/interp.c | 106 | ||||
-rw-r--r-- | byterun/interp.h | 7 | ||||
-rw-r--r-- | byterun/major_gc.c | 30 | ||||
-rw-r--r-- | byterun/major_gc.h | 3 | ||||
-rw-r--r-- | byterun/memory.c | 52 | ||||
-rw-r--r-- | byterun/memory.h | 23 | ||||
-rw-r--r-- | byterun/meta.c | 1 | ||||
-rw-r--r-- | byterun/misc.c | 7 | ||||
-rw-r--r-- | byterun/misc.h | 18 | ||||
-rw-r--r-- | byterun/obj.c | 72 | ||||
-rw-r--r-- | byterun/parsing.c | 1 | ||||
-rw-r--r-- | byterun/startup.c | 2 | ||||
-rw-r--r-- | byterun/str.c | 2 | ||||
-rw-r--r-- | byterun/sys.c | 24 |
29 files changed, 621 insertions, 539 deletions
diff --git a/byterun/Makefile b/byterun/Makefile index dcbcdaee52..34d024961c 100644 --- a/byterun/Makefile +++ b/byterun/Makefile @@ -84,6 +84,7 @@ prims.c : primitives echo ' 0 };') > prims.c opnames.h : instruct.h + LANG=C; \ sed -e '/\/\*/d' \ -e '/^#/d' \ -e 's/enum /char * names_of_/' \ diff --git a/byterun/Makefile.nt b/byterun/Makefile.nt index 506ae7549d..0325cf37fb 100644 --- a/byterun/Makefile.nt +++ b/byterun/Makefile.nt @@ -35,7 +35,7 @@ PRIMS=alloc.c array.c compare.c extern.c floats.c gc_ctrl.c hash.c \ dynlink.c PUBLIC_INCLUDES=alloc.h callback.h config.h custom.h fail.h intext.h \ - memory.h misc.h mlvalues.h + memory.h misc.h mlvalues.h signals.h compatibility.h all: ocamlrun.exe libcamlrun.$(A) @@ -68,10 +68,10 @@ prims.c : primitives (echo '#include "mlvalues.h"'; \ echo '#include "prims.h"'; \ sed -e 's/.*/extern value &();/' primitives; \ - echo 'c_primitive builtin_cprim[] = {'; \ + echo 'c_primitive caml_builtin_cprim[] = {'; \ sed -e 's/.*/ &,/' primitives; \ echo ' 0 };'; \ - echo 'char * names_of_builtin_cprim[] = {'; \ + echo 'char * caml_names_of_builtin_cprim[] = {'; \ sed -e 's/.*/ "&",/' primitives; \ echo ' 0 };') > prims.c diff --git a/byterun/callback.c b/byterun/callback.c index f16c4728c9..a960df5448 100644 --- a/byterun/callback.c +++ b/byterun/callback.c @@ -32,7 +32,10 @@ CAMLexport int caml_callback_depth = 0; +#ifndef LOCAL_CALLBACK_BYTECODE static opcode_t callback_code[] = { ACC, 0, APPLY, 0, POP, 1, STOP }; +#endif + #ifdef THREADED_CODE @@ -57,17 +60,44 @@ CAMLexport value caml_callbackN_exn(value closure, int narg, value args[]) int i; value res; + /* some alternate bytecode implementations (e.g. a JIT translator) + might require that the bytecode is kept in a local variable on + the C stack */ +#ifdef LOCAL_CALLBACK_BYTECODE + opcode_t local_callback_code[7]; +#endif + Assert(narg + 4 <= 256); - Init_callback(); + caml_extern_sp -= narg + 4; for (i = 0; i < narg; i++) caml_extern_sp[i] = args[i]; /* arguments */ +#ifndef LOCAL_CALLBACK_BYTECODE caml_extern_sp[narg] = (value) (callback_code + 4); /* return address */ caml_extern_sp[narg + 1] = Val_unit; /* environment */ caml_extern_sp[narg + 2] = Val_long(0); /* extra args */ caml_extern_sp[narg + 3] = closure; + Init_callback(); callback_code[1] = narg + 3; callback_code[3] = narg; res = caml_interprete(callback_code, sizeof(callback_code)); +#else /*have LOCAL_CALLBACK_BYTECODE*/ + caml_extern_sp[narg] = (value) (local_callback_code + 4); /* return address */ + caml_extern_sp[narg + 1] = Val_unit; /* environment */ + caml_extern_sp[narg + 2] = Val_long(0); /* extra args */ + caml_extern_sp[narg + 3] = closure; + local_callback_code[0] = ACC; + local_callback_code[1] = narg + 3; + local_callback_code[2] = APPLY; + local_callback_code[3] = narg; + local_callback_code[4] = POP; + local_callback_code[5] = 1; + local_callback_code[6] = STOP; +#ifdef THREADED_CODE + caml_thread_code(local_callback_code, sizeof(local_callback_code)); +#endif /*THREADED_CODE*/ + res = caml_interprete(local_callback_code, sizeof(local_callback_code)); + caml_release_bytecode(local_callback_code, sizeof(local_callback_code)); +#endif /*LOCAL_CALLBACK_BYTECODE*/ if (Is_exception_result(res)) caml_extern_sp += narg + 4; /* PR#1228 */ return res; } diff --git a/byterun/compatibility.h b/byterun/compatibility.h index 8db284f3fc..f65717b62e 100644 --- a/byterun/compatibility.h +++ b/byterun/compatibility.h @@ -48,33 +48,14 @@ #define alloc_array caml_alloc_array #define copy_string_array caml_copy_string_array #define convert_flag_list caml_convert_flag_list -/* alloc_dummy -> caml_alloc_dummy */ -/* update_dummy -> caml_update_dummy */ -/* **** asmrun/<arch>.s */ -/* g caml_alloc -> caml_allocN SP*/ /* **** array.c */ -/* array_get_addr -> caml_array_get_addr */ -/* array_get_float -> caml_array_get_float */ -/* array_get -> caml_array_get */ -/* array_set_addr -> caml_array_set_addr */ -/* array_set_float -> caml_array_set_float */ -/* array_set -> caml_array_set */ -/* array_unsafe_get_float -> caml_array_unsafe_get_float */ -/* array_unsafe_get -> caml_array_unsafe_get */ -/* array_unsafe_set_addr -> caml_array_unsafe_set_addr */ -/* array_unsafe_set_float -> caml_array_unsafe_set_float */ -/* array_unsafe_set -> caml_array_unsafe_set */ -/* make_vect -> caml_make_vect */ -/* make_array -> caml_make_array */ /* **** backtrace.c */ #define backtrace_active caml_backtrace_active #define backtrace_pos caml_backtrace_pos #define backtrace_buffer caml_backtrace_buffer #define backtrace_last_exn caml_backtrace_last_exn -/* g init_backtrace -> caml_init_backtrace */ -/* g stash_backtrace -> caml_stash_backtrace */ #define print_exception_backtrace caml_print_exception_backtrace /* **** callback.c */ @@ -87,52 +68,22 @@ #define callback2 caml_callback2 #define callback3 caml_callback3 #define callbackN caml_callbackN -/* register_named_value -> caml_register_named_value */ /* **** compact.c */ -/* g compact_heap -> caml_compact_heap */ -/* g percent_max -> caml_percent_max */ -/* g compact_heap_maybe -> caml_compact_heap_maybe */ /* **** compare.c */ #define compare_unordered caml_compare_unordered -/* compare -> caml_compare */ -/* equal -> caml_equal */ -/* notequal -> caml_notequal */ -/* lessthan -> caml_lessthan */ -/* lessequal -> caml_lessequal */ -/* greaterthan -> caml_greaterthan */ -/* greaterequal -> caml_greaterequal */ /* **** custom.c */ #define alloc_custom caml_alloc_custom #define register_custom_operations caml_register_custom_operations -/* g find_custom_operations -> caml_find_custom_operations */ -/* g final_custom_operations -> caml_final_custom_operations */ -/* g init_custom_operations -> caml_init_custom_operations */ /* **** debugger.c */ -/* g debugger_in_use -> caml_debugger_in_use */ -/* g event_count -> caml_event_count */ -/* g debugger_init -> caml_debugger_init */ -/* g debugger -> caml_debugger */ /* **** dynlink.c */ -/* g prim_table -> caml_prim_table */ -/* g prim_name_table -> caml_prim_name_table */ -/* g shared_libs_path -> caml_shared_libs_path */ -/* g build_primitive_table -> caml_build_primitive_table */ -/* dynlink_open_lib -> caml_dynlink_open_lib */ -/* dynlink_close_lib -> caml_dynlink_close_lib */ -/* dynlink_lookup_symbol -> caml_dynlink_lookup_symbol */ -/* dynlink_add_primitive -> caml_dynlink_add_primitive */ -/* dynlink_get_current_libs -> caml_dynlink_get_current_libs */ /* **** extern.c */ #define output_val caml_output_val -/* output_value -> caml_output_value */ -/* output_value_to_string -> caml_output_value_to_string */ -/* output_value_to_buffer -> caml_output_value_to_buffer */ #define output_value_to_malloc caml_output_value_to_malloc #define output_value_to_block caml_output_value_to_block #define serialize_int_1 caml_serialize_int_1 @@ -149,7 +100,6 @@ /* **** fail.c */ #define external_raise caml_external_raise -/* g exn_bucket -> caml_exn_bucket */ #define mlraise caml_raise /*SP*/ #define raise_constant caml_raise_constant #define raise_with_arg caml_raise_with_arg @@ -166,132 +116,35 @@ #define raise_sys_blocked_io caml_raise_sys_blocked_io #define init_exceptions caml_init_exceptions /* **** asmrun/fail.c */ -/* g raise_caml_exception -> caml_raise_exception SP*/ /* **** asmrun/<arch>.s */ -/* g caml_array_bound_error -> caml_ml_array_bound_error SP*/ /* **** finalise.c */ -/* g final_update -> caml_final_update */ -/* g final_do_calls -> caml_final_do_calls */ -/* g final_do_strong_roots -> caml_final_do_strong_roots */ -/* g final_do_weak_roots -> caml_final_do_weak_roots */ -/* g final_do_young_roots -> caml_final_do_young_roots */ -/* g final_empty_young -> caml_final_empty_young */ -/* final_register -> caml_final_register */ /* **** fix_code.c */ -/* g start_code -> caml_start_code */ -/* g code_size -> caml_code_size */ -/* g saved_code -> caml_saved_code */ -/* g code_md5 -> caml_code_md5 */ -/* g load_code -> caml_load_code */ -/* g fixup_endianness -> caml_fixup_endianness */ -/* g instr_table -> caml_instr_table */ -/* g instr_base -> caml_instr_base */ -/* g thread_code -> caml_thread_code */ -/* g set_instruction -> caml_set_instruction */ -/* g is_instruction -> caml_is_instruction */ /* **** floats.c */ /*#define Double_val caml_Double_val done in mlvalues.h as needed */ /*#define Store_double_val caml_Store_double_val done in mlvalues.h as needed */ #define copy_double caml_copy_double -/* format_float -> caml_format_float */ -/* float_of_string -> caml_float_of_string */ -/* int_of_float -> caml_int_of_float */ -/* float_of_int -> caml_float_of_int */ -/* neg_float -> caml_neg_float */ -/* abs_float -> caml_abs_float */ -/* add_float -> caml_add_float */ -/* sub_float -> caml_sub_float */ -/* mul_float -> caml_mul_float */ -/* div_float -> caml_div_float */ -/* exp_float -> caml_exp_float */ -/* floor_float -> caml_floor_float */ -/* fmod_float -> caml_fmod_float */ -/* frexp_float -> caml_frexp_float */ -/* ldexp_float -> caml_ldexp_float */ -/* log_float -> caml_log_float */ -/* log10_float -> caml_log10_float */ -/* modf_float -> caml_modf_float */ -/* sqrt_float -> caml_sqrt_float */ -/* power_float -> caml_power_float */ -/* sin_float -> caml_sin_float */ -/* sinh_float -> caml_sinh_float */ -/* cos_float -> caml_cos_float */ -/* cosh_float -> caml_cosh_float */ -/* tan_float -> caml_tan_float */ -/* tanh_float -> caml_tanh_float */ -/* asin_float -> caml_asin_float */ -/* acos_float -> caml_acos_float */ -/* atan_float -> caml_atan_float */ -/* atan2_float -> caml_atan2_float */ -/* ceil_float -> caml_ceil_float */ -/* eq_float -> caml_eq_float */ -/* neq_float -> caml_neq_float */ -/* le_float -> caml_le_float */ -/* lt_float -> caml_lt_float */ -/* ge_float -> caml_ge_float */ -/* gt_float -> caml_gt_float */ -/* float_compare -> caml_float_compare */ -/* classify_float -> caml_classify_float */ -/* init_ieee_float -> caml_init_ieee_float */ /* **** freelist.c */ -/* g fl_merge -> caml_fl_merge */ -/* g fl_cur_size -> caml_fl_cur_size */ -/* * fl_check *** becomes static */ -/* g fl_allocate -> caml_fl_allocate */ -/* g fl_init_merge -> caml_fl_init_merge */ -/* g fl_reset -> caml_fl_reset */ -/* g fl_merge_block -> caml_fl_merge_block */ -/* g fl_add_block -> caml_fl_add_block */ -/* g make_free_blocks -> caml_make_free_blocks */ /* **** gc_ctrl.c */ -/* g stat_minor_words -> caml_stat_minor_words */ -/* g stat_promoted_words -> caml_stat_promoted_words */ -/* g stat_major-words -> caml_stat_major_words */ -/* g stat_minor_collections -> caml_stat_minor_collections */ -/* g stat_major_collections -> caml_stat_major_collections */ -/* g stat_heap_size -> caml_stat_heap_size */ -/* g stat_top_heap_size -> caml_stat_top_heap_size */ -/* g stat_compactions -> caml_stat_compactions */ -/* g stat_heap_chunks -> caml_stat_heap_chunks */ -/* g heap_check -> caml_heap_check */ -/* gc_stat -> caml_gc_stat */ -/* gc_counters -> caml_gc_counters */ -/* gc_get -> caml_gc_get */ -/* gc_set -> caml_gc_set */ -/* gc_minor -> caml_gc_minor */ -/* gc_major -> caml_gc_major */ -/* gc_full_major -> caml_gc_full_major */ -/* gc_major_slice -> caml_gc_major_slice */ -/* gc_compaction -> caml_gc_compaction */ /* **** globroots.c */ #define register_global_root caml_register_global_root #define remove_global_root caml_remove_global_root /* **** hash.c */ -/* hash_univ_param -> caml_hash_univ_param */ #define hash_variant caml_hash_variant /* **** instrtrace.c */ -/* g icount -> caml_icount */ -/* g stop_here -> caml_stop_here */ -/* g trace_flag -> caml_trace_flag */ -/* g disasm_instr -> caml_disasm_instr */ /* **** intern.c */ #define input_val caml_input_val -/* input_value -> caml_input_value */ #define input_val_from_string caml_input_val_from_string -/* input_value_from_string -> caml_input_value_from_string */ #define input_value_from_malloc caml_input_value_from_malloc #define input_value_from_block caml_input_value_from_block -/* marshal_data_size -> caml_marshal_data_size */ -/* g code_checksum -> caml_code_checksum */ #define deserialize_uint_1 caml_deserialize_uint_1 #define deserialize_sint_1 caml_deserialize_sint_1 #define deserialize_uint_2 caml_deserialize_uint_2 @@ -310,86 +163,15 @@ #define deserialize_error caml_deserialize_error /* **** interp.c */ -/* g interprete -> caml_interprete */ /* **** ints.c */ -/* int_compare -> caml_int_compare */ -/* int_of_string -> caml_int_of_string */ -/* format_int -> caml_format_int */ #define int32_ops caml_int32_ops #define copy_int32 caml_copy_int32 -/* int32_neg -> caml_int32_neg */ -/* int32_add -> caml_int32_add */ -/* int32_sub -> caml_int32_sub */ -/* int32_mul -> caml_int32_mul */ -/* int32_div -> caml_int32_div */ -/* int32_mod -> caml_int32_mod */ -/* int32_and -> caml_int32_and */ -/* int32_or -> caml_int32_or */ -/* int32_xor -> caml_int32_xor */ -/* int32_shift_left -> caml_int32_shift_left */ -/* int32_shift_right -> caml_int32_shift_right */ -/* int32_shift_right_unsigned -> caml_int32_shift_right_unsigned */ -/* int32_of_int -> caml_int32_of_int */ -/* int32_to_int -> caml_int32_to_int */ -/* int32_of_float -> caml_int32_of_float */ -/* int32_to_float -> caml_int32_to_float */ -/* int32_compare -> caml_int32_compare */ -/* int32_format -> caml_int32_format */ -/* int32_of_string -> caml_int32_of_string */ -/* int32_bits_of_float -> caml_int32_bits_of_float */ -/* int32_float_of_bits -> caml_int32_float_of_bits */ /*#define Int64_val caml_Int64_val *** done in mlvalues.h as needed */ #define int64_ops caml_int64_ops #define copy_int64 caml_copy_int64 -/* int64_neg -> caml_int64_neg */ -/* int64_add -> caml_int64_add */ -/* int64_sub -> caml_int64_sub */ -/* int64_mul -> caml_int64_mul */ -/* int64_div -> caml_int64_div */ -/* int64_mod -> caml_int64_mod */ -/* int64_and -> caml_int64_and */ -/* int64_or -> caml_int64_or */ -/* int64_xor -> caml_int64_xor */ -/* int64_shift_left -> caml_int64_shift_left */ -/* int64_shift_right -> caml_int64_shift_right */ -/* int64_shift_right_unsigned -> caml_int64_shift_right_unsigned */ -/* int64_of_int -> caml_int64_of_int */ -/* int64_to_int -> caml_int64_to_int */ -/* int64_of_float -> caml_int64_of_float */ -/* int64_to_float -> caml_int64_to_float */ -/* int64_of_int32 -> caml_int64_of_int32 */ -/* int64_to_int32 -> caml_int64_to_int32 */ -/* int64_of_nativeint -> caml_int64_of_nativeint */ -/* int64_to_nativeint -> caml_int64_to_nativeint */ -/* int64_compare -> caml_int64_compare */ -/* int64_format -> caml_int64_format */ -/* int64_of_string -> caml_int64_of_string */ -/* int64_bits_of_float -> caml_int64_bits_of_float */ -/* int64_float_of_bits -> caml_int64_float_of_bits */ #define nativeint_ops caml_nativeint_ops #define copy_nativeint caml_copy_nativeint -/* nativeint_neg -> caml_nativeint_neg */ -/* nativeint_add -> caml_nativeint_add */ -/* nativeint_sub -> caml_nativeint_sub */ -/* nativeint_mul -> caml_nativeint_mul */ -/* nativeint_div -> caml_nativeint_div */ -/* nativeint_mod -> caml_nativeint_mod */ -/* nativeint_and -> caml_nativeint_and */ -/* nativeint_or -> caml_nativeint_or */ -/* nativeint_xor -> caml_nativeint_xor */ -/* nativeint_shift_left -> caml_nativeint_shift_left */ -/* nativeint_shift_right -> caml_nativeint_shift_right */ -/* nativeint_shift_right_unsigned -> caml_nativeint_shift_right_unsigned */ -/* nativeint_of_int -> caml_nativeint_of_int */ -/* nativeint_to_int -> caml_nativeint_to_int */ -/* nativeint_of_float -> caml_nativeint_of_float */ -/* nativeint_to_float -> caml_nativeint_to_float */ -/* nativeint_of_int32 -> caml_nativeint_of_int32 */ -/* nativeint_to_int32 -> caml_nativeint_to_int32 */ -/* nativeint_compare -> caml_nativeint_compare */ -/* nativeint_format -> caml_nativeint_format */ -/* nativeint_of_string -> caml_nativeint_of_string */ /* **** io.c */ #define channel_mutex_free caml_channel_mutex_free @@ -419,60 +201,18 @@ #define input_scan_line caml_input_scan_line /*SP*/ #define finalize_channel caml_finalize_channel #define alloc_channel caml_alloc_channel -/* caml_open_descriptor_in -> caml_ml_open_descriptor_in SP*/ -/* caml_open_descriptor_out -> caml_ml_open_descriptor_out SP*/ -/* caml_out_channels_list -> caml_ml_out_channels_list SP*/ -/* channel_descriptor -> caml_channel_descriptor */ -/* caml_close_channel -> caml_ml_close_channel SP*/ -/* caml_channel_size -> caml_ml_channel_size SP*/ -/* caml_channel_size_64 -> caml_ml_channel_size_64 SP*/ -/* caml_set_binary_mode -> caml_ml_set_binary_mode SP*/ -/* caml_flush_partial -> caml_ml_flush_partial SP*/ -/* caml_flush -> caml_ml_flush SP*/ -/* caml_output_char -> caml_ml_output_char SP*/ -/* caml_output_int -> caml_ml_output_int SP*/ -/* caml_output_partial -> caml_ml_output_partial SP*/ -/* caml_output -> caml_ml_output SP*/ -/* caml_seek_out -> caml_ml_seek_out SP*/ -/* caml_seek_out_64 -> caml_ml_seek_out_64 SP*/ -/* caml_pos_out -> caml_ml_pos_out SP*/ -/* caml_pos_out_64 -> caml_ml_pos_out_64 SP*/ -/* caml_input_char -> caml_ml_input_char SP*/ -/* caml_input_int -> caml_ml_input_int SP*/ -/* caml_input -> caml_ml_input SP*/ -/* caml_seek_in -> caml_ml_seek_in SP*/ -/* caml_seek_in_64 -> caml_ml_seek_in_64 SP*/ -/* caml_pos_in -> caml_ml_pos_in SP*/ -/* caml_pos_in_64 -> caml_ml_pos_in_64 SP*/ -/* caml_input_scan_line -> caml_ml_input_scan_line SP*/ /*#define Val_file_offset caml_Val_file_offset *** done in io.h as needed */ /*#define File_offset_val caml_File_offset_val *** done in io.h as needed */ /* **** lexing.c */ -/* lex_engine -> caml_lex_engine */ -/* new_lex_engine -> caml_new_lex_engine */ /* **** main.c */ /* *** no change */ /* **** major_gc.c */ -/* g percent_free -> caml_percent_free */ -/* g major_heap_increment -> caml_major_heap_increment */ #define heap_start caml_heap_start #define heap_end caml_heap_end #define page_table caml_page_table -/* g page_low -> caml_page_low */ -/* g page_high -> caml_page_high */ -/* g gc_sweep_hp -> caml_gc_sweep_hp */ -/* g gc_phase -> caml_gc_phase */ -/* g allocated_words -> caml_allocated_words */ -/* g extra_heap_memory -> caml_extra_heap_memory */ -/* g fl_size_at_phase_change -> caml_fl_size_at_phase_change */ -/* g darken -> caml_darken */ -/* g major_collection_slice -> caml_major_collection_slice */ -/* g finish_major_cycle -> caml_finish_major_cycle */ -/* g round_heap_chunk_size -> caml_round_heap_chunk_size */ -/* g init_major_heap -> caml_init_major_heap */ /* **** md5.c */ #define md5_string caml_md5_string @@ -483,13 +223,7 @@ #define MD5Transform caml_MD5Transform /* **** memory.c */ -/* g alloc_for_heap -> caml_alloc_for_heap */ -/* g free_for_heap -> caml_free_for_heap */ -/* g add_to_heap -> caml_add_to_heap */ -/* g shrink_heap -> caml_shrink_heap */ -/* g allocation_color -> caml_allocation_color */ #define alloc_shr caml_alloc_shr -/* g adjust_gc_speed -> caml_adjust_gc_speed */ #define initialize caml_initialize #define modify caml_modify #define stat_alloc caml_stat_alloc @@ -497,93 +231,45 @@ #define stat_resize caml_stat_resize /* **** meta.c */ -/* get_global_data -> caml_get_global_data */ -/* reify_bytecode -> caml_reify_bytecode */ -/* realloc_global -> caml_realloc_global */ -/* get_current_environment -> caml_get_current_environment */ -/* invoke_traced_function -> caml_invoke_traced_function */ /* **** minor_gc.c */ -/* g minor_heap_size -> caml_minor_heap_size */ #define young_start caml_young_start #define young_end caml_young_end #define young_ptr caml_young_ptr #define young_limit caml_young_limit #define ref_table_ptr caml_ref_table_ptr #define ref_table_limit caml_ref_table_limit -/* g in_minor_collection -> caml_in_minor_collection */ -/* g set_minor_heap_size -> caml_set_minor_heap_size */ -/* g oldify_one -> caml_oldify_one */ -/* g oldify_mopup -> caml_oldify_mopup */ -/* g empty_minor_heap -> caml_empty_minor_heap */ #define minor_collection caml_minor_collection #define check_urgent_gc caml_check_urgent_gc -/* g realloc_ref_table -> caml_realloc_ref_table */ /* **** misc.c */ -/* g verb_gc -> caml_verb_gc */ -/* g gc_message -> caml_gc_message */ -/* g fatal_error -> caml_fatal_error */ -/* g fatal_error_arg -> caml_fatal_error_arg */ -/* g fatal_error_arg2 -> caml_fatal_error_arg2 */ -/* g aligned_malloc -> caml_aligned_malloc */ -/* g ext_table_init -> caml_ext_table_init */ -/* g ext_table_add -> caml_ext_table_add */ -/* g ext_table_free -> caml_ext_table_free */ /* **** obj.c */ -/* static_alloc -> caml_static_alloc */ -/* static_free -> caml_static_free */ -/* static_resize -> caml_static_resize */ -/* obj_is_block -> caml_obj_is_block */ -/* obj_tag -> caml_obj_tag */ -/* obj_set_tag -> caml_obj_set_tag */ -/* obj_block -> caml_obj_block */ -/* obj_dup -> caml_obj_dup */ -/* obj_truncate -> caml_obj_truncate */ -/* lazy_follow_forward -> caml_lazy_follow_forward */ -/* lazy_make_forward -> caml_lazy_make_forward */ /* **** parsing.c */ -/* g parser_trace -> caml_parser_trace */ -/* parse_engine -> caml_parse_engine */ /* **** prims.c */ -/* g buitin_cprim -> caml_builtin_cprim */ -/* g names_of_builtin_cprim -> caml_names_of_builtin_cprim */ /* **** printexc.c */ #define format_caml_exception caml_format_exception /*SP*/ -/* g fatal_uncaught_exception -> caml_fatal_uncaught_exception */ /* **** roots.c */ #define local_roots caml_local_roots #define scan_roots_hook caml_scan_roots_hook -/* g oldify_local_roots -> caml_oldify_local_roots */ -/* g darken_all_roots -> caml_darken_all_roots */ -/* g do_roots -> caml_do_roots */ #define do_local_roots caml_do_local_roots /* **** signals.c */ #define async_signal_mode caml_async_signal_mode #define pending_signal caml_pending_signal #define something_to_do caml_something_to_do -/* g force_major_slice -> caml_force_major_slice */ -/* g signal_handlers -> caml_signal_handlers */ #define enter_blocking_section_hook caml_enter_blocking_section_hook #define leave_blocking_section_hook caml_leave_blocking_section_hook #define async_action_hook caml_async_action_hook -/* g process_event -> caml_process_event */ -/* g execute_signal -> caml_execute_signal */ -/* * handle_signal *** becomes static */ -/* g urge_major_slice -> caml_urge_major_slice */ #define enter_blocking_section caml_enter_blocking_section #define leave_blocking_section caml_leave_blocking_section #define convert_signal_number caml_convert_signal_number -/* install_signal_handler -> caml_install_signal_handler */ /* **** asmrun/signals.c */ #define garbage_collection caml_garbage_collection -/* g init_signals -> caml_init_signals */ /* **** stacks.c */ #define stack_low caml_stack_low @@ -592,110 +278,32 @@ #define extern_sp caml_extern_sp #define trapsp caml_trapsp #define trap_barrier caml_trap_barrier -/* g global_data -> caml_global_data */ -/* g max_stack_size -> caml_max_stack_size */ -/* g init_stack -> caml_init_stack */ -/* g realloc_stack -> caml_realloc_stack */ -/* ensure_stack_capacity -> caml_ensure_stack_capacity */ -/* g change_max_stack_size -> caml_change_max_stack_size */ /* **** startup.c */ #define atom_table caml_atom_table -/* g attempt_open -> caml_attempt_open */ -/* g read_section_descriptors -> caml_read_section_descriptors */ -/* g seek_optional_section -> caml_seek_optional_section */ -/* g seek_section -> caml_seek_section */ /* **** asmrun/startup.c */ #define static_data_start caml_static_data_start #define static_data_end caml_static_data_end -/* g code_area_start -> caml_code_area_start */ -/* g code_area_end -> caml_code_area_end */ /* **** str.c */ #define string_length caml_string_length -/* ml_string_length -> caml_ml_string_length */ -/* create_string -> caml_create_string */ -/* string_get -> caml_string_get */ -/* string_set -> caml_string_set */ -/* string_equal -> caml_string_equal */ -/* string_notequal -> caml_string_notequal */ -/* string_compare -> caml_string_compare */ -/* string_lessthan -> caml_string_lessthan */ -/* string_lessequal -> caml_string_lessequal */ -/* string_greaterthan -> caml_string_greaterthan */ -/* string_greaterequal -> caml_string_greaterequal */ -/* blit_string -> caml_blit_string */ -/* fill_string -> caml_fill_string */ -/* is_printable -> caml_is_printable */ -/* bitvect_test -> caml_bitvect_test */ /* **** sys.c */ #define sys_error caml_sys_error #define sys_exit caml_sys_exit -/* sys_open -> caml_sys_open */ -/* sys_close -> caml_sys_close */ -/* sys_file_exists -> caml_sys_file_exists */ -/* sys_remove -> caml_sys_remove */ -/* sys_chdir -> caml_sys_chdir */ -/* sys_getcwd -> caml_sys_getcwd */ -/* sys_getenv -> caml_sys_getenv */ -/* sys_get_argv -> caml_sys_get_argv */ -/* g sys_init -> caml_sys_init */ -/* sys_system_command -> caml_sys_system_command */ -/* sys_time -> caml_sys_time */ -/* sys_random_seed -> caml_sys_random_seed */ -/* sys_get_config -> caml_sys_get_config */ -/* sys_read_directory -> caml_sys_read_directory */ /* **** terminfo.c */ -/* terminfo_setup -> caml_terminfo_setup */ -/* terminfo_backup -> caml_terminfo_backup */ -/* terminfo_standout -> caml_terminfo_standout*/ -/* terminfo_resume -> caml_terminfo_resume */ /* **** unix.c & win32.c */ -/* g decompose_path -> caml_decompose_path */ -/* g search_in_path -> caml_search_in_path */ #define search_exe_in_path caml_search_exe_in_path -/* g search_dll_in_path -> caml_search_dll_in_path */ -/* g aligned_mmap -> caml_aligned_mmap */ -/* g aligned_munmap -> caml_aligned_munmap */ -/* g executable_name -> caml_executable_name */ -/* g win32_signal -> caml_win32_signal */ -/* x expand_command_line -> caml_expand_command_line private CAMLexport */ /* **** weak.c */ -/* g weak_list_head -> caml_weak_list_head */ -/* g weak_none -> caml_weak_none */ -/* weak_create -> caml_weak_create */ -/* weak_set -> caml_weak_set */ -/* weak_get -> caml_weak_get */ -/* weak_get_copy -> caml_weak_get_copy */ -/* weak_check -> caml_weak_check */ /* **** asmcomp/asmlink.ml */ -/* g startup -> caml_startup */ -/* g startup__frametable -> caml_startup_frametable */ -/* g system__frametable -> caml_system__frametable */ /* **** asmcomp/cmmgen.ml */ -/* g bucket_* -> caml_bucket_* */ -/* g globals_map -> caml_globals_map */ -/* g Match_failure -> caml_exn_Match_failure */ -/* g Out_of_memory -> caml_exn_Out_of_memory */ -/* g Invalid_argument -> caml_exn_Invalid_argument */ -/* g Failure -> caml_exn_Failure */ -/* g Not_found -> caml_exn_Not_found */ -/* g Sys_error -> caml_exn_Sys_error */ -/* g End_of_file -> caml_exn_End_of_file */ -/* g Division_by_zero -> caml_exn_Division_by_zero */ -/* g Stack_overflow -> caml_exn_Stack_overflow */ -/* g Sys_blocked_io -> caml_exn_Sys_blocked_io */ -/* g Assert_failure -> caml_exn_Assert_failure */ -/* g Undefined_recursive_module -> caml_exn_Undefined_recursive_module */ /* **** asmcomp/asmlink.ml, asmcomp/cmmgen.ml, asmcomp/compilenv.ml */ -/* g Module_name -> camlModule_name */ #endif /* CAML_NAME_SPACE */ #endif /* CAML_COMPATIBILITY_H */ diff --git a/byterun/config.h b/byterun/config.h index b2e79aa19a..da9612489c 100644 --- a/byterun/config.h +++ b/byterun/config.h @@ -74,7 +74,7 @@ typedef struct { uint32 l, h; } uint64, int64; /* We use threaded code interpretation if the compiler provides labels as first-class values (GCC 2.x). */ -#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(DEBUG) && !defined (SHRINKED_GNUC) +#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(DEBUG) && !defined (SHRINKED_GNUC) && !defined(CAML_JIT) #define THREADED_CODE #endif diff --git a/byterun/exec.h b/byterun/exec.h index 56609573e6..1abfa455c3 100644 --- a/byterun/exec.h +++ b/byterun/exec.h @@ -56,7 +56,7 @@ struct exec_trailer { /* Magic number for this release */ -#define EXEC_MAGIC "Caml1999X007" +#define EXEC_MAGIC "Caml1999X008" #endif /* CAML_EXEC_H */ diff --git a/byterun/extern.c b/byterun/extern.c index 2faeb9e853..85a549539b 100644 --- a/byterun/extern.c +++ b/byterun/extern.c @@ -332,15 +332,17 @@ static void extern_rec(value v) break; } case Abstract_tag: - extern_invalid_argument("output_value: abstract value"); + extern_invalid_argument("output_value: abstract value (Abstract)"); break; case Infix_tag: writecode32(CODE_INFIXPOINTER, Infix_offset_hd(hd)); extern_rec(v - Infix_offset_hd(hd)); break; + /* Use default case for objects case Object_tag: extern_invalid_argument("output_value: object value"); break; + */ case Custom_tag: { unsigned long sz_32, sz_64; char * ident = Custom_ops_val(v)->identifier; @@ -348,7 +350,7 @@ static void extern_rec(value v) unsigned long * wsize_64) = Custom_ops_val(v)->serialize; if (serialize == NULL) - extern_invalid_argument("output_value: abstract value"); + extern_invalid_argument("output_value: abstract value (Custom)"); Write(CODE_CUSTOM); writeblock(ident, strlen(ident) + 1); Custom_ops_val(v)->serialize(v, &sz_32, &sz_64); @@ -383,7 +385,7 @@ static void extern_rec(value v) writeblock((char *) caml_code_checksum(), 16); return; } - extern_invalid_argument("output_value: abstract value"); + extern_invalid_argument("output_value: abstract value (outside heap)"); } enum { NO_SHARING = 1, CLOSURES = 2 }; @@ -565,13 +567,15 @@ CAMLexport void caml_serialize_block_1(void * data, long len) CAMLexport void caml_serialize_block_2(void * data, long len) { - unsigned char * p; - char * q; if (extern_ptr + 2 * len > extern_limit) resize_extern_block(2 * len); #ifndef ARCH_BIG_ENDIAN - for (p = data, q = extern_ptr; len > 0; len--, p += 2, q += 2) - Reverse_16(q, p); - extern_ptr = q; + { + unsigned char * p; + char * q; + for (p = data, q = extern_ptr; len > 0; len--, p += 2, q += 2) + Reverse_16(q, p); + extern_ptr = q; + } #else memmove(extern_ptr, data, len * 2); extern_ptr += len * 2; @@ -580,13 +584,15 @@ CAMLexport void caml_serialize_block_2(void * data, long len) CAMLexport void caml_serialize_block_4(void * data, long len) { - unsigned char * p; - char * q; if (extern_ptr + 4 * len > extern_limit) resize_extern_block(4 * len); #ifndef ARCH_BIG_ENDIAN - for (p = data, q = extern_ptr; len > 0; len--, p += 4, q += 4) - Reverse_32(q, p); - extern_ptr = q; + { + unsigned char * p; + char * q; + for (p = data, q = extern_ptr; len > 0; len--, p += 4, q += 4) + Reverse_32(q, p); + extern_ptr = q; + } #else memmove(extern_ptr, data, len * 4); extern_ptr += len * 4; @@ -595,13 +601,15 @@ CAMLexport void caml_serialize_block_4(void * data, long len) CAMLexport void caml_serialize_block_8(void * data, long len) { - unsigned char * p; - char * q; if (extern_ptr + 8 * len > extern_limit) resize_extern_block(8 * len); #ifndef ARCH_BIG_ENDIAN - for (p = data, q = extern_ptr; len > 0; len--, p += 8, q += 8) - Reverse_64(q, p); - extern_ptr = q; + { + unsigned char * p; + char * q; + for (p = data, q = extern_ptr; len > 0; len--, p += 8, q += 8) + Reverse_64(q, p); + extern_ptr = q; + } #else memmove(extern_ptr, data, len * 8); extern_ptr += len * 8; diff --git a/byterun/fail.c b/byterun/fail.c index d785d98f31..64d766fe4f 100644 --- a/byterun/fail.c +++ b/byterun/fail.c @@ -49,6 +49,7 @@ CAMLexport void caml_raise_constant(value tag) bucket = caml_alloc_small (1, 0); Field(bucket, 0) = tag; caml_raise(bucket); + CAMLnoreturn; } CAMLexport void caml_raise_with_arg(value tag, value arg) @@ -60,6 +61,7 @@ CAMLexport void caml_raise_with_arg(value tag, value arg) Field(bucket, 0) = tag; Field(bucket, 1) = arg; caml_raise(bucket); + CAMLnoreturn; } CAMLexport void caml_raise_with_string(value tag, char *msg) @@ -69,6 +71,7 @@ CAMLexport void caml_raise_with_string(value tag, char *msg) vmsg = caml_copy_string(msg); caml_raise_with_arg(tag, vmsg); + CAMLnoreturn; } CAMLexport void caml_failwith (char *msg) diff --git a/byterun/finalise.c b/byterun/finalise.c index 6b955d9c59..76c2d43d49 100644 --- a/byterun/finalise.c +++ b/byterun/finalise.c @@ -27,31 +27,61 @@ struct final { }; static struct final *final_table = NULL; -static unsigned long old = 0, young = 0, active = 0, size = 0; +static unsigned long old = 0, young = 0, size = 0; /* [0..old) : finalisable set [old..young) : recent set - [young..active) : free space - [active..size) : finalising set + [young..size) : free space */ -/* Find white finalisable values, darken them, and put them in the - finalising set. +struct to_do { + struct to_do *next; + int size; + struct final item[1]; /* variable size */ +}; + +static struct to_do *to_do_hd = NULL; +static struct to_do *to_do_tl = NULL; + +static void alloc_to_do (int size) +{ + struct to_do *result = malloc (sizeof (struct to_do) + + size * sizeof (struct final)); + if (result == NULL) caml_fatal_error ("out of memory"); + result->next = NULL; + result->size = size; + if (to_do_tl == NULL){ + to_do_hd = result; + to_do_tl = result; + }else{ + Assert (to_do_tl->next == NULL); + to_do_tl->next = result; + to_do_tl = result; + } +} + +/* Find white finalisable values, put them in the finalising set, and + darken them. The recent set is empty. */ void caml_final_update (void) { - unsigned long i; - unsigned long oldactive = active; + unsigned long i, j, k; + unsigned long todo_count = 0; Assert (young == old); - Assert (young <= active); + for (i = 0; i < old; i++){ + Assert (Is_block (final_table[i].val)); + Assert (Is_in_heap (final_table[i].val)); + if (Is_white_val (final_table[i].val)) ++ todo_count; + } + + alloc_to_do (todo_count); + j = k = 0; for (i = 0; i < old; i++){ again: Assert (Is_block (final_table[i].val)); Assert (Is_in_heap (final_table[i].val)); if (Is_white_val (final_table[i].val)){ - struct final f; - if (Tag_val (final_table[i].val) == Forward_tag){ value fv = Forward_val (final_table[i].val); if (Is_block (fv) && (Is_young (fv) || Is_in_heap (fv)) @@ -65,31 +95,40 @@ void caml_final_update (void) } } } - f = final_table[i]; - final_table[i] = final_table[--old]; - final_table[--active] = f; - -- i; + to_do_tl->item[k++] = final_table[i]; + }else{ + final_table[j++] = final_table[i]; } } - young = old; - for (i = active; i < oldactive; i++) caml_darken (final_table[i].val, NULL); + old = young = j; + to_do_tl->size = k; + for (i = 0; i < k; i++) caml_darken (to_do_tl->item[i++].val, NULL); } +static int running_finalisation_function = 0; + /* Call the finalisation functions for the finalising set. Note that this function must be reentrant. */ void caml_final_do_calls (void) { struct final f; - - Assert (active <= size); - if (active < size){ - caml_gc_message (0x80, "Calling finalisation functions.\n", 0); - while (active < size){ - f = final_table[active++]; - caml_callback (f.fun, f.val); - } - caml_gc_message (0x80, "Done calling finalisation functions.\n", 0); + + if (running_finalisation_function) return; + + while (to_do_hd != NULL && to_do_hd->size == 0){ + to_do_hd = to_do_hd->next; + if (to_do_hd == NULL) to_do_tl = NULL; + } + if (to_do_hd != NULL){ + Assert (to_do_hd->size > 0); + -- to_do_hd->size; + f = to_do_hd->item[to_do_hd->size]; + caml_gc_message (0x80, "Calling finalisation function.\n", 0); + running_finalisation_function = 1; + caml_callback (f.fun, f.val); + running_finalisation_function = 0; + caml_gc_message (0x80, "Return from finalisation function.\n", 0); } } @@ -105,14 +144,16 @@ void caml_final_do_calls (void) void caml_final_do_strong_roots (scanning_action f) { unsigned long i; + struct to_do *todo; Assert (old == young); - Assert (young <= active); - Assert (active <= size); for (i = 0; i < old; i++) Call_action (f, final_table[i].fun); - for (i = active; i < size; i++){ - Call_action (f, final_table[i].fun); - Call_action (f, final_table[i].val); + + for (todo = to_do_hd; todo != NULL; todo = todo->next){ + for (i = 0; i < todo->size; i++){ + Call_action (f, todo->item[i].fun); + Call_action (f, todo->item[i].val); + } } } @@ -159,29 +200,22 @@ CAMLprim value caml_final_register (value f, value v) } Assert (old <= young); - Assert (young <= active); - Assert (active <= size); - if (young >= active){ + if (young >= size){ if (final_table == NULL){ unsigned long new_size = 30; final_table = caml_stat_alloc (new_size * sizeof (struct final)); Assert (old == 0); Assert (young == 0); - active = size = new_size; + size = new_size; }else{ unsigned long new_size = size * 2; - unsigned long i; final_table = caml_stat_resize (final_table, new_size * sizeof (struct final)); - for (i = size-1; i >= active; i--){ - final_table[i + new_size - size] = final_table[i]; - } - active += new_size - size; size = new_size; } } - Assert (young < active); + Assert (young < size); final_table[young].fun = f; if (Tag_val (v) == Infix_tag) v -= Infix_offset_val (v); final_table[young].val = v; @@ -189,3 +223,9 @@ CAMLprim value caml_final_register (value f, value v) return Val_unit; } + +CAMLprim value caml_final_release (value unit) +{ + running_finalisation_function = 0; + return Val_unit; +} diff --git a/byterun/fix_code.c b/byterun/fix_code.c index 470ae825e1..b626f2cb07 100644 --- a/byterun/fix_code.c +++ b/byterun/fix_code.c @@ -113,7 +113,7 @@ void caml_thread_code (code_t code, asize_t len) l[APPTERM] = l[CLOSURE] = l[PUSHGETGLOBALFIELD] = l[GETGLOBALFIELD] = l[MAKEBLOCK] = l[C_CALLN] = l[BEQ] = l[BNEQ] = l[BLTINT] = l[BLEINT] = l[BGTINT] = l[BGEINT] = - l[BULTINT] = l[BUGEINT] = 2; + l[BULTINT] = l[BUGEINT] = l[GETPUBMET] = 2; len /= sizeof(opcode_t); for (p = code; p < code + len; /*nothing*/) { opcode_t instr = *p; diff --git a/byterun/gc_ctrl.c b/byterun/gc_ctrl.c index b262bbd9b2..f31ef1de88 100644 --- a/byterun/gc_ctrl.c +++ b/byterun/gc_ctrl.c @@ -434,6 +434,7 @@ CAMLprim value caml_gc_compaction(value v) caml_finish_major_cycle (); caml_finish_major_cycle (); caml_compact_heap (); + caml_final_do_calls (); return Val_unit; } diff --git a/byterun/instrtrace.c b/byterun/instrtrace.c index aba9787490..03260b41e3 100644 --- a/byterun/instrtrace.c +++ b/byterun/instrtrace.c @@ -18,11 +18,15 @@ #ifdef DEBUG #include <stdio.h> +#include <string.h> +#include <ctype.h> + #include "instruct.h" #include "misc.h" #include "mlvalues.h" #include "opnames.h" #include "prims.h" +#include "stacks.h" extern code_t caml_start_code; @@ -74,4 +78,196 @@ void caml_disasm_instr(pc) fflush (stdout); } + + + +char * +caml_instr_string (code_t pc) +{ + static char buf[96]; + char nambuf[36]; + int instr = *pc; + char *nam = 0; + memset (buf, 0, sizeof (buf)); +#define bufprintf(Fmt,...) snprintf(buf,sizeof(buf)-1,Fmt,##__VA_ARGS__) + nam = (instr < 0 || instr > STOP) + ? (snprintf (nambuf, sizeof (nambuf), "???%d", instr), nambuf) + : names_of_instructions[instr]; + pc++; + switch (instr) { + /* Instructions with one integer operand */ + case PUSHACC: + case ACC: + case POP: + case ASSIGN: + case PUSHENVACC: + case ENVACC: + case PUSH_RETADDR: + case APPLY: + case APPTERM1: + case APPTERM2: + case APPTERM3: + case RETURN: + case GRAB: + case PUSHGETGLOBAL: + case GETGLOBAL: + case SETGLOBAL: + case PUSHATOM: + case ATOM: + case MAKEBLOCK1: + case MAKEBLOCK2: + case MAKEBLOCK3: + case MAKEFLOATBLOCK: + case GETFIELD: + case SETFIELD: + case GETFLOATFIELD: + case SETFLOATFIELD: + case BRANCH: + case BRANCHIF: + case BRANCHIFNOT: + case PUSHTRAP: + case CONSTINT: + case PUSHCONSTINT: + case OFFSETINT: + case OFFSETREF: + case OFFSETCLOSURE: + case PUSHOFFSETCLOSURE: + bufprintf ("%s %d", nam, pc[0]); + break; + /* Instructions with two operands */ + case APPTERM: + case CLOSURE: + case CLOSUREREC: + case PUSHGETGLOBALFIELD: + case GETGLOBALFIELD: + case MAKEBLOCK: + case BEQ: + case BNEQ: + case BLTINT: + case BLEINT: + case BGTINT: + case BGEINT: + case BULTINT: + case BUGEINT: + bufprintf ("%s %d, %d", nam, pc[0], pc[1]); + break; + case SWITCH: + bufprintf ("SWITCH sz%#lx=%ld::ntag%ld nint%ld", + (long) pc[0], (long) pc[0], (unsigned long) pc[0] >> 16, + (unsigned long) pc[0] & 0xffff); + break; + /* Instructions with a C primitive as operand */ + case C_CALLN: + bufprintf ("%s %d,", nam, pc[0]); + pc++; + /* fallthrough */ + case C_CALL1: + case C_CALL2: + case C_CALL3: + case C_CALL4: + case C_CALL5: + if (pc[0] < 0 || pc[0] >= caml_prim_name_table.size) + bufprintf ("%s unknown primitive %d", nam, pc[0]); + else + bufprintf ("%s %s", nam, (char *) caml_prim_name_table.contents[pc[0]]); + break; + default: + bufprintf ("%s", nam); + break; + }; + return buf; +} + + +void +caml_trace_value_file (value v, code_t prog, int proglen, FILE * f) +{ + int i; + fprintf (f, "%#lx", v); + if (!v) + return; + if (Is_atom (v)) + fprintf (f, "=atom%ld", v - Atom (0)); + else if (prog && v % sizeof (int) == 0 + && (code_t) v >= prog + && (code_t) v < (code_t) ((char *) prog + proglen)) + fprintf (f, "=code@%d", (code_t) v - prog); + else if (Is_long (v)) + fprintf (f, "=long%ld", Long_val (v)); + else if ((void*)v >= (void*)caml_stack_low + && (void*)v < (void*)caml_stack_high) + fprintf (f, "=stack_%d", (long*)caml_stack_high - (long*)v); + else if (Is_block (v)) { + int s = Wosize_val (v); + int tg = Tag_val (v); + int l = 0; + switch (tg) { + case Closure_tag: + fprintf (f, "=closure[s%d,cod%d]", s, (code_t) (Code_val (v)) - prog); + goto displayfields; + case String_tag: + l = caml_string_length (v); + fprintf (f, "=string[s%dL%d]'", s, l); + for (i = 0; i < ((l>0x1f)?0x1f:l) ; i++) { + if (isprint (Byte (v, i))) + putc (Byte (v, i), f); + else + putc ('?', f); + }; + fprintf (f, "'"); + goto displayfields; + case Double_tag: + fprintf (f, "=float[s%d]=%g", s, Double_val (v)); + goto displayfields; + case Double_array_tag: + fprintf (f, "=floatarray[s%d]", s); + for (i = 0; i < ((s>0xf)?0xf:s); i++) + fprintf (f, " %g", Double_field (v, i)); + goto displayfields; + case Abstract_tag: + fprintf (f, "=abstract[s%d]", s); + goto displayfields; + case Custom_tag: + fprintf (f, "=custom[s%d]", s); + goto displayfields; + default: + fprintf (f, "=block<T%d/s%d>", tg, s); + displayfields: + if (s > 0) + fputs ("=(", f); + for (i = 0; i < s; i++) { + if (i > 20) { + fputs ("....", f); + break; + }; + if (i > 0) + putc (' ', f); + fprintf (f, "%#lx", Field (v, i)); + }; + if (s > 0) + putc (')', f); + }; + } +} + +// added by Basile +void +caml_trace_accu_sp_file (value accu, value * sp, code_t prog, int proglen, + FILE * f) +{ + int i; + value *p; + fprintf (f, "accu="); + caml_trace_value_file (accu, prog, proglen, f); + fprintf (f, "\n sp=%#lx @%d:", (long) sp, caml_stack_high - sp); + for (p = sp, i = 0; i < 12 + (1 << caml_trace_flag) && p < caml_stack_high; + p++, i++) { + fprintf (f, "\n[%d] ", caml_stack_high - p); + caml_trace_value_file (*p, prog, proglen, f); + }; + putc ('\n', f); + fflush (f); +} + #endif /* DEBUG */ +/* eof $Id$ */ diff --git a/byterun/instrtrace.h b/byterun/instrtrace.h index 6b899766b0..9df4a62352 100644 --- a/byterun/instrtrace.h +++ b/byterun/instrtrace.h @@ -26,6 +26,6 @@ extern int caml_trace_flag; extern long caml_icount; void caml_stop_here (void); void caml_disasm_instr (code_t pc); - - +void caml_trace_value_file (value v, code_t prog, int proglen, FILE * f); +void caml_trace_accu_sp_file(value accu, value * sp, code_t prog, int proglen, FILE * f); #endif diff --git a/byterun/instruct.h b/byterun/instruct.h index c0cf5f2df7..a2eb5b7b5e 100644 --- a/byterun/instruct.h +++ b/byterun/instruct.h @@ -53,6 +53,7 @@ enum instructions { BEQ, BNEQ, BLTINT, BLEINT, BGTINT, BGEINT, ULTINT, UGEINT, BULTINT, BUGEINT, + GETPUBMET, GETDYNMET, STOP, EVENT, BREAK }; diff --git a/byterun/intern.c b/byterun/intern.c index 34b22340a0..00872d6d50 100644 --- a/byterun/intern.c +++ b/byterun/intern.c @@ -651,8 +651,8 @@ CAMLexport void caml_deserialize_block_1(void * data, long len) CAMLexport void caml_deserialize_block_2(void * data, long len) { - unsigned char * p, * q; #ifndef ARCH_BIG_ENDIAN + unsigned char * p, * q; for (p = intern_src, q = data; len > 0; len--, p += 2, q += 2) Reverse_16(q, p); intern_src = p; @@ -664,8 +664,8 @@ CAMLexport void caml_deserialize_block_2(void * data, long len) CAMLexport void caml_deserialize_block_4(void * data, long len) { - unsigned char * p, * q; #ifndef ARCH_BIG_ENDIAN + unsigned char * p, * q; for (p = intern_src, q = data; len > 0; len--, p += 4, q += 4) Reverse_32(q, p); intern_src = p; @@ -677,8 +677,8 @@ CAMLexport void caml_deserialize_block_4(void * data, long len) CAMLexport void caml_deserialize_block_8(void * data, long len) { - unsigned char * p, * q; #ifndef ARCH_BIG_ENDIAN + unsigned char * p, * q; for (p = intern_src, q = data; len > 0; len--, p += 8, q += 8) Reverse_64(q, p); intern_src = p; diff --git a/byterun/interp.c b/byterun/interp.c index 146baa7744..abf504131a 100644 --- a/byterun/interp.c +++ b/byterun/interp.c @@ -114,7 +114,7 @@ sp is a local copy of the global variable caml_extern_sp. */ For GCC, I have hand-assigned hardware registers for several architectures. */ -#if defined(__GNUC__) && !defined(DEBUG) +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(DEBUG) #ifdef __mips__ #define PC_REG asm("$16") #define SP_REG asm("$17") @@ -183,6 +183,11 @@ extern long caml_safe_div(long p, long q); extern long caml_safe_mod(long p, long q); #endif + +#ifdef DEBUG +static long caml_bcodcount; +#endif + /* The interpreter itself */ value caml_interprete(code_t prog, asize_t prog_size) @@ -207,15 +212,15 @@ value caml_interprete(code_t prog, asize_t prog_size) long extra_args; struct longjmp_buffer * initial_external_raise; int initial_sp_offset; - /* volatile prevents collapsing initial_local_roots with another - local variable, like Digital Unix 4.0 C compiler does (wrongly) */ + /* volatile ensures that initial_local_roots and saved_pc + will keep correct value across longjmp */ struct caml__roots_block * volatile initial_local_roots; + volatile code_t saved_pc; struct longjmp_buffer raise_buf; value * modify_dest, modify_newval; #ifndef THREADED_CODE opcode_t curr_instr; #endif - code_t saved_pc; #ifdef THREADED_CODE static void * jumptable[] = { @@ -266,8 +271,17 @@ value caml_interprete(code_t prog, asize_t prog_size) #else while(1) { #ifdef DEBUG + caml_bcodcount++; if (caml_icount-- == 0) caml_stop_here (); + if (caml_trace_flag>1) printf("\n##%ld\n", caml_bcodcount); if (caml_trace_flag) caml_disasm_instr(pc); + if (caml_trace_flag>1) { + printf("env="); + caml_trace_value_file(env,prog,prog_size,stdout); + putchar('\n'); + caml_trace_accu_sp_file(accu,sp,prog,prog_size,stdout); + fflush(stdout); + }; Assert(sp >= caml_stack_low); Assert(sp <= caml_stack_high); #endif @@ -1012,14 +1026,73 @@ value caml_interprete(code_t prog, asize_t prog_size) /* Object-oriented operations */ -#define Lookup(obj, lab) \ - Field (Field (Field (obj, 0), ((lab) >> 16) / sizeof (value)), \ - ((lab) / sizeof (value)) & 0xFF) +#define Lookup(obj, lab) Field (Field (obj, 0), Int_val(lab)) + + /* please don't forget to keep below code in sync with the + functions caml_cache_public_method and + caml_cache_public_method2 in obj.c */ Instruct(GETMETHOD): accu = Lookup(sp[0], accu); Next; +#define CAML_METHOD_CACHE +#ifdef CAML_METHOD_CACHE + Instruct(GETPUBMET): { + /* accu == object, pc[0] == tag, pc[1] == cache */ + value meths = Field (accu, 0); + value ofs; +#ifdef CAML_TEST_CACHE + static int calls = 0, hits = 0; + if (calls >= 10000000) { + fprintf(stderr, "cache hit = %d%%\n", hits / 100000); + calls = 0; hits = 0; + } + calls++; +#endif + *--sp = accu; + accu = Val_int(*pc++); + ofs = *pc & Field(meths,1); + if (*(value*)(((char*)&Field(meths,3)) + ofs) == accu) { +#ifdef CAML_TEST_CACHE + hits++; +#endif + accu = *(value*)(((char*)&Field(meths,2)) + ofs); + } + else + { + int li = 3, hi = Field(meths,0), mi; + while (li < hi) { + mi = ((li+hi) >> 1) | 1; + if (accu < Field(meths,mi)) hi = mi-2; + else li = mi; + } + *pc = (li-3)*sizeof(value); + accu = Field (meths, li-1); + } + pc++; + Next; + } +#else + Instruct(GETPUBMET): + *--sp = accu; + accu = Val_int(*pc); + pc += 2; + /* Fallthrough */ +#endif + Instruct(GETDYNMET): { + /* accu == tag, sp[0] == object, *pc == cache */ + value meths = Field (sp[0], 0); + int li = 3, hi = Field(meths,0), mi; + while (li < hi) { + mi = ((li+hi) >> 1) | 1; + if (accu < Field(meths,mi)) hi = mi-2; + else li = mi; + } + accu = Field (meths, li-1); + Next; + } + /* Debugging and machine control */ Instruct(STOP): @@ -1054,3 +1127,22 @@ value caml_interprete(code_t prog, asize_t prog_size) } #endif } + +void caml_prepare_bytecode(code_t prog, asize_t prog_size) { + /* other implementations of the interpreter (such as an hypothetical + JIT translator) might want to do something with a bytecode before + running it */ + Assert(prog); + Assert(prog_size>0); + /* actually, the threading of the bytecode might be done here */ +} + +void caml_release_bytecode(code_t prog, asize_t prog_size) { + /* other implementations of the interpreter (such as an hypothetical + JIT translator) might want to know when a bytecode is removed */ + /* check that we have a program */ + Assert(prog); + Assert(prog_size>0); +} + +/* eof $Id$ */ diff --git a/byterun/interp.h b/byterun/interp.h index 075f0ff818..9eb7339405 100644 --- a/byterun/interp.h +++ b/byterun/interp.h @@ -18,11 +18,16 @@ #ifndef CAML_INTERP_H #define CAML_INTERP_H - #include "misc.h" #include "mlvalues.h" +/* interpret a bytecode */ value caml_interprete (code_t prog, asize_t prog_size); +/* tell the runtime that a bytecode program might be needed */ +void caml_prepare_bytecode(code_t prog, asize_t prog_size); + +/* tell the runtime that a bytecode program is no more needed */ +void caml_release_bytecode(code_t prog, asize_t prog_size); #endif /* CAML_INTERP_H */ diff --git a/byterun/major_gc.c b/byterun/major_gc.c index d39cd2f203..06183d5196 100644 --- a/byterun/major_gc.c +++ b/byterun/major_gc.c @@ -42,7 +42,8 @@ static asize_t gray_vals_size; static int heap_is_pure; /* The heap is pure if the only gray objects below [markhp] are also in [gray_vals]. */ unsigned long caml_allocated_words; -double caml_extra_heap_memory; +unsigned long caml_dependent_size, caml_dependent_allocated; +double caml_extra_heap_resources; unsigned long caml_fl_size_at_phase_change = 0; extern char *caml_fl_merge; /* Defined in freelist.c. */ @@ -294,7 +295,7 @@ static void sweep_slice (long work) */ long caml_major_collection_slice (long howmuch) { - double p; + double p, dp; long computed_work; /* Free memory at the start of the GC cycle (garbage + free list) (assumed): @@ -304,15 +305,15 @@ long caml_major_collection_slice (long howmuch) Assuming steady state and enforcing a constant allocation rate, then FM is divided in 2/3 for garbage and 1/3 for free list. G = 2 * FM / 3 - G is also the amount of memory that will be used during this slice + G is also the amount of memory that will be used during this cycle (still assuming steady state). Proportion of G consumed since the previous slice: PH = caml_allocated_words / G = caml_allocated_words * 3 * (100 + caml_percent_free) / (2 * caml_stat_heap_size * caml_percent_free) - Proportion of extra-heap memory consumed since the previous slice: - PE = caml_extra_heap_memory + Proportion of extra-heap resources consumed since the previous slice: + PE = caml_extra_heap_resources Proportion of total work to do in this slice: P = max (PH, PE) Amount of marking work for the GC cycle: @@ -332,11 +333,18 @@ long caml_major_collection_slice (long howmuch) p = (double) caml_allocated_words * 3.0 * (100 + caml_percent_free) / Wsize_bsize (caml_stat_heap_size) / caml_percent_free / 2.0; - if (p < caml_extra_heap_memory) p = caml_extra_heap_memory; + if (caml_dependent_size > 0){ + dp = (double) caml_dependent_allocated * (100 + caml_percent_free) + / caml_dependent_size / caml_percent_free; + }else{ + dp = 0.0; + } + if (p < dp) p = dp; + if (p < caml_extra_heap_resources) p = caml_extra_heap_resources; caml_gc_message (0x40, "allocated_words = %lu\n", caml_allocated_words); - caml_gc_message (0x40, "extra_heap_memory = %luu\n", - (unsigned long) (caml_extra_heap_memory * 1000000)); + caml_gc_message (0x40, "extra_heap_resources = %luu\n", + (unsigned long) (caml_extra_heap_resources * 1000000)); caml_gc_message (0x40, "amount of work to do = %luu\n", (unsigned long) (p * 1000000)); @@ -362,7 +370,8 @@ long caml_major_collection_slice (long howmuch) caml_stat_major_words += caml_allocated_words; caml_allocated_words = 0; - caml_extra_heap_memory = 0.0; + caml_dependent_allocated = 0; + caml_extra_heap_resources = 0.0; return computed_work; } @@ -417,7 +426,6 @@ asize_t caml_round_heap_chunk_size (asize_t request) void caml_init_major_heap (asize_t heap_size) { asize_t i; - void *block; asize_t page_table_size; page_table_entry *page_table_block; @@ -459,5 +467,5 @@ void caml_init_major_heap (asize_t heap_size) gray_vals_end = gray_vals + gray_vals_size; heap_is_pure = 1; caml_allocated_words = 0; - caml_extra_heap_memory = 0.0; + caml_extra_heap_resources = 0.0; } diff --git a/byterun/major_gc.h b/byterun/major_gc.h index 0c3eb14ec0..3a53d04ac2 100644 --- a/byterun/major_gc.h +++ b/byterun/major_gc.h @@ -34,7 +34,8 @@ typedef struct { extern int caml_gc_phase; extern unsigned long caml_allocated_words; -extern double caml_extra_heap_memory; +extern double caml_extra_heap_resources; +extern unsigned long caml_dependent_size, caml_dependent_allocated; extern unsigned long caml_fl_size_at_phase_change; #define Phase_mark 0 diff --git a/byterun/memory.c b/byterun/memory.c index 824a01d44c..a4780c6ea2 100644 --- a/byterun/memory.c +++ b/byterun/memory.c @@ -21,6 +21,7 @@ #include "gc_ctrl.h" #include "major_gc.h" #include "memory.h" +#include "major_gc.h" #include "minor_gc.h" #include "misc.h" #include "mlvalues.h" @@ -297,26 +298,49 @@ CAMLexport value caml_alloc_shr (mlsize_t wosize, tag_t tag) return Val_hp (hp); } +/* Dependent memory is all memory blocks allocated out of the heap + that depend on the GC (and finalizers) for deallocation. + For the GC to take dependent memory in its automatic speed setting, + you must call [caml_alloc_dependent_memory] when you alloate some + dependent memory, and [caml_free_dependent_memory] when you + free it. In both cases, you pass as argument the size of the + block being allocated or freed. +*/ +CAMLexport void caml_alloc_dependent_memory (mlsize_t nbytes) +{ + caml_dependent_size += nbytes / sizeof (value); + caml_dependent_allocated += nbytes / sizeof (value); +} + +CAMLexport void caml_free_dependent_memory (mlsize_t nbytes) +{ + if (caml_dependent_size < nbytes / sizeof (value)){ + caml_dependent_size = 0; + }else{ + caml_dependent_size -= nbytes / sizeof (value); + } +} + /* Use this function to tell the major GC to speed up when you use - finalized blocks to automatically deallocate extra-heap stuff. - The GC will do at least one cycle every [max] allocated words; - [mem] is the number of words allocated this time. - Note that only [mem/max] is relevant. You can use numbers of bytes - (or kilobytes, ...) instead of words. You can change units between - calls to [caml_adjust_gc_speed]. + finalized blocks to automatically deallocate resources (other + than memory). The GC will do at least one cycle every [max] + allocated resources; [res] is the number of resources allocated + this time. + Note that only [res/max] is relevant. The units (and kind of + resource) can change between calls to [caml_adjust_gc_speed]. */ -CAMLexport void caml_adjust_gc_speed (mlsize_t mem, mlsize_t max) +CAMLexport void caml_adjust_gc_speed (mlsize_t res, mlsize_t max) { if (max == 0) max = 1; - if (mem > max) mem = max; - caml_extra_heap_memory += (double) mem / (double) max; - if (caml_extra_heap_memory > 1.0){ - caml_extra_heap_memory = 1.0; + if (res > max) res = max; + caml_extra_heap_resources += (double) res / (double) max; + if (caml_extra_heap_resources > 1.0){ + caml_extra_heap_resources = 1.0; caml_urge_major_slice (); } - if (caml_extra_heap_memory > (double) Wsize_bsize (caml_minor_heap_size) - / 2.0 - / (double) Wsize_bsize (caml_stat_heap_size)) { + if (caml_extra_heap_resources + > (double) Wsize_bsize (caml_minor_heap_size) / 2.0 + / (double) Wsize_bsize (caml_stat_heap_size)) { caml_urge_major_slice (); } } diff --git a/byterun/memory.h b/byterun/memory.h index 4be908b8c5..f986793c9a 100644 --- a/byterun/memory.h +++ b/byterun/memory.h @@ -32,6 +32,8 @@ CAMLextern value caml_alloc_shr (mlsize_t, tag_t); CAMLextern void caml_adjust_gc_speed (mlsize_t, mlsize_t); +CAMLextern void caml_alloc_dependent_memory (mlsize_t); +CAMLextern void caml_free_dependent_memory (mlsize_t); CAMLextern void caml_modify (value *, value); CAMLextern void caml_initialize (value *, value); CAMLextern value caml_check_urgent_gc (value); @@ -168,9 +170,15 @@ CAMLextern struct caml__roots_block *caml_local_roots; /* defined in roots.c */ CAMLxparamN (x, (size)) +#if defined (__GNUC__) + #define CAMLunused __attribute__ ((unused)) +#else + #define CAMLunused +#endif + #define CAMLxparam1(x) \ struct caml__roots_block caml__roots_##x; \ - int caml__dummy_##x = ( \ + CAMLunused int caml__dummy_##x = ( \ (caml__roots_##x.next = caml_local_roots), \ (caml_local_roots = &caml__roots_##x), \ (caml__roots_##x.nitems = 1), \ @@ -180,7 +188,7 @@ CAMLextern struct caml__roots_block *caml_local_roots; /* defined in roots.c */ #define CAMLxparam2(x, y) \ struct caml__roots_block caml__roots_##x; \ - int caml__dummy_##x = ( \ + CAMLunused int caml__dummy_##x = ( \ (caml__roots_##x.next = caml_local_roots), \ (caml_local_roots = &caml__roots_##x), \ (caml__roots_##x.nitems = 1), \ @@ -191,7 +199,7 @@ CAMLextern struct caml__roots_block *caml_local_roots; /* defined in roots.c */ #define CAMLxparam3(x, y, z) \ struct caml__roots_block caml__roots_##x; \ - int caml__dummy_##x = ( \ + CAMLunused int caml__dummy_##x = ( \ (caml__roots_##x.next = caml_local_roots), \ (caml_local_roots = &caml__roots_##x), \ (caml__roots_##x.nitems = 1), \ @@ -203,7 +211,7 @@ CAMLextern struct caml__roots_block *caml_local_roots; /* defined in roots.c */ #define CAMLxparam4(x, y, z, t) \ struct caml__roots_block caml__roots_##x; \ - int caml__dummy_##x = ( \ + CAMLunused int caml__dummy_##x = ( \ (caml__roots_##x.next = caml_local_roots), \ (caml_local_roots = &caml__roots_##x), \ (caml__roots_##x.nitems = 1), \ @@ -216,7 +224,7 @@ CAMLextern struct caml__roots_block *caml_local_roots; /* defined in roots.c */ #define CAMLxparam5(x, y, z, t, u) \ struct caml__roots_block caml__roots_##x; \ - int caml__dummy_##x = ( \ + CAMLunused int caml__dummy_##x = ( \ (caml__roots_##x.next = caml_local_roots), \ (caml_local_roots = &caml__roots_##x), \ (caml__roots_##x.nitems = 1), \ @@ -230,7 +238,7 @@ CAMLextern struct caml__roots_block *caml_local_roots; /* defined in roots.c */ #define CAMLxparamN(x, size) \ struct caml__roots_block caml__roots_##x; \ - int caml__dummy_##x = ( \ + CAMLunused int caml__dummy_##x = ( \ (caml__roots_##x.next = caml_local_roots), \ (caml_local_roots = &caml__roots_##x), \ (caml__roots_##x.nitems = (size)), \ @@ -273,6 +281,9 @@ CAMLextern struct caml__roots_block *caml_local_roots; /* defined in roots.c */ return (result); \ }while(0) +#define CAMLnoreturn ((void) caml__frame) + + /* convenience macro */ #define Store_field(block, offset, val) do{ \ mlsize_t caml__temp_offset = (offset); \ diff --git a/byterun/meta.c b/byterun/meta.c index 021e4680cb..ac86ee8e17 100644 --- a/byterun/meta.c +++ b/byterun/meta.c @@ -55,6 +55,7 @@ CAMLprim value caml_reify_bytecode(value prog, value len) #ifdef THREADED_CODE caml_thread_code((code_t) prog, (asize_t) Long_val(len)); #endif + caml_prepare_bytecode((code_t) prog, (asize_t) Long_val(len)); clos = caml_alloc_small (1, Closure_tag); Code_val(clos) = (code_t) prog; return clos; diff --git a/byterun/misc.c b/byterun/misc.c index 618729e4af..8791eca42a 100644 --- a/byterun/misc.c +++ b/byterun/misc.c @@ -41,19 +41,20 @@ void caml_gc_message (int level, char *msg, unsigned long arg) } } -void caml_fatal_error (char *msg) +CAMLexport void caml_fatal_error (char *msg) { fprintf (stderr, "%s", msg); exit(2); } -void caml_fatal_error_arg (char *fmt, char *arg) +CAMLexport void caml_fatal_error_arg (char *fmt, char *arg) { fprintf (stderr, fmt, arg); exit(2); } -void caml_fatal_error_arg2 (char *fmt1, char *arg1, char *fmt2, char *arg2) +CAMLexport void caml_fatal_error_arg2 (char *fmt1, char *arg1, + char *fmt2, char *arg2) { fprintf (stderr, fmt1, arg1); fprintf (stderr, fmt2, arg2); diff --git a/byterun/misc.h b/byterun/misc.h index 298e7c6693..bda864fc49 100644 --- a/byterun/misc.h +++ b/byterun/misc.h @@ -41,10 +41,10 @@ typedef char * addr; /* </private> */ #ifdef __GNUC__ -/* Works only in GCC 2.5 and later */ -#define Noreturn __attribute ((noreturn)) + /* Works only in GCC 2.5 and later */ + #define Noreturn __attribute__ ((noreturn)) #else -#define Noreturn + #define Noreturn #endif /* Export control (to mark primitives and to handle Windows DLL) */ @@ -69,15 +69,15 @@ typedef char * addr; #ifdef DEBUG #define CAMLassert(x) ((x) ? 0 : caml_failed_assert ( #x , __FILE__, __LINE__)) -int caml_failed_assert (char *, char *, int); +CAMLextern int caml_failed_assert (char *, char *, int); #else -#define CAMLassert(x) 0 +#define CAMLassert(x) ((void) 0) #endif -void caml_fatal_error (char *msg) Noreturn; -void caml_fatal_error_arg (char *fmt, char *arg) Noreturn; -void caml_fatal_error_arg2 (char *fmt1, char *arg1, - char *fmt2, char *arg2) Noreturn; +CAMLextern void caml_fatal_error (char *msg) Noreturn; +CAMLextern void caml_fatal_error_arg (char *fmt, char *arg) Noreturn; +CAMLextern void caml_fatal_error_arg2 (char *fmt1, char *arg1, + char *fmt2, char *arg2) Noreturn; /* Data structures */ diff --git a/byterun/obj.c b/byterun/obj.c index 277c24180a..809aeab6d0 100644 --- a/byterun/obj.c +++ b/byterun/obj.c @@ -19,6 +19,7 @@ #include "alloc.h" #include "fail.h" #include "gc.h" +#include "interp.h" #include "major_gc.h" #include "memory.h" #include "minor_gc.h" @@ -37,6 +38,21 @@ CAMLprim value caml_static_free(value blk) return Val_unit; } +/* signal to the interpreter machinery that a bytecode is no more + needed (before freeing it) - this might be useful for a JIT + implementation */ + +CAMLprim value caml_static_release_bytecode(value blk, value size) +{ +#ifndef NATIVE_CODE + caml_release_bytecode((code_t) blk, (asize_t) Long_val(size)); +#else + caml_failwith("Meta.static_release_bytecode impossible with native code"); +#endif + return Val_unit; +} + + CAMLprim value caml_static_resize(value blk, value new_size) { return (value) caml_stat_resize((char *) blk, (asize_t) Long_val(new_size)); @@ -181,3 +197,59 @@ CAMLprim value caml_lazy_make_forward (value v) Modify (&Field (res, 0), v); CAMLreturn (res); } + +/* For camlinternalOO.ml + See also GETPUBMET in interp.c + */ + +CAMLprim value caml_get_public_method (value obj, value tag) +{ + value meths = Field (obj, 0); + int li = 3, hi = Field(meths,0), mi; + while (li < hi) { + mi = ((li+hi) >> 1) | 1; + if (tag < Field(meths,mi)) hi = mi-2; + else li = mi; + } + return Field (meths, li-1); +} + +/* these two functions might be useful to an hypothetical JIT */ + +#ifdef CAML_JIT +#ifdef NATIVE_CODE +#define MARK 1 +#else +#define MARK 0 +#endif +value caml_cache_public_method (value meths, value tag, value *cache) +{ + int li = 3, hi = Field(meths,0), mi; + while (li < hi) { + mi = ((li+hi) >> 1) | 1; + if (tag < Field(meths,mi)) hi = mi-2; + else li = mi; + } + *cache = (li-3)*sizeof(value) + MARK; + return Field (meths, li-1); +} + +value caml_cache_public_method2 (value *meths, value tag, value *cache) +{ + value ofs = *cache & meths[1]; + if (*(value*)(((char*)(meths+3)) + ofs - MARK) == tag) + return *(value*)(((char*)(meths+2)) + ofs - MARK); + { + int li = 3, hi = meths[0], mi; + while (li < hi) { + mi = ((li+hi) >> 1) | 1; + if (tag < meths[mi]) hi = mi-2; + else li = mi; + } + *cache = (li-3)*sizeof(value) + MARK; + return meths[li-1]; + } +} +#endif /*CAML_JIT*/ + +/* eof $Id$ */ diff --git a/byterun/parsing.c b/byterun/parsing.c index 68e687ffdb..2d90fa5524 100644 --- a/byterun/parsing.c +++ b/byterun/parsing.c @@ -115,7 +115,6 @@ static char * token_name(char * names, int number) static void print_token(struct parser_tables *tables, int state, value tok) { - mlsize_t i; value v; if (Is_long(tok)) { diff --git a/byterun/startup.c b/byterun/startup.c index 7918f0eea3..57f8c970a5 100644 --- a/byterun/startup.c +++ b/byterun/startup.c @@ -236,7 +236,7 @@ static int parse_command_line(char **argv) switch(argv[i][1]) { #ifdef DEBUG case 't': - caml_trace_flag = 1; + caml_trace_flag++; break; #endif case 'v': diff --git a/byterun/str.c b/byterun/str.c index 08bbf839e7..8151fa37c1 100644 --- a/byterun/str.c +++ b/byterun/str.c @@ -83,7 +83,7 @@ CAMLprim value caml_string_notequal(value s1, value s2) CAMLprim value caml_string_compare(value s1, value s2) { - mlsize_t len1, len2, len; + mlsize_t len1, len2; int res; len1 = caml_string_length(s1); diff --git a/byterun/sys.c b/byterun/sys.c index 96d0c7bb2a..c5f5c60e14 100644 --- a/byterun/sys.c +++ b/byterun/sys.c @@ -51,32 +51,11 @@ extern int errno; #endif -#ifdef HAS_STRERROR - -#ifndef _WIN32 -extern char * strerror(int); -#endif - static char * error_message(void) { return strerror(errno); } -#else - -extern int sys_nerr; -extern char * sys_errlist []; - -static char * error_message(void) -{ - if (errno < 0 || errno >= sys_nerr) - return "unknown error"; - else - return sys_errlist[errno]; -} - -#endif /* HAS_STRERROR */ - #ifndef EAGAIN #define EAGAIN (-1) #endif @@ -106,6 +85,7 @@ CAMLexport void caml_sys_error(value arg) } caml_raise_sys_error(str); } + CAMLnoreturn; } CAMLprim value caml_sys_exit(value retcode) @@ -179,7 +159,7 @@ CAMLprim value caml_sys_remove(value name) CAMLprim value caml_sys_rename(value oldname, value newname) { if (rename(String_val(oldname), String_val(newname)) != 0) - caml_sys_error(oldname); + caml_sys_error(NO_ARG); return Val_unit; } |