Index: VERSION =================================================================== --- VERSION (.../vendor/ocaml/4.00.0) (revision 103) +++ VERSION (.../trunk/ocamlxsim/3.1) (revision 103) @@ -1,4 +1,4 @@ -4.00.0 +4.00.0+xsim-3.1.7 # The version string is the first line of this file. # It must be in the format described in stdlib/sys.mli Index: asmcomp/schedgen.ml =================================================================== --- asmcomp/schedgen.ml (.../vendor/ocaml/4.00.0) (revision 103) +++ asmcomp/schedgen.ml (.../trunk/ocamlxsim/3.1) (revision 103) @@ -10,11 +10,10 @@ (* *) (***********************************************************************) -(* $Id: schedgen.ml 12179 2012-02-21 17:41:02Z xleroy $ *) +(* $Id$ *) (* Instruction scheduling *) -open Misc open Reg open Mach open Linearize @@ -65,6 +64,33 @@ let add_edge_after son ancestor = add_edge ancestor son 0 +(* Add edges from all instructions that define a pseudoregister [arg] being used + as argument to node [node] (RAW dependencies *) + +let add_RAW_dependencies node arg = + try + let ancestor = Hashtbl.find code_results arg.loc in + add_edge ancestor node ancestor.delay + with Not_found -> + () + +(* Add edges from all instructions that use a pseudoregister [res] that is + defined by node [node] (WAR dependencies). *) + +let add_WAR_dependencies node res = + let ancestors = Hashtbl.find_all code_uses res.loc in + List.iter (add_edge_after node) ancestors + +(* Add edges from all instructions that have already defined a pseudoregister + [res] that is defined by node [node] (WAW dependencies). *) + +let add_WAW_dependencies node res = + try + let ancestor = Hashtbl.find code_results res.loc in + add_edge ancestor node 0 + with Not_found -> + () + (* Compute length of longest path to a result. For leafs of the DAG, see whether their result is used in the instruction immediately following the basic block (a "critical" output). *) @@ -200,10 +226,19 @@ | Lreloadretaddr -> self#reload_retaddr_issue_cycles | _ -> assert false +(* Pseudoregisters destroyed by an instruction *) + +method private destroyed_by_instr instr = + match instr.desc with + | Lop op -> Proc.destroyed_at_oper (Iop op) + | Lreloadretaddr -> [||] + | _ -> assert false + (* Add an instruction to the code dag *) method private add_instruction ready_queue instr = let delay = self#instr_latency instr in + let destroyed = self#destroyed_by_instr instr in let node = { instr = instr; delay = delay; @@ -214,28 +249,17 @@ emitted_ancestors = 0 } in (* Add edges from all instructions that define one of the registers used (RAW dependencies) *) - for i = 0 to Array.length instr.arg - 1 do - try - let ancestor = Hashtbl.find code_results instr.arg.(i).loc in - add_edge ancestor node ancestor.delay - with Not_found -> - () - done; + Array.iter (add_RAW_dependencies node) instr.arg; (* Also add edges from all instructions that use one of the result regs - of this instruction (WAR dependencies). *) - for i = 0 to Array.length instr.res - 1 do - let ancestors = Hashtbl.find_all code_uses instr.res.(i).loc in - List.iter (add_edge_after node) ancestors - done; + of this instruction, or a reg destroyed by this instruction + (WAR dependencies). *) + Array.iter (add_WAR_dependencies node) instr.res; + Array.iter (add_WAR_dependencies node) destroyed; (* PR#5731 *) (* Also add edges from all instructions that have already defined one - of the results of this instruction (WAW dependencies). *) - for i = 0 to Array.length instr.res - 1 do - try - let ancestor = Hashtbl.find code_results instr.res.(i).loc in - add_edge ancestor node 0 - with Not_found -> - () - done; + of the results of this instruction, or a reg destroyed by + this instruction (WAW dependencies). *) + Array.iter (add_WAW_dependencies node) instr.res; + Array.iter (add_WAW_dependencies node) destroyed; (* PR#5731 *) (* If this is a load, add edges from the most recent store viewed so far (if any) and remember the load. Also add edges from the most recent checkbound and forget that checkbound. *) @@ -264,6 +288,9 @@ for i = 0 to Array.length instr.res - 1 do Hashtbl.add code_results instr.res.(i).loc node done; + for i = 0 to Array.length destroyed - 1 do + Hashtbl.add code_results destroyed.(i).loc node (* PR#5731 *) + done; for i = 0 to Array.length instr.arg - 1 do Hashtbl.add code_uses instr.arg.(i).loc node done; Index: asmcomp/i386/emit.mlp =================================================================== --- asmcomp/i386/emit.mlp (.../vendor/ocaml/4.00.0) (revision 103) +++ asmcomp/i386/emit.mlp (.../trunk/ocamlxsim/3.1) (revision 103) @@ -85,7 +85,14 @@ let emit_data_label lbl = emit_string label_prefix; emit_string "d"; emit_int lbl +(* Emit truncated native int, necessary when cross compiling from 64 to + * 32 bit environments. For the usual self-hosted 32-bit environment + * this acts exactly like emit_nativeint. + *) +let emit_t_nativeint n = + emit_int32 (Nativeint.to_int32 n) + (* Some data directives have different names under Solaris *) let word_dir = @@ -451,7 +458,7 @@ Reg n -> ` xorl {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` | _ -> ` movl $0, {emit_reg i.res.(0)}\n` end else - ` movl ${emit_nativeint n}, {emit_reg i.res.(0)}\n` + ` movl ${emit_t_nativeint n}, {emit_reg i.res.(0)}\n` | Lop(Iconst_float s) -> begin match Int64.bits_of_float (float_of_string s) with | 0x0000_0000_0000_0000L -> (* +0.0 *) @@ -685,7 +692,7 @@ | Lop(Ispecific(Ilea addr)) -> ` lea {emit_addressing addr i.arg 0}, {emit_reg i.res.(0)}\n` | Lop(Ispecific(Istore_int(n, addr))) -> - ` movl ${emit_nativeint n}, {emit_addressing addr i.arg 0}\n` + ` movl ${emit_t_nativeint n}, {emit_addressing addr i.arg 0}\n` | Lop(Ispecific(Istore_symbol(s, addr))) -> ` movl ${emit_symbol s}, {emit_addressing addr i.arg 0}\n` | Lop(Ispecific(Ioffset_loc(n, addr))) -> @@ -712,7 +719,7 @@ stack_offset := !stack_offset + 4 done | Lop(Ispecific(Ipush_int n)) -> - ` pushl ${emit_nativeint n}\n`; + ` pushl ${emit_t_nativeint n}\n`; cfi_adjust_cfa_offset 4; stack_offset := !stack_offset + 4 | Lop(Ispecific(Ipush_symbol s)) -> @@ -961,9 +968,9 @@ | Cint16 n -> ` {emit_string word_dir} {emit_int n}\n` | Cint32 n -> - ` .long {emit_nativeint n}\n` + ` .long {emit_t_nativeint n}\n` | Cint n -> - ` .long {emit_nativeint n}\n` + ` .long {emit_t_nativeint n}\n` | Csingle f -> emit_float32_directive ".long" f | Cdouble f -> Index: tools/make-package-macosx =================================================================== --- tools/make-package-macosx (.../vendor/ocaml/4.00.0) (revision 103) +++ tools/make-package-macosx (.../trunk/ocamlxsim/3.1) (revision 103) @@ -30,9 +30,9 @@ IFPkgDescriptionDeleteWarning IFPkgDescriptionDescription - The OCaml compiler and tools + The OCaml compiler and tools for iOS Simulator IFPkgDescriptionTitle - OCaml + OCaml for iOS Simulator IFPkgDescriptionVersion ${VERSION} @@ -46,11 +46,11 @@ CFBundleGetInfoString - OCaml ${VERSION} + OCaml ${VERSION} for iOS Simulator CFBundleIdentifier - fr.inria.ocaml + com.psellos.ocamlxsim CFBundleName - OCaml + OCaml iOSSim CFBundleShortVersionString ${VERSION} IFMajorVersion @@ -62,7 +62,7 @@ IFPkgFlagAuthorizationAction AdminAuthorization IFPkgFlagDefaultLocation - /usr/local + /usr/local/ocamlxsim IFPkgFlagInstallFat IFPkgFlagIsRequired @@ -85,15 +85,16 @@ # stop here -> | cat >resources/ReadMe.txt < asmrun/Makefile + make world && make opt + mv -f asmrun/Makefile.aside asmrun/Makefile + trap - EXIT + # Save the Phase 1 shared (dynamically loadable) libraries and + # restore them after Phase 2. They're required by some OCaml + # utilities, such as camlp4. + # + # The shared libraries are useful only with the bytecode + # interpreter, which we don't support under iOS. This lets us (just + # barely) fit OCamlXSim into the form of a usual OCaml release. + find . -name '*.so' -exec mv {} {}phase1 \; +} + +config2 () { + # Clean out OS X runtime + echo 'xsim-build: ----- configure phase 2 -----' + cd asmrun; make clean; cd .. + cd stdlib; make clean; cd .. + cd otherlibs/bigarray; make clean; cd ../.. + cd otherlibs/dynlink; make clean; cd ../.. + cd otherlibs/num; make clean; cd ../.. + cd otherlibs/str; make clean; cd ../.. + cd otherlibs/systhreads; make clean; cd ../.. + cd otherlibs/threads; make clean; cd ../.. + cd otherlibs/unix; make clean; cd ../.. + # Reconfigure for iOSSim environment + ./configure \ + -bindir $XSIMTARGET/bin \ + -libdir $XSIMTARGET/lib/ocaml \ + -mandir $XSIMTARGET/man/man1 \ + -no-curses \ + -no-tk \ + -no-graph \ + -host i386-apple-darwin10.0.0d3 \ + -cc "$PLT/Developer/usr/bin/gcc -arch i386 -gdwarf-2 -isysroot $PLT$SDK" \ + -as "$PLT/Developer/usr/bin/gcc -arch i386 -c" \ + -aspp "$PLT/Developer/usr/bin/gcc -arch i386 -c" + # Rebuild ocamlmklib, so libraries work with iOSSim. + rm myocamlbuild_config.ml + cd tools + make ocamlmklib + cd .. +} + +build2 () { + # Make iOSSim runtime + echo 'xsim-build: ----- build phase 2 -----' + cd asmrun; make all; cd .. + cd stdlib; make all allopt; cd .. + cd otherlibs/unix; make all allopt; cd ../.. + cd otherlibs/str; make all allopt; cd ../.. + cd otherlibs/num; make all allopt; cd ../.. + cd otherlibs/dynlink; make all allopt; cd ../.. + cd otherlibs/bigarray; make all allopt; cd ../.. + cd otherlibs/systhreads; make all allopt; cd ../.. + cd otherlibs/threads; make all allopt; cd ../.. + # Restore the saved Phase 1 .so files (see above). + find . -name '*.sophase1' -print | \ + while read f; do \ + fso="$(expr "$f" : '\(.*\)sophase1$')so"; mv -f $f $fso; \ + done +} + +# Bigger steps + +phase1 () { + config1 && build1 +} + +phase2 () { + config2 && build2 +} + +all () { + phase1 && phase2 +} + +clean () { + rm -f myocamlbuild_config.ml + make clean +} + +case "$1" in +config1) config1 ;; +build1) build1 ;; +config2) config2 ;; +build2) build2 ;; +phase1) phase1 ;; +phase2) phase2 ;; +all) all ;; +clean) clean ;; +*) echo "usage: $(basename $0) {all|phase1|phase2|config1|build1|config2|build2}" >&2; + echo " $(basename $0) clean" >&2; + exit 1 + ;; +esac Index: Makefile =================================================================== --- Makefile (.../vendor/ocaml/4.00.0) (revision 103) +++ Makefile (.../trunk/ocamlxsim/3.1) (revision 103) @@ -762,7 +762,10 @@ package-macosx: sudo rm -rf package-macosx/root - $(MAKE) PREFIX="`pwd`"/package-macosx/root install + $(MAKE) BINDIR="`pwd`"/package-macosx/root/bin \ + LIBDIR="`pwd`"/package-macosx/root/lib/ocaml \ + MANDIR="`pwd`"/package-macosx/root/man \ + install tools/make-package-macosx sudo rm -rf package-macosx/root Index: byterun/intern.c =================================================================== --- byterun/intern.c (.../vendor/ocaml/4.00.0) (revision 103) +++ byterun/intern.c (.../trunk/ocamlxsim/3.1) (revision 103) @@ -558,7 +558,7 @@ Assert(intern_dest <= end_extra_block); if (intern_dest < end_extra_block){ caml_make_free_blocks ((value *) intern_dest, - end_extra_block - intern_dest, 0); + end_extra_block - intern_dest, 0, Caml_white); } caml_allocated_words += Wsize_bsize ((char *) intern_dest - intern_extra_block); Index: byterun/memory.c =================================================================== --- byterun/memory.c (.../vendor/ocaml/4.00.0) (revision 103) +++ byterun/memory.c (.../trunk/ocamlxsim/3.1) (revision 103) @@ -318,7 +318,7 @@ } remain = malloc_request; prev = hp = mem; - /* XXX find a way to do this with a call to caml_make_free_blocks */ + /* FIXME find a way to do this with a call to caml_make_free_blocks */ while (Wosize_bhsize (remain) > Max_wosize){ Hd_hp (hp) = Make_header (Max_wosize, 0, Caml_blue); #ifdef DEBUG Index: byterun/freelist.c =================================================================== --- byterun/freelist.c (.../vendor/ocaml/4.00.0) (revision 103) +++ byterun/freelist.c (.../trunk/ocamlxsim/3.1) (revision 103) @@ -509,8 +509,11 @@ p: pointer to the first word of the block size: size of the block (in words) do_merge: 1 -> do merge; 0 -> do not merge + color: which color to give to the pieces; if [do_merge] is 1, this + is overridden by the merge code, but we have historically used + [Caml_white]. */ -void caml_make_free_blocks (value *p, mlsize_t size, int do_merge) +void caml_make_free_blocks (value *p, mlsize_t size, int do_merge, int color) { mlsize_t sz; @@ -520,7 +523,7 @@ }else{ sz = size; } - *(header_t *)p = Make_header (Wosize_whsize (sz), 0, Caml_white); + *(header_t *)p = Make_header (Wosize_whsize (sz), 0, color); if (do_merge) caml_fl_merge_block (Bp_hp (p)); size -= sz; p += sz; Index: byterun/freelist.h =================================================================== --- byterun/freelist.h (.../vendor/ocaml/4.00.0) (revision 103) +++ byterun/freelist.h (.../trunk/ocamlxsim/3.1) (revision 103) @@ -29,7 +29,7 @@ void caml_fl_reset (void); char *caml_fl_merge_block (char *); void caml_fl_add_blocks (char *); -void caml_make_free_blocks (value *, mlsize_t, int); +void caml_make_free_blocks (value *, mlsize_t, int, int); void caml_set_allocation_policy (uintnat); Index: byterun/compact.c =================================================================== --- byterun/compact.c (.../vendor/ocaml/4.00.0) (revision 103) +++ byterun/compact.c (.../trunk/ocamlxsim/3.1) (revision 103) @@ -331,7 +331,7 @@ word q = *p; if (Color_hd (q) == Caml_white){ size_t sz = Bhsize_hd (q); - char *newadr = compact_allocate (sz); Assert (newadr <= (char *)p); + char *newadr = compact_allocate (sz); memmove (newadr, p, sz); p += Wsize_bsize (sz); }else{ @@ -384,7 +384,8 @@ while (ch != NULL){ if (Chunk_size (ch) > Chunk_alloc (ch)){ caml_make_free_blocks ((value *) (ch + Chunk_alloc (ch)), - Wsize_bsize (Chunk_size(ch)-Chunk_alloc(ch)), 1); + Wsize_bsize (Chunk_size(ch)-Chunk_alloc(ch)), 1, + Caml_white); } ch = Chunk_next (ch); } @@ -397,7 +398,7 @@ void caml_compact_heap (void) { - uintnat target_size, live; + uintnat target_words, target_size, live; do_compaction (); /* Compaction may fail to shrink the heap to a reasonable size @@ -414,26 +415,33 @@ See PR#5389 */ /* We compute: - freewords = caml_fl_cur_size (exact) - heapsize = caml_heap_size (exact) - live = heap_size - freewords - target_size = live * (1 + caml_percent_free / 100) - = live / 100 * (100 + caml_percent_free) - We add 1 to live/100 to make sure it isn't 0. + freewords = caml_fl_cur_size (exact) + heapwords = Wsize_bsize (caml_heap_size) (exact) + live = heapwords - freewords + wanted = caml_percent_free * (live / 100 + 1) (same as in do_compaction) + target_words = live + wanted + We add one page to make sure a small difference in counting sizes + won't make [do_compaction] keep the second block (and break all sorts + of invariants). We recompact if target_size < heap_size / 2 */ - live = caml_stat_heap_size - Bsize_wsize (caml_fl_cur_size); - target_size = (live / 100 + 1) * (100 + caml_percent_free); - target_size = caml_round_heap_chunk_size (target_size); + live = Wsize_bsize (caml_stat_heap_size) - caml_fl_cur_size; + target_words = live + caml_percent_free * (live / 100 + 1) + + Wsize_bsize (Page_size); + target_size = caml_round_heap_chunk_size (Bsize_wsize (target_words)); if (target_size < caml_stat_heap_size / 2){ char *chunk; - /* round it up to a page size */ + caml_gc_message (0x10, "Recompacting heap (target=%luk)\n", + target_size / 1024); + chunk = caml_alloc_for_heap (target_size); if (chunk == NULL) return; + /* PR#5757: we need to make the new blocks blue, or they won't be + recognized as free by the recompaction. */ caml_make_free_blocks ((value *) chunk, - Wsize_bsize (Chunk_size (chunk)), 0); + Wsize_bsize (Chunk_size (chunk)), 0, Caml_blue); if (caml_page_table_add (In_heap, chunk, chunk + Chunk_size (chunk)) != 0){ caml_free_for_heap (chunk); return; @@ -448,6 +456,7 @@ do_compaction (); Assert (caml_stat_heap_chunks == 1); Assert (Chunk_next (caml_heap_start) == NULL); + Assert (caml_stat_heap_size == Chunk_size (chunk)); } } Index: byterun/major_gc.c =================================================================== --- byterun/major_gc.c (.../vendor/ocaml/4.00.0) (revision 103) +++ byterun/major_gc.c (.../trunk/ocamlxsim/3.1) (revision 103) @@ -496,7 +496,7 @@ caml_fl_init_merge (); caml_make_free_blocks ((value *) caml_heap_start, - Wsize_bsize (caml_stat_heap_size), 1); + Wsize_bsize (caml_stat_heap_size), 1, Caml_white); caml_gc_phase = Phase_idle; gray_vals_size = 2048; gray_vals = (value *) malloc (gray_vals_size * sizeof (value)); Index: testsuite/tests/regression/pr5757/pr5757.ml =================================================================== --- testsuite/tests/regression/pr5757/pr5757.ml (.../vendor/ocaml/4.00.0) (revision 0) +++ testsuite/tests/regression/pr5757/pr5757.ml (.../trunk/ocamlxsim/3.1) (revision 103) @@ -0,0 +1,5 @@ +Random.init 3;; +for i = 0 to 100_000 do + ignore (String.create (Random.int 1_000_000)) +done;; +Printf.printf "hello world\n";; Index: testsuite/tests/regression/pr5757/pr5757.reference =================================================================== --- testsuite/tests/regression/pr5757/pr5757.reference (.../vendor/ocaml/4.00.0) (revision 0) +++ testsuite/tests/regression/pr5757/pr5757.reference (.../trunk/ocamlxsim/3.1) (revision 103) @@ -0,0 +1 @@ +hello world Index: testsuite/tests/regression/pr5757/Makefile =================================================================== --- testsuite/tests/regression/pr5757/Makefile (.../vendor/ocaml/4.00.0) (revision 0) +++ testsuite/tests/regression/pr5757/Makefile (.../trunk/ocamlxsim/3.1) (revision 103) @@ -0,0 +1,4 @@ +MAIN_MODULE=pr5757 + +include ../../../makefiles/Makefile.one +include ../../../makefiles/Makefile.common Index: asmrun/signals_osdep.h =================================================================== --- asmrun/signals_osdep.h (.../vendor/ocaml/4.00.0) (revision 103) +++ asmrun/signals_osdep.h (.../trunk/ocamlxsim/3.1) (revision 103) @@ -34,7 +34,7 @@ /****************** AMD64, MacOSX */ -#elif defined(TARGET_amd64) && defined (SYS_macosx) +#elif (defined(TARGET_amd64) || (defined(TARGET_i386) && defined(__x86_64))) && defined (SYS_macosx) #define DECLARE_SIGNAL_HANDLER(name) \ static void name(int sig, siginfo_t * info, void * context)