Commit 41b8dbc3 authored by Rudi Chen's avatar Rudi Chen

Keep track of pointers in compiled functions and visit them.

parent dffaf33c
......@@ -53,8 +53,6 @@ void ICInvalidator::invalidateAll() {
dependents.clear();
}
void ICSlotInfo::clear() {
ic->clear(this);
}
......
......@@ -1042,6 +1042,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames*
}
CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, exception_style, entry_descriptor);
setPointersInCodeStorage(&cf->pointers_in_code);
// Make sure that the instruction memory keeps the module object alive.
// TODO: implement this for real
......
......@@ -753,6 +753,7 @@ void CompiledFunction::speculationFailed() {
}
}
std::unordered_set<CompiledFunction*> all_compiled_functions;
CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization* spec, void* code, EffortLevel effort,
ExceptionStyle exception_style, const OSREntryDescriptor* entry_descriptor)
: clfunc(NULL),
......@@ -766,6 +767,26 @@ CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization*
times_speculation_failed(0),
location_map(nullptr) {
assert((spec != NULL) + (entry_descriptor != NULL) == 1);
#if MOVING_GC
assert(all_compiled_functions.count(this) == 0);
all_compiled_functions.insert(this);
#endif
}
#if MOVING_GC
CompiledFunction::~CompiledFunction() {
assert(all_compiled_functions.count(this) == 1);
all_compiled_functions.erase(this);
}
#endif
void CompiledFunction::visitAllCompiledFunctions(GCVisitor* visitor) {
for (CompiledFunction* cf : all_compiled_functions) {
for (const void* ptr : cf->pointers_in_code) {
visitor->visitNonRelocatable(const_cast<void*>(ptr));
}
}
}
ConcreteCompilerType* CompiledFunction::getReturnType() {
......
......@@ -98,12 +98,20 @@ llvm::Constant* getStringConstantPtr(llvm::StringRef str) {
// It's slightly easier to emit them as integers (there are primitive integer constants but not pointer constants),
// but doing it this way makes it clearer what's going on.
llvm::StringMap<const void*> relocatable_syms;
static llvm::StringMap<const void*> relocatable_syms;
// Pointer to a vector where we want to keep track of all the pointers written directly into
// the compiled code, which the GC needs to be aware of.
std::vector<const void*>* pointers_in_code;
void clearRelocatableSymsMap() {
relocatable_syms.clear();
}
void setPointersInCodeStorage(std::vector<const void*>* v) {
pointers_in_code = v;
}
const void* getValueOfRelocatableSym(const std::string& str) {
auto it = relocatable_syms.find(str);
if (it != relocatable_syms.end())
......@@ -130,6 +138,13 @@ llvm::Constant* embedRelocatablePtr(const void* addr, llvm::Type* type, llvm::St
relocatable_syms[name] = addr;
#if MOVING_GC
gc::GCAllocation* al = gc::global_heap.getAllocationFromInteriorPointer(const_cast<void*>(addr));
if (al) {
pointers_in_code->push_back(al->user_data);
}
#endif
llvm::Type* var_type = type->getPointerElementType();
return new llvm::GlobalVariable(*g.cur_module, var_type, true, llvm::GlobalVariable::ExternalLinkage, 0, name);
}
......@@ -138,6 +153,14 @@ llvm::Constant* embedConstantPtr(const void* addr, llvm::Type* type) {
assert(type);
llvm::Constant* int_val = llvm::ConstantInt::get(g.i64, reinterpret_cast<uintptr_t>(addr), false);
llvm::Constant* ptr_val = llvm::ConstantExpr::getIntToPtr(int_val, type);
#if MOVING_GC
gc::GCAllocation* al = gc::global_heap.getAllocationFromInteriorPointer(const_cast<void*>(addr));
if (al) {
pointers_in_code->push_back(al->user_data);
}
#endif
return ptr_val;
}
......
......@@ -40,6 +40,7 @@ llvm::Constant* getConstantInt(int64_t val, llvm::Type*);
llvm::Constant* getNullPtr(llvm::Type* t);
void clearRelocatableSymsMap();
void setPointersInCodeStorage(std::vector<const void*>* v);
const void* getValueOfRelocatableSym(const std::string& str);
void visitRelocatableSymsMap(gc::GCVisitor* visitor);
......
......@@ -262,6 +262,9 @@ public:
FunctionSpecialization* spec;
const OSREntryDescriptor* entry_descriptor;
// Pointers that were written directly into the code, which the GC should be aware of.
std::vector<const void*> pointers_in_code;
union {
Box* (*call)(Box*, Box*, Box*, Box**);
Box* (*closure_call)(BoxedClosure*, Box*, Box*, Box*, Box**);
......@@ -298,6 +301,8 @@ public:
// Call this when a speculation inside this version failed
void speculationFailed();
static void visitAllCompiledFunctions(GCVisitor* visitor);
};
typedef int FutureFlags;
......
......@@ -435,6 +435,7 @@ static void markRoots(GCVisitor& visitor) {
GC_TRACE_LOG("Looking at generated code pointers\n");
#if MOVING_GC
ICInfo::visitGCReferences(&visitor);
CompiledFunction::visitAllCompiledFunctions(&visitor);
#endif
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment