diff options
| author | Rob Arnold <robarnold@cs.cmu.edu> | 2011-07-05 22:55:41 -0700 |
|---|---|---|
| committer | Rob Arnold <robarnold@cs.cmu.edu> | 2011-07-06 20:41:24 -0700 |
| commit | f6117173c9f26efdcf50cb664d006ea2bdf0d0cb (patch) | |
| tree | 04f20cc1e1a057d520b9329e343ef6b63ddb52e9 /src/rt/rust_builtin.cpp | |
| parent | 2e2e1f7cb36aeac0abb730a752fcd78cf91a380f (diff) | |
| download | rust-f6117173c9f26efdcf50cb664d006ea2bdf0d0cb.tar.gz rust-f6117173c9f26efdcf50cb664d006ea2bdf0d0cb.zip | |
Allocate rust_ivec buffers out of the kernel pool
The duplication of upcalls is due to the fact that the runtime is shared between stage0/rustc and stage1/rustc. Once snapshots are updated, they should be de-duplicated.
Diffstat (limited to 'src/rt/rust_builtin.cpp')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 6438c549c55..872a317ca38 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -649,6 +649,37 @@ ivec_reserve(rust_task *task, type_desc *ty, rust_ivec *v, size_t n_elems) } /** + * 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)); + 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. */ @@ -706,6 +737,35 @@ ivec_copy_from_buf(rust_task *task, type_desc *ty, rust_ivec *v, void *ptr, 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(1); + 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(); |
