diff options
-rw-r--r-- | Changes | 6 | ||||
-rw-r--r-- | byterun/alloc.c | 47 | ||||
-rw-r--r-- | byterun/array.c | 19 | ||||
-rw-r--r-- | byterun/intern.c | 12 |
4 files changed, 44 insertions, 40 deletions
@@ -31,6 +31,12 @@ Working version - GPR#1150: Fix typo in arm64 assembler directives (KC Sivaramakrishnan) +- GPR#1143: tweaked several allocation functions in the runtime by + checking for likely conditions before unlikely ones and eliminating + some redundant checks. + (Markus Mottl, review by Alain Frisch, Xavier Leroy, Gabriel Scherer, + Mark Shinwell and Leo White) + ### Standard library: - GRP#1119: Change Set (private) type to inline records. diff --git a/byterun/alloc.c b/byterun/alloc.c index fee22ed4d6..39377ccc65 100644 --- a/byterun/alloc.c +++ b/byterun/alloc.c @@ -38,12 +38,14 @@ CAMLexport value caml_alloc (mlsize_t wosize, tag_t tag) CAMLassert (tag < 256); CAMLassert (tag != Infix_tag); - if (wosize == 0){ - result = Atom (tag); - }else if (wosize <= Max_young_wosize){ - Alloc_small (result, wosize, tag); - if (tag < No_scan_tag){ - for (i = 0; i < wosize; i++) Field (result, i) = Val_unit; + if (wosize <= Max_young_wosize){ + if (wosize == 0){ + result = Atom (tag); + }else{ + Alloc_small (result, wosize, tag); + if (tag < No_scan_tag){ + for (i = 0; i < wosize; i++) Field (result, i) = Val_unit; + } } }else{ result = caml_alloc_shr (wosize, tag); @@ -138,19 +140,15 @@ CAMLexport value caml_alloc_array(value (*funct)(char const *), nbr = 0; while (arr[nbr] != 0) nbr++; - if (nbr == 0) { - CAMLreturn (Atom(0)); - } else { - result = caml_alloc (nbr, 0); - for (n = 0; n < nbr; n++) { - /* The two statements below must be separate because of evaluation - order (don't take the address &Field(result, n) before - calling funct, which may cause a GC and move result). */ - v = funct(arr[n]); - caml_modify(&Field(result, n), v); - } - CAMLreturn (result); + result = caml_alloc (nbr, 0); + for (n = 0; n < nbr; n++) { + /* The two statements below must be separate because of evaluation + order (don't take the address &Field(result, n) before + calling funct, which may cause a GC and move result). */ + v = funct(arr[n]); + caml_modify(&Field(result, n), v); } + CAMLreturn (result); } /* [len] is a number of floats */ @@ -161,10 +159,11 @@ CAMLprim value caml_alloc_float_array(mlsize_t len) /* For consistency with [caml_make_vect], which can't tell whether it should create a float array or not when the size is zero, the tag is set to zero when the size is zero. */ - if (wosize == 0) - return Atom(0); - else if (wosize <= Max_young_wosize){ - Alloc_small (result, wosize, Double_array_tag); + if (wosize <= Max_young_wosize){ + if (wosize == 0) + return Atom(0); + else + Alloc_small (result, wosize, Double_array_tag); }else { result = caml_alloc_shr (wosize, Double_array_tag); result = caml_check_urgent_gc (result); @@ -195,8 +194,6 @@ CAMLexport int caml_convert_flag_list(value list, int *flags) CAMLprim value caml_alloc_dummy(value size) { mlsize_t wosize = Long_val(size); - - if (wosize == 0) return Atom(0); return caml_alloc (wosize, 0); } @@ -211,8 +208,6 @@ CAMLprim value caml_alloc_dummy_function(value size,value arity) CAMLprim value caml_alloc_dummy_float (value size) { mlsize_t wosize = Long_val(size) * Double_wosize; - - if (wosize == 0) return Atom(0); return caml_alloc (wosize, 0); } diff --git a/byterun/array.c b/byterun/array.c index 4b0e834df1..d7eb9508b4 100644 --- a/byterun/array.c +++ b/byterun/array.c @@ -149,12 +149,13 @@ CAMLprim value caml_make_float_vect(value len) { mlsize_t wosize = Long_val(len) * Double_wosize; value result; - if (wosize == 0) - return Atom(0); - else if (wosize <= Max_young_wosize){ + if (wosize <= Max_young_wosize){ + if (wosize == 0) + return Atom(0); + else #define Setup_for_gc #define Restore_after_gc - Alloc_small (result, wosize, Double_array_tag); + Alloc_small (result, wosize, Double_array_tag); #undef Setup_for_gc #undef Restore_after_gc }else if (wosize > Max_wosize) @@ -190,13 +191,13 @@ CAMLprim value caml_make_vect(value len, value init) Store_double_field(res, i, d); } } else { - if (size > Max_wosize) caml_invalid_argument("Array.make"); if (size <= Max_young_wosize) { uintnat profinfo; Get_my_profinfo_with_cached_backtrace(profinfo, size); res = caml_alloc_small_with_my_or_given_profinfo(size, 0, profinfo); for (i = 0; i < size; i++) Field(res, i) = init; } + else if (size > Max_wosize) caml_invalid_argument("Array.make"); else if (Is_block(init) && Is_young(init)) { /* We don't want to create so many major-to-minor references, so [init] is moved to the major heap by doing a minor GC. */ @@ -337,10 +338,6 @@ static value caml_array_gather(intnat num_arrays, } CAMLassert(pos == size); } - else if (size > Max_wosize) { - /* Array of values, too big. */ - caml_invalid_argument("Array.concat"); - } else if (size <= Max_young_wosize) { /* Array of values, small enough to fit in young generation. We can use memcpy directly. */ @@ -352,6 +349,10 @@ static value caml_array_gather(intnat num_arrays, pos += lengths[i]; } CAMLassert(pos == size); + } + else if (size > Max_wosize) { + /* Array of values, too big. */ + caml_invalid_argument("Array.concat"); } else { /* Array of values, must be allocated in old generation and filled using caml_initialize. */ diff --git a/byterun/intern.c b/byterun/intern.c index 9144f874c5..9b5dc951f5 100644 --- a/byterun/intern.c +++ b/byterun/intern.c @@ -570,7 +570,7 @@ static void intern_alloc(mlsize_t whsize, mlsize_t num_objects, return; } wosize = Wosize_whsize(whsize); - if (wosize > Max_wosize || outside_heap) { + if (outside_heap || wosize > Max_wosize) { /* Round desired size up to next page */ asize_t request = ((Bsize_wsize(whsize) + Page_size - 1) >> Page_log) << Page_log; @@ -585,10 +585,12 @@ static void intern_alloc(mlsize_t whsize, mlsize_t num_objects, CAMLassert (intern_block == 0); } else { /* this is a specialised version of caml_alloc from alloc.c */ - if (wosize == 0){ - intern_block = Atom (String_tag); - }else if (wosize <= Max_young_wosize){ - intern_block = caml_alloc_small (wosize, String_tag); + if (wosize <= Max_young_wosize){ + if (wosize == 0){ + intern_block = Atom (String_tag); + } else { + intern_block = caml_alloc_small (wosize, String_tag); + } }else{ intern_block = caml_alloc_shr_no_raise (wosize, String_tag); /* do not do the urgent_gc check here because it might darken |