summaryrefslogtreecommitdiff
path: root/typd_mlc.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-06-07 08:22:35 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-06-07 14:10:37 +0300
commit1f45c9a9f32b60e3a76e9397e956a47d485f8679 (patch)
tree82f15e89fd5c3b87b640902b1bc1126d0b411a2e /typd_mlc.c
parentc3cccd9456208f23a7a1e669f9f13adb930da7f1 (diff)
downloadbdwgc-1f45c9a9f32b60e3a76e9397e956a47d485f8679.tar.gz
Avoid code duplication in GC_make_array_descriptor
(refactoring) * typd_mlc.c (GC_make_sequence_descriptor): Move definition upper and replace its declaration; change type of result local variable from SequenceDescriptor* to complex_descriptor*. * typd_mlc.c (COMPLEX, LEAF): Reorder macro definition. * typd_mlc.c (GC_make_leaf_descriptor): New STATIC function. * typd_mlc.c (GC_make_array_descriptor): Reformat comment and code; use GC_make_leaf_descriptor(); change type of one_element and beginning local variables from LeafDescriptor* to complex_descriptor*; rewrite code to call GC_make_sequence_descriptor only in one place.
Diffstat (limited to 'typd_mlc.c')
-rw-r--r--typd_mlc.c187
1 files changed, 78 insertions, 109 deletions
diff --git a/typd_mlc.c b/typd_mlc.c
index 08c08bb1..9b7cfbf0 100644
--- a/typd_mlc.c
+++ b/typd_mlc.c
@@ -168,29 +168,57 @@ STATIC GC_descr GC_double_descr(GC_descr descriptor, word nwords)
return descriptor;
}
-STATIC complex_descriptor *
-GC_make_sequence_descriptor(complex_descriptor *first,
- complex_descriptor *second);
-
-/* Build a descriptor for an array with nelements elements, */
-/* each of which can be described by a simple descriptor. */
-/* We try to optimize some common cases. */
-/* If the result is COMPLEX, then a complex_descr* is returned */
-/* in *complex_d. */
-/* If the result is LEAF, then we built a LeafDescriptor in */
-/* the structure pointed to by leaf. */
-/* The tag in the leaf structure is not set. */
-/* If the result is SIMPLE, then a GC_descr */
-/* is returned in *simple_d. */
-/* If the result is NO_MEM, then */
-/* we failed to allocate the descriptor. */
-/* The implementation knows that GC_DS_LENGTH is 0. */
-/* *leaf, *complex_d, and *simple_d may be used as temporaries */
-/* during the construction. */
-#define COMPLEX 2
-#define LEAF 1
+STATIC complex_descriptor *GC_make_leaf_descriptor(size_t size,
+ size_t nelements,
+ GC_descr descriptor)
+{
+ complex_descriptor *result = (complex_descriptor *)
+ GC_malloc_atomic(sizeof(struct LeafDescriptor));
+
+ if (EXPECT(NULL == result, FALSE)) return NULL;
+
+ result -> ld.ld_tag = LEAF_TAG;
+ result -> ld.ld_size = size;
+ result -> ld.ld_nelements = nelements;
+ result -> ld.ld_descriptor = descriptor;
+ return result;
+}
+
+STATIC complex_descriptor *GC_make_sequence_descriptor(
+ complex_descriptor *first,
+ complex_descriptor *second)
+{
+ complex_descriptor *result = (complex_descriptor *)
+ GC_malloc(sizeof(struct SequenceDescriptor));
+
+ if (EXPECT(NULL == result, FALSE)) return NULL;
+
+ /* Can't result in overly conservative marking, since tags are */
+ /* very small integers. Probably faster than maintaining type info. */
+ result -> sd.sd_tag = SEQUENCE_TAG;
+ result -> sd.sd_first = first;
+ result -> sd.sd_second = second;
+ GC_dirty(result);
+ REACHABLE_AFTER_DIRTY(first);
+ REACHABLE_AFTER_DIRTY(second);
+ return result;
+}
+
#define SIMPLE 0
+#define LEAF 1
+#define COMPLEX 2
#define NO_MEM (-1)
+
+/* Build a descriptor for an array with nelements elements, each of */
+/* which can be described by a simple descriptor. We try to optimize */
+/* some common cases. If the result is COMPLEX, then a complex_descr* */
+/* value is returned in *complex_d. If the result is LEAF, then */
+/* a LeafDescriptor value is built in the structure pointed to by leaf. */
+/* The tag in the leaf structure is not set. If the result is SIMPLE, */
+/* then a GC_descr value is returned in *simple_d. If the result is */
+/* NO_MEM, then we failed to allocate the descriptor. */
+/* The implementation knows that GC_DS_LENGTH is 0. *leaf, *complex_d */
+/* and *simple_d may be used as temporaries during the construction. */
STATIC int GC_make_array_descriptor(size_t nelements, size_t size,
GC_descr descriptor, GC_descr *simple_d,
complex_descriptor **complex_d,
@@ -200,87 +228,49 @@ STATIC int GC_make_array_descriptor(size_t nelements, size_t size,
/* For larger arrays, we try to combine descriptors of adjacent */
/* descriptors to speed up marking, and to reduce the amount */
/* of space needed on the mark stack. */
+
if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) {
if (descriptor == (GC_descr)size) {
*simple_d = nelements * descriptor;
return SIMPLE;
- } else if ((word)descriptor == 0) {
- *simple_d = (GC_descr)0;
+ } else if (0 == descriptor) {
+ *simple_d = 0;
return SIMPLE;
}
}
if (nelements <= OPT_THRESHOLD) {
if (nelements <= 1) {
- if (nelements == 1) {
- *simple_d = descriptor;
- return SIMPLE;
- } else {
- *simple_d = (GC_descr)0;
- return SIMPLE;
- }
+ *simple_d = nelements == 1 ? descriptor : 0;
+ return SIMPLE;
}
} else if (size <= BITMAP_BITS/2
&& (descriptor & GC_DS_TAGS) != GC_DS_PROC
&& (size & (sizeof(word)-1)) == 0) {
- int result =
- GC_make_array_descriptor(nelements/2, 2*size,
- GC_double_descr(descriptor,
- BYTES_TO_WORDS(size)),
- simple_d, complex_d, leaf);
- if ((nelements & 1) == 0) {
- return result;
- } else {
- struct LeafDescriptor * one_element =
- (struct LeafDescriptor *)
- GC_malloc_atomic(sizeof(struct LeafDescriptor));
-
- if (EXPECT(NO_MEM == result || NULL == one_element, FALSE))
- return NO_MEM;
- one_element -> ld_tag = LEAF_TAG;
- one_element -> ld_size = size;
- one_element -> ld_nelements = 1;
- one_element -> ld_descriptor = descriptor;
- switch(result) {
- case SIMPLE:
- {
- struct LeafDescriptor * beginning =
- (struct LeafDescriptor *)
- GC_malloc_atomic(sizeof(struct LeafDescriptor));
- if (EXPECT(NULL == beginning, FALSE)) return NO_MEM;
- beginning -> ld_tag = LEAF_TAG;
- beginning -> ld_size = size;
- beginning -> ld_nelements = 1;
- beginning -> ld_descriptor = *simple_d;
- *complex_d = GC_make_sequence_descriptor(
- (complex_descriptor *)beginning,
- (complex_descriptor *)one_element);
- break;
- }
- case LEAF:
- {
- struct LeafDescriptor * beginning =
- (struct LeafDescriptor *)
- GC_malloc_atomic(sizeof(struct LeafDescriptor));
- if (EXPECT(NULL == beginning, FALSE)) return NO_MEM;
- beginning -> ld_tag = LEAF_TAG;
- beginning -> ld_size = leaf -> ld_size;
- beginning -> ld_nelements = leaf -> ld_nelements;
- beginning -> ld_descriptor = leaf -> ld_descriptor;
- *complex_d = GC_make_sequence_descriptor(
- (complex_descriptor *)beginning,
- (complex_descriptor *)one_element);
- break;
- }
- case COMPLEX:
- *complex_d = GC_make_sequence_descriptor(
- *complex_d,
- (complex_descriptor *)one_element);
- break;
- }
- if (EXPECT(NULL == *complex_d, FALSE)) return NO_MEM;
-
- return COMPLEX;
+ complex_descriptor *one_element, *beginning;
+ int result = GC_make_array_descriptor(nelements / 2, 2 * size,
+ GC_double_descr(descriptor,
+ BYTES_TO_WORDS(size)),
+ simple_d, complex_d, leaf);
+
+ if ((nelements & 1) == 0 || EXPECT(NO_MEM == result, FALSE))
+ return result;
+
+ one_element = GC_make_leaf_descriptor(size, 1, descriptor);
+ if (EXPECT(NULL == one_element, FALSE)) return NO_MEM;
+
+ beginning = *complex_d;
+ if (result != COMPLEX) {
+ beginning = SIMPLE == result ?
+ GC_make_leaf_descriptor(size, 1, *simple_d) :
+ GC_make_leaf_descriptor(leaf -> ld_size,
+ leaf -> ld_nelements,
+ leaf -> ld_descriptor);
+ if (EXPECT(NULL == beginning, FALSE)) return NO_MEM;
}
+ *complex_d = GC_make_sequence_descriptor(beginning, one_element);
+ if (EXPECT(NULL == *complex_d, FALSE)) return NO_MEM;
+
+ return COMPLEX;
}
leaf -> ld_size = size;
@@ -289,27 +279,6 @@ STATIC int GC_make_array_descriptor(size_t nelements, size_t size,
return LEAF;
}
-STATIC complex_descriptor *
-GC_make_sequence_descriptor(complex_descriptor *first,
- complex_descriptor *second)
-{
- struct SequenceDescriptor * result =
- (struct SequenceDescriptor *)
- GC_malloc(sizeof(struct SequenceDescriptor));
-
- if (EXPECT(NULL == result, FALSE)) return NULL;
-
- /* Can't result in overly conservative marking, since tags are */
- /* very small integers. Probably faster than maintaining type info. */
- result -> sd_tag = SEQUENCE_TAG;
- result -> sd_first = first;
- result -> sd_second = second;
- GC_dirty(result);
- REACHABLE_AFTER_DIRTY(first);
- REACHABLE_AFTER_DIRTY(second);
- return (complex_descriptor *)result;
-}
-
STATIC mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr,
mse * mark_stack_limit, word env);