Remove experimental GC code
It's been sitting unused long enough to have bitrotted completely.
This commit is contained in:
parent
1ea184285e
commit
c1b075d042
2
mk/rt.mk
2
mk/rt.mk
@ -56,7 +56,6 @@ RUNTIME_CS_$(1) := \
|
||||
rt/rust_kernel.cpp \
|
||||
rt/rust_shape.cpp \
|
||||
rt/rust_obstack.cpp \
|
||||
rt/rust_gc.cpp \
|
||||
rt/rust_abi.cpp \
|
||||
rt/rust_cc.cpp \
|
||||
rt/rust_debug.cpp \
|
||||
@ -73,7 +72,6 @@ RUNTIME_HDR_$(1) := rt/globals.h \
|
||||
rt/rust_abi.h \
|
||||
rt/rust_cc.h \
|
||||
rt/rust_debug.h \
|
||||
rt/rust_gc.h \
|
||||
rt/rust_internal.h \
|
||||
rt/rust_util.h \
|
||||
rt/rust_env.h \
|
||||
|
@ -56,7 +56,7 @@ fn declare_upcalls(targ_cfg: @session::config,
|
||||
d("malloc", [T_ptr(tydesc_type)],
|
||||
T_ptr(T_i8())),
|
||||
free:
|
||||
dv("free", [T_ptr(T_i8()), int_t]),
|
||||
dv("free", [T_ptr(T_i8())]),
|
||||
validate_box:
|
||||
dv("validate_box", [T_ptr(T_i8())]),
|
||||
shared_malloc:
|
||||
|
@ -412,7 +412,6 @@ fn build_session_options(match: getopts::match,
|
||||
let addl_lib_search_paths = getopts::opt_strs(match, "L");
|
||||
let cfg = parse_cfgspecs(getopts::opt_strs(match, "cfg"));
|
||||
let test = opt_present(match, "test");
|
||||
let do_gc = opt_present(match, "gc");
|
||||
let warn_unused_imports = opt_present(match, "warn-unused-imports");
|
||||
let sopts: @session::options =
|
||||
@{crate_type: crate_type,
|
||||
@ -434,7 +433,6 @@ fn build_session_options(match: getopts::match,
|
||||
test: test,
|
||||
parse_only: parse_only,
|
||||
no_trans: no_trans,
|
||||
do_gc: do_gc,
|
||||
no_asm_comments: no_asm_comments,
|
||||
warn_unused_imports: warn_unused_imports};
|
||||
ret sopts;
|
||||
|
@ -46,7 +46,6 @@ type options =
|
||||
test: bool,
|
||||
parse_only: bool,
|
||||
no_trans: bool,
|
||||
do_gc: bool,
|
||||
no_asm_comments: bool,
|
||||
warn_unused_imports: bool};
|
||||
|
||||
|
@ -1,148 +0,0 @@
|
||||
// Routines useful for garbage collection.
|
||||
|
||||
import lib::llvm::{True, ValueRef};
|
||||
import trans::base::get_tydesc;
|
||||
import trans::common::*;
|
||||
import trans::base;
|
||||
import option::none;
|
||||
import str;
|
||||
import driver::session::session;
|
||||
|
||||
import lll = lib::llvm::llvm;
|
||||
import bld = trans::build;
|
||||
|
||||
type ctxt = @{mutable next_tydesc_num: uint};
|
||||
|
||||
fn mk_ctxt() -> ctxt { ret @{mutable next_tydesc_num: 0u}; }
|
||||
|
||||
fn add_global(ccx: @crate_ctxt, llval: ValueRef, name: str) -> ValueRef {
|
||||
let llglobal =
|
||||
str::as_buf(name,
|
||||
{|buf|
|
||||
lll::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
|
||||
});
|
||||
lll::LLVMSetInitializer(llglobal, llval);
|
||||
lll::LLVMSetGlobalConstant(llglobal, True);
|
||||
ret llglobal;
|
||||
}
|
||||
|
||||
fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
|
||||
let bcx = cx;
|
||||
let ccx = bcx_ccx(cx);
|
||||
if !type_is_gc_relevant(bcx_tcx(cx), ty) ||
|
||||
ty::type_has_dynamic_size(bcx_tcx(cx), ty) {
|
||||
ret bcx;
|
||||
}
|
||||
|
||||
let gc_cx = bcx_ccx(cx).gc_cx;
|
||||
|
||||
// FIXME (issue #839): For now, we are unconditionally zeroing out all
|
||||
// GC-relevant types. Eventually we should use typestate for this.
|
||||
bcx = base::zero_alloca(bcx, llval, ty);
|
||||
|
||||
let ti = none;
|
||||
let td_r = get_tydesc(bcx, ty, false, ti);
|
||||
bcx = td_r.result.bcx;
|
||||
let lltydesc = td_r.result.val;
|
||||
|
||||
let gcroot = bcx_ccx(bcx).intrinsics.get("llvm.gcroot");
|
||||
let llvalptr = bld::PointerCast(bcx, llval, T_ptr(T_ptr(T_i8())));
|
||||
|
||||
alt td_r.kind {
|
||||
tk_derived {
|
||||
// It's a derived type descriptor. First, spill it.
|
||||
let lltydescptr = base::alloca(bcx, val_ty(lltydesc));
|
||||
|
||||
let llderivedtydescs =
|
||||
base::llderivedtydescs_block_ctxt(bcx_fcx(bcx));
|
||||
bld::Store(llderivedtydescs, lltydesc, lltydescptr);
|
||||
|
||||
let number = gc_cx.next_tydesc_num;
|
||||
gc_cx.next_tydesc_num += 1u;
|
||||
|
||||
let lldestindex =
|
||||
add_global(bcx_ccx(bcx), C_struct([C_int(ccx, 0),
|
||||
C_uint(ccx, number)]),
|
||||
"rust_gc_tydesc_dest_index");
|
||||
let llsrcindex =
|
||||
add_global(bcx_ccx(bcx), C_struct([C_int(ccx, 1),
|
||||
C_uint(ccx, number)]),
|
||||
"rust_gc_tydesc_src_index");
|
||||
|
||||
lldestindex = lll::LLVMConstPointerCast(lldestindex, T_ptr(T_i8()));
|
||||
llsrcindex = lll::LLVMConstPointerCast(llsrcindex, T_ptr(T_i8()));
|
||||
|
||||
lltydescptr =
|
||||
bld::PointerCast(llderivedtydescs, lltydescptr,
|
||||
T_ptr(T_ptr(T_i8())));
|
||||
|
||||
bld::Call(llderivedtydescs, gcroot, [lltydescptr, lldestindex]);
|
||||
bld::Call(bcx, gcroot, [llvalptr, llsrcindex]);
|
||||
}
|
||||
tk_param {
|
||||
bcx_tcx(cx).sess.bug("we should never be trying to root values " +
|
||||
"of a type parameter");
|
||||
}
|
||||
tk_static {
|
||||
// Static type descriptor.
|
||||
|
||||
let llstaticgcmeta =
|
||||
add_global(bcx_ccx(bcx), C_struct([C_int(ccx, 2), lltydesc]),
|
||||
"rust_gc_tydesc_static_gc_meta");
|
||||
let llstaticgcmetaptr =
|
||||
lll::LLVMConstPointerCast(llstaticgcmeta, T_ptr(T_i8()));
|
||||
|
||||
bld::Call(bcx, gcroot, [llvalptr, llstaticgcmetaptr]);
|
||||
}
|
||||
}
|
||||
|
||||
ret bcx;
|
||||
}
|
||||
|
||||
fn type_is_gc_relevant(cx: ty::ctxt, ty: ty::t) -> bool {
|
||||
alt ty::struct(cx, ty) {
|
||||
ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_int(_) |
|
||||
ty::ty_float(_) | ty::ty_uint(_) | ty::ty_str |
|
||||
ty::ty_type | ty::ty_send_type | ty::ty_ptr(_) {
|
||||
ret false;
|
||||
}
|
||||
ty::ty_rec(fields) {
|
||||
for f in fields { if type_is_gc_relevant(cx, f.mt.ty) { ret true; } }
|
||||
ret false;
|
||||
}
|
||||
ty::ty_tup(elts) {
|
||||
for elt in elts { if type_is_gc_relevant(cx, elt) { ret true; } }
|
||||
ret false;
|
||||
}
|
||||
ty::ty_enum(did, tps) {
|
||||
let variants = ty::enum_variants(cx, did);
|
||||
for variant in *variants {
|
||||
for aty in variant.args {
|
||||
let arg_ty = ty::substitute_type_params(cx, tps, aty);
|
||||
if type_is_gc_relevant(cx, arg_ty) { ret true; }
|
||||
}
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
ty::ty_vec(tm) {
|
||||
ret type_is_gc_relevant(cx, tm.ty);
|
||||
}
|
||||
ty::ty_constr(sub, _) { ret type_is_gc_relevant(cx, sub); }
|
||||
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_fn(_) |
|
||||
ty::ty_param(_, _) | ty::ty_res(_, _, _) { ret true; }
|
||||
ty::ty_opaque_closure_ptr(_) {
|
||||
ret false; // I guess?
|
||||
}
|
||||
// A precondition to rule out these cases would be nice
|
||||
ty::ty_var(_) {
|
||||
fail "ty_var in type_is_gc_relevant";
|
||||
}
|
||||
ty::ty_iface(_, _) {
|
||||
fail "ty_iface in type_is_gc_relevant";
|
||||
}
|
||||
ty::ty_named(_,_) {
|
||||
fail "ty_named in type_is_gc_relevant";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import option::{some, none};
|
||||
import driver::session;
|
||||
import session::session;
|
||||
import front::attr;
|
||||
import middle::{ty, gc, resolve, debuginfo};
|
||||
import middle::freevars::*;
|
||||
import back::{link, abi, upcall};
|
||||
import syntax::{ast, ast_util, codemap};
|
||||
@ -350,14 +349,9 @@ fn trans_native_call(cx: @block_ctxt, externs: hashmap<str, ValueRef>,
|
||||
ret Call(cx, llnative, call_args);
|
||||
}
|
||||
|
||||
fn trans_free_if_not_gc(cx: @block_ctxt, v: ValueRef) -> @block_ctxt {
|
||||
let ccx = bcx_ccx(cx);
|
||||
if !ccx.sess.opts.do_gc {
|
||||
Call(cx, ccx.upcalls.free,
|
||||
[PointerCast(cx, v, T_ptr(T_i8())),
|
||||
C_int(bcx_ccx(cx), 0)]);
|
||||
}
|
||||
ret cx;
|
||||
fn trans_free(cx: @block_ctxt, v: ValueRef) -> @block_ctxt {
|
||||
Call(cx, bcx_ccx(cx).upcalls.free, [PointerCast(cx, v, T_ptr(T_i8()))]);
|
||||
cx
|
||||
}
|
||||
|
||||
fn trans_shared_free(cx: @block_ctxt, v: ValueRef) -> @block_ctxt {
|
||||
@ -1245,7 +1239,7 @@ fn free_box(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
|
||||
let v = PointerCast(bcx, v, type_of_1(bcx, t));
|
||||
let body = GEPi(bcx, v, [0, abi::box_field_body]);
|
||||
let bcx = drop_ty(bcx, body, body_mt.ty);
|
||||
trans_free_if_not_gc(bcx, v)
|
||||
trans_free(bcx, v)
|
||||
}
|
||||
|
||||
_ { fail "free_box invoked with non-box type"; }
|
||||
@ -1280,7 +1274,7 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) {
|
||||
let ti = none;
|
||||
call_tydesc_glue_full(bcx, body, tydesc,
|
||||
abi::tydesc_field_drop_glue, ti);
|
||||
trans_free_if_not_gc(bcx, b)
|
||||
trans_free(bcx, b)
|
||||
}
|
||||
ty::ty_send_type {
|
||||
// sendable type descriptors are basically unique pointers,
|
||||
@ -4226,10 +4220,6 @@ fn alloc_ty(cx: @block_ctxt, t: ty::t) -> result {
|
||||
// past caller conventions and may well make sense again,
|
||||
// so we leave it as-is.
|
||||
|
||||
if bcx_tcx(cx).sess.opts.do_gc {
|
||||
bcx = gc::add_gc_root(bcx, val, t);
|
||||
}
|
||||
|
||||
ret rslt(cx, val);
|
||||
}
|
||||
|
||||
@ -5604,7 +5594,6 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
|
||||
opaque_vec_type: T_opaque_vec(targ_cfg),
|
||||
builder: BuilderRef_res(llvm::LLVMCreateBuilder()),
|
||||
shape_cx: shape::mk_ctxt(llmod),
|
||||
gc_cx: gc::mk_ctxt(),
|
||||
crate_map: crate_map,
|
||||
dbg_cx: dbg_cx,
|
||||
mutable do_not_commit_warning_issued: false};
|
||||
|
@ -716,7 +716,7 @@ fn make_opaque_cbox_free_glue(
|
||||
alt ck {
|
||||
ty::ck_block { fail "Impossible"; }
|
||||
ty::ck_box {
|
||||
trans_free_if_not_gc(bcx, cbox)
|
||||
trans_free(bcx, cbox)
|
||||
}
|
||||
ty::ck_uniq {
|
||||
let bcx = free_ty(bcx, tydesc, mk_tydesc_ty(tcx, ck));
|
||||
|
@ -120,7 +120,6 @@ type crate_ctxt =
|
||||
opaque_vec_type: TypeRef,
|
||||
builder: BuilderRef_res,
|
||||
shape_cx: shape::ctxt,
|
||||
gc_cx: gc::ctxt,
|
||||
crate_map: ValueRef,
|
||||
dbg_cx: option<@debuginfo::debug_ctxt>,
|
||||
mutable do_not_commit_warning_issued: bool};
|
||||
@ -286,7 +285,7 @@ fn add_clean_temp_mem(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
|
||||
fn add_clean_free(cx: @block_ctxt, ptr: ValueRef, shared: bool) {
|
||||
let scope_cx = find_scope_cx(cx);
|
||||
let free_fn = if shared { bind base::trans_shared_free(_, ptr) }
|
||||
else { bind base::trans_free_if_not_gc(_, ptr) };
|
||||
else { bind base::trans_free(_, ptr) };
|
||||
scope_cx.cleanups += [clean_temp(ptr, free_fn)];
|
||||
scope_cx.lpad_dirty = true;
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ mod middle {
|
||||
mod kind;
|
||||
mod freevars;
|
||||
mod shape;
|
||||
mod gc;
|
||||
mod debuginfo;
|
||||
mod capture;
|
||||
mod pat_util;
|
||||
|
@ -17,7 +17,6 @@ native mod rustrt {
|
||||
// visible-in-crate, but not re-exported.
|
||||
fn last_os_error() -> str;
|
||||
fn refcount<T>(t: @T) -> ctypes::intptr_t;
|
||||
fn do_gc();
|
||||
fn unsupervise();
|
||||
fn shape_log_str<T>(t: *sys::type_desc, data: T) -> str;
|
||||
fn rust_set_exit_status(code: ctypes::intptr_t);
|
||||
@ -74,15 +73,6 @@ fn refcount<T>(t: @T) -> uint {
|
||||
ret rustrt::refcount::<T>(t);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: do_gc
|
||||
|
||||
Force a garbage collection
|
||||
*/
|
||||
fn do_gc() -> () {
|
||||
ret rustrt::do_gc();
|
||||
}
|
||||
|
||||
// FIXME: There's a wrapper for this in the task module and this really
|
||||
// just belongs there
|
||||
fn unsupervise() -> () {
|
||||
|
@ -91,11 +91,6 @@ refcount(intptr_t *v) {
|
||||
return (*v) - 1;
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
do_gc() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
unsupervise() {
|
||||
rust_task *task = rust_scheduler::get_task();
|
||||
|
@ -2,7 +2,6 @@
|
||||
// time until LLVM's GC infrastructure is more mature.
|
||||
|
||||
#include "rust_debug.h"
|
||||
#include "rust_gc.h"
|
||||
#include "rust_internal.h"
|
||||
#include "rust_shape.h"
|
||||
#include "rust_task.h"
|
||||
|
@ -1,164 +0,0 @@
|
||||
// Rust garbage collection.
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rust_abi.h"
|
||||
#include "rust_debug.h"
|
||||
#include "rust_gc.h"
|
||||
#include "rust_internal.h"
|
||||
#include "rust_shape.h"
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
using namespace stack_walk;
|
||||
|
||||
namespace gc {
|
||||
|
||||
weak_symbol<const uintptr_t> safe_point_data("rust_gc_safe_points");
|
||||
|
||||
struct root_info {
|
||||
intptr_t frame_offset;
|
||||
uintptr_t dynamic; // 0 = static, 1 = dynamic
|
||||
const type_desc *tydesc;
|
||||
};
|
||||
|
||||
struct root {
|
||||
const type_desc *tydesc;
|
||||
uint8_t *data;
|
||||
|
||||
root(const root_info &info, const frame &frame)
|
||||
: tydesc(info.tydesc),
|
||||
data((uint8_t *)frame.bp + info.frame_offset) {}
|
||||
};
|
||||
|
||||
struct safe_point {
|
||||
uintptr_t n_roots;
|
||||
root_info roots[0];
|
||||
};
|
||||
|
||||
struct safe_point_index_entry {
|
||||
void (*ra)(); // The return address.
|
||||
const struct safe_point *safe_point; // The safe point.
|
||||
|
||||
struct cmp {
|
||||
bool operator()(const safe_point_index_entry &entry, void (*ra)())
|
||||
const {
|
||||
return entry.ra < ra;
|
||||
}
|
||||
bool operator()(void (*ra)(), const safe_point_index_entry &entry)
|
||||
const {
|
||||
return ra < entry.ra;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class safe_point_map {
|
||||
uintptr_t n_safe_points;
|
||||
const safe_point_index_entry *index;
|
||||
const safe_point *safe_points;
|
||||
|
||||
public:
|
||||
safe_point_map() {
|
||||
const uintptr_t *data = *safe_point_data;
|
||||
n_safe_points = *data++;
|
||||
index = (const safe_point_index_entry *)data;
|
||||
data += n_safe_points * 2;
|
||||
safe_points = (const safe_point *)data;
|
||||
}
|
||||
|
||||
const safe_point *get_safe_point(void (*addr)());
|
||||
};
|
||||
|
||||
class gc {
|
||||
private:
|
||||
rust_task *task;
|
||||
|
||||
void mark(std::vector<root> &roots);
|
||||
void sweep();
|
||||
|
||||
public:
|
||||
gc(rust_task *in_task) : task(in_task) {}
|
||||
void run();
|
||||
};
|
||||
|
||||
const safe_point *
|
||||
safe_point_map::get_safe_point(void (*addr)()) {
|
||||
safe_point_index_entry::cmp cmp;
|
||||
const safe_point_index_entry *entry =
|
||||
std::lower_bound(index, index + n_safe_points, addr, cmp);
|
||||
return (entry && entry->ra == addr) ? entry->safe_point : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gc::mark(std::vector<root> &roots) {
|
||||
std::vector<root>::iterator ri = roots.begin(), rend = roots.end();
|
||||
while (ri < rend) {
|
||||
DPRINT("root: %p\n", ri->data);
|
||||
|
||||
shape::arena arena;
|
||||
shape::type_param *params =
|
||||
shape::type_param::from_tydesc_and_data(ri->tydesc, ri->data,
|
||||
arena);
|
||||
shape::log log(task, true, ri->tydesc->shape, params,
|
||||
ri->tydesc->shape_tables, ri->data, std::cerr);
|
||||
log.walk();
|
||||
DPRINT("\n");
|
||||
|
||||
++ri;
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
gc::sweep() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
gc::run() {
|
||||
safe_point_map map;
|
||||
|
||||
// Find roots.
|
||||
std::vector<root> roots;
|
||||
std::vector<frame> call_stack = backtrace();
|
||||
for (unsigned i = 0; i < call_stack.size(); i++) {
|
||||
frame f = call_stack[i];
|
||||
const safe_point *sp = map.get_safe_point(f.ra);
|
||||
if (!sp)
|
||||
continue;
|
||||
|
||||
DPRINT("%u: ra %p, ebp %p\n", i, call_stack[i].ra, call_stack[i].bp);
|
||||
for (unsigned j = 0; j < sp->n_roots; j++) {
|
||||
root r(sp->roots[j], f);
|
||||
roots.push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
// Mark and sweep.
|
||||
mark(roots);
|
||||
sweep();
|
||||
}
|
||||
|
||||
void
|
||||
maybe_gc(rust_task *task) {
|
||||
if (*safe_point_data == NULL)
|
||||
return;
|
||||
|
||||
static debug::flag zeal("RUST_GC_ZEAL");
|
||||
|
||||
if (*zeal) {
|
||||
gc gc(task);
|
||||
gc.run();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
// Rust garbage collection.
|
||||
|
||||
struct rust_task;
|
||||
|
||||
namespace gc {
|
||||
|
||||
void maybe_gc(rust_task *task);
|
||||
|
||||
}
|
||||
|
@ -523,13 +523,13 @@ rust_task::malloc(size_t sz, const char *tag, type_desc *td)
|
||||
}
|
||||
|
||||
void *
|
||||
rust_task::realloc(void *data, size_t sz, bool is_gc)
|
||||
rust_task::realloc(void *data, size_t sz)
|
||||
{
|
||||
return local_region.realloc(data, sz);
|
||||
}
|
||||
|
||||
void
|
||||
rust_task::free(void *p, bool is_gc)
|
||||
rust_task::free(void *p)
|
||||
{
|
||||
local_region.free(p);
|
||||
}
|
||||
|
@ -141,8 +141,8 @@ rust_task : public kernel_owned<rust_task>, rust_cond
|
||||
bool dead();
|
||||
|
||||
void *malloc(size_t sz, const char *tag, type_desc *td=0);
|
||||
void *realloc(void *data, size_t sz, bool gc_mem=false);
|
||||
void free(void *p, bool gc_mem=false);
|
||||
void *realloc(void *data, size_t sz);
|
||||
void free(void *p);
|
||||
|
||||
void transition(rust_task_list *src, rust_task_list *dst);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include "rust_cc.h"
|
||||
#include "rust_gc.h"
|
||||
#include "rust_internal.h"
|
||||
#include "rust_scheduler.h"
|
||||
#include "rust_unwind.h"
|
||||
@ -122,7 +121,6 @@ upcall_s_malloc(s_malloc_args *args) {
|
||||
|
||||
LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", args->td);
|
||||
|
||||
gc::maybe_gc(task);
|
||||
cc::maybe_cc(task);
|
||||
|
||||
// FIXME--does this have to be calloc?
|
||||
@ -151,7 +149,6 @@ upcall_malloc(type_desc *td) {
|
||||
|
||||
struct s_free_args {
|
||||
void *ptr;
|
||||
uintptr_t is_gc;
|
||||
};
|
||||
|
||||
extern "C" CDECL void
|
||||
@ -162,7 +159,7 @@ upcall_s_free(s_free_args *args) {
|
||||
rust_scheduler *sched = task->sched;
|
||||
DLOG(sched, mem,
|
||||
"upcall free(0x%" PRIxPTR ", is_gc=%" PRIdPTR ")",
|
||||
(uintptr_t)args->ptr, args->is_gc);
|
||||
(uintptr_t)args->ptr);
|
||||
|
||||
debug::maybe_untrack_origin(task, args->ptr);
|
||||
|
||||
@ -171,8 +168,8 @@ upcall_s_free(s_free_args *args) {
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
upcall_free(void* ptr, uintptr_t is_gc) {
|
||||
s_free_args args = {ptr, is_gc};
|
||||
upcall_free(void* ptr) {
|
||||
s_free_args args = {ptr};
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_free);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ debug_ptrcast
|
||||
debug_tag
|
||||
debug_tydesc
|
||||
debug_get_stk_seg
|
||||
do_gc
|
||||
drop_task
|
||||
get_port_id
|
||||
get_task_id
|
||||
|
@ -83,7 +83,6 @@ fn build_session() -> session::session {
|
||||
test: false,
|
||||
parse_only: false,
|
||||
no_trans: false,
|
||||
do_gc: false,
|
||||
no_asm_comments: false,
|
||||
warn_unused_imports: false
|
||||
};
|
||||
|
@ -8,14 +8,14 @@
|
||||
use std;
|
||||
|
||||
native mod rustrt {
|
||||
fn do_gc();
|
||||
fn last_os_error() -> str;
|
||||
}
|
||||
|
||||
fn getbig_call_c_and_fail(i: int) {
|
||||
if i != 0 {
|
||||
getbig_call_c_and_fail(i - 1);
|
||||
} else {
|
||||
rustrt::do_gc();
|
||||
rustrt::last_os_error();
|
||||
fail;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ Can we bind native things?
|
||||
|
||||
#[abi = "cdecl"]
|
||||
native mod rustrt {
|
||||
fn do_gc();
|
||||
fn rand_new() -> *ctypes::void;
|
||||
}
|
||||
|
||||
fn main() { bind rustrt::do_gc(); }
|
||||
fn main() { bind rustrt::rand_new(); }
|
||||
|
@ -120,15 +120,13 @@ fn test_fn() {
|
||||
#[abi = "cdecl"]
|
||||
#[nolink]
|
||||
native mod test {
|
||||
fn do_gc();
|
||||
fn unsupervise();
|
||||
}
|
||||
|
||||
// FIXME (#1058): comparison of native fns
|
||||
fn test_native_fn() {
|
||||
/*
|
||||
assert (native_mod::do_gc == native_mod::do_gc);
|
||||
assert (native_mod::do_gc != native_mod::unsupervise);
|
||||
assert (native_mod::last_os_error != native_mod::unsupervise);
|
||||
*/
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ native mod rustrt {
|
||||
fn last_os_error() -> str;
|
||||
fn rust_getcwd() -> str;
|
||||
fn refcount(box: @int);
|
||||
fn do_gc();
|
||||
fn get_task_id();
|
||||
fn sched_threads();
|
||||
fn rust_get_task();
|
||||
@ -22,7 +21,6 @@ fn calllink01() { rustrt::unsupervise(); }
|
||||
fn calllink02() { rustrt::last_os_error(); }
|
||||
fn calllink03() { rustrt::rust_getcwd(); }
|
||||
fn calllink04() { rustrt::refcount(@0); }
|
||||
fn calllink05() { rustrt::do_gc(); }
|
||||
fn calllink08() { rustrt::get_task_id(); }
|
||||
fn calllink09() { rustrt::sched_threads(); }
|
||||
fn calllink10() { rustrt::rust_get_task(); }
|
||||
@ -55,7 +53,6 @@ fn main() {
|
||||
calllink02,
|
||||
calllink03,
|
||||
calllink04,
|
||||
calllink05,
|
||||
calllink08,
|
||||
calllink09,
|
||||
calllink10
|
||||
|
@ -4,16 +4,16 @@
|
||||
#[abi = "cdecl"]
|
||||
#[link_name = "rustrt"]
|
||||
native mod rustrt1 {
|
||||
fn do_gc();
|
||||
fn last_os_error() -> str;
|
||||
}
|
||||
|
||||
#[abi = "cdecl"]
|
||||
#[link_name = "rustrt"]
|
||||
native mod rustrt2 {
|
||||
fn do_gc();
|
||||
fn last_os_error() -> str;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
rustrt1::do_gc();
|
||||
rustrt2::do_gc();
|
||||
rustrt1::last_os_error();
|
||||
rustrt2::last_os_error();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user