Commit d74e336f authored by Kevin Modzelewski's avatar Kevin Modzelewski

Change the way we pass line numbers to the runtime

Before, for compiled functions we used dwarf line number information.

Now it's switched to using the new frame introspection support, and
we pass through the AST_stmt* as one of the arguments.  This gets us
the line number and also the definition of execution point.
parent 048c730d
...@@ -900,7 +900,7 @@ watch_%: ...@@ -900,7 +900,7 @@ watch_%:
TARGET=$(dir $@)$(patsubst watch_%,%,$(notdir $@)); \ TARGET=$(dir $@)$(patsubst watch_%,%,$(notdir $@)); \
clear; $(MAKE) $$TARGET $(WATCH_ARGS); true; \ clear; $(MAKE) $$TARGET $(WATCH_ARGS); true; \
while inotifywait -q -e modify -e attrib -e move -e move_self -e create -e delete -e delete_self \ while inotifywait -q -e modify -e attrib -e move -e move_self -e create -e delete -e delete_self \
Makefile $$(find .. \( -name '*.cpp' -o -name '*.h' -o -name '*.py' \) ); do clear; $(MAKE) $$TARGET $(WATCH_ARGS); done ) Makefile $$(find . \( -name '*.cpp' -o -name '*.h' -o -name '*.py' \) ); do clear; $(MAKE) $$TARGET $(WATCH_ARGS); done )
# Makefile $$(find \( -name '*.cpp' -o -name '*.h' -o -name '*.py' \) -o -type d ); do clear; $(MAKE) $(patsubst watch_%,%,$@); done ) # Makefile $$(find \( -name '*.cpp' -o -name '*.h' -o -name '*.py' \) -o -type d ); do clear; $(MAKE) $(patsubst watch_%,%,$@); done )
# -r . ; do clear; $(MAKE) $(patsubst watch_%,%,$@); done # -r . ; do clear; $(MAKE) $(patsubst watch_%,%,$@); done
watch: watch_pyston_dbg watch: watch_pyston_dbg
......
...@@ -65,7 +65,7 @@ public: ...@@ -65,7 +65,7 @@ public:
void initArguments(int nargs, BoxedClosure* closure, BoxedGenerator* generator, Box* arg1, Box* arg2, Box* arg3, void initArguments(int nargs, BoxedClosure* closure, BoxedGenerator* generator, Box* arg1, Box* arg2, Box* arg3,
Box** args); Box** args);
static Value execute(ASTInterpreter& interpreter, AST* start_at = NULL); static Value execute(ASTInterpreter& interpreter, AST_stmt* start_at = NULL);
private: private:
Box* createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body); Box* createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body);
...@@ -122,15 +122,19 @@ private: ...@@ -122,15 +122,19 @@ private:
SymMap sym_table; SymMap sym_table;
CFGBlock* next_block, *current_block; CFGBlock* next_block, *current_block;
AST* current_inst; AST_stmt* current_inst;
Box* last_exception; Box* last_exception;
BoxedClosure* passed_closure, *created_closure; BoxedClosure* passed_closure, *created_closure;
BoxedGenerator* generator; BoxedGenerator* generator;
unsigned edgecount; unsigned edgecount;
public: public:
LineInfo* getCurrentLineInfo(); AST_stmt* getCurrentStatement() {
BoxedModule* getParentModule() { return source_info->parent_module; } assert(current_inst);
return current_inst;
}
CompiledFunction* getCF() { return compiled_func; }
const SymMap& getSymbolTable() { return sym_table; } const SymMap& getSymbolTable() { return sym_table; }
}; };
...@@ -162,25 +166,26 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge ...@@ -162,25 +166,26 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
return v.o ? v.o : None; return v.o ? v.o : None;
} }
const LineInfo* getLineInfoForInterpretedFrame(void* frame_ptr) { Box* astInterpretFrom(CompiledFunction* cf, AST_stmt* start_at, BoxedDict* locals) {
ASTInterpreter* interpreter = s_interpreterMap[frame_ptr]; assert(locals->d.size() == 0);
assert(interpreter);
return interpreter->getCurrentLineInfo(); ASTInterpreter interpreter(cf);
}
Value v = ASTInterpreter::execute(interpreter, start_at);
LineInfo* ASTInterpreter::getCurrentLineInfo() { return v.o ? v.o : None;
if (!current_inst) }
return NULL;
LineInfo* line_info = new LineInfo(current_inst->lineno, current_inst->col_offset, source_info->parent_module->fn, AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr) {
source_info->getName()); ASTInterpreter* interpreter = s_interpreterMap[frame_ptr];
return line_info; assert(interpreter);
return interpreter->getCurrentStatement();
} }
BoxedModule* getModuleForInterpretedFrame(void* frame_ptr) { CompiledFunction* getCFForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = s_interpreterMap[frame_ptr]; ASTInterpreter* interpreter = s_interpreterMap[frame_ptr];
assert(interpreter); assert(interpreter);
return interpreter->getParentModule(); return interpreter->getCF();
} }
BoxedDict* localsForInterpretedFrame(void* frame_ptr, bool only_user_visible) { BoxedDict* localsForInterpretedFrame(void* frame_ptr, bool only_user_visible) {
...@@ -263,7 +268,7 @@ public: ...@@ -263,7 +268,7 @@ public:
}; };
} }
Value ASTInterpreter::execute(ASTInterpreter& interpreter, AST* start_at) { Value ASTInterpreter::execute(ASTInterpreter& interpreter, AST_stmt* start_at) {
assert(start_at == NULL); assert(start_at == NULL);
void* frame_addr = __builtin_frame_address(0); void* frame_addr = __builtin_frame_address(0);
......
...@@ -21,10 +21,9 @@ namespace gc { ...@@ -21,10 +21,9 @@ namespace gc {
class GCVisitor; class GCVisitor;
} }
class AST; class AST_stmt;
class Box; class Box;
class BoxedDict; class BoxedDict;
class BoxedModule;
struct CompiledFunction; struct CompiledFunction;
struct LineInfo; struct LineInfo;
...@@ -32,9 +31,10 @@ extern const void* interpreter_instr_addr; ...@@ -32,9 +31,10 @@ extern const void* interpreter_instr_addr;
Box* astInterpretFunction(CompiledFunction* f, int nargs, Box* closure, Box* generator, Box* arg1, Box* arg2, Box* arg3, Box* astInterpretFunction(CompiledFunction* f, int nargs, Box* closure, Box* generator, Box* arg1, Box* arg2, Box* arg3,
Box** args); Box** args);
Box* astInterpretFrom(CompiledFunction* cf, AST_stmt* start_at, BoxedDict* locals);
const LineInfo* getLineInfoForInterpretedFrame(void* frame_ptr); AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr);
BoxedModule* getModuleForInterpretedFrame(void* frame_ptr); CompiledFunction* getCFForInterpretedFrame(void* frame_ptr);
void gatherInterpreterRoots(gc::GCVisitor* visitor); void gatherInterpreterRoots(gc::GCVisitor* visitor);
BoxedDict* localsForInterpretedFrame(void* frame_ptr, bool only_user_visible); BoxedDict* localsForInterpretedFrame(void* frame_ptr, bool only_user_visible);
......
...@@ -25,18 +25,23 @@ ...@@ -25,18 +25,23 @@
namespace pyston { namespace pyston {
class AST_expr; class AST_expr;
class AST_stmt;
class GCBuilder; class GCBuilder;
class IREmitter; class IREmitter;
struct UnwindInfo { struct UnwindInfo {
public: public:
AST_stmt* current_stmt;
llvm::BasicBlock* exc_dest; llvm::BasicBlock* exc_dest;
bool needsInvoke() { return exc_dest != NULL; } bool needsInvoke() { return exc_dest != NULL; }
UnwindInfo(llvm::BasicBlock* exc_dest) : exc_dest(exc_dest) {} UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* exc_dest) : current_stmt(current_stmt), exc_dest(exc_dest) {}
static UnwindInfo none() { return UnwindInfo(NULL); } // Risky! This means that we can't unwind from this location, and should be used in the
// rare case that there are language-specific reasons that the statement should not unwind
// (ex: loading function arguments into the appropriate scopes).
static UnwindInfo cantUnwind() { return UnwindInfo(NULL, NULL); }
}; };
// TODO get rid of this // TODO get rid of this
......
...@@ -138,18 +138,6 @@ static void compileIR(CompiledFunction* cf, EffortLevel::EffortLevel effort) { ...@@ -138,18 +138,6 @@ static void compileIR(CompiledFunction* cf, EffortLevel::EffortLevel effort) {
delete stackmap; delete stackmap;
} }
static std::unordered_map<std::string, CompiledFunction*> machine_name_to_cf;
CompiledFunction* cfForMachineFunctionName(const std::string& machine_name) {
assert(machine_name.size());
auto r = machine_name_to_cf[machine_name];
return r;
}
void registerMachineName(const std::string& machine_name, CompiledFunction* cf) {
assert(machine_name_to_cf.count(machine_name) == 0);
machine_name_to_cf[machine_name] = cf;
}
// Compiles a new version of the function with the given signature and adds it to the list; // Compiles a new version of the function with the given signature and adds it to the list;
// should only be called after checking to see if the other versions would work. // should only be called after checking to see if the other versions would work.
// The codegen_lock needs to be held in W mode before calling this function: // The codegen_lock needs to be held in W mode before calling this function:
...@@ -208,7 +196,6 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E ...@@ -208,7 +196,6 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
cf = new CompiledFunction(0, spec, true, NULL, NULL, effort, 0); cf = new CompiledFunction(0, spec, true, NULL, NULL, effort, 0);
} else { } else {
cf = doCompile(source, entry, effort, spec, name); cf = doCompile(source, entry, effort, spec, name);
registerMachineName(cf->func->getName(), cf);
compileIR(cf, effort); compileIR(cf, effort);
} }
......
...@@ -142,7 +142,7 @@ private: ...@@ -142,7 +142,7 @@ private:
pp_args.insert(pp_args.end(), ic_stackmap_args.begin(), ic_stackmap_args.end()); pp_args.insert(pp_args.end(), ic_stackmap_args.begin(), ic_stackmap_args.end());
irgenerator->addFrameStackmapArgs(info, pp_args); irgenerator->addFrameStackmapArgs(info, unw_info.current_stmt, pp_args);
llvm::Intrinsic::ID intrinsic_id; llvm::Intrinsic::ID intrinsic_id;
if (return_type->isIntegerTy() || return_type->isPointerTy()) { if (return_type->isIntegerTy() || return_type->isPointerTy()) {
...@@ -1336,7 +1336,7 @@ private: ...@@ -1336,7 +1336,7 @@ private:
CompilerVariable* closure = _getFake(CREATED_CLOSURE_NAME, false); CompilerVariable* closure = _getFake(CREATED_CLOSURE_NAME, false);
assert(closure); assert(closure);
closure->setattr(emitter, getEmptyOpInfo(UnwindInfo::none()), &name, val); closure->setattr(emitter, getEmptyOpInfo(unw_info), &name, val);
} }
} }
} }
...@@ -2055,7 +2055,7 @@ private: ...@@ -2055,7 +2055,7 @@ private:
endBlock(DEAD); endBlock(DEAD);
} }
void doStmt(AST* node, UnwindInfo unw_info) { void doStmt(AST_stmt* node, UnwindInfo unw_info) {
// printf("%d stmt: %d\n", node->type, node->lineno); // printf("%d stmt: %d\n", node->type, node->lineno);
if (node->lineno) { if (node->lineno) {
emitter.getBuilder()->SetCurrentDebugLocation( emitter.getBuilder()->SetCurrentDebugLocation(
...@@ -2113,7 +2113,7 @@ private: ...@@ -2113,7 +2113,7 @@ private:
case AST_TYPE::Invoke: { case AST_TYPE::Invoke: {
assert(!unw_info.needsInvoke()); assert(!unw_info.needsInvoke());
AST_Invoke* invoke = ast_cast<AST_Invoke>(node); AST_Invoke* invoke = ast_cast<AST_Invoke>(node);
doStmt(invoke->stmt, UnwindInfo(entry_blocks[invoke->exc_dest])); doStmt(invoke->stmt, UnwindInfo(node, entry_blocks[invoke->exc_dest]));
assert(state == RUNNING || state == DEAD); assert(state == RUNNING || state == DEAD);
if (state == RUNNING) { if (state == RUNNING) {
...@@ -2234,8 +2234,14 @@ private: ...@@ -2234,8 +2234,14 @@ private:
} }
public: public:
void addFrameStackmapArgs(PatchpointInfo* pp, std::vector<llvm::Value*>& stackmap_args) override { void addFrameStackmapArgs(PatchpointInfo* pp, AST_stmt* current_stmt,
std::vector<llvm::Value*>& stackmap_args) override {
int initial_args = stackmap_args.size(); int initial_args = stackmap_args.size();
assert(INT->llvmType() == g.i64);
stackmap_args.push_back(getConstantInt((uint64_t)current_stmt, g.i64));
pp->addFrameVar("!current_stmt", INT);
if (ENABLE_FRAME_INTROSPECTION) { if (ENABLE_FRAME_INTROSPECTION) {
// TODO: don't need to use a sorted symbol table if we're explicitly recording the names! // TODO: don't need to use a sorted symbol table if we're explicitly recording the names!
// nice for debugging though. // nice for debugging though.
...@@ -2406,16 +2412,16 @@ public: ...@@ -2406,16 +2412,16 @@ public:
if (arg_names.args) { if (arg_names.args) {
int i = 0; int i = 0;
for (; i < arg_names.args->size(); i++) { for (; i < arg_names.args->size(); i++) {
loadArgument((*arg_names.args)[i], arg_types[i], python_parameters[i], UnwindInfo::none()); loadArgument((*arg_names.args)[i], arg_types[i], python_parameters[i], UnwindInfo::cantUnwind());
} }
if (arg_names.vararg->size()) { if (arg_names.vararg->size()) {
loadArgument(*arg_names.vararg, arg_types[i], python_parameters[i], UnwindInfo::none()); loadArgument(*arg_names.vararg, arg_types[i], python_parameters[i], UnwindInfo::cantUnwind());
i++; i++;
} }
if (arg_names.kwarg->size()) { if (arg_names.kwarg->size()) {
loadArgument(*arg_names.kwarg, arg_types[i], python_parameters[i], UnwindInfo::none()); loadArgument(*arg_names.kwarg, arg_types[i], python_parameters[i], UnwindInfo::cantUnwind());
i++; i++;
} }
...@@ -2424,12 +2430,11 @@ public: ...@@ -2424,12 +2430,11 @@ public:
} }
void run(const CFGBlock* block) override { void run(const CFGBlock* block) override {
UnwindInfo unw_info = UnwindInfo::none();
for (int i = 0; i < block->body.size(); i++) { for (int i = 0; i < block->body.size(); i++) {
if (state == DEAD) if (state == DEAD)
break; break;
assert(state != FINISHED); assert(state != FINISHED);
doStmt(block->body[i], unw_info); doStmt(block->body[i], UnwindInfo(block->body[i], NULL));
} }
} }
......
...@@ -198,7 +198,8 @@ public: ...@@ -198,7 +198,8 @@ public:
virtual void run(const CFGBlock* block) = 0; virtual void run(const CFGBlock* block) = 0;
virtual EndingState getEndingSymbolTable() = 0; virtual EndingState getEndingSymbolTable() = 0;
virtual void doSafePoint() = 0; virtual void doSafePoint() = 0;
virtual void addFrameStackmapArgs(PatchpointInfo* pp, std::vector<llvm::Value*>& stackmap_args) = 0; virtual void addFrameStackmapArgs(PatchpointInfo* pp, AST_stmt* current_stmt,
std::vector<llvm::Value*>& stackmap_args) = 0;
}; };
class IREmitter; class IREmitter;
......
...@@ -152,8 +152,10 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) { ...@@ -152,8 +152,10 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) {
PatchpointInfo* pp = reinterpret_cast<PatchpointInfo*>(r->id); PatchpointInfo* pp = reinterpret_cast<PatchpointInfo*>(r->id);
assert(pp); assert(pp);
if (VERBOSITY()) if (VERBOSITY()) {
printf("Processing pp %ld\n", reinterpret_cast<int64_t>(pp)); printf("Processing pp %ld; [%d, %d)\n", reinterpret_cast<int64_t>(pp), r->offset,
r->offset + pp->patchpointSize());
}
assert(r->locations.size() == pp->totalStackmapArgs()); assert(r->locations.size() == pp->totalStackmapArgs());
......
...@@ -101,8 +101,6 @@ public: ...@@ -101,8 +101,6 @@ public:
std::unique_ptr<llvm::DIContext> Context(llvm::DIContext::getDWARFContext(*Obj.getObjectFile())); std::unique_ptr<llvm::DIContext> Context(llvm::DIContext::getDWARFContext(*Obj.getObjectFile()));
assert(g.cur_cf); assert(g.cur_cf);
assert(!g.cur_cf->line_table);
LineTable* line_table = g.cur_cf->line_table = new LineTable();
llvm_error_code ec; llvm_error_code ec;
for (llvm::object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E && !ec; ++I) { for (llvm::object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E && !ec; ++I) {
...@@ -141,11 +139,6 @@ public: ...@@ -141,11 +139,6 @@ public:
g.cur_cf->code_start = Addr; g.cur_cf->code_start = Addr;
g.cur_cf->code_size = Size; g.cur_cf->code_size = Size;
cf_registry.registerCF(g.cur_cf); cf_registry.registerCF(g.cur_cf);
for (const auto& p : lines) {
line_table->entries.push_back(std::make_pair(
p.first, LineInfo(p.second.Line, p.second.Column, p.second.FileName, p.second.FunctionName)));
}
} }
} }
...@@ -236,8 +229,9 @@ private: ...@@ -236,8 +229,9 @@ private:
unw_context_t ctx; unw_context_t ctx;
unw_cursor_t cursor; unw_cursor_t cursor;
CompiledFunction* cf; CompiledFunction* cf;
bool cur_is_osr;
PythonFrameIterator() {} PythonFrameIterator() : cf(NULL), cur_is_osr(false) {}
// not copyable or movable, since 'cursor' holds an internal pointer to 'ctx' // not copyable or movable, since 'cursor' holds an internal pointer to 'ctx'
PythonFrameIterator(const PythonFrameIterator&) = delete; PythonFrameIterator(const PythonFrameIterator&) = delete;
...@@ -251,6 +245,55 @@ public: ...@@ -251,6 +245,55 @@ public:
return cf; return cf;
} }
uint64_t readLocation(const StackMap::Record::Location& loc) {
if (loc.type == StackMap::Record::Location::LocationType::Register) {
// TODO: need to make sure we deal with patchpoints appropriately
return getReg(loc.regnum);
} else if (loc.type == StackMap::Record::Location::LocationType::Indirect) {
uint64_t reg_val = getReg(loc.regnum);
uint64_t addr = reg_val + loc.offset;
return *reinterpret_cast<uint64_t*>(addr);
} else if (loc.type == StackMap::Record::Location::LocationType::Constant) {
return loc.offset;
} else if (loc.type == StackMap::Record::Location::LocationType::ConstIndex) {
int const_idx = loc.offset;
assert(const_idx >= 0);
assert(const_idx < cf->location_map->constants.size());
return getCF()->location_map->constants[const_idx];
} else {
printf("%d %d %d %d\n", loc.type, loc.flags, loc.regnum, loc.offset);
abort();
}
}
AST_stmt* getCurrentStatement() {
if (id.type == PythonFrameId::COMPILED) {
CompiledFunction* cf = getCF();
uint64_t ip = getId().ip;
assert(ip > cf->code_start);
unsigned offset = ip - cf->code_start;
assert(cf->location_map);
const LocationMap::LocationTable& table = cf->location_map->names["!current_stmt"];
assert(table.locations.size());
// printf("Looking for something at offset %d (total ip: %lx)\n", offset, ip);
for (const LocationMap::LocationTable::LocationEntry& e : table.locations) {
// printf("(%d, %d]\n", e.offset, e.offset + e.length);
if (e.offset < offset && offset <= e.offset + e.length) {
// printf("Found it\n");
assert(e.locations.size() == 1);
return reinterpret_cast<AST_stmt*>(readLocation(e.locations[0]));
}
}
abort();
} else if (id.type == PythonFrameId::INTERPRETED) {
return getCurrentStatementForInterpretedFrame((void*)id.bp);
}
abort();
}
const PythonFrameId& getId() const { return id; } const PythonFrameId& getId() const { return id; }
static std::unique_ptr<PythonFrameIterator> end() { return std::unique_ptr<PythonFrameIterator>(nullptr); } static std::unique_ptr<PythonFrameIterator> end() { return std::unique_ptr<PythonFrameIterator>(nullptr); }
...@@ -279,6 +322,8 @@ public: ...@@ -279,6 +322,8 @@ public:
} }
bool incr() { bool incr() {
bool was_osr = cur_is_osr;
while (true) { while (true) {
int r = unw_step(&this->cursor); int r = unw_step(&this->cursor);
...@@ -289,8 +334,7 @@ public: ...@@ -289,8 +334,7 @@ public:
unw_word_t ip; unw_word_t ip;
unw_get_reg(&this->cursor, UNW_REG_IP, &ip); unw_get_reg(&this->cursor, UNW_REG_IP, &ip);
CompiledFunction* cf = getCFForAddress(ip); cf = getCFForAddress(ip);
this->cf = cf;
if (cf) { if (cf) {
this->id.type = PythonFrameId::COMPILED; this->id.type = PythonFrameId::COMPILED;
this->id.ip = ip; this->id.ip = ip;
...@@ -298,6 +342,13 @@ public: ...@@ -298,6 +342,13 @@ public:
unw_word_t bp; unw_word_t bp;
unw_get_reg(&this->cursor, UNW_TDEP_BP, &bp); unw_get_reg(&this->cursor, UNW_TDEP_BP, &bp);
cur_is_osr = (bool)cf->entry_descriptor;
if (was_osr) {
// Skip the frame we just found if the previous one was its OSR
// TODO this will break if we start collapsing the OSR frames
return incr();
}
return true; return true;
} }
...@@ -313,6 +364,15 @@ public: ...@@ -313,6 +364,15 @@ public:
this->id.type = PythonFrameId::INTERPRETED; this->id.type = PythonFrameId::INTERPRETED;
this->id.bp = bp; this->id.bp = bp;
cf = getCFForInterpretedFrame((void*)bp);
cur_is_osr = (bool)cf->entry_descriptor;
if (was_osr) {
// Skip the frame we just found if the previous one was its OSR
// TODO this will break if we start collapsing the OSR frames
return incr();
}
return true; return true;
} }
...@@ -368,15 +428,12 @@ static std::unique_ptr<PythonFrameIterator> getTopPythonFrame() { ...@@ -368,15 +428,12 @@ static std::unique_ptr<PythonFrameIterator> getTopPythonFrame() {
return fr; return fr;
} }
static const LineInfo* lineInfoForFrame(const PythonFrameIterator& frame_it) { static const LineInfo* lineInfoForFrame(PythonFrameIterator& frame_it) {
auto& id = frame_it.getId(); AST_stmt* current_stmt = frame_it.getCurrentStatement();
switch (id.type) { auto* cf = frame_it.getCF();
case PythonFrameId::COMPILED: assert(cf);
return frame_it.getCF()->line_table->getLineInfoFor(id.ip); return new LineInfo(current_stmt->lineno, current_stmt->col_offset, cf->clfunc->source->parent_module->fn,
case PythonFrameId::INTERPRETED: cf->clfunc->source->getName());
return getLineInfoForInterpretedFrame((void*)id.bp);
}
abort();
} }
std::vector<const LineInfo*> getTracebackEntries() { std::vector<const LineInfo*> getTracebackEntries() {
...@@ -398,24 +455,20 @@ const LineInfo* getMostRecentLineInfo() { ...@@ -398,24 +455,20 @@ const LineInfo* getMostRecentLineInfo() {
} }
CompiledFunction* getTopCompiledFunction() { CompiledFunction* getTopCompiledFunction() {
// TODO This is a bad way to do this... return getTopPythonFrame()->getCF();
const LineInfo* last_entry = getMostRecentLineInfo();
assert(last_entry->func.size());
CompiledFunction* cf = cfForMachineFunctionName(last_entry->func);
return cf;
} }
BoxedModule* getCurrentModule() { BoxedModule* getCurrentModule() {
CompiledFunction* compiledFunction = getTopCompiledFunction(); CompiledFunction* compiledFunction = getTopCompiledFunction();
if (compiledFunction) assert(compiledFunction);
return compiledFunction->clfunc->source->parent_module; return compiledFunction->clfunc->source->parent_module;
else { }
std::unique_ptr<PythonFrameIterator> frame = getTopPythonFrame();
auto& id = frame->getId(); ExecutionPoint getExecutionPoint() {
assert(id.type == PythonFrameId::INTERPRETED); auto frame = getTopPythonFrame();
return getModuleForInterpretedFrame((void*)id.bp); auto cf = frame->getCF();
} auto current_stmt = frame->getCurrentStatement();
return ExecutionPoint({.cf = cf, .current_stmt = current_stmt });
} }
BoxedDict* getLocals(bool only_user_visible) { BoxedDict* getLocals(bool only_user_visible) {
...@@ -442,28 +495,7 @@ BoxedDict* getLocals(bool only_user_visible) { ...@@ -442,28 +495,7 @@ BoxedDict* getLocals(bool only_user_visible) {
// printf("%s: %s\n", p.first.c_str(), e.type->debugName().c_str()); // printf("%s: %s\n", p.first.c_str(), e.type->debugName().c_str());
for (auto& loc : locs) { for (auto& loc : locs) {
uint64_t n; vals.push_back(frame_info.readLocation(loc));
// printf("%d %d %d %d\n", loc.type, loc.flags, loc.regnum, loc.offset);
if (loc.type == StackMap::Record::Location::LocationType::Register) {
// TODO: need to make sure we deal with patchpoints appropriately
n = frame_info.getReg(loc.regnum);
} else if (loc.type == StackMap::Record::Location::LocationType::Indirect) {
uint64_t reg_val = frame_info.getReg(loc.regnum);
uint64_t addr = reg_val + loc.offset;
n = *reinterpret_cast<uint64_t*>(addr);
} else if (loc.type == StackMap::Record::Location::LocationType::Constant) {
n = loc.offset;
} else if (loc.type == StackMap::Record::Location::LocationType::ConstIndex) {
int const_idx = loc.offset;
assert(const_idx >= 0);
assert(const_idx < cf->location_map->constants.size());
n = cf->location_map->constants[const_idx];
} else {
printf("%d %d %d %d\n", loc.type, loc.flags, loc.regnum, loc.offset);
abort();
}
vals.push_back(n);
} }
Box* v = e.type->deserializeFromFrame(vals); Box* v = e.type->deserializeFromFrame(vals);
......
...@@ -21,19 +21,6 @@ ...@@ -21,19 +21,6 @@
namespace pyston { namespace pyston {
class LineTable {
public:
std::vector<std::pair<uint64_t, LineInfo> > entries;
const LineInfo* getLineInfoFor(uint64_t addr) {
for (int i = entries.size() - 1; i >= 0; i--) {
if (entries[i].first < addr)
return &entries[i].second;
}
abort();
}
};
std::vector<const LineInfo*> getTracebackEntries(); std::vector<const LineInfo*> getTracebackEntries();
const LineInfo* getMostRecentLineInfo(); const LineInfo* getMostRecentLineInfo();
class BoxedModule; class BoxedModule;
...@@ -42,6 +29,12 @@ BoxedModule* getCurrentModule(); ...@@ -42,6 +29,12 @@ BoxedModule* getCurrentModule();
CompiledFunction* getCFForAddress(uint64_t addr); CompiledFunction* getCFForAddress(uint64_t addr);
class BoxedDict; class BoxedDict;
BoxedDict* getLocals(bool only_user_visible); BoxedDict* getLocals(bool only_user_visible);
struct ExecutionPoint {
CompiledFunction* cf;
AST_stmt* current_stmt;
};
ExecutionPoint getExecutionPoint();
} }
#endif #endif
...@@ -167,7 +167,6 @@ struct FunctionSpecialization { ...@@ -167,7 +167,6 @@ struct FunctionSpecialization {
class BoxedClosure; class BoxedClosure;
class BoxedGenerator; class BoxedGenerator;
class LineTable;
class ICInfo; class ICInfo;
class LocationMap; class LocationMap;
...@@ -196,9 +195,6 @@ public: ...@@ -196,9 +195,6 @@ public:
int64_t times_called; int64_t times_called;
ICInvalidator dependent_callsites; ICInvalidator dependent_callsites;
// Unfortunately, can't make this a std::unique_ptr if we want to forward-declare LineTable:
LineTable* line_table;
LocationMap* location_map; // only meaningful if this is a compiled frame LocationMap* location_map; // only meaningful if this is a compiled frame
std::vector<ICInfo*> ics; std::vector<ICInfo*> ics;
...@@ -207,8 +203,7 @@ public: ...@@ -207,8 +203,7 @@ public:
llvm::Value* llvm_code, EffortLevel::EffortLevel effort, llvm::Value* llvm_code, EffortLevel::EffortLevel effort,
const OSREntryDescriptor* entry_descriptor) const OSREntryDescriptor* entry_descriptor)
: clfunc(NULL), func(func), spec(spec), entry_descriptor(entry_descriptor), is_interpreted(is_interpreted), : clfunc(NULL), func(func), spec(spec), entry_descriptor(entry_descriptor), is_interpreted(is_interpreted),
code(code), llvm_code(llvm_code), effort(effort), times_called(0), line_table(nullptr), code(code), llvm_code(llvm_code), effort(effort), times_called(0), location_map(nullptr) {}
location_map(nullptr) {}
// TODO this will need to be implemented eventually; things to delete: // TODO this will need to be implemented eventually; things to delete:
// - line_table if it exists // - line_table if it exists
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "codegen/ast_interpreter.h"
#include "codegen/irgen/hooks.h" #include "codegen/irgen/hooks.h"
#include "codegen/parser.h" #include "codegen/parser.h"
#include "codegen/unwinding.h" #include "codegen/unwinding.h"
...@@ -583,6 +584,13 @@ Box* locals() { ...@@ -583,6 +584,13 @@ Box* locals() {
return getLocals(true /* filter */); return getLocals(true /* filter */);
} }
Box* deopt() {
auto locals = getLocals(false /* filter */);
auto execution_point = getExecutionPoint();
return astInterpretFrom(execution_point.cf, execution_point.current_stmt, locals);
}
Box* divmod(Box* lhs, Box* rhs) { Box* divmod(Box* lhs, Box* rhs) {
return binopInternal(lhs, rhs, AST_TYPE::DivMod, false, NULL); return binopInternal(lhs, rhs, AST_TYPE::DivMod, false, NULL);
} }
...@@ -808,6 +816,7 @@ void setupBuiltins() { ...@@ -808,6 +816,7 @@ void setupBuiltins() {
builtins_module->giveAttr("globals", new BoxedFunction(boxRTFunction((void*)globals, UNKNOWN, 0, 0, false, false))); builtins_module->giveAttr("globals", new BoxedFunction(boxRTFunction((void*)globals, UNKNOWN, 0, 0, false, false)));
builtins_module->giveAttr("locals", new BoxedFunction(boxRTFunction((void*)locals, UNKNOWN, 0, 0, false, false))); builtins_module->giveAttr("locals", new BoxedFunction(boxRTFunction((void*)locals, UNKNOWN, 0, 0, false, false)));
builtins_module->giveAttr("deopt", new BoxedFunction(boxRTFunction((void*)deopt, UNKNOWN, 0, 0, false, false)));
builtins_module->giveAttr("iter", new BoxedFunction(boxRTFunction((void*)getiter, UNKNOWN, 1, 0, false, false))); builtins_module->giveAttr("iter", new BoxedFunction(boxRTFunction((void*)getiter, UNKNOWN, 1, 0, false, false)));
......
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