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() { ...@@ -53,8 +53,6 @@ void ICInvalidator::invalidateAll() {
dependents.clear(); dependents.clear();
} }
void ICSlotInfo::clear() { void ICSlotInfo::clear() {
ic->clear(this); ic->clear(this);
} }
......
...@@ -1042,6 +1042,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* ...@@ -1042,6 +1042,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames*
} }
CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, exception_style, entry_descriptor); 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. // Make sure that the instruction memory keeps the module object alive.
// TODO: implement this for real // TODO: implement this for real
......
...@@ -753,6 +753,7 @@ void CompiledFunction::speculationFailed() { ...@@ -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, CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization* spec, void* code, EffortLevel effort,
ExceptionStyle exception_style, const OSREntryDescriptor* entry_descriptor) ExceptionStyle exception_style, const OSREntryDescriptor* entry_descriptor)
: clfunc(NULL), : clfunc(NULL),
...@@ -766,6 +767,26 @@ CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization* ...@@ -766,6 +767,26 @@ CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization*
times_speculation_failed(0), times_speculation_failed(0),
location_map(nullptr) { location_map(nullptr) {
assert((spec != NULL) + (entry_descriptor != NULL) == 1); 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() { ConcreteCompilerType* CompiledFunction::getReturnType() {
......
...@@ -98,12 +98,20 @@ llvm::Constant* getStringConstantPtr(llvm::StringRef str) { ...@@ -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), // 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. // 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() { void clearRelocatableSymsMap() {
relocatable_syms.clear(); relocatable_syms.clear();
} }
void setPointersInCodeStorage(std::vector<const void*>* v) {
pointers_in_code = v;
}
const void* getValueOfRelocatableSym(const std::string& str) { const void* getValueOfRelocatableSym(const std::string& str) {
auto it = relocatable_syms.find(str); auto it = relocatable_syms.find(str);
if (it != relocatable_syms.end()) if (it != relocatable_syms.end())
...@@ -130,6 +138,13 @@ llvm::Constant* embedRelocatablePtr(const void* addr, llvm::Type* type, llvm::St ...@@ -130,6 +138,13 @@ llvm::Constant* embedRelocatablePtr(const void* addr, llvm::Type* type, llvm::St
relocatable_syms[name] = addr; 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(); llvm::Type* var_type = type->getPointerElementType();
return new llvm::GlobalVariable(*g.cur_module, var_type, true, llvm::GlobalVariable::ExternalLinkage, 0, name); 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) { ...@@ -138,6 +153,14 @@ llvm::Constant* embedConstantPtr(const void* addr, llvm::Type* type) {
assert(type); assert(type);
llvm::Constant* int_val = llvm::ConstantInt::get(g.i64, reinterpret_cast<uintptr_t>(addr), false); 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); 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; return ptr_val;
} }
......
...@@ -40,6 +40,7 @@ llvm::Constant* getConstantInt(int64_t val, llvm::Type*); ...@@ -40,6 +40,7 @@ llvm::Constant* getConstantInt(int64_t val, llvm::Type*);
llvm::Constant* getNullPtr(llvm::Type* t); llvm::Constant* getNullPtr(llvm::Type* t);
void clearRelocatableSymsMap(); void clearRelocatableSymsMap();
void setPointersInCodeStorage(std::vector<const void*>* v);
const void* getValueOfRelocatableSym(const std::string& str); const void* getValueOfRelocatableSym(const std::string& str);
void visitRelocatableSymsMap(gc::GCVisitor* visitor); void visitRelocatableSymsMap(gc::GCVisitor* visitor);
......
...@@ -262,6 +262,9 @@ public: ...@@ -262,6 +262,9 @@ public:
FunctionSpecialization* spec; FunctionSpecialization* spec;
const OSREntryDescriptor* entry_descriptor; 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 { union {
Box* (*call)(Box*, Box*, Box*, Box**); Box* (*call)(Box*, Box*, Box*, Box**);
Box* (*closure_call)(BoxedClosure*, Box*, Box*, Box*, Box**); Box* (*closure_call)(BoxedClosure*, Box*, Box*, Box*, Box**);
...@@ -298,6 +301,8 @@ public: ...@@ -298,6 +301,8 @@ public:
// Call this when a speculation inside this version failed // Call this when a speculation inside this version failed
void speculationFailed(); void speculationFailed();
static void visitAllCompiledFunctions(GCVisitor* visitor);
}; };
typedef int FutureFlags; typedef int FutureFlags;
......
...@@ -435,6 +435,7 @@ static void markRoots(GCVisitor& visitor) { ...@@ -435,6 +435,7 @@ static void markRoots(GCVisitor& visitor) {
GC_TRACE_LOG("Looking at generated code pointers\n"); GC_TRACE_LOG("Looking at generated code pointers\n");
#if MOVING_GC #if MOVING_GC
ICInfo::visitGCReferences(&visitor); ICInfo::visitGCReferences(&visitor);
CompiledFunction::visitAllCompiledFunctions(&visitor);
#endif #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