Commit 971519a0 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #760 from undingen/bjit_missing_core

bjit: add support for most common missing nodes and don't JIT compile cold blocks
parents f7367f15 d18ff95a
...@@ -75,7 +75,7 @@ public: ...@@ -75,7 +75,7 @@ public:
static Box* executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, AST_stmt* start_at); static Box* executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, AST_stmt* start_at);
private: private:
Box* createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body); Value createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body);
Value doBinOp(Value left, Value right, int op, BinExpType exp_type); Value doBinOp(Value left, Value right, int op, BinExpType exp_type);
void doStore(AST_expr* node, Value value); void doStore(AST_expr* node, Value value);
void doStore(AST_Name* name, Value value); void doStore(AST_Name* name, Value value);
...@@ -153,6 +153,7 @@ private: ...@@ -153,6 +153,7 @@ private:
// This is either a module or a dict // This is either a module or a dict
Box* globals; Box* globals;
std::unique_ptr<JitFragmentWriter> jit; std::unique_ptr<JitFragmentWriter> jit;
bool should_jit;
public: public:
llvm::DenseMap<InternedString, int>& getSymVRegMap() { llvm::DenseMap<InternedString, int>& getSymVRegMap() {
...@@ -240,7 +241,8 @@ ASTInterpreter::ASTInterpreter(CLFunction* clfunc, Box** vregs) ...@@ -240,7 +241,8 @@ ASTInterpreter::ASTInterpreter(CLFunction* clfunc, Box** vregs)
edgecount(0), edgecount(0),
frame_info(ExcInfo(NULL, NULL, NULL)), frame_info(ExcInfo(NULL, NULL, NULL)),
parent_module(source_info->parent_module), parent_module(source_info->parent_module),
globals(0) { globals(0),
should_jit(false) {
scope_info = source_info->getScopeInfo(); scope_info = source_info->getScopeInfo();
...@@ -300,6 +302,8 @@ void ASTInterpreter::startJITing(CFGBlock* block, int exit_offset) { ...@@ -300,6 +302,8 @@ void ASTInterpreter::startJITing(CFGBlock* block, int exit_offset) {
void ASTInterpreter::abortJITing() { void ASTInterpreter::abortJITing() {
if (jit) { if (jit) {
static StatCounter bjit_aborts("num_baselinejit_aborts");
bjit_aborts.log();
jit->abortCompilation(); jit->abortCompilation();
jit.reset(); jit.reset();
} }
...@@ -338,17 +342,12 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) { ...@@ -338,17 +342,12 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) {
Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, AST_stmt* start_at) { Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, AST_stmt* start_at) {
Value v; Value v;
bool should_jit = false;
bool from_start = start_block == NULL && start_at == NULL; bool from_start = start_block == NULL && start_at == NULL;
assert((start_block == NULL) == (start_at == NULL)); assert((start_block == NULL) == (start_at == NULL));
if (start_block == NULL) { if (start_block == NULL) {
start_block = interpreter.source_info->cfg->getStartingBlock(); start_block = interpreter.source_info->cfg->getStartingBlock();
start_at = start_block->body[0]; start_at = start_block->body[0];
if (ENABLE_BASELINEJIT && interpreter.clfunc->times_interpreted >= REOPT_THRESHOLD_INTERPRETER
&& !start_block->code)
should_jit = true;
} }
// Important that this happens after RegisterHelper: // Important that this happens after RegisterHelper:
...@@ -370,12 +369,12 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -370,12 +369,12 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
v = interpreter.visit_stmt(s); v = interpreter.visit_stmt(s);
} }
} else { } else {
if (should_jit)
interpreter.startJITing(start_block);
interpreter.next_block = start_block; interpreter.next_block = start_block;
} }
if (ENABLE_BASELINEJIT && interpreter.clfunc->times_interpreted >= REOPT_THRESHOLD_INTERPRETER)
interpreter.should_jit = true;
while (interpreter.next_block) { while (interpreter.next_block) {
interpreter.current_block = interpreter.next_block; interpreter.current_block = interpreter.next_block;
interpreter.next_block = 0; interpreter.next_block = 0;
...@@ -383,7 +382,6 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -383,7 +382,6 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
if (ENABLE_BASELINEJIT && !interpreter.jit) { if (ENABLE_BASELINEJIT && !interpreter.jit) {
CFGBlock* b = interpreter.current_block; CFGBlock* b = interpreter.current_block;
if (b->entry_code) { if (b->entry_code) {
should_jit = true;
Box* rtn = interpreter.execJITedBlock(b); Box* rtn = interpreter.execJITedBlock(b);
if (interpreter.next_block) if (interpreter.next_block)
continue; continue;
...@@ -391,7 +389,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -391,7 +389,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
} }
} }
if (ENABLE_BASELINEJIT && should_jit && !interpreter.jit) { if (ENABLE_BASELINEJIT && interpreter.should_jit && !interpreter.jit) {
assert(!interpreter.current_block->code); assert(!interpreter.current_block->code);
interpreter.startJITing(interpreter.current_block); interpreter.startJITing(interpreter.current_block);
} }
...@@ -604,13 +602,20 @@ Value ASTInterpreter::visit_jump(AST_Jump* node) { ...@@ -604,13 +602,20 @@ Value ASTInterpreter::visit_jump(AST_Jump* node) {
jit->emitOSRPoint(node); jit->emitOSRPoint(node);
jit->emitJump(node->target); jit->emitJump(node->target);
finishJITing(node->target); finishJITing(node->target);
// we may have started JITing because the OSR thresholds got triggered in this case we don't want to jit
// additional blocks ouside of the loop if the function is cold.
if (clfunc->times_interpreted < REOPT_THRESHOLD_INTERPRETER)
should_jit = false;
} }
if (backedge) if (backedge)
++edgecount; ++edgecount;
if (ENABLE_BASELINEJIT && backedge && edgecount == OSR_THRESHOLD_INTERPRETER && !jit && !node->target->code) if (ENABLE_BASELINEJIT && backedge && edgecount == OSR_THRESHOLD_INTERPRETER && !jit && !node->target->code) {
should_jit = true;
startJITing(node->target); startJITing(node->target);
}
if (backedge && edgecount == OSR_THRESHOLD_BASELINE) { if (backedge && edgecount == OSR_THRESHOLD_BASELINE) {
Box* rtn = doOSR(node); Box* rtn = doOSR(node);
...@@ -788,7 +793,6 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -788,7 +793,6 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
Value val = visit_expr(node->args[0]); Value val = visit_expr(node->args[0]);
v = Value(getPystonIter(val.o), jit ? jit->emitGetPystonIter(val) : NULL); v = Value(getPystonIter(val.o), jit ? jit->emitGetPystonIter(val) : NULL);
} else if (node->opcode == AST_LangPrimitive::IMPORT_FROM) { } else if (node->opcode == AST_LangPrimitive::IMPORT_FROM) {
abortJITing();
assert(node->args.size() == 2); assert(node->args.size() == 2);
assert(node->args[0]->type == AST_TYPE::Name); assert(node->args[0]->type == AST_TYPE::Name);
assert(node->args[1]->type == AST_TYPE::Str); assert(node->args[1]->type == AST_TYPE::Str);
...@@ -798,10 +802,11 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -798,10 +802,11 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
assert(ast_str->str_type == AST_Str::STR); assert(ast_str->str_type == AST_Str::STR);
const std::string& name = ast_str->str_data; const std::string& name = ast_str->str_data;
assert(name.size()); assert(name.size());
// TODO: shouldn't have to rebox here BoxedString* name_boxed = source_info->parent_module->getStringConstant(name, true);
v.o = importFrom(module.o, internStringMortal(name)); if (jit)
v.var = jit->emitImportFrom(module, name_boxed);
v.o = importFrom(module.o, name_boxed);
} else if (node->opcode == AST_LangPrimitive::IMPORT_NAME) { } else if (node->opcode == AST_LangPrimitive::IMPORT_NAME) {
abortJITing();
assert(node->args.size() == 3); assert(node->args.size() == 3);
assert(node->args[0]->type == AST_TYPE::Num); assert(node->args[0]->type == AST_TYPE::Num);
assert(static_cast<AST_Num*>(node->args[0])->num_type == AST_Num::INT); assert(static_cast<AST_Num*>(node->args[0])->num_type == AST_Num::INT);
...@@ -812,9 +817,10 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -812,9 +817,10 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
auto ast_str = ast_cast<AST_Str>(node->args[2]); auto ast_str = ast_cast<AST_Str>(node->args[2]);
assert(ast_str->str_type == AST_Str::STR); assert(ast_str->str_type == AST_Str::STR);
const std::string& module_name = ast_str->str_data; const std::string& module_name = ast_str->str_data;
if (jit)
v.var = jit->emitImportName(level, froms, module_name);
v.o = import(level, froms.o, module_name); v.o = import(level, froms.o, module_name);
} else if (node->opcode == AST_LangPrimitive::IMPORT_STAR) { } else if (node->opcode == AST_LangPrimitive::IMPORT_STAR) {
abortJITing();
assert(node->args.size() == 1); assert(node->args.size() == 1);
assert(node->args[0]->type == AST_TYPE::Name); assert(node->args[0]->type == AST_TYPE::Name);
...@@ -822,8 +828,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -822,8 +828,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
"import * not supported in functions"); "import * not supported in functions");
Value module = visit_expr(node->args[0]); Value module = visit_expr(node->args[0]);
v = Value(importStar(module.o, globals), jit ? jit->emitImportStar(module) : NULL);
v.o = importStar(module.o, globals);
} else if (node->opcode == AST_LangPrimitive::NONE) { } else if (node->opcode == AST_LangPrimitive::NONE) {
v = getNone(); v = getNone();
} else if (node->opcode == AST_LangPrimitive::LANDINGPAD) { } else if (node->opcode == AST_LangPrimitive::LANDINGPAD) {
...@@ -943,13 +948,21 @@ Value ASTInterpreter::visit_return(AST_Return* node) { ...@@ -943,13 +948,21 @@ Value ASTInterpreter::visit_return(AST_Return* node) {
return s; return s;
} }
Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body) { Value ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body) {
abortJITing();
CLFunction* cl = wrapFunction(node, args, body, source_info); CLFunction* cl = wrapFunction(node, args, body, source_info);
std::vector<Box*, StlCompatAllocator<Box*>> defaults; std::vector<Box*, StlCompatAllocator<Box*>> defaults;
for (AST_expr* d : args->defaults)
defaults.push_back(visit_expr(d).o); RewriterVar* defaults_var = NULL;
if (jit)
defaults_var = args->defaults.size() ? jit->allocate(args->defaults.size()) : jit->imm(0ul);
int i = 0;
for (AST_expr* d : args->defaults) {
Value v = visit_expr(d);
defaults.push_back(v.o);
if (jit)
defaults_var->setAttr(i++ * sizeof(void*), v);
}
defaults.push_back(0); defaults.push_back(0);
// FIXME: Using initializer_list is pretty annoying since you're not supposed to create them: // FIXME: Using initializer_list is pretty annoying since you're not supposed to create them:
...@@ -977,37 +990,60 @@ Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::v ...@@ -977,37 +990,60 @@ Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::v
} }
BoxedClosure* closure = 0; BoxedClosure* closure = 0;
RewriterVar* closure_var = NULL;
if (takes_closure) { if (takes_closure) {
if (scope_info->createsClosure()) { if (scope_info->createsClosure()) {
closure = created_closure; closure = created_closure;
if (jit)
closure_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, created_closure));
} else { } else {
assert(scope_info->passesThroughClosure()); assert(scope_info->passesThroughClosure());
closure = passed_closure; closure = passed_closure;
if (jit)
closure_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, passed_closure));
} }
assert(closure); assert(closure);
} }
Box* passed_globals = NULL; Box* passed_globals = NULL;
if (!getCL()->source->scoping->areGlobalsFromModule()) RewriterVar* passed_globals_var = NULL;
if (!getCL()->source->scoping->areGlobalsFromModule()) {
passed_globals = globals; passed_globals = globals;
return boxCLFunction(cl, closure, passed_globals, u.il); if (jit)
passed_globals_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, globals));
}
Value rtn;
if (jit) {
if (!closure_var)
closure_var = jit->imm(0ul);
if (!passed_globals_var)
passed_globals_var = jit->imm(0ul);
rtn.var = jit->call(false, (void*)boxCLFunction, jit->imm(cl), closure_var, passed_globals_var, defaults_var,
jit->imm(args->defaults.size()));
}
rtn.o = boxCLFunction(cl, closure, passed_globals, u.il);
return rtn;
} }
Value ASTInterpreter::visit_makeFunction(AST_MakeFunction* mkfn) { Value ASTInterpreter::visit_makeFunction(AST_MakeFunction* mkfn) {
abortJITing();
AST_FunctionDef* node = mkfn->function_def; AST_FunctionDef* node = mkfn->function_def;
AST_arguments* args = node->args; AST_arguments* args = node->args;
std::vector<Box*, StlCompatAllocator<Box*>> decorators; std::vector<Value, StlCompatAllocator<Value>> decorators;
for (AST_expr* d : node->decorator_list) for (AST_expr* d : node->decorator_list)
decorators.push_back(visit_expr(d).o); decorators.push_back(visit_expr(d));
Box* func = createFunction(node, args, node->body); Value func = createFunction(node, args, node->body);
for (int i = decorators.size() - 1; i >= 0; i--) for (int i = decorators.size() - 1; i >= 0; i--) {
func = runtimeCall(decorators[i], ArgPassSpec(1), func, 0, 0, 0, 0); if (jit)
func.var = jit->emitRuntimeCall(NULL, decorators[i], ArgPassSpec(1), { func }, NULL);
return Value(func, NULL); func.o = runtimeCall(decorators[i].o, ArgPassSpec(1), func.o, 0, 0, 0, 0);
}
return func;
} }
Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) { Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
...@@ -1091,52 +1127,51 @@ Value ASTInterpreter::visit_assert(AST_Assert* node) { ...@@ -1091,52 +1127,51 @@ Value ASTInterpreter::visit_assert(AST_Assert* node) {
} }
Value ASTInterpreter::visit_global(AST_Global* node) { Value ASTInterpreter::visit_global(AST_Global* node) {
abortJITing(); #ifndef NDEBUG
for (auto name : node->names) { for (auto name : node->names) {
if (getSymVRegMap().count(name)) assert(!getSymVRegMap().count(name));
vregs[getSymVRegMap()[name]] = NULL;
} }
#endif
return Value(); return Value();
} }
Value ASTInterpreter::visit_delete(AST_Delete* node) { Value ASTInterpreter::visit_delete(AST_Delete* node) {
abortJITing();
for (AST_expr* target_ : node->targets) { for (AST_expr* target_ : node->targets) {
switch (target_->type) { switch (target_->type) {
case AST_TYPE::Subscript: { case AST_TYPE::Subscript: {
AST_Subscript* sub = (AST_Subscript*)target_; AST_Subscript* sub = (AST_Subscript*)target_;
Value value = visit_expr(sub->value); Value value = visit_expr(sub->value);
Value slice = visit_expr(sub->slice); Value slice = visit_expr(sub->slice);
if (jit)
jit->emitDelItem(value, slice);
delitem(value.o, slice.o); delitem(value.o, slice.o);
break; break;
} }
case AST_TYPE::Attribute: { case AST_TYPE::Attribute: {
AST_Attribute* attr = (AST_Attribute*)target_; AST_Attribute* attr = (AST_Attribute*)target_;
pyston::delattr(visit_expr(attr->value).o, attr->attr.getBox()); Value target = visit_expr(attr->value);
BoxedString* str = attr->attr.getBox();
if (jit)
jit->emitDelAttr(target, str);
delattr(target.o, str);
break; break;
} }
case AST_TYPE::Name: { case AST_TYPE::Name: {
AST_Name* target = (AST_Name*)target_; AST_Name* target = (AST_Name*)target_;
if (target->lookup_type == ScopeInfo::VarScopeType::UNKNOWN)
ScopeInfo::VarScopeType vst = scope_info->getScopeTypeOfName(target->id); target->lookup_type = scope_info->getScopeTypeOfName(target->id);
ScopeInfo::VarScopeType vst = target->lookup_type;
if (vst == ScopeInfo::VarScopeType::GLOBAL) { if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (jit)
jit->emitDelGlobal(target->id.getBox());
delGlobal(globals, target->id.getBox()); delGlobal(globals, target->id.getBox());
continue; continue;
} else if (vst == ScopeInfo::VarScopeType::NAME) { } else if (vst == ScopeInfo::VarScopeType::NAME) {
assert(frame_info.boxedLocals != NULL); if (jit)
if (frame_info.boxedLocals->cls == dict_cls) { jit->emitDelName(target->id);
auto& d = static_cast<BoxedDict*>(frame_info.boxedLocals)->d; ASTInterpreterJitInterface::delNameHelper(this, target->id);
auto it = d.find(target->id.getBox());
if (it == d.end()) {
assertNameDefined(0, target->id.c_str(), NameError, false /* local_var_msg */);
}
d.erase(it);
} else if (frame_info.boxedLocals->cls == attrwrapper_cls) {
attrwrapperDel(frame_info.boxedLocals, target->id);
} else {
RELEASE_ASSERT(0, "%s", frame_info.boxedLocals->cls->tp_name);
}
} else { } else {
abortJITing();
assert(vst == ScopeInfo::VarScopeType::FAST); assert(vst == ScopeInfo::VarScopeType::FAST);
assert(getSymVRegMap().count(target->id)); assert(getSymVRegMap().count(target->id));
...@@ -1370,12 +1405,11 @@ Value ASTInterpreter::visit_repr(AST_Repr* node) { ...@@ -1370,12 +1405,11 @@ Value ASTInterpreter::visit_repr(AST_Repr* node) {
} }
Value ASTInterpreter::visit_lambda(AST_Lambda* node) { Value ASTInterpreter::visit_lambda(AST_Lambda* node) {
abortJITing();
AST_Return* expr = new AST_Return(); AST_Return* expr = new AST_Return();
expr->value = node->body; expr->value = node->body;
std::vector<AST_stmt*> body = { expr }; std::vector<AST_stmt*> body = { expr };
return Value(createFunction(node, node->args, body), NULL); return createFunction(node, node->args, body);
} }
Value ASTInterpreter::visit_dict(AST_Dict* node) { Value ASTInterpreter::visit_dict(AST_Dict* node) {
...@@ -1543,6 +1577,24 @@ int ASTInterpreterJitInterface::getGlobalsOffset() { ...@@ -1543,6 +1577,24 @@ int ASTInterpreterJitInterface::getGlobalsOffset() {
return offsetof(ASTInterpreter, globals); return offsetof(ASTInterpreter, globals);
} }
void ASTInterpreterJitInterface::delNameHelper(void* _interpreter, InternedString name) {
ASTInterpreter* interpreter = (ASTInterpreter*)_interpreter;
Box* boxed_locals = interpreter->frame_info.boxedLocals;
assert(boxed_locals != NULL);
if (boxed_locals->cls == dict_cls) {
auto& d = static_cast<BoxedDict*>(boxed_locals)->d;
auto it = d.find(name.getBox());
if (it == d.end()) {
assertNameDefined(0, name.c_str(), NameError, false /* local_var_msg */);
}
d.erase(it);
} else if (boxed_locals->cls == attrwrapper_cls) {
attrwrapperDel(boxed_locals, name);
} else {
RELEASE_ASSERT(0, "%s", boxed_locals->cls->tp_name);
}
}
Box* ASTInterpreterJitInterface::derefHelper(void* _interpreter, InternedString s) { Box* ASTInterpreterJitInterface::derefHelper(void* _interpreter, InternedString s) {
ASTInterpreter* interpreter = (ASTInterpreter*)_interpreter; ASTInterpreter* interpreter = (ASTInterpreter*)_interpreter;
DerefInfo deref_info = interpreter->scope_info->getDerefInfo(s); DerefInfo deref_info = interpreter->scope_info->getDerefInfo(s);
...@@ -1583,12 +1635,6 @@ Box* ASTInterpreterJitInterface::setExcInfoHelper(void* _interpreter, Box* type, ...@@ -1583,12 +1635,6 @@ Box* ASTInterpreterJitInterface::setExcInfoHelper(void* _interpreter, Box* type,
return None; return None;
} }
Box* ASTInterpreterJitInterface::uncacheExcInfoHelper(void* _interpreter) {
ASTInterpreter* interpreter = (ASTInterpreter*)_interpreter;
interpreter->getFrameInfo()->exc = ExcInfo(NULL, NULL, NULL);
return None;
}
void ASTInterpreterJitInterface::setLocalClosureHelper(void* _interpreter, long vreg, InternedString id, Box* v) { void ASTInterpreterJitInterface::setLocalClosureHelper(void* _interpreter, long vreg, InternedString id, Box* v) {
ASTInterpreter* interpreter = (ASTInterpreter*)_interpreter; ASTInterpreter* interpreter = (ASTInterpreter*)_interpreter;
...@@ -1599,6 +1645,12 @@ void ASTInterpreterJitInterface::setLocalClosureHelper(void* _interpreter, long ...@@ -1599,6 +1645,12 @@ void ASTInterpreterJitInterface::setLocalClosureHelper(void* _interpreter, long
interpreter->created_closure->elts[interpreter->scope_info->getClosureOffset(id)] = v; interpreter->created_closure->elts[interpreter->scope_info->getClosureOffset(id)] = v;
} }
Box* ASTInterpreterJitInterface::uncacheExcInfoHelper(void* _interpreter) {
ASTInterpreter* interpreter = (ASTInterpreter*)_interpreter;
interpreter->getFrameInfo()->exc = ExcInfo(NULL, NULL, NULL);
return None;
}
const void* interpreter_instr_addr = (void*)&executeInnerAndSetupFrame; const void* interpreter_instr_addr = (void*)&executeInnerAndSetupFrame;
// small wrapper around executeInner because we can not directly call the member function from asm. // small wrapper around executeInner because we can not directly call the member function from asm.
......
...@@ -41,12 +41,13 @@ struct ASTInterpreterJitInterface { ...@@ -41,12 +41,13 @@ struct ASTInterpreterJitInterface {
static int getGeneratorOffset(); static int getGeneratorOffset();
static int getGlobalsOffset(); static int getGlobalsOffset();
static void delNameHelper(void* _interpreter, InternedString name);
static Box* derefHelper(void* interp, InternedString s); static Box* derefHelper(void* interp, InternedString s);
static Box* doOSRHelper(void* interp, AST_Jump* node); static Box* doOSRHelper(void* interp, AST_Jump* node);
static Box* landingpadHelper(void* interp); static Box* landingpadHelper(void* interp);
static Box* setExcInfoHelper(void* interp, Box* type, Box* value, Box* traceback); static Box* setExcInfoHelper(void* interp, Box* type, Box* value, Box* traceback);
static Box* uncacheExcInfoHelper(void* interp);
static void setLocalClosureHelper(void* interp, long vreg, InternedString id, Box* v); static void setLocalClosureHelper(void* interp, long vreg, InternedString id, Box* v);
static Box* uncacheExcInfoHelper(void* interp);
}; };
class RewriterVar; class RewriterVar;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "codegen/type_recording.h" #include "codegen/type_recording.h"
#include "core/cfg.h" #include "core/cfg.h"
#include "runtime/generator.h" #include "runtime/generator.h"
#include "runtime/import.h"
#include "runtime/inline/list.h" #include "runtime/inline/list.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
#include "runtime/set.h" #include "runtime/set.h"
...@@ -148,6 +149,10 @@ JitFragmentWriter::JitFragmentWriter(CFGBlock* block, std::unique_ptr<ICInfo> ic ...@@ -148,6 +149,10 @@ JitFragmentWriter::JitFragmentWriter(CFGBlock* block, std::unique_ptr<ICInfo> ic
addAction([=]() { vregs_array->bumpUse(); }, vregs_array, ActionType::NORMAL); addAction([=]() { vregs_array->bumpUse(); }, vregs_array, ActionType::NORMAL);
} }
RewriterVar* JitFragmentWriter::getInterp() {
return interp;
}
RewriterVar* JitFragmentWriter::imm(uint64_t val) { RewriterVar* JitFragmentWriter::imm(uint64_t val) {
return loadConst(val); return loadConst(val);
} }
...@@ -330,6 +335,20 @@ RewriterVar* JitFragmentWriter::emitHasnext(RewriterVar* v) { ...@@ -330,6 +335,20 @@ RewriterVar* JitFragmentWriter::emitHasnext(RewriterVar* v) {
return call(false, (void*)hasnextHelper, v); return call(false, (void*)hasnextHelper, v);
} }
RewriterVar* JitFragmentWriter::emitImportFrom(RewriterVar* module, BoxedString* name) {
return call(false, (void*)importFrom, module, imm(name));
}
RewriterVar* JitFragmentWriter::emitImportName(int level, RewriterVar* from_imports, llvm::StringRef module_name) {
return call(false, (void*)import, imm(level), from_imports, imm(const_cast<char*>(module_name.data())),
imm(module_name.size()));
}
RewriterVar* JitFragmentWriter::emitImportStar(RewriterVar* module) {
RewriterVar* globals = getInterp()->getAttr(ASTInterpreterJitInterface::getGlobalsOffset());
return call(false, (void*)importStar, module, globals);
}
RewriterVar* JitFragmentWriter::emitLandingpad() { RewriterVar* JitFragmentWriter::emitLandingpad() {
return call(false, (void*)ASTInterpreterJitInterface::landingpadHelper, getInterp()); return call(false, (void*)ASTInterpreterJitInterface::landingpadHelper, getInterp());
} }
...@@ -408,6 +427,27 @@ RewriterVar* JitFragmentWriter::emitYield(RewriterVar* v) { ...@@ -408,6 +427,27 @@ RewriterVar* JitFragmentWriter::emitYield(RewriterVar* v) {
return call(false, (void*)yield, generator, v); return call(false, (void*)yield, generator, v);
} }
void JitFragmentWriter::emitDelAttr(RewriterVar* target, BoxedString* attr) {
emitPPCall((void*)delattr, { target, imm(attr) }, 1, 512);
}
void JitFragmentWriter::emitDelGlobal(BoxedString* name) {
RewriterVar* globals = getInterp()->getAttr(ASTInterpreterJitInterface::getGlobalsOffset());
emitPPCall((void*)delGlobal, { globals, imm(name) }, 1, 512);
}
void JitFragmentWriter::emitDelItem(RewriterVar* target, RewriterVar* slice) {
emitPPCall((void*)delitem, { target, slice }, 1, 512);
}
void JitFragmentWriter::emitDelName(InternedString name) {
call(false, (void*)ASTInterpreterJitInterface::delNameHelper, getInterp(),
#ifndef NDEBUG
imm(asUInt(name).first), imm(asUInt(name).second));
#else
imm(asUInt(name)));
#endif
}
void JitFragmentWriter::emitExec(RewriterVar* code, RewriterVar* globals, RewriterVar* locals, FutureFlags flags) { void JitFragmentWriter::emitExec(RewriterVar* code, RewriterVar* globals, RewriterVar* locals, FutureFlags flags) {
if (!globals) if (!globals)
...@@ -606,10 +646,6 @@ uint64_t JitFragmentWriter::asUInt(InternedString s) { ...@@ -606,10 +646,6 @@ uint64_t JitFragmentWriter::asUInt(InternedString s) {
} }
#endif #endif
RewriterVar* JitFragmentWriter::getInterp() {
return interp;
}
RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, RewriterVar* JitFragmentWriter::emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots,
int slot_size, TypeRecorder* type_recorder) { int slot_size, TypeRecorder* type_recorder) {
RewriterVar::SmallVector args_vec(args.begin(), args.end()); RewriterVar::SmallVector args_vec(args.begin(), args.end());
......
...@@ -200,10 +200,10 @@ public: ...@@ -200,10 +200,10 @@ public:
JitFragmentWriter(CFGBlock* block, std::unique_ptr<ICInfo> ic_info, std::unique_ptr<ICSlotRewrite> rewrite, JitFragmentWriter(CFGBlock* block, std::unique_ptr<ICInfo> ic_info, std::unique_ptr<ICSlotRewrite> rewrite,
int code_offset, int num_bytes_overlapping, void* entry_code, JitCodeBlock& code_block); int code_offset, int num_bytes_overlapping, void* entry_code, JitCodeBlock& code_block);
RewriterVar* getInterp();
RewriterVar* imm(uint64_t val); RewriterVar* imm(uint64_t val);
RewriterVar* imm(void* val); RewriterVar* imm(void* val);
RewriterVar* emitAugbinop(RewriterVar* lhs, RewriterVar* rhs, int op_type); RewriterVar* emitAugbinop(RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitBinop(RewriterVar* lhs, RewriterVar* rhs, int op_type); RewriterVar* emitBinop(RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags, RewriterVar* emitCallattr(AST_expr* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags,
...@@ -226,6 +226,9 @@ public: ...@@ -226,6 +226,9 @@ public:
RewriterVar* emitGetLocal(InternedString s, int vreg); RewriterVar* emitGetLocal(InternedString s, int vreg);
RewriterVar* emitGetPystonIter(RewriterVar* v); RewriterVar* emitGetPystonIter(RewriterVar* v);
RewriterVar* emitHasnext(RewriterVar* v); RewriterVar* emitHasnext(RewriterVar* v);
RewriterVar* emitImportFrom(RewriterVar* module, BoxedString* name);
RewriterVar* emitImportName(int level, RewriterVar* from_imports, llvm::StringRef module_name);
RewriterVar* emitImportStar(RewriterVar* module);
RewriterVar* emitLandingpad(); RewriterVar* emitLandingpad();
RewriterVar* emitNonzero(RewriterVar* v); RewriterVar* emitNonzero(RewriterVar* v);
RewriterVar* emitNotNonzero(RewriterVar* v); RewriterVar* emitNotNonzero(RewriterVar* v);
...@@ -236,6 +239,10 @@ public: ...@@ -236,6 +239,10 @@ public:
RewriterVar* emitUnpackIntoArray(RewriterVar* v, uint64_t num); RewriterVar* emitUnpackIntoArray(RewriterVar* v, uint64_t num);
RewriterVar* emitYield(RewriterVar* v); RewriterVar* emitYield(RewriterVar* v);
void emitDelAttr(RewriterVar* target, BoxedString* attr);
void emitDelGlobal(BoxedString* name);
void emitDelItem(RewriterVar* target, RewriterVar* slice);
void emitDelName(InternedString name);
void emitExec(RewriterVar* code, RewriterVar* globals, RewriterVar* locals, FutureFlags flags); void emitExec(RewriterVar* code, RewriterVar* globals, RewriterVar* locals, FutureFlags flags);
void emitJump(CFGBlock* b); void emitJump(CFGBlock* b);
void emitOSRPoint(AST_Jump* node); void emitOSRPoint(AST_Jump* node);
...@@ -266,7 +273,6 @@ private: ...@@ -266,7 +273,6 @@ private:
#else #else
uint64_t asUInt(InternedString s); uint64_t asUInt(InternedString s);
#endif #endif
RewriterVar* getInterp();
RewriterVar* emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, int slot_size, RewriterVar* emitPPCall(void* func_addr, llvm::ArrayRef<RewriterVar*> args, int num_slots, int slot_size,
TypeRecorder* type_recorder = NULL); TypeRecorder* type_recorder = NULL);
......
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