Remove dynastack support from runtime

Issue #1982
This commit is contained in:
Marijn Haverbeke 2012-03-15 17:34:57 +01:00
parent 146b61189a
commit 76d07f4056
7 changed files with 0 additions and 369 deletions

View File

@ -56,7 +56,6 @@ RUNTIME_CS_$(1) := \
rt/rust_srv.cpp \
rt/rust_kernel.cpp \
rt/rust_shape.cpp \
rt/rust_obstack.cpp \
rt/rust_abi.cpp \
rt/rust_cc.cpp \
rt/rust_debug.cpp \
@ -76,7 +75,6 @@ RUNTIME_HDR_$(1) := rt/globals.h \
rt/rust_internal.h \
rt/rust_util.h \
rt/rust_env.h \
rt/rust_obstack.h \
rt/rust_unwind.h \
rt/rust_upcall.h \
rt/rust_port.h \

View File

@ -1,195 +0,0 @@
// Object stacks, used in lieu of dynamically-sized frames.
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <new>
#include <stdint.h>
#include "rust_internal.h"
#include "rust_obstack.h"
#include "rust_shape.h"
#include "rust_task.h"
// ISAAC, let go of max()!
#ifdef max
#undef max
#endif
#undef DPRINT
#define DPRINT(fmt, ...)
const size_t DEFAULT_CHUNK_SIZE = 128;
const size_t MAX_CHUNK_SIZE = (1024*64);
const size_t DEFAULT_ALIGNMENT = 16;
// A single type-tagged allocation in a chunk.
struct rust_obstack_alloc {
size_t len;
const type_desc *tydesc;
uint32_t pad0; // FIXME: x86-specific
uint32_t pad1;
uint8_t data[];
rust_obstack_alloc(size_t in_len, const type_desc *in_tydesc)
: len(in_len), tydesc(in_tydesc) {}
};
void *
rust_obstack_chunk::alloc(size_t len, type_desc *tydesc) {
DPRINT("alloc(%lu) alen=%lu size=%lu\n", len, alen, size);
size_t aligned_alen = align_to(alen, DEFAULT_ALIGNMENT);
size_t end_alen = aligned_alen + sizeof(rust_obstack_alloc) + len;
if (end_alen > size) {
DPRINT("Not enough space, len=%lu alen=%lu aligned=%lu end=%lu!\n",
len, alen, aligned_alen, end_alen);
return NULL; // Not enough space.
}
rust_obstack_alloc *a =
new(data + aligned_alen) rust_obstack_alloc(len, tydesc);
memset(a->data, '\0', len); // FIXME: For GC.
alen = end_alen;
return &a->data;
}
bool
rust_obstack_chunk::free(void *ptr) {
uint8_t *p = (uint8_t *)ptr;
if (p < data || p > data + size)
return false;
assert(p <= data + alen);
alen = (size_t)(p - data);
return true;
}
void *
rust_obstack_chunk::mark() {
uint8_t *m = data + alen;
assert (m >= data && m <= data+size);
return m;
}
// Allocates the given number of bytes in a new chunk.
void *
rust_obstack::alloc_new(size_t len, type_desc *tydesc) {
size_t default_chunk_size = DEFAULT_CHUNK_SIZE;
if (chunk) {
default_chunk_size = std::min(chunk->size * 2, MAX_CHUNK_SIZE);
}
size_t chunk_size = std::max(sizeof(rust_obstack_alloc) + len,
default_chunk_size);
void *ptr = task->malloc(sizeof(rust_obstack_chunk) + chunk_size,
"obstack");
DPRINT("making new chunk at %p, len %lu\n", ptr, chunk_size);
chunk = new(ptr) rust_obstack_chunk(chunk, chunk_size);
return chunk->alloc(len, tydesc);
}
rust_obstack::~rust_obstack() {
while (chunk) {
rust_obstack_chunk *prev = chunk->prev;
task->free(chunk);
chunk = prev;
}
}
void *
rust_obstack::alloc(size_t len, type_desc *tydesc) {
if (!chunk)
return alloc_new(len, tydesc);
void *ptr = chunk->alloc(len, tydesc);
ptr = ptr ? ptr : alloc_new(len, tydesc);
return ptr;
}
void
rust_obstack::free(void *ptr) {
if (!ptr)
return;
assert(chunk);
while (!chunk->free(ptr)) {
DPRINT("deleting chunk at %p (ptr=%p, data=%p-%p)\n",
chunk, ptr,
chunk->data, chunk->data + chunk->size);
rust_obstack_chunk *prev = chunk->prev;
task->free(chunk);
chunk = prev;
assert(chunk);
}
}
void *
rust_obstack::mark() {
void *m = chunk ? chunk->mark() : NULL;
DPRINT("mark == %p, chunk == %p, data == %p-%p\n", m, chunk,
(chunk ? chunk->data : NULL),
(chunk ? chunk->data + chunk->size : NULL));
return m;
}
// Iteration over self-describing obstacks
std::pair<const type_desc *,void *>
rust_obstack::iterator::operator*() const {
return std::make_pair(alloc->tydesc, alloc->data);
}
rust_obstack::iterator &
rust_obstack::iterator::operator++() {
uint8_t *adata = align_to(alloc->data + alloc->len, DEFAULT_ALIGNMENT);
alloc = reinterpret_cast<rust_obstack_alloc *>(adata);
if (reinterpret_cast<uint8_t *>(alloc) >= chunk->data + chunk->alen) {
// We reached the end of this chunk; go on to the next one.
chunk = chunk->prev;
if (chunk)
alloc = reinterpret_cast<rust_obstack_alloc *>(chunk->data);
else
alloc = NULL;
}
return *this;
}
bool
rust_obstack::iterator::operator==(const rust_obstack::iterator &other)
const {
return chunk == other.chunk && alloc == other.alloc;
}
bool
rust_obstack::iterator::operator!=(const rust_obstack::iterator &other)
const {
return !(*this == other);
}
// Debugging
void
rust_obstack::dump() const {
iterator b = begin(), e = end();
while (b != e) {
std::pair<const type_desc *,void *> data = *b;
uint8_t *dp = reinterpret_cast<uint8_t *>(data.second);
shape::arena arena;
shape::type_param *params =
shape::type_param::from_tydesc_and_data(data.first, dp, arena);
shape::log log(task, true, data.first->shape, params,
data.first->shape_tables, dp, std::cerr);
log.walk();
std::cerr << "\n";
++b;
}
std::cerr << "end of dynastack dump\n";
}

View File

@ -1,75 +0,0 @@
// Object stacks, used in lieu of dynamically-sized frames.
#ifndef RUST_OBSTACK_H
#define RUST_OBSTACK_H
#include <utility>
struct rust_obstack_alloc;
struct rust_task;
struct type_desc;
// A contiguous set of allocations.
struct rust_obstack_chunk {
rust_obstack_chunk *prev;
size_t size;
size_t alen;
size_t pad;
uint8_t data[];
rust_obstack_chunk(rust_obstack_chunk *in_prev, size_t in_size)
: prev(in_prev), size(in_size), alen(0) {}
void *alloc(size_t len, type_desc *tydesc);
bool free(void *ptr);
void *mark();
};
class rust_obstack {
rust_obstack_chunk *chunk;
rust_task *task;
// Allocates the given number of bytes in a new chunk.
void *alloc_new(size_t len, type_desc *tydesc);
public:
class iterator {
rust_obstack_chunk *chunk;
rust_obstack_alloc *alloc;
public:
iterator(rust_obstack_chunk *in_chunk)
: chunk(in_chunk),
alloc(in_chunk
? reinterpret_cast<rust_obstack_alloc *>(in_chunk->data)
: NULL) {}
std::pair<const type_desc *,void *> operator*() const;
iterator &operator++();
bool operator==(const iterator &other) const;
bool operator!=(const iterator &other) const;
};
rust_obstack(rust_task *in_task) : chunk(NULL), task(in_task) {}
~rust_obstack();
inline iterator begin() const {
iterator it(chunk);
return it;
}
inline iterator end() const {
iterator it(NULL);
return it;
}
void *alloc(size_t len, type_desc *tydesc);
void free(void *ptr);
void *mark();
/** Debugging tool: dumps the contents of this obstack to stderr. */
void dump() const;
};
#endif

View File

@ -79,7 +79,6 @@ rust_task::rust_task(rust_task_thread *thread, rust_task_list *state,
boxed(&local_region),
unwinding(false),
propagate_failure(true),
dynastack(this),
cc_counter(0),
total_stack_sz(0),
state(state),

View File

@ -13,7 +13,6 @@
#include "rust_debug.h"
#include "rust_internal.h"
#include "rust_kernel.h"
#include "rust_obstack.h"
#include "boxed_region.h"
#include "rust_stack.h"
#include "rust_port_selector.h"
@ -80,8 +79,6 @@ rust_task : public kernel_owned<rust_task>, rust_cond
bool propagate_failure;
rust_obstack dynastack;
uint32_t cc_counter;
debug::task_debug_info debug;

View File

@ -382,95 +382,6 @@ upcall_vec_grow(rust_vec** vp, size_t new_sz) {
UPCALL_SWITCH_STACK(&args, upcall_s_vec_grow);
}
/**********************************************************************
* Returns a token that can be used to deallocate all of the allocated space
* space in the dynamic stack.
*/
struct s_dynastack_mark_args {
void *retval;
};
extern "C" CDECL void
upcall_s_dynastack_mark(s_dynastack_mark_args *args) {
args->retval = rust_task_thread::get_task()->dynastack.mark();
}
extern "C" CDECL void *
upcall_dynastack_mark() {
s_dynastack_mark_args args = {0};
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_mark);
return args.retval;
}
/**********************************************************************
* Allocates space in the dynamic stack and returns it.
*
* FIXME: Deprecated since dynamic stacks need to be self-describing for GC.
*/
struct s_dynastack_alloc_args {
void *retval;
size_t sz;
};
extern "C" CDECL void
upcall_s_dynastack_alloc(s_dynastack_alloc_args *args) {
size_t sz = args->sz;
args->retval = sz ?
rust_task_thread::get_task()->dynastack.alloc(sz, NULL) : NULL;
}
extern "C" CDECL void *
upcall_dynastack_alloc(size_t sz) {
s_dynastack_alloc_args args = {0, sz};
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_alloc);
return args.retval;
}
/**********************************************************************
* Allocates space associated with a type descriptor in the dynamic stack and
* returns it.
*/
struct s_dynastack_alloc_2_args {
void *retval;
size_t sz;
type_desc *ty;
};
extern "C" CDECL void
upcall_s_dynastack_alloc_2(s_dynastack_alloc_2_args *args) {
size_t sz = args->sz;
type_desc *ty = args->ty;
args->retval = sz ?
rust_task_thread::get_task()->dynastack.alloc(sz, ty) : NULL;
}
extern "C" CDECL void *
upcall_dynastack_alloc_2(size_t sz, type_desc *ty) {
s_dynastack_alloc_2_args args = {0, sz, ty};
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_alloc_2);
return args.retval;
}
struct s_dynastack_free_args {
void *ptr;
};
extern "C" CDECL void
upcall_s_dynastack_free(s_dynastack_free_args *args) {
return rust_task_thread::get_task()->dynastack.free(args->ptr);
}
/** Frees space in the dynamic stack. */
extern "C" CDECL void
upcall_dynastack_free(void *ptr) {
s_dynastack_free_args args = {ptr};
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_free);
}
extern "C" _Unwind_Reason_Code
__gxx_personality_v0(int version,
_Unwind_Action actions,

View File

@ -56,10 +56,6 @@ str_reserve_shared
vec_from_buf_shared
unsupervise
upcall_cmp_type
upcall_dynastack_alloc
upcall_dynastack_alloc_2
upcall_dynastack_free
upcall_dynastack_mark
upcall_fail
upcall_free
upcall_validate_box