summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes6
-rw-r--r--byterun/alloc.c47
-rw-r--r--byterun/array.c19
-rw-r--r--byterun/intern.c12
4 files changed, 44 insertions, 40 deletions
diff --git a/Changes b/Changes
index 6633637b12..f2cc7d74b9 100644
--- a/Changes
+++ b/Changes
@@ -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