about summary refs log tree commit diff
path: root/src/rt/rust_builtin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rt/rust_builtin.cpp')
-rw-r--r--src/rt/rust_builtin.cpp222
1 files changed, 45 insertions, 177 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 044239065e9..a8929677aff 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -206,18 +206,14 @@ str_byte_len(rust_task *task, rust_str *s)
 }
 
 extern "C" CDECL rust_str *
-str_from_ivec(rust_task *task, rust_ivec *v)
+str_from_vec(rust_task *task, rust_vec **vp)
 {
-    bool is_interior = v->fill || !v->payload.ptr;
-    uintptr_t fill = is_interior ? v->fill : v->payload.ptr->fill;
-    void *data = is_interior ? v->payload.data : v->payload.ptr->data;
-
-    rust_str *st =
-        vec_alloc_with_data(task,
-                            fill + 1,   // +1 to fit at least '\0'
-                            fill,
-                            1,
-                            fill ? data : NULL);
+    rust_vec* v = *vp;
+    rust_str *st = vec_alloc_with_data(task,
+                                       v->fill + 1, // +1 for \0
+                                       v->fill,
+                                       1,
+                                       &v->data[0]);
     if (!st) {
         task->fail();
         return NULL;
@@ -226,6 +222,33 @@ str_from_ivec(rust_task *task, rust_ivec *v)
     return st;
 }
 
+extern "C" CDECL void
+vec_reserve_shared(rust_task* task, type_desc* ty, rust_vec** vp,
+                    size_t n_elts) {
+    size_t new_sz = n_elts * ty->size;
+    if (new_sz > (*vp)->alloc) {
+        size_t new_alloc = next_power_of_two(new_sz);
+        *vp = (rust_vec*)task->kernel->realloc(*vp, new_alloc +
+                                                sizeof(rust_vec));
+        (*vp)->alloc = new_alloc;
+    }
+}
+
+/**
+ * Copies elements in an unsafe buffer to the given interior vector. The
+ * vector must have size zero.
+ */
+extern "C" CDECL rust_vec*
+vec_from_buf_shared(rust_task *task, type_desc *ty,
+                     void *ptr, size_t count) {
+    size_t fill = ty->size * count;
+    rust_vec* v = (rust_vec*)task->kernel->malloc(fill + sizeof(rust_vec),
+                                                    "vec_from_buf");
+    v->fill = v->alloc = fill;
+    memmove(&v->data[0], ptr, fill);
+    return v;
+}
+
 extern "C" CDECL rust_str *
 str_from_cstr(rust_task *task, char *sbuf)
 {
@@ -471,23 +494,19 @@ rust_list_files(rust_task *task, rust_str *path) {
       closedir(dirp);
   }
 #endif
-  size_t str_ivec_sz =
-      sizeof(size_t)            // fill
-      + sizeof(size_t)          // alloc
-      + sizeof(rust_str *) * 4; // payload
-  rust_box *box = (rust_box *)task->malloc(sizeof(rust_box) + str_ivec_sz,
-                                           "rust_box(list_files_ivec)");
+  rust_box *box =
+      (rust_box *)task->malloc(sizeof(rust_box) + sizeof(rust_vec*),
+                               "rust_box(list_files_vec)");
+  rust_vec* vec =
+      (rust_vec*)task->kernel->malloc(vec_size<rust_str*>(strings.size()),
+                                       "list_files_vec");
 
   box->ref_count = 1;
-  rust_ivec *iv = (rust_ivec *)&box->data;
-  iv->fill = 0;
-
-  size_t alloc_sz = sizeof(rust_str *) * strings.size();
-  iv->alloc = alloc_sz;
-  iv->payload.ptr = (rust_ivec_heap *)
-      task->kernel->malloc(alloc_sz + sizeof(size_t), "files ivec");
-  iv->payload.ptr->fill = alloc_sz;
-  memcpy(&iv->payload.ptr->data, strings.data(), alloc_sz);
+  rust_vec** box_content = (rust_vec**)&box->data[0];
+  *box_content = vec;
+  size_t alloc_sz = sizeof(rust_str*) * strings.size();
+  vec->fill = vec->alloc = alloc_sz;
+  memcpy(&vec->data[0], strings.data(), alloc_sz);
   return box;
 }
 
@@ -549,157 +568,6 @@ nano_time(rust_task *task, uint64_t *ns) {
     *ns = t.time_ns();
 }
 
-/**
- * Preallocates the exact number of bytes in the given interior vector.
- */
-extern "C" CDECL void
-ivec_reserve(rust_task *task, type_desc *ty, rust_ivec *v, size_t n_elems)
-{
-    size_t new_alloc = n_elems * ty->size;
-    if (new_alloc <= v->alloc)
-        return;     // Already big enough.
-
-    rust_ivec_heap *heap_part;
-    if (v->fill || !v->payload.ptr) {
-        // On stack; spill to heap.
-        heap_part = (rust_ivec_heap *)task->malloc(new_alloc +
-                                                   sizeof(size_t),
-                                                   "ivec reserve heap part");
-        heap_part->fill = v->fill;
-        memcpy(&heap_part->data, v->payload.data, v->fill);
-
-        v->fill = 0;
-        v->payload.ptr = heap_part;
-    } else {
-        // On heap; resize.
-        heap_part = (rust_ivec_heap *)
-            task->realloc(v->payload.ptr,
-                          new_alloc + sizeof(size_t));
-        v->payload.ptr = heap_part;
-    }
-
-    v->alloc = new_alloc;
-}
-
-/**
- * Preallocates the exact number of bytes in the given interior vector.
- */
-extern "C" CDECL void
-ivec_reserve_shared(rust_task *task, type_desc *ty, rust_ivec *v,
-                    size_t n_elems)
-{
-    size_t new_alloc = n_elems * ty->size;
-    if (new_alloc <= v->alloc)
-        return;     // Already big enough.
-
-    rust_ivec_heap *heap_part;
-    if (v->fill || !v->payload.ptr) {
-        // On stack; spill to heap.
-        heap_part = (rust_ivec_heap *)
-            task->kernel->malloc(new_alloc + sizeof(size_t),
-                                 "ivec reserve shared");
-        heap_part->fill = v->fill;
-        memcpy(&heap_part->data, v->payload.data, v->fill);
-
-        v->fill = 0;
-        v->payload.ptr = heap_part;
-    } else {
-        // On heap; resize.
-        heap_part = (rust_ivec_heap *)task->kernel->realloc(v->payload.ptr,
-                                                new_alloc + sizeof(size_t));
-        v->payload.ptr = heap_part;
-    }
-
-    v->alloc = new_alloc;
-}
-
-/**
- * Returns true if the given vector is on the heap and false if it's on the
- * stack.
- */
-extern "C" CDECL bool
-ivec_on_heap(rust_task *task, type_desc *ty, rust_ivec *v)
-{
-    return !v->fill && v->payload.ptr;
-}
-
-/**
- * Returns an unsafe pointer to the data part of an interior vector.
- */
-extern "C" CDECL void *
-ivec_to_ptr(rust_task *task, type_desc *ty, rust_ivec *v)
-{
-    return v->fill ? v->payload.data : v->payload.ptr->data;
-}
-
-static size_t
-get_ivec_size(rust_ivec *v)
-{
-    if (v->fill)
-        return v->fill;
-    if (v->payload.ptr)
-        return v->payload.ptr->fill;
-    return 0;
-}
-
-/**
- * Copies elements in an unsafe buffer to the given interior vector. The
- * vector must have size zero.
- */
-extern "C" CDECL void
-ivec_copy_from_buf(rust_task *task, type_desc *ty, rust_ivec *v, void *ptr,
-                   size_t count)
-{
-    size_t old_size = get_ivec_size(v);
-    if (old_size) {
-        task->fail();
-        return;
-    }
-
-    ivec_reserve(task, ty, v, count);
-
-    size_t new_size = count * ty->size;
-    if (v->fill || !v->payload.ptr) {
-        // On stack.
-        memmove(v->payload.data, ptr, new_size);
-        v->fill = new_size;
-        return;
-    }
-
-    // On heap.
-    memmove(v->payload.ptr->data, ptr, new_size);
-    v->payload.ptr->fill = new_size;
-}
-
-/**
- * Copies elements in an unsafe buffer to the given interior vector. The
- * vector must have size zero.
- */
-extern "C" CDECL void
-ivec_copy_from_buf_shared(rust_task *task, type_desc *ty, rust_ivec *v,
-                   void *ptr, size_t count)
-{
-    size_t old_size = get_ivec_size(v);
-    if (old_size) {
-        task->fail();
-        return;
-    }
-
-    ivec_reserve_shared(task, ty, v, count);
-
-    size_t new_size = count * ty->size;
-    if (v->fill || !v->payload.ptr) {
-        // On stack.
-        memmove(v->payload.data, ptr, new_size);
-        v->fill = new_size;
-        return;
-    }
-
-    // On heap.
-    memmove(v->payload.ptr->data, ptr, new_size);
-    v->payload.ptr->fill = new_size;
-}
-
 extern "C" CDECL void
 pin_task(rust_task *task) {
     task->pin();