Commit 1d96f534 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Have ICs keep their referenced-objects alive

This is kind of dumb but it's the same thing that we were doing
with a tracing GC.
parent 70bc1669
...@@ -82,9 +82,6 @@ uint8_t* ICSlotRewrite::getSlotStart() { ...@@ -82,9 +82,6 @@ uint8_t* ICSlotRewrite::getSlotStart() {
return (uint8_t*)ic->start_addr + ic_entry->idx * ic->getSlotSize(); return (uint8_t*)ic->start_addr + ic_entry->idx * ic->getSlotSize();
} }
// Map of gc pointers -> number of ics that point tot hem.
static llvm::DenseMap<void*, int> ic_gc_references;
void ICSlotRewrite::commit(CommitHook* hook, std::vector<void*> gc_references) { void ICSlotRewrite::commit(CommitHook* hook, std::vector<void*> gc_references) {
bool still_valid = true; bool still_valid = true;
for (int i = 0; i < dependencies.size(); i++) { for (int i = 0; i < dependencies.size(); i++) {
...@@ -121,16 +118,13 @@ void ICSlotRewrite::commit(CommitHook* hook, std::vector<void*> gc_references) { ...@@ -121,16 +118,13 @@ void ICSlotRewrite::commit(CommitHook* hook, std::vector<void*> gc_references) {
// if (VERBOSITY()) printf("Commiting to %p-%p\n", start, start + ic->slot_size); // if (VERBOSITY()) printf("Commiting to %p-%p\n", start, start + ic->slot_size);
memcpy(slot_start, buf, ic->getSlotSize()); memcpy(slot_start, buf, ic->getSlotSize());
for (auto p : gc_references) {
Py_INCREF(p);
}
for (auto p : ic_entry->gc_references) { for (auto p : ic_entry->gc_references) {
int& i = ic_gc_references[p]; Py_DECREF(p);
if (i == 1)
ic_gc_references.erase(p);
else
--i;
} }
ic_entry->gc_references = std::move(gc_references); ic_entry->gc_references = std::move(gc_references);
for (auto p : ic_entry->gc_references)
ic_gc_references[p]++;
ic->times_rewritten++; ic->times_rewritten++;
...@@ -231,6 +225,7 @@ ICInfo::ICInfo(void* start_addr, void* slowpath_rtn_addr, void* continue_addr, S ...@@ -231,6 +225,7 @@ ICInfo::ICInfo(void* start_addr, void* slowpath_rtn_addr, void* continue_addr, S
start_addr(start_addr), start_addr(start_addr),
slowpath_rtn_addr(slowpath_rtn_addr), slowpath_rtn_addr(slowpath_rtn_addr),
continue_addr(continue_addr) { continue_addr(continue_addr) {
slots.reserve(num_slots);
for (int i = 0; i < num_slots; i++) { for (int i = 0; i < num_slots; i++) {
slots.emplace_back(this, i); slots.emplace_back(this, i);
} }
...@@ -323,6 +318,10 @@ void ICInfo::clear(ICSlotInfo* icentry) { ...@@ -323,6 +318,10 @@ void ICInfo::clear(ICSlotInfo* icentry) {
writer.jmp(JumpDestination::fromStart(getSlotSize())); writer.jmp(JumpDestination::fromStart(getSlotSize()));
assert(writer.bytesWritten() <= IC_INVALDITION_HEADER_SIZE); assert(writer.bytesWritten() <= IC_INVALDITION_HEADER_SIZE);
for (auto p : icentry->gc_references) {
Py_DECREF(p);
}
// std::unique_ptr<MCWriter> writer(createMCWriter(start, getSlotSize(), 0)); // std::unique_ptr<MCWriter> writer(createMCWriter(start, getSlotSize(), 0));
// writer->emitNop(); // writer->emitNop();
// writer->emitGuardFalse(); // writer->emitGuardFalse();
...@@ -358,4 +357,10 @@ ICInfo* ICInfo::getICInfoForNode(AST* node) { ...@@ -358,4 +357,10 @@ ICInfo* ICInfo::getICInfoForNode(AST* node) {
void ICInfo::associateNodeWithICInfo(AST* node) { void ICInfo::associateNodeWithICInfo(AST* node) {
ics_by_ast_node[node] = this; ics_by_ast_node[node] = this;
} }
void clearAllICs() {
for (auto&& p : ics_by_ast_node) {
p.second->clearAll();
}
}
} }
...@@ -134,6 +134,11 @@ public: ...@@ -134,6 +134,11 @@ public:
std::unique_ptr<ICSlotRewrite> startRewrite(const char* debug_name); std::unique_ptr<ICSlotRewrite> startRewrite(const char* debug_name);
void clear(ICSlotInfo* entry); void clear(ICSlotInfo* entry);
void clearAll() {
for (ICSlotInfo& slot_info : slots) {
clear(&slot_info);
}
}
bool shouldAttempt(); bool shouldAttempt();
bool isMegamorphic(); bool isMegamorphic();
...@@ -160,6 +165,8 @@ std::unique_ptr<ICInfo> registerCompiledPatchpoint(uint8_t* start_addr, uint8_t* ...@@ -160,6 +165,8 @@ std::unique_ptr<ICInfo> registerCompiledPatchpoint(uint8_t* start_addr, uint8_t*
void deregisterCompiledPatchpoint(ICInfo* ic); void deregisterCompiledPatchpoint(ICInfo* ic);
ICInfo* getICInfo(void* rtn_addr); ICInfo* getICInfo(void* rtn_addr);
void clearAllICs(); // mostly for refcount debugging
} }
#endif #endif
...@@ -4797,6 +4797,7 @@ extern "C" void Py_Finalize() noexcept { ...@@ -4797,6 +4797,7 @@ extern "C" void Py_Finalize() noexcept {
break; break;
} }
clearAllICs();
PyType_ClearCache(); PyType_ClearCache();
PyOS_FiniInterrupts(); PyOS_FiniInterrupts();
_PyCodecRegistry_Deinit(); _PyCodecRegistry_Deinit();
......
# expected: reffail
# Regression test: make sure we guard / invalidate our getattr() rewrites: # Regression test: make sure we guard / invalidate our getattr() rewrites:
class C(object): class C(object):
......
# expected: reffail
class Random(object): class Random(object):
def __init__(self, seed): def __init__(self, seed):
self.cur = seed self.cur = seed
......
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