Commit 8c667486 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Box traceback strings once

It had gotten to the point that a large part of the cost of throwing an
eception was allocating the std::string's to represent the function and
filename.

Most of the other strings have already been converted to being represented
as BoxedString's (ie python strings), so do that conversion here and a few
more places.
parent 21257c97
......@@ -294,7 +294,7 @@ void ASTInterpreter::startJITing(CFGBlock* block, int exit_offset) {
code_block = code_blocks[code_blocks.size() - 1].get();
if (!code_block || code_block->shouldCreateNewBlock()) {
code_blocks.push_back(std::unique_ptr<JitCodeBlock>(new JitCodeBlock(source_info->getName())));
code_blocks.push_back(std::unique_ptr<JitCodeBlock>(new JitCodeBlock(source_info->getName()->s())));
code_block = code_blocks[code_blocks.size() - 1].get();
exit_offset = 0;
}
......@@ -334,7 +334,7 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) {
auto source = getCL()->source.get();
stmt->cxx_exception_count++;
caughtCxxException(LineInfo(stmt->lineno, stmt->col_offset, source->fn, source->getName()), &e);
caughtCxxException(LineInfo(stmt->lineno, stmt->col_offset, source->getFn(), source->getName()), &e);
next_block = ((AST_Invoke*)stmt)->exc_dest;
last_exception = e;
......@@ -791,7 +791,7 @@ Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
auto source = getCL()->source.get();
node->cxx_exception_count++;
caughtCxxException(LineInfo(node->lineno, node->col_offset, source->fn, source->getName()), &e);
caughtCxxException(LineInfo(node->lineno, node->col_offset, source->getFn(), source->getName()), &e);
next_block = node->exc_dest;
last_exception = e;
......@@ -925,7 +925,7 @@ Value ASTInterpreter::visit_stmt(AST_stmt* node) {
#endif
if (0) {
printf("%20s % 2d ", source_info->getName().data(), current_block->idx);
printf("%20s % 2d ", source_info->getName()->c_str(), current_block->idx);
print_ast(node);
printf("\n");
}
......
......@@ -31,6 +31,7 @@
#include "codegen/compvars.h"
#include "core/ast.h"
#include "core/util.h"
#include "runtime/types.h"
namespace pyston {
......@@ -60,16 +61,18 @@ CLFunction::CLFunction(int num_args, int num_defaults, bool takes_varargs, bool
}
SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags future_flags, AST* ast,
std::vector<AST_stmt*> body, std::string fn)
std::vector<AST_stmt*> body, BoxedString* fn)
: parent_module(m),
scoping(scoping),
scope_info(NULL),
future_flags(future_flags),
ast(ast),
cfg(NULL),
fn(std::move(fn)),
body(std::move(body)) {
assert(this->fn.size());
assert(fn->size());
// TODO: we should track this reference correctly rather than making it a root
gc::registerPermanentRoot(fn, true);
this->fn = fn;
switch (ast->type) {
case AST_TYPE::ClassDef:
......
......@@ -934,18 +934,18 @@ static llvm::MDNode* setupDebugInfo(SourceInfo* source, llvm::Function* f, std::
llvm::DIBuilder builder(*g.cur_module);
const std::string& fn = source->fn;
BoxedString* fn = source->getFn();
std::string dir = "";
std::string producer = "pyston; git rev " STRINGIFY(GITREV);
llvm::DIFile file = builder.createFile(fn, dir);
llvm::DIFile file = builder.createFile(fn->s(), dir);
llvm::DITypeArray param_types = builder.getOrCreateTypeArray(llvm::None);
llvm::DICompositeType func_type = builder.createSubroutineType(file, param_types);
llvm::DISubprogram func_info = builder.createFunction(file, f->getName(), f->getName(), file, lineno, func_type,
false, true, lineno + 1, 0, true, f);
llvm::DICompileUnit compile_unit
= builder.createCompileUnit(llvm::dwarf::DW_LANG_Python, fn, dir, producer, true, "", 0);
= builder.createCompileUnit(llvm::dwarf::DW_LANG_Python, fn->s(), dir, producer, true, "", 0);
builder.finalize();
return func_info;
......@@ -967,7 +967,7 @@ static std::string getUniqueFunctionName(std::string nameprefix, EffortLevel eff
CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* param_names,
const OSREntryDescriptor* entry_descriptor, EffortLevel effort,
ExceptionStyle exception_style, FunctionSpecialization* spec, std::string nameprefix) {
ExceptionStyle exception_style, FunctionSpecialization* spec, llvm::StringRef nameprefix) {
Timer _t("in doCompile");
Timer _t2;
long irgen_us = 0;
......
......@@ -113,7 +113,7 @@ bool isIsDefinedName(llvm::StringRef name);
CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* param_names,
const OSREntryDescriptor* entry_descriptor, EffortLevel effort,
ExceptionStyle exception_style, FunctionSpecialization* spec, std::string nameprefix);
ExceptionStyle exception_style, FunctionSpecialization* spec, llvm::StringRef nameprefix);
// A common pattern is to branch based off whether a variable is defined but only if it is
// potentially-undefined. If it is potentially-undefined, we have to generate control-flow
......
This diff is collapsed.
......@@ -2961,7 +2961,7 @@ CLFunction* wrapFunction(AST* node, AST_arguments* args, const std::vector<AST_s
CLFunction*& cl = made[node];
if (cl == NULL) {
std::unique_ptr<SourceInfo> si(
new SourceInfo(source->parent_module, source->scoping, source->future_flags, node, body, source->fn));
new SourceInfo(source->parent_module, source->scoping, source->future_flags, node, body, source->getFn()));
if (args)
cl = new CLFunction(args->args.size(), args->defaults.size(), args->vararg.s().size(),
args->kwarg.s().size(), std::move(si));
......
......@@ -490,7 +490,7 @@ static const LineInfo lineInfoForFrame(PythonFrameIteratorImpl* frame_it) {
auto source = cl->source.get();
return LineInfo(current_stmt->lineno, current_stmt->col_offset, source->fn, source->getName());
return LineInfo(current_stmt->lineno, current_stmt->col_offset, source->getFn(), source->getName());
}
// A class that converts a C stack trace to a Python stack trace.
......@@ -1146,7 +1146,7 @@ std::string getCurrentPythonLine() {
auto current_stmt = frame_iter->getCurrentStatement();
stream << source->fn << ":" << current_stmt->lineno;
stream << source->getFn()->c_str() << ":" << current_stmt->lineno;
return stream.str();
}
return "unknown:-1";
......
......@@ -2733,7 +2733,7 @@ CFG* computeCFG(SourceInfo* source, std::vector<AST_stmt*> body) {
if (b->predecessors.size() == 0) {
if (b != rtn->getStartingBlock()) {
rtn->print();
printf("%s\n", source->getName().data());
printf("%s\n", source->getName()->c_str());
}
ASSERT(b == rtn->getStartingBlock(), "%d", b->idx);
}
......
......@@ -304,6 +304,8 @@ class ScopeInfo;
class InternedStringPool;
class LivenessAnalysis;
class SourceInfo {
private:
BoxedString* fn; // equivalent of code.co_filename
public:
BoxedModule* parent_module;
ScopingAnalysis* scoping;
......@@ -312,7 +314,6 @@ public:
AST* ast;
CFG* cfg;
bool is_generator;
std::string fn; // equivalent of code.co_filename
InternedStringPool& getInternedStrings();
......@@ -323,13 +324,15 @@ public:
// body and we have to create one. Ideally, we'd be able to avoid the space duplication for non-lambdas.
const std::vector<AST_stmt*> body;
llvm::StringRef getName();
BoxedString* getName();
BoxedString* getFn() { return fn; }
InternedString mangleName(InternedString id);
Box* getDocString();
SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags future_flags, AST* ast,
std::vector<AST_stmt*> body, std::string fn);
std::vector<AST_stmt*> body, BoxedString* fn);
~SourceInfo();
private:
......@@ -727,9 +730,9 @@ void raiseSyntaxErrorHelper(llvm::StringRef file, llvm::StringRef func, AST* nod
struct LineInfo {
public:
int line, column;
std::string file, func;
BoxedString* file, *func;
LineInfo(int line, int column, llvm::StringRef file, llvm::StringRef func)
LineInfo(int line, int column, BoxedString* file, BoxedString* func)
: line(line), column(column), file(file), func(func) {}
};
......
......@@ -44,12 +44,12 @@ public:
static Box* name(Box* b, void*) {
RELEASE_ASSERT(b->cls == code_cls, "");
return boxString(static_cast<BoxedCode*>(b)->f->source->getName());
return static_cast<BoxedCode*>(b)->f->source->getName();
}
static Box* filename(Box* b, void*) {
RELEASE_ASSERT(b->cls == code_cls, "");
return boxString(static_cast<BoxedCode*>(b)->f->source->fn);
return static_cast<BoxedCode*>(b)->f->source->getFn();
}
static Box* firstlineno(Box* b, void*) {
......
......@@ -359,8 +359,8 @@ static void print_frame(unw_cursor_t* cursor, const unw_proc_info_t* pip) {
if (frame_type == INTERPRETED && cf && cur_stmt) {
auto source = cf->clfunc->source.get();
// FIXME: dup'ed from lineInfoForFrame
LineInfo line(cur_stmt->lineno, cur_stmt->col_offset, source->fn, source->getName());
printf(" File \"%s\", line %d, in %s\n", line.file.c_str(), line.line, line.func.c_str());
LineInfo line(cur_stmt->lineno, cur_stmt->col_offset, source->getFn(), source->getName());
printf(" File \"%s\", line %d, in %s\n", line.file->c_str(), line.line, line.func->c_str());
}
}
......
......@@ -37,7 +37,7 @@ void raiseExc(Box* exc_obj) {
void raiseSyntaxError(const char* msg, int lineno, int col_offset, llvm::StringRef file, llvm::StringRef func) {
Box* exc = runtimeCall(SyntaxError, ArgPassSpec(1), boxString(msg), NULL, NULL, NULL, NULL);
auto tb = new BoxedTraceback(LineInfo(lineno, col_offset, file, func), None);
auto tb = new BoxedTraceback(LineInfo(lineno, col_offset, boxString(file), boxString(func)), None);
assert(!PyErr_Occurred());
throw ExcInfo(exc->cls, exc, tb);
}
......@@ -243,7 +243,8 @@ extern "C" void caughtCapiException(AST_stmt* stmt, void* _source_info) {
SourceInfo* source = static_cast<SourceInfo*>(_source_info);
PyThreadState* tstate = PyThreadState_GET();
exceptionAtLine(LineInfo(stmt->lineno, stmt->col_offset, source->fn, source->getName()), &tstate->curexc_traceback);
exceptionAtLine(LineInfo(stmt->lineno, stmt->col_offset, source->getFn(), source->getName()),
&tstate->curexc_traceback);
}
extern "C" void reraiseCapiExcAsCxx() {
......
......@@ -468,7 +468,7 @@ Box* generatorName(Box* _self, void* context) {
assert(isSubclass(_self->cls, generator_cls));
BoxedGenerator* self = static_cast<BoxedGenerator*>(_self);
return boxString(self->function->f->source->getName());
return self->function->f->source->getName();
}
void generatorDestructor(Box* b) {
......
......@@ -2958,7 +2958,7 @@ static CompiledFunction* pickVersion(CLFunction* f, ExceptionStyle S, int num_ou
static llvm::StringRef getFunctionName(CLFunction* f) {
if (f->source)
return f->source->getName();
return f->source->getName()->s();
else if (f->versions.size()) {
return "<builtin function>";
// std::ostringstream oss;
......
......@@ -45,6 +45,9 @@ void BoxedTraceback::gcHandler(GCVisitor* v, Box* b) {
if (self->tb_next)
v->visit(self->tb_next);
v->visit(self->line.file);
v->visit(self->line.func);
Box::gcHandler(v, b);
}
......@@ -59,12 +62,12 @@ void printTraceback(Box* b) {
for (; tb && tb != None; tb = static_cast<BoxedTraceback*>(tb->tb_next)) {
auto& line = tb->line;
fprintf(stderr, " File \"%s\", line %d, in %s:\n", line.file.c_str(), line.line, line.func.c_str());
fprintf(stderr, " File \"%s\", line %d, in %s:\n", line.file->c_str(), line.line, line.func->c_str());
if (line.line < 0)
continue;
FILE* f = fopen(line.file.c_str(), "r");
FILE* f = fopen(line.file->c_str(), "r");
if (f) {
assert(line.line < 10000000 && "Refusing to try to seek that many lines forward");
for (int i = 1; i < line.line; i++) {
......@@ -104,7 +107,7 @@ Box* BoxedTraceback::getLines(Box* b) {
BoxedList* lines = new BoxedList();
for (BoxedTraceback* wtb = tb; wtb && wtb != None; wtb = static_cast<BoxedTraceback*>(wtb->tb_next)) {
auto& line = wtb->line;
auto l = BoxedTuple::create({ boxString(line.file), boxString(line.func), boxInt(line.line) });
auto l = BoxedTuple::create({ line.file, line.func, boxInt(line.line) });
listAppendInternal(lines, l);
}
tb->py_lines = lines;
......
......@@ -432,7 +432,7 @@ BoxedFunction::BoxedFunction(CLFunction* f, std::initializer_list<Box*> defaults
// some builtin functions that are BoxedFunctions but really ought to be a type that
// we don't have yet.
if (f->source) {
this->name = static_cast<BoxedString*>(boxString(f->source->getName()));
this->name = static_cast<BoxedString*>(f->source->getName());
}
}
......
......@@ -256,7 +256,7 @@ extern "C" void dumpEx(void* p, int levels) {
CLFunction* cl = f->f;
if (cl->source) {
printf("User-defined function '%s'\n", cl->source->getName().data());
printf("User-defined function '%s'\n", cl->source->getName()->c_str());
} else {
printf("A builtin function\n");
}
......
......@@ -12,6 +12,7 @@
#include "codegen/parser.h"
#include "core/ast.h"
#include "core/cfg.h"
#include "runtime/types.h"
#include "unittests.h"
using namespace pyston;
......@@ -39,7 +40,8 @@ TEST_F(AnalysisTest, augassign) {
FutureFlags future_flags = getFutureFlags(module->body, fn.c_str());
SourceInfo* si = new SourceInfo(createModule("augassign", fn.c_str()), scoping, future_flags, func, func->body, fn);
SourceInfo* si = new SourceInfo(createModule("augassign", fn.c_str()), scoping, future_flags, func,
func->body, boxString(fn));
CFG* cfg = computeCFG(si, func->body);
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg);
......@@ -69,7 +71,7 @@ void doOsrTest(bool is_osr, bool i_maybe_undefined) {
ScopeInfo* scope_info = scoping->getScopeInfoForNode(func);
std::unique_ptr<SourceInfo> si(new SourceInfo(createModule("osr" + std::to_string((is_osr << 1) + i_maybe_undefined),
fn.c_str()), scoping, future_flags, func, func->body, fn));
fn.c_str()), scoping, future_flags, func, func->body, boxString(fn)));
CLFunction* clfunc = new CLFunction(0, 0, false, false, std::move(si));
CFG* cfg = computeCFG(clfunc->source.get(), func->body);
......
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