rustc: Shove the address of the box annihilator into the crate map

This commit is contained in:
Patrick Walton 2012-09-21 11:42:47 -07:00
parent a51a561852
commit 3c2b6110dd
4 changed files with 84 additions and 12 deletions

View File

@ -12,13 +12,13 @@ void iter_crate_map(const cratemap* map,
void (*fn)(const mod_entry* map, void *cookie),
void *cookie) {
// First iterate this crate
iter_module_map(map->entries, fn, cookie);
iter_module_map(map->entries(), fn, cookie);
// Then recurse on linked crates
// FIXME (#2673) this does double work in diamond-shaped deps. could
// keep a set of visited addresses, if it turns out to be actually
// slow
for (size_t i = 0; map->children[i]; i++) {
iter_crate_map(map->children[i], fn, cookie);
for (cratemap::iterator i = map->begin(), e = map->end(); i != e; ++i) {
iter_crate_map(*i, fn, cookie);
}
}

View File

@ -2,15 +2,71 @@
#define RUST_CRATE_MAP_H
#include "rust_log.h"
#include <stdint.h>
struct mod_entry {
const char* name;
uint32_t* state;
};
struct cratemap {
const mod_entry* entries;
const cratemap* children[1];
class cratemap;
class cratemap_v0 {
friend class cratemap;
const mod_entry *m_entries;
const cratemap* m_children[1];
};
class cratemap {
private:
int32_t m_version;
const void *m_annihilate_fn;
const mod_entry* m_entries;
const cratemap* m_children[1];
inline int32_t version() const {
switch (m_version) {
case 1: return 1;
default: return 0;
}
}
public:
typedef const cratemap *const *iterator;
inline const void *annihilate_fn() const {
switch (version()) {
case 0: return NULL;
case 1: return m_annihilate_fn;
default: assert(false && "Unknown crate map version!");
}
}
inline const mod_entry *entries() const {
switch (version()) {
case 0: return reinterpret_cast<const cratemap_v0 *>(this)->m_entries;
case 1: return m_entries;
default: assert(false && "Unknown crate map version!");
}
}
inline const iterator begin() const {
switch (version()) {
case 0:
return &reinterpret_cast<const cratemap_v0 *>(this)->
m_children[0];
case 1:
return &m_children[1];
default: assert(false && "Unknown crate map version!");
}
}
inline const iterator end() const {
iterator i = begin();
while (*i)
i++;
return i;
}
};
void iter_module_map(const mod_entry* map,

View File

@ -236,11 +236,11 @@ void update_crate_map(const cratemap* map, log_directive* dirs,
}
void print_crate_log_map(const cratemap* map) {
for (const mod_entry* cur = map->entries; cur->name; cur++) {
for (const mod_entry* cur = map->entries(); cur->name; cur++) {
printf(" %s\n", cur->name);
}
for (size_t i = 0; map->children[i]; i++) {
print_crate_log_map(map->children[i]);
for (cratemap::iterator i = map->begin(), e = map->end(); i != e; ++i) {
print_crate_log_map(*i);
}
}

View File

@ -2478,7 +2478,7 @@ fn decl_crate_map(sess: session::session, mapmeta: link_meta,
} else { ~"toplevel" };
let sym_name = ~"_rust_crate_map_" + mapname;
let arrtype = T_array(int_type, n_subcrates as uint);
let maptype = T_struct(~[int_type, arrtype]);
let maptype = T_struct(~[T_i32(), T_ptr(T_i8()), int_type, arrtype]);
let map = str::as_c_str(sym_name, |buf| {
llvm::LLVMAddGlobal(llmod, maptype, buf)
});
@ -2502,9 +2502,25 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
i += 1;
}
vec::push(subcrates, C_int(ccx, 0));
let llannihilatefn;
let annihilate_def_id = ccx.tcx.lang_items.annihilate_fn.get();
if annihilate_def_id.crate == ast::local_crate {
llannihilatefn = get_item_val(ccx, annihilate_def_id.node);
} else {
let annihilate_fn_type = csearch::get_type(ccx.tcx,
annihilate_def_id).ty;
llannihilatefn = trans_external_path(ccx,
annihilate_def_id,
annihilate_fn_type);
}
llvm::LLVMSetInitializer(map, C_struct(
~[p2i(ccx, create_module_map(ccx)),
C_array(ccx.int_type, subcrates)]));
~[C_i32(1),
lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn,
T_ptr(T_i8())),
p2i(ccx, create_module_map(ccx)),
C_array(ccx.int_type, subcrates)]));
}
fn crate_ctxt_to_encode_parms(cx: @crate_ctxt)