Commit 67360572 authored by Marius Wachtler's avatar Marius Wachtler

Don't generate patchpoints for calls to fixed functions which don't need patching

Previously we generated patchpoints for every call because the callee could do a frame introspection
and we could not retrieve the frame info without the additional patchpoint informations.

This change moves all required information inside the FrameInfo.
Because the FrameInfo does not have a fixed offset (different num of stack args and OSR functions reuse the frame info from the interpreter),
we generate at function entry a stack variable which points to the frame_info and than we emit a stackmap intrinsic
in order to know which basepointer relative address it has.
The current statement inside the FrameInfo gets only updated on direct calls - patchpoints still attach it directly instead of updating the memory.
Because always updating the variable is a small slowdown.

This allows us todo inlining of trivial call sites at the llvm IR level.
parent ff657c1f
...@@ -136,23 +136,19 @@ private: ...@@ -136,23 +136,19 @@ private:
// this variables are used by the baseline JIT, make sure they have an offset < 0x80 so we can use shorter // this variables are used by the baseline JIT, make sure they have an offset < 0x80 so we can use shorter
// instructions // instructions
CFGBlock* next_block, *current_block; CFGBlock* next_block, *current_block;
AST_stmt* current_inst; FrameInfo frame_info;
FunctionMetadata* md; FunctionMetadata* md;
SourceInfo* source_info; SourceInfo* source_info;
ScopeInfo* scope_info; ScopeInfo* scope_info;
PhiAnalysis* phis; PhiAnalysis* phis;
Box** vregs; Box** vregs;
ExcInfo last_exception; ExcInfo last_exception;
BoxedClosure* created_closure; BoxedClosure* created_closure;
BoxedGenerator* generator; BoxedGenerator* generator;
unsigned edgecount; unsigned edgecount;
FrameInfo frame_info;
BoxedModule* parent_module; BoxedModule* parent_module;
// This is either a module or a dict
Box* globals;
std::unique_ptr<JitFragmentWriter> jit; std::unique_ptr<JitFragmentWriter> jit;
bool should_jit; bool should_jit;
...@@ -163,13 +159,15 @@ public: ...@@ -163,13 +159,15 @@ public:
} }
AST_stmt* getCurrentStatement() { AST_stmt* getCurrentStatement() {
assert(current_inst); assert(frame_info.stmt);
return current_inst; return frame_info.stmt;
} }
void setCurrentStatement(AST_stmt* stmt) { frame_info.stmt = stmt; }
Box* getGlobals() { Box* getGlobals() {
assert(globals); assert(frame_info.globals);
return globals; return frame_info.globals;
} }
FunctionMetadata* getMD() { return md; } FunctionMetadata* getMD() { return md; }
...@@ -224,12 +222,12 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* frame_info) { ...@@ -224,12 +222,12 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* frame_info) {
void ASTInterpreter::setGlobals(Box* globals) { void ASTInterpreter::setGlobals(Box* globals) {
assert(gc::isValidGCObject(globals)); assert(gc::isValidGCObject(globals));
this->globals = globals; this->frame_info.globals = globals;
} }
ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs) ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs)
: current_block(0), : current_block(0),
current_inst(0), frame_info(ExcInfo(NULL, NULL, NULL)),
md(md), md(md),
source_info(md->source.get()), source_info(md->source.get()),
scope_info(0), scope_info(0),
...@@ -239,9 +237,7 @@ ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs) ...@@ -239,9 +237,7 @@ ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs)
created_closure(0), created_closure(0),
generator(0), generator(0),
edgecount(0), edgecount(0),
frame_info(ExcInfo(NULL, NULL, NULL)),
parent_module(source_info->parent_module), parent_module(source_info->parent_module),
globals(0),
should_jit(false) { should_jit(false) {
scope_info = source_info->getScopeInfo(); scope_info = source_info->getScopeInfo();
...@@ -352,9 +348,9 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -352,9 +348,9 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
} }
// Important that this happens after RegisterHelper: // Important that this happens after RegisterHelper:
interpreter.current_inst = start_at; interpreter.setCurrentStatement(start_at);
threading::allowGLReadPreemption(); threading::allowGLReadPreemption();
interpreter.current_inst = NULL; interpreter.setCurrentStatement(NULL);
if (!from_start) { if (!from_start) {
interpreter.current_block = start_block; interpreter.current_block = start_block;
...@@ -366,7 +362,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -366,7 +362,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
started = true; started = true;
} }
interpreter.current_inst = s; interpreter.setCurrentStatement(s);
v = interpreter.visit_stmt(s); v = interpreter.visit_stmt(s);
} }
} else { } else {
...@@ -396,7 +392,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -396,7 +392,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
} }
for (AST_stmt* s : interpreter.current_block->body) { for (AST_stmt* s : interpreter.current_block->body) {
interpreter.current_inst = s; interpreter.setCurrentStatement(s);
if (interpreter.jit) if (interpreter.jit)
interpreter.jit->emitSetCurrentInst(s); interpreter.jit->emitSetCurrentInst(s);
v = interpreter.visit_stmt(s); v = interpreter.visit_stmt(s);
...@@ -432,8 +428,8 @@ void ASTInterpreter::doStore(AST_Name* node, Value value) { ...@@ -432,8 +428,8 @@ void ASTInterpreter::doStore(AST_Name* node, Value value) {
ScopeInfo::VarScopeType vst = node->lookup_type; ScopeInfo::VarScopeType vst = node->lookup_type;
if (vst == ScopeInfo::VarScopeType::GLOBAL) { if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (jit) if (jit)
jit->emitSetGlobal(globals, name.getBox(), value); jit->emitSetGlobal(frame_info.globals, name.getBox(), value);
setGlobal(globals, name.getBox(), value.o); setGlobal(frame_info.globals, name.getBox(), value.o);
} else if (vst == ScopeInfo::VarScopeType::NAME) { } else if (vst == ScopeInfo::VarScopeType::NAME) {
if (jit) if (jit)
jit->emitSetItemName(name.getBox(), value); jit->emitSetItemName(name.getBox(), value);
...@@ -719,9 +715,6 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) { ...@@ -719,9 +715,6 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
if (created_closure) if (created_closure)
sorted_symbol_table[source_info->getInternedStrings().get(CREATED_CLOSURE_NAME)] = created_closure; sorted_symbol_table[source_info->getInternedStrings().get(CREATED_CLOSURE_NAME)] = created_closure;
if (!source_info->scoping->areGlobalsFromModule())
sorted_symbol_table[source_info->getInternedStrings().get(PASSED_GLOBALS_NAME)] = globals;
sorted_symbol_table[source_info->getInternedStrings().get(FRAME_INFO_PTR_NAME)] = (Box*)&frame_info; sorted_symbol_table[source_info->getInternedStrings().get(FRAME_INFO_PTR_NAME)] = (Box*)&frame_info;
if (found_entry == nullptr) { if (found_entry == nullptr) {
...@@ -849,7 +842,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -849,7 +842,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 = Value(importStar(module.o, frame_info.globals), jit ? jit->emitImportStar(module) : NULL);
} 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) {
...@@ -1037,9 +1030,9 @@ Value ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std:: ...@@ -1037,9 +1030,9 @@ Value ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::
Box* passed_globals = NULL; Box* passed_globals = NULL;
RewriterVar* passed_globals_var = NULL; RewriterVar* passed_globals_var = NULL;
if (!getMD()->source->scoping->areGlobalsFromModule()) { if (!getMD()->source->scoping->areGlobalsFromModule()) {
passed_globals = globals; passed_globals = frame_info.globals;
if (jit) if (jit)
passed_globals_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, globals)); passed_globals_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, frame_info.globals));
} }
Value rtn; Value rtn;
...@@ -1103,7 +1096,7 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) { ...@@ -1103,7 +1096,7 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
Box* passed_globals = NULL; Box* passed_globals = NULL;
if (!getMD()->source->scoping->areGlobalsFromModule()) if (!getMD()->source->scoping->areGlobalsFromModule())
passed_globals = globals; passed_globals = frame_info.globals;
Box* attrDict Box* attrDict
= runtimeCall(createFunctionFromMetadata(md, closure, passed_globals, {}), ArgPassSpec(0), 0, 0, 0, 0, 0); = runtimeCall(createFunctionFromMetadata(md, closure, passed_globals, {}), ArgPassSpec(0), 0, 0, 0, 0, 0);
...@@ -1150,7 +1143,7 @@ Value ASTInterpreter::visit_assert(AST_Assert* node) { ...@@ -1150,7 +1143,7 @@ Value ASTInterpreter::visit_assert(AST_Assert* node) {
#endif #endif
static BoxedString* AssertionError_str = internStringImmortal("AssertionError"); static BoxedString* AssertionError_str = internStringImmortal("AssertionError");
Box* assertion_type = getGlobal(globals, AssertionError_str); Box* assertion_type = getGlobal(frame_info.globals, AssertionError_str);
assertFail(assertion_type, node->msg ? visit_expr(node->msg).o : 0); assertFail(assertion_type, node->msg ? visit_expr(node->msg).o : 0);
return Value(); return Value();
...@@ -1194,7 +1187,7 @@ Value ASTInterpreter::visit_delete(AST_Delete* node) { ...@@ -1194,7 +1187,7 @@ Value ASTInterpreter::visit_delete(AST_Delete* node) {
if (vst == ScopeInfo::VarScopeType::GLOBAL) { if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (jit) if (jit)
jit->emitDelGlobal(target->id.getBox()); jit->emitDelGlobal(target->id.getBox());
delGlobal(globals, target->id.getBox()); delGlobal(frame_info.globals, target->id.getBox());
continue; continue;
} else if (vst == ScopeInfo::VarScopeType::NAME) { } else if (vst == ScopeInfo::VarScopeType::NAME) {
if (jit) if (jit)
...@@ -1489,9 +1482,9 @@ Value ASTInterpreter::visit_name(AST_Name* node) { ...@@ -1489,9 +1482,9 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
case ScopeInfo::VarScopeType::GLOBAL: { case ScopeInfo::VarScopeType::GLOBAL: {
Value v; Value v;
if (jit) if (jit)
v.var = jit->emitGetGlobal(globals, node->id.getBox()); v.var = jit->emitGetGlobal(frame_info.globals, node->id.getBox());
v.o = getGlobal(globals, node->id.getBox()); v.o = getGlobal(frame_info.globals, node->id.getBox());
return v; return v;
} }
case ScopeInfo::VarScopeType::DEREF: { case ScopeInfo::VarScopeType::DEREF: {
...@@ -1529,7 +1522,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) { ...@@ -1529,7 +1522,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
Value v; Value v;
if (jit) if (jit)
v.var = jit->emitGetBoxedLocal(node->id.getBox()); v.var = jit->emitGetBoxedLocal(node->id.getBox());
v.o = boxedLocalsGet(frame_info.boxedLocals, node->id.getBox(), globals); v.o = boxedLocalsGet(frame_info.boxedLocals, node->id.getBox(), frame_info.globals);
assert(gc::isValidGCObject(v.o)); assert(gc::isValidGCObject(v.o));
return v; return v;
} }
...@@ -1590,7 +1583,7 @@ int ASTInterpreterJitInterface::getCurrentBlockOffset() { ...@@ -1590,7 +1583,7 @@ int ASTInterpreterJitInterface::getCurrentBlockOffset() {
} }
int ASTInterpreterJitInterface::getCurrentInstOffset() { int ASTInterpreterJitInterface::getCurrentInstOffset() {
return offsetof(ASTInterpreter, current_inst); return offsetof(ASTInterpreter, frame_info.stmt);
} }
int ASTInterpreterJitInterface::getGeneratorOffset() { int ASTInterpreterJitInterface::getGeneratorOffset() {
...@@ -1598,7 +1591,7 @@ int ASTInterpreterJitInterface::getGeneratorOffset() { ...@@ -1598,7 +1591,7 @@ int ASTInterpreterJitInterface::getGeneratorOffset() {
} }
int ASTInterpreterJitInterface::getGlobalsOffset() { int ASTInterpreterJitInterface::getGlobalsOffset() {
return offsetof(ASTInterpreter, globals); return offsetof(ASTInterpreter, frame_info.globals);
} }
void ASTInterpreterJitInterface::delNameHelper(void* _interpreter, InternedString name) { void ASTInterpreterJitInterface::delNameHelper(void* _interpreter, InternedString name) {
...@@ -1855,9 +1848,6 @@ static Box* astInterpretDeoptInner(FunctionMetadata* md, AST_expr* after_expr, A ...@@ -1855,9 +1848,6 @@ static Box* astInterpretDeoptInner(FunctionMetadata* md, AST_expr* after_expr, A
interpreter.setPassedClosure(p.second); interpreter.setPassedClosure(p.second);
} else if (name == CREATED_CLOSURE_NAME) { } else if (name == CREATED_CLOSURE_NAME) {
interpreter.setCreatedClosure(p.second); interpreter.setCreatedClosure(p.second);
} else if (name == PASSED_GLOBALS_NAME) {
assert(!source_info->scoping->areGlobalsFromModule());
interpreter.setGlobals(p.second);
} else { } else {
InternedString interned = md->source->getInternedStrings().get(name); InternedString interned = md->source->getInternedStrings().get(name);
interpreter.addSymbol(interned, p.second, false); interpreter.addSymbol(interned, p.second, false);
...@@ -1937,18 +1927,6 @@ static ASTInterpreter* getInterpreterFromFramePtr(void* frame_ptr) { ...@@ -1937,18 +1927,6 @@ static ASTInterpreter* getInterpreterFromFramePtr(void* frame_ptr) {
return *ptr; return *ptr;
} }
AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr);
assert(interpreter);
return interpreter->getCurrentStatement();
}
Box* getGlobalsForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr);
assert(interpreter);
return interpreter->getGlobals();
}
FunctionMetadata* getMDForInterpretedFrame(void* frame_ptr) { FunctionMetadata* getMDForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr); ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr);
assert(interpreter); assert(interpreter);
...@@ -1961,12 +1939,6 @@ FrameInfo* getFrameInfoForInterpretedFrame(void* frame_ptr) { ...@@ -1961,12 +1939,6 @@ FrameInfo* getFrameInfoForInterpretedFrame(void* frame_ptr) {
return interpreter->getFrameInfo(); return interpreter->getFrameInfo();
} }
Box** getVRegsForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr);
assert(interpreter);
return interpreter->getVRegs();
}
BoxedDict* localsForInterpretedFrame(Box** vregs, CFG* cfg) { BoxedDict* localsForInterpretedFrame(Box** vregs, CFG* cfg) {
BoxedDict* rtn = new BoxedDict(); BoxedDict* rtn = new BoxedDict();
for (auto& l : cfg->sym_vreg_map_user_visible) { for (auto& l : cfg->sym_vreg_map_user_visible) {
......
...@@ -76,13 +76,10 @@ Box* astInterpretFunctionEval(FunctionMetadata* cf, Box* globals, Box* boxedLoca ...@@ -76,13 +76,10 @@ Box* astInterpretFunctionEval(FunctionMetadata* cf, Box* globals, Box* boxedLoca
Box* astInterpretDeopt(FunctionMetadata* cf, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val, Box* astInterpretDeopt(FunctionMetadata* cf, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val,
FrameStackState frame_state); FrameStackState frame_state);
AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr);
Box* getGlobalsForInterpretedFrame(void* frame_ptr);
FunctionMetadata* getMDForInterpretedFrame(void* frame_ptr); FunctionMetadata* getMDForInterpretedFrame(void* frame_ptr);
struct FrameInfo; struct FrameInfo;
FrameInfo* getFrameInfoForInterpretedFrame(void* frame_ptr); FrameInfo* getFrameInfoForInterpretedFrame(void* frame_ptr);
Box** getVRegsForInterpretedFrame(void* frame_ptr);
BoxedDict* localsForInterpretedFrame(Box** vregs, CFG* cfg); BoxedDict* localsForInterpretedFrame(Box** vregs, CFG* cfg);
BoxedDict* localsForInterpretedFrame(void* frame_ptr); BoxedDict* localsForInterpretedFrame(void* frame_ptr);
......
...@@ -369,6 +369,8 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -369,6 +369,8 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
llvm_entry_blocks[block] = llvm::BasicBlock::Create(g.context, buf, irstate->getLLVMFunction()); llvm_entry_blocks[block] = llvm::BasicBlock::Create(g.context, buf, irstate->getLLVMFunction());
} }
llvm::Value* osr_frame_info_arg = NULL;
// the function entry block, where we add the type guards [no guards anymore] // the function entry block, where we add the type guards [no guards anymore]
llvm::BasicBlock* osr_entry_block = NULL; llvm::BasicBlock* osr_entry_block = NULL;
llvm::BasicBlock* osr_unbox_block_end = NULL; // the block after type guards where we up/down-convert things llvm::BasicBlock* osr_unbox_block_end = NULL; // the block after type guards where we up/down-convert things
...@@ -438,17 +440,11 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -438,17 +440,11 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
if (from_arg->getType() == g.llvm_frame_info_type->getPointerTo()) { if (from_arg->getType() == g.llvm_frame_info_type->getPointerTo()) {
assert(p.first.s() == FRAME_INFO_PTR_NAME); assert(p.first.s() == FRAME_INFO_PTR_NAME);
irstate->setFrameInfoArgument(from_arg); osr_frame_info_arg = from_arg;
// Don't add the frame info to the symbol table since we will store it separately: // Don't add the frame info to the symbol table since we will store it separately:
continue; continue;
} }
if (p.first.s() == PASSED_GLOBALS_NAME) {
assert(!source->scoping->areGlobalsFromModule());
irstate->setGlobals(from_arg);
continue;
}
ConcreteCompilerType* phi_type; ConcreteCompilerType* phi_type;
phi_type = getTypeAtBlockStart(types, p.first, target_block); phi_type = getTypeAtBlockStart(types, p.first, target_block);
...@@ -609,13 +605,13 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -609,13 +605,13 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
assert(osr_entry_block); assert(osr_entry_block);
assert(phis); assert(phis);
irstate->setupFrameInfoVarOSR(osr_frame_info_arg);
for (const auto& p : entry_descriptor->args) { for (const auto& p : entry_descriptor->args) {
// Don't add the frame info to the symbol table since we will store it separately // Don't add the frame info to the symbol table since we will store it separately
// (we manually added it during the calculation of osr_syms): // (we manually added it during the calculation of osr_syms):
if (p.first.s() == FRAME_INFO_PTR_NAME) if (p.first.s() == FRAME_INFO_PTR_NAME)
continue; continue;
if (p.first.s() == PASSED_GLOBALS_NAME)
continue;
ConcreteCompilerType* analyzed_type = getTypeAtBlockStart(types, p.first, block); ConcreteCompilerType* analyzed_type = getTypeAtBlockStart(types, p.first, block);
......
...@@ -56,9 +56,9 @@ IRGenState::IRGenState(FunctionMetadata* md, CompiledFunction* cf, SourceInfo* s ...@@ -56,9 +56,9 @@ IRGenState::IRGenState(FunctionMetadata* md, CompiledFunction* cf, SourceInfo* s
func_dbg_info(func_dbg_info), func_dbg_info(func_dbg_info),
scratch_space(NULL), scratch_space(NULL),
frame_info(NULL), frame_info(NULL),
frame_info_arg(NULL),
globals(NULL), globals(NULL),
vregs(NULL), vregs(NULL),
stmt(NULL),
scratch_size(0) { scratch_size(0) {
assert(cf->func); assert(cf->func);
assert(!cf->md); // in this case don't need to pass in sourceinfo assert(!cf->md); // in this case don't need to pass in sourceinfo
...@@ -164,7 +164,18 @@ template <typename Builder> static llvm::Value* getVRegsGep(Builder& builder, ll ...@@ -164,7 +164,18 @@ template <typename Builder> static llvm::Value* getVRegsGep(Builder& builder, ll
return builder.CreateConstInBoundsGEP2_32(v, 0, 4); return builder.CreateConstInBoundsGEP2_32(v, 0, 4);
} }
llvm::Value* IRGenState::getFrameInfoVar() { template <typename Builder> static llvm::Value* getStmtGep(Builder& builder, llvm::Value* v) {
static_assert(offsetof(FrameInfo, stmt) == 56, "");
return builder.CreateConstInBoundsGEP2_32(v, 0, 5);
}
template <typename Builder> static llvm::Value* getGlobalsGep(Builder& builder, llvm::Value* v) {
static_assert(offsetof(FrameInfo, globals) == 64, "");
return builder.CreateConstInBoundsGEP2_32(v, 0, 6);
}
void IRGenState::setupFrameInfoVar(llvm::Value* passed_closure, llvm::Value* passed_globals,
llvm::Value* frame_info_arg) {
/* /*
There is a matrix of possibilities here. There is a matrix of possibilities here.
...@@ -182,8 +193,7 @@ llvm::Value* IRGenState::getFrameInfoVar() { ...@@ -182,8 +193,7 @@ llvm::Value* IRGenState::getFrameInfoVar() {
- If the function is NAME-scope, we extract the boxedLocals from the frame_info in order - If the function is NAME-scope, we extract the boxedLocals from the frame_info in order
to set this->boxed_locals. to set this->boxed_locals.
*/ */
assert(!frame_info);
if (!this->frame_info) {
llvm::BasicBlock& entry_block = getLLVMFunction()->getEntryBlock(); llvm::BasicBlock& entry_block = getLLVMFunction()->getEntryBlock();
llvm::IRBuilder<true> builder(&entry_block); llvm::IRBuilder<true> builder(&entry_block);
...@@ -196,13 +206,20 @@ llvm::Value* IRGenState::getFrameInfoVar() { ...@@ -196,13 +206,20 @@ llvm::Value* IRGenState::getFrameInfoVar() {
else else
builder.SetInsertPoint(&entry_block); builder.SetInsertPoint(&entry_block);
llvm::AllocaInst* al_pointer_to_frame_info
= builder.CreateAlloca(g.llvm_frame_info_type->getPointerTo(), NULL, "frame_info_ptr");
if (frame_info_arg) { if (frame_info_arg) {
assert(!passed_closure);
assert(!passed_globals);
// The OSR case // The OSR case
this->frame_info = frame_info_arg; this->frame_info = frame_info_arg;
// use vrags array from the interpreter // use vrags array from the interpreter
vregs = builder.CreateLoad(getVRegsGep(builder, frame_info_arg)); vregs = builder.CreateLoad(getVRegsGep(builder, frame_info_arg));
this->globals = builder.CreateLoad(getGlobalsGep(builder, frame_info_arg));
if (getScopeInfo()->usesNameLookup()) { if (getScopeInfo()->usesNameLookup()) {
// load frame_info.boxedLocals // load frame_info.boxedLocals
...@@ -211,7 +228,6 @@ llvm::Value* IRGenState::getFrameInfoVar() { ...@@ -211,7 +228,6 @@ llvm::Value* IRGenState::getFrameInfoVar() {
} else { } else {
// The "normal" case // The "normal" case
assert(!vregs); assert(!vregs);
getMD()->calculateNumVRegs(); getMD()->calculateNumVRegs();
int num_user_visible_vregs = getMD()->source->cfg->sym_vreg_map_user_visible.size(); int num_user_visible_vregs = getMD()->source->cfg->sym_vreg_map_user_visible.size();
...@@ -220,8 +236,7 @@ llvm::Value* IRGenState::getFrameInfoVar() { ...@@ -220,8 +236,7 @@ llvm::Value* IRGenState::getFrameInfoVar() {
= builder.CreateAlloca(g.llvm_value_type_ptr, getConstantInt(num_user_visible_vregs), "vregs"); = builder.CreateAlloca(g.llvm_value_type_ptr, getConstantInt(num_user_visible_vregs), "vregs");
// Clear the vregs array because 0 means undefined valued. // Clear the vregs array because 0 means undefined valued.
builder.CreateMemSet(vregs_alloca, getConstantInt(0, g.i8), builder.CreateMemSet(vregs_alloca, getConstantInt(0, g.i8),
getConstantInt(num_user_visible_vregs * sizeof(Box*)), getConstantInt(num_user_visible_vregs * sizeof(Box*)), vregs_alloca->getAlignment());
vregs_alloca->getAlignment());
vregs = vregs_alloca; vregs = vregs_alloca;
} else } else
vregs = getNullPtr(g.llvm_value_type_ptr_ptr); vregs = getNullPtr(g.llvm_value_type_ptr_ptr);
...@@ -229,11 +244,12 @@ llvm::Value* IRGenState::getFrameInfoVar() { ...@@ -229,11 +244,12 @@ llvm::Value* IRGenState::getFrameInfoVar() {
llvm::AllocaInst* al = builder.CreateAlloca(g.llvm_frame_info_type, NULL, "frame_info"); llvm::AllocaInst* al = builder.CreateAlloca(g.llvm_frame_info_type, NULL, "frame_info");
assert(al->isStaticAlloca()); assert(al->isStaticAlloca());
// frame_info.exc.type = NULL // frame_info.exc.type = NULL
llvm::Constant* null_value = getNullPtr(g.llvm_value_type_ptr); llvm::Constant* null_value = getNullPtr(g.llvm_value_type_ptr);
llvm::Value* exc_info = getExcinfoGep(builder, al); llvm::Value* exc_info = getExcinfoGep(builder, al);
builder.CreateStore( builder.CreateStore(null_value,
null_value, builder.CreateConstInBoundsGEP2_32(exc_info, 0, offsetof(ExcInfo, type) / sizeof(Box*))); builder.CreateConstInBoundsGEP2_32(exc_info, 0, offsetof(ExcInfo, type) / sizeof(Box*)));
// frame_info.boxedLocals = NULL // frame_info.boxedLocals = NULL
llvm::Value* boxed_locals_gep = getBoxedLocalsGep(builder, al); llvm::Value* boxed_locals_gep = getBoxedLocalsGep(builder, al);
...@@ -251,34 +267,51 @@ llvm::Value* IRGenState::getFrameInfoVar() { ...@@ -251,34 +267,51 @@ llvm::Value* IRGenState::getFrameInfoVar() {
= llvm::cast<llvm::StructType>(g.llvm_frame_info_type)->getElementType(2); = llvm::cast<llvm::StructType>(g.llvm_frame_info_type)->getElementType(2);
builder.CreateStore(getNullPtr(llvm_frame_obj_type_ptr), getFrameObjGep(builder, al)); builder.CreateStore(getNullPtr(llvm_frame_obj_type_ptr), getFrameObjGep(builder, al));
// frame_info.passed_closure = NULL // set frame_info.passed_closure
builder.CreateStore(getNullPtr(g.llvm_closure_type_ptr), getPassedClosureGep(builder, al)); builder.CreateStore(passed_closure, getPassedClosureGep(builder, al));
// set frame_info.globals
builder.CreateStore(passed_globals, getGlobalsGep(builder, al));
// set frame_info.vregs // set frame_info.vregs
builder.CreateStore(vregs, getVRegsGep(builder, al)); builder.CreateStore(vregs, getVRegsGep(builder, al));
this->frame_info = al; this->frame_info = al;
this->globals = passed_globals;
} }
}
return this->frame_info; stmt = getStmtGep(builder, frame_info);
builder.CreateStore(this->frame_info, al_pointer_to_frame_info);
// Create stackmap to make a pointer to the frame_info location known
PatchpointInfo* info = PatchpointInfo::create(getCurFunction(), 0, 0, 0);
std::vector<llvm::Value*> args;
args.push_back(getConstantInt(info->getId(), g.i64));
args.push_back(getConstantInt(0, g.i32));
args.push_back(al_pointer_to_frame_info);
info->setNumFrameArgs(1);
info->setIsFrameInfoStackmap();
builder.CreateCall(llvm::Intrinsic::getDeclaration(g.cur_module, llvm::Intrinsic::experimental_stackmap), args);
}
llvm::Value* IRGenState::getFrameInfoVar() {
assert(frame_info);
return frame_info;
} }
llvm::Value* IRGenState::getBoxedLocalsVar() { llvm::Value* IRGenState::getBoxedLocalsVar() {
assert(getScopeInfo()->usesNameLookup()); assert(getScopeInfo()->usesNameLookup());
getFrameInfoVar(); // ensures this->boxed_locals_var is initialized
assert(this->boxed_locals != NULL); assert(this->boxed_locals != NULL);
return this->boxed_locals; return this->boxed_locals;
} }
llvm::Value* IRGenState::getVRegsVar() { llvm::Value* IRGenState::getVRegsVar() {
if (!vregs) {
// calling this sets also the vregs member
getFrameInfoVar();
assert(vregs); assert(vregs);
}
return vregs; return vregs;
} }
llvm::Value* IRGenState::getStmtVar() {
assert(stmt);
return stmt;
}
ScopeInfo* IRGenState::getScopeInfo() { ScopeInfo* IRGenState::getScopeInfo() {
return getSourceInfo()->getScopeInfo(); return getSourceInfo()->getScopeInfo();
} }
...@@ -288,18 +321,9 @@ ScopeInfo* IRGenState::getScopeInfoForNode(AST* node) { ...@@ -288,18 +321,9 @@ ScopeInfo* IRGenState::getScopeInfoForNode(AST* node) {
return source->scoping->getScopeInfoForNode(node); return source->scoping->getScopeInfoForNode(node);
} }
void IRGenState::setGlobals(llvm::Value* globals) {
assert(!source_info->scoping->areGlobalsFromModule());
assert(!this->globals);
this->globals = globals;
}
llvm::Value* IRGenState::getGlobals() { llvm::Value* IRGenState::getGlobals() {
if (!globals) { assert(globals);
assert(source_info->scoping->areGlobalsFromModule()); return globals;
this->globals = embedRelocatablePtr(source_info->parent_module, g.llvm_value_type_ptr);
}
return this->globals;
} }
llvm::Value* IRGenState::getGlobalsIfCustom() { llvm::Value* IRGenState::getGlobalsIfCustom() {
...@@ -464,28 +488,11 @@ public: ...@@ -464,28 +488,11 @@ public:
} }
#endif #endif
if (ENABLE_FRAME_INTROSPECTION) { llvm::Value* stmt = unw_info.current_stmt ? embedRelocatablePtr(unw_info.current_stmt, g.llvm_aststmt_type_ptr)
llvm::Type* rtn_type = llvm::cast<llvm::FunctionType>(llvm::cast<llvm::PointerType>(callee->getType()) : getNullPtr(g.llvm_aststmt_type_ptr);
->getElementType())->getReturnType(); getBuilder()->CreateStore(stmt, irstate->getStmtVar());
llvm::Value* bitcasted = getBuilder()->CreateBitCast(callee, g.i8->getPointerTo());
llvm::CallSite cs = emitPatchpoint(rtn_type, NULL, bitcasted, args, {}, unw_info, target_exception_style);
if (rtn_type == cs->getType()) {
return cs.getInstruction();
} else if (rtn_type == g.i1) {
return getBuilder()->CreateTrunc(cs.getInstruction(), rtn_type);
} else if (llvm::isa<llvm::PointerType>(rtn_type)) {
return getBuilder()->CreateIntToPtr(cs.getInstruction(), rtn_type);
} else {
cs.getInstruction()->getType()->dump();
rtn_type->dump();
RELEASE_ASSERT(0, "don't know how to convert those");
}
} else {
return emitCall(unw_info, callee, args, target_exception_style).getInstruction(); return emitCall(unw_info, callee, args, target_exception_style).getInstruction();
} }
}
llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee,
ExceptionStyle target_exception_style = CXX) override { ExceptionStyle target_exception_style = CXX) override {
...@@ -577,7 +584,6 @@ const std::string CREATED_CLOSURE_NAME = "#created_closure"; ...@@ -577,7 +584,6 @@ const std::string CREATED_CLOSURE_NAME = "#created_closure";
const std::string PASSED_CLOSURE_NAME = "#passed_closure"; const std::string PASSED_CLOSURE_NAME = "#passed_closure";
const std::string PASSED_GENERATOR_NAME = "#passed_generator"; const std::string PASSED_GENERATOR_NAME = "#passed_generator";
const std::string FRAME_INFO_PTR_NAME = "#frame_info_ptr"; const std::string FRAME_INFO_PTR_NAME = "#frame_info_ptr";
const std::string PASSED_GLOBALS_NAME = "#passed_globals";
bool isIsDefinedName(llvm::StringRef name) { bool isIsDefinedName(llvm::StringRef name) {
return startswith(name, "!is_defined_"); return startswith(name, "!is_defined_");
...@@ -1131,11 +1137,6 @@ private: ...@@ -1131,11 +1137,6 @@ private:
return new ConcreteCompilerVariable(typeFromClass(ellipsis_cls), ellipsis, false); return new ConcreteCompilerVariable(typeFromClass(ellipsis_cls), ellipsis, false);
} }
llvm::Constant* embedParentModulePtr() {
BoxedModule* parent_module = irstate->getSourceInfo()->parent_module;
return embedRelocatablePtr(parent_module, g.llvm_value_type_ptr, "cParentModule");
}
ConcreteCompilerVariable* _getGlobal(AST_Name* node, const UnwindInfo& unw_info) { ConcreteCompilerVariable* _getGlobal(AST_Name* node, const UnwindInfo& unw_info) {
if (node->id.s() == "None") if (node->id.s() == "None")
return getNone(); return getNone();
...@@ -1778,7 +1779,7 @@ private: ...@@ -1778,7 +1779,7 @@ private:
if (vst == ScopeInfo::VarScopeType::GLOBAL) { if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (irstate->getSourceInfo()->scoping->areGlobalsFromModule()) { if (irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
auto parent_module = llvm::ConstantExpr::getPointerCast(embedParentModulePtr(), g.llvm_value_type_ptr); auto parent_module = irstate->getGlobals();
ConcreteCompilerVariable* module = new ConcreteCompilerVariable(MODULE, parent_module, false); ConcreteCompilerVariable* module = new ConcreteCompilerVariable(MODULE, parent_module, false);
module->setattr(emitter, getEmptyOpInfo(unw_info), name.getBox(), val); module->setattr(emitter, getEmptyOpInfo(unw_info), name.getBox(), val);
module->decvref(emitter); module->decvref(emitter);
...@@ -2209,11 +2210,6 @@ private: ...@@ -2209,11 +2210,6 @@ private:
sorted_symbol_table[internString(FRAME_INFO_PTR_NAME)] sorted_symbol_table[internString(FRAME_INFO_PTR_NAME)]
= new ConcreteCompilerVariable(FRAME_INFO, irstate->getFrameInfoVar(), true); = new ConcreteCompilerVariable(FRAME_INFO, irstate->getFrameInfoVar(), true);
if (!irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
sorted_symbol_table[internString(PASSED_GLOBALS_NAME)]
= new ConcreteCompilerVariable(UNKNOWN, irstate->getGlobals(), true);
}
// For OSR calls, we use the same calling convention as in some other places; namely, // For OSR calls, we use the same calling convention as in some other places; namely,
// arg1, arg2, arg3, argarray [nargs is ommitted] // arg1, arg2, arg3, argarray [nargs is ommitted]
// It would be nice to directly pass all variables as arguments, instead of packing them into // It would be nice to directly pass all variables as arguments, instead of packing them into
...@@ -2595,13 +2591,6 @@ public: ...@@ -2595,13 +2591,6 @@ public:
std::vector<llvm::Value*>& stackmap_args) override { std::vector<llvm::Value*>& stackmap_args) override {
int initial_args = stackmap_args.size(); int initial_args = stackmap_args.size();
stackmap_args.push_back(irstate->getFrameInfoVar());
if (!irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
stackmap_args.push_back(irstate->getGlobals());
pp->addFrameVar(PASSED_GLOBALS_NAME, UNKNOWN);
}
assert(UNBOXED_INT->llvmType() == g.i64); assert(UNBOXED_INT->llvmType() == g.i64);
if (ENABLE_JIT_OBJECT_CACHE) { if (ENABLE_JIT_OBJECT_CACHE) {
llvm::Value* v; llvm::Value* v;
...@@ -2756,40 +2745,48 @@ public: ...@@ -2756,40 +2745,48 @@ public:
auto scope_info = irstate->getScopeInfo(); auto scope_info = irstate->getScopeInfo();
llvm::Value* passed_closure = NULL;
llvm::Function::arg_iterator AI = irstate->getLLVMFunction()->arg_begin(); llvm::Function::arg_iterator AI = irstate->getLLVMFunction()->arg_begin();
llvm::Value* passed_closure = NULL;
llvm::Value* generator = NULL;
llvm::Value* globals = NULL;
if (scope_info->takesClosure()) { if (scope_info->takesClosure()) {
passed_closure = AI; passed_closure = AI;
symbol_table[internString(PASSED_CLOSURE_NAME)] ++AI;
= new ConcreteCompilerVariable(getPassedClosureType(), AI, true); } else
passed_closure = getNullPtr(g.llvm_closure_type_ptr);
// store the passed_closure inside the frame info so that frame introspection can access it without needing if (irstate->getSourceInfo()->is_generator) {
// a stackmap entry generator = AI;
emitter.getBuilder()->CreateStore(passed_closure,
getPassedClosureGep(*emitter.getBuilder(), irstate->getFrameInfoVar()));
++AI; ++AI;
} }
if (scope_info->createsClosure()) { if (!irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
if (!passed_closure) globals = AI;
passed_closure = getNullPtr(g.llvm_closure_type_ptr); ++AI;
} else {
BoxedModule* parent_module = irstate->getSourceInfo()->parent_module;
globals = embedRelocatablePtr(parent_module, g.llvm_value_type_ptr, "cParentModule");
}
irstate->setupFrameInfoVar(passed_closure, globals);
if (scope_info->takesClosure()) {
symbol_table[internString(PASSED_CLOSURE_NAME)]
= new ConcreteCompilerVariable(getPassedClosureType(), passed_closure, true);
}
if (scope_info->createsClosure()) {
llvm::Value* new_closure = emitter.getBuilder()->CreateCall2( llvm::Value* new_closure = emitter.getBuilder()->CreateCall2(
g.funcs.createClosure, passed_closure, getConstantInt(scope_info->getClosureSize(), g.i64)); g.funcs.createClosure, passed_closure, getConstantInt(scope_info->getClosureSize(), g.i64));
symbol_table[internString(CREATED_CLOSURE_NAME)] symbol_table[internString(CREATED_CLOSURE_NAME)]
= new ConcreteCompilerVariable(getCreatedClosureType(), new_closure, true); = new ConcreteCompilerVariable(getCreatedClosureType(), new_closure, true);
} }
if (irstate->getSourceInfo()->is_generator) { if (irstate->getSourceInfo()->is_generator)
symbol_table[internString(PASSED_GENERATOR_NAME)] = new ConcreteCompilerVariable(GENERATOR, AI, true); symbol_table[internString(PASSED_GENERATOR_NAME)]
++AI; = new ConcreteCompilerVariable(GENERATOR, generator, true);
}
if (!irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
irstate->setGlobals(AI);
++AI;
}
std::vector<llvm::Value*> python_parameters; std::vector<llvm::Value*> python_parameters;
for (int i = 0; i < arg_types.size(); i++) { for (int i = 0; i < arg_types.size(); i++) {
......
...@@ -49,7 +49,6 @@ extern const std::string CREATED_CLOSURE_NAME; ...@@ -49,7 +49,6 @@ extern const std::string CREATED_CLOSURE_NAME;
extern const std::string PASSED_CLOSURE_NAME; extern const std::string PASSED_CLOSURE_NAME;
extern const std::string PASSED_GENERATOR_NAME; extern const std::string PASSED_GENERATOR_NAME;
extern const std::string FRAME_INFO_PTR_NAME; extern const std::string FRAME_INFO_PTR_NAME;
extern const std::string PASSED_GLOBALS_NAME;
// Class that holds state of the current IR generation, that might not be local // Class that holds state of the current IR generation, that might not be local
...@@ -70,9 +69,9 @@ private: ...@@ -70,9 +69,9 @@ private:
llvm::AllocaInst* scratch_space; llvm::AllocaInst* scratch_space;
llvm::Value* frame_info; llvm::Value* frame_info;
llvm::Value* boxed_locals; llvm::Value* boxed_locals;
llvm::Value* frame_info_arg;
llvm::Value* globals; llvm::Value* globals;
llvm::Value* vregs; llvm::Value* vregs;
llvm::Value* stmt;
int scratch_size; int scratch_size;
public: public:
...@@ -91,10 +90,15 @@ public: ...@@ -91,10 +90,15 @@ public:
GCBuilder* getGC() { return gc; } GCBuilder* getGC() { return gc; }
void setupFrameInfoVar(llvm::Value* passed_closure, llvm::Value* passed_globals,
llvm::Value* frame_info_arg = NULL);
void setupFrameInfoVarOSR(llvm::Value* frame_info_arg) { return setupFrameInfoVar(NULL, NULL, frame_info_arg); }
llvm::Value* getScratchSpace(int min_bytes); llvm::Value* getScratchSpace(int min_bytes);
llvm::Value* getFrameInfoVar(); llvm::Value* getFrameInfoVar();
llvm::Value* getBoxedLocalsVar(); llvm::Value* getBoxedLocalsVar();
llvm::Value* getVRegsVar(); llvm::Value* getVRegsVar();
llvm::Value* getStmtVar();
ConcreteCompilerType* getReturnType() { return cf->getReturnType(); } ConcreteCompilerType* getReturnType() { return cf->getReturnType(); }
...@@ -110,9 +114,6 @@ public: ...@@ -110,9 +114,6 @@ public:
ParamNames* getParamNames() { return param_names; } ParamNames* getParamNames() { return param_names; }
void setFrameInfoArgument(llvm::Value* v) { frame_info_arg = v; }
void setGlobals(llvm::Value* globals);
// Returns the custom globals, or the module if the globals come from the module. // Returns the custom globals, or the module if the globals come from the module.
llvm::Value* getGlobals(); llvm::Value* getGlobals();
// Returns the custom globals, or null if the globals come from the module. // Returns the custom globals, or null if the globals come from the module.
......
...@@ -80,16 +80,6 @@ void PatchpointInfo::parseLocationMap(StackMap::Record* r, LocationMap* map) { ...@@ -80,16 +80,6 @@ void PatchpointInfo::parseLocationMap(StackMap::Record* r, LocationMap* map) {
// printf("parsing pp %ld:\n", reinterpret_cast<int64_t>(this)); // printf("parsing pp %ld:\n", reinterpret_cast<int64_t>(this));
StackMap::Record::Location frame_info_location = r->locations[cur_arg];
cur_arg++;
// We could allow the frame_info to exist in a different location for each callsite,
// but in reality it will always live at a fixed stack offset.
if (map->frameInfoFound()) {
assert(frame_info_location == map->frame_info_location);
} else {
map->frame_info_location = frame_info_location;
}
for (FrameVarInfo& frame_var : frame_vars) { for (FrameVarInfo& frame_var : frame_vars) {
int num_args = frame_var.type->numFrameArgs(); int num_args = frame_var.type->numFrameArgs();
...@@ -165,6 +155,16 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) { ...@@ -165,6 +155,16 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) {
PatchpointInfo* pp = new_patchpoints[r->id].first; PatchpointInfo* pp = new_patchpoints[r->id].first;
assert(pp); assert(pp);
if (pp->isFrameInfoStackmap()) {
assert(r->locations.size() == pp->totalStackmapArgs());
StackMap::Record::Location frame_info_location = r->locations[0];
assert(!cf->location_map->frameInfoFound());
assert(frame_info_location.type == StackMap::Record::Location::Direct);
assert(frame_info_location.regnum == 6 /* must be rbp based */);
cf->location_map->frame_info_location = frame_info_location;
continue;
}
void* slowpath_func = PatchpointInfo::getSlowpathAddr(r->id); void* slowpath_func = PatchpointInfo::getSlowpathAddr(r->id);
if (VERBOSITY() >= 2) { if (VERBOSITY() >= 2) {
printf("Processing pp %ld; [%d, %d)\n", reinterpret_cast<int64_t>(pp), r->offset, printf("Processing pp %ld; [%d, %d)\n", reinterpret_cast<int64_t>(pp), r->offset,
......
...@@ -106,6 +106,7 @@ private: ...@@ -106,6 +106,7 @@ private:
const ICSetupInfo* icinfo; const ICSetupInfo* icinfo;
int num_ic_stackmap_args; int num_ic_stackmap_args;
int num_frame_stackmap_args; int num_frame_stackmap_args;
bool is_frame_info_stackmap;
std::vector<FrameVarInfo> frame_vars; std::vector<FrameVarInfo> frame_vars;
unsigned int id; unsigned int id;
...@@ -115,6 +116,7 @@ private: ...@@ -115,6 +116,7 @@ private:
icinfo(icinfo), icinfo(icinfo),
num_ic_stackmap_args(num_ic_stackmap_args), num_ic_stackmap_args(num_ic_stackmap_args),
num_frame_stackmap_args(-1), num_frame_stackmap_args(-1),
is_frame_info_stackmap(false),
id(0) {} id(0) {}
...@@ -129,6 +131,7 @@ public: ...@@ -129,6 +131,7 @@ public:
int scratchStackmapArg() { return 0; } int scratchStackmapArg() { return 0; }
int scratchSize() { return 80 + MAX_FRAME_SPILLS * sizeof(void*); } int scratchSize() { return 80 + MAX_FRAME_SPILLS * sizeof(void*); }
bool isDeopt() const { return icinfo ? icinfo->isDeopt() : false; } bool isDeopt() const { return icinfo ? icinfo->isDeopt() : false; }
bool isFrameInfoStackmap() const { return is_frame_info_stackmap; }
int numFrameSpillsSupported() const { return isDeopt() ? MAX_FRAME_SPILLS : 0; } int numFrameSpillsSupported() const { return isDeopt() ? MAX_FRAME_SPILLS : 0; }
void addFrameVar(llvm::StringRef name, CompilerType* type); void addFrameVar(llvm::StringRef name, CompilerType* type);
...@@ -136,8 +139,9 @@ public: ...@@ -136,8 +139,9 @@ public:
assert(num_frame_stackmap_args == -1); assert(num_frame_stackmap_args == -1);
num_frame_stackmap_args = num_frame_args; num_frame_stackmap_args = num_frame_args;
} }
void setIsFrameInfoStackmap(bool b = true) { is_frame_info_stackmap = b; }
int icStackmapArgsStart() { return 1; } int icStackmapArgsStart() { return isFrameInfoStackmap() ? 0 : 1; }
int numICStackmapArgs() { return num_ic_stackmap_args; } int numICStackmapArgs() { return num_ic_stackmap_args; }
int frameStackmapArgsStart() { return icStackmapArgsStart() + numICStackmapArgs(); } int frameStackmapArgsStart() { return icStackmapArgsStart() + numICStackmapArgs(); }
......
...@@ -344,7 +344,6 @@ public: ...@@ -344,7 +344,6 @@ public:
assert(cf->location_map); assert(cf->location_map);
const LocationMap::LocationTable& table = cf->location_map->names[name]; const LocationMap::LocationTable& table = cf->location_map->names[name];
assert(table.locations.size());
auto entry = table.findEntry(offset); auto entry = table.findEntry(offset);
if (!entry) if (!entry)
...@@ -356,28 +355,17 @@ public: ...@@ -356,28 +355,17 @@ public:
AST_stmt* getCurrentStatement() { AST_stmt* getCurrentStatement() {
if (id.type == PythonFrameId::COMPILED) { if (id.type == PythonFrameId::COMPILED) {
auto locations = findLocations("!current_stmt"); auto locations = findLocations("!current_stmt");
RELEASE_ASSERT(locations.size() == 1, "%ld", locations.size()); if (locations.size() == 1)
return reinterpret_cast<AST_stmt*>(readLocation(locations[0])); return reinterpret_cast<AST_stmt*>(readLocation(locations[0]));
} else if (id.type == PythonFrameId::INTERPRETED) {
return getCurrentStatementForInterpretedFrame((void*)id.bp);
} }
abort(); assert(getFrameInfo()->stmt);
return getFrameInfo()->stmt;
} }
Box* getGlobals() { Box* getGlobals() {
if (id.type == PythonFrameId::COMPILED) { Box* r = getFrameInfo()->globals;
CompiledFunction* cf = getCF();
if (cf->md->source->scoping->areGlobalsFromModule())
return cf->md->source->parent_module;
auto locations = findLocations(PASSED_GLOBALS_NAME);
assert(locations.size() == 1);
Box* r = (Box*)readLocation(locations[0]);
ASSERT(gc::isValidGCObject(r), "%p", r); ASSERT(gc::isValidGCObject(r), "%p", r);
return r; return r;
} else if (id.type == PythonFrameId::INTERPRETED) {
return getGlobalsForInterpretedFrame((void*)id.bp);
}
abort();
} }
Box* getGlobalsDict() { Box* getGlobalsDict() {
...@@ -395,8 +383,7 @@ public: ...@@ -395,8 +383,7 @@ public:
CompiledFunction* cf = getCF(); CompiledFunction* cf = getCF();
assert(cf->location_map->frameInfoFound()); assert(cf->location_map->frameInfoFound());
const auto& frame_info_loc = cf->location_map->frame_info_location; const auto& frame_info_loc = cf->location_map->frame_info_location;
return *reinterpret_cast<FrameInfo**>(readLocation(frame_info_loc));
return reinterpret_cast<FrameInfo*>(readLocation(frame_info_loc));
} else if (id.type == PythonFrameId::INTERPRETED) { } else if (id.type == PythonFrameId::INTERPRETED) {
return getFrameInfoForInterpretedFrame((void*)id.bp); return getFrameInfoForInterpretedFrame((void*)id.bp);
} }
......
...@@ -886,8 +886,14 @@ struct FrameInfo { ...@@ -886,8 +886,14 @@ struct FrameInfo {
BoxedClosure* passed_closure; BoxedClosure* passed_closure;
Box** vregs; Box** vregs;
// Current statement
FrameInfo(ExcInfo exc) : exc(exc), boxedLocals(NULL), frame_obj(0), passed_closure(0), vregs(0) {} // Caution the llvm tier only updates this information on direct external calls but not for patchpoints.
// This means if a patchpoint "current_stmt" info is available it must be used instead of this field.
AST_stmt* stmt;
// This is either a module or a dict
Box* globals;
FrameInfo(ExcInfo exc) : exc(exc), boxedLocals(NULL), frame_obj(0), passed_closure(0), vregs(0), stmt(0), globals(0) {}
void gcVisit(GCVisitor* visitor); void gcVisit(GCVisitor* visitor);
}; };
......
...@@ -47,5 +47,9 @@ i64 unboxInt(Box* b) { ...@@ -47,5 +47,9 @@ i64 unboxInt(Box* b) {
return ((BoxedInt*)b)->n; return ((BoxedInt*)b)->n;
} }
extern "C" bool hasnext(Box* o) {
return o->cls->tpp_hasnext(o);
}
// BoxedInt::BoxedInt(int64_t n) : Box(int_cls), n(n) {} // BoxedInt::BoxedInt(int64_t n) : Box(int_cls), n(n) {}
} }
...@@ -82,22 +82,6 @@ Box* listiter_next(Box* s) noexcept { ...@@ -82,22 +82,6 @@ Box* listiter_next(Box* s) noexcept {
return rtn; return rtn;
} }
template <ExceptionStyle S> Box* listiterNext(Box* s) noexcept(S == CAPI) {
Box* rtn = listiter_next(s);
if (!rtn) {
if (S == CAPI) {
PyErr_SetObject(StopIteration, None);
return NULL;
} else
raiseExcHelper(StopIteration, "");
}
return rtn;
}
// force instantiation:
template Box* listiterNext<CAPI>(Box*);
template Box* listiterNext<CXX>(Box*);
Box* listReversed(Box* s) { Box* listReversed(Box* s) {
assert(PyList_Check(s)); assert(PyList_Check(s));
BoxedList* self = static_cast<BoxedList*>(s); BoxedList* self = static_cast<BoxedList*>(s);
......
...@@ -1246,6 +1246,22 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P ...@@ -1246,6 +1246,22 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
} }
} }
template <ExceptionStyle S> Box* listiterNext(Box* s) noexcept(S == CAPI) {
Box* rtn = listiter_next(s);
if (!rtn) {
if (S == CAPI) {
PyErr_SetObject(StopIteration, None);
return NULL;
} else
raiseExcHelper(StopIteration, (const char*)NULL);
}
return rtn;
}
// force instantiation:
template Box* listiterNext<CAPI>(Box*) noexcept;
template Box* listiterNext<CXX>(Box*);
void BoxedListIterator::gcHandler(GCVisitor* v, Box* b) { void BoxedListIterator::gcHandler(GCVisitor* v, Box* b) {
Box::gcHandler(v, b); Box::gcHandler(v, b);
BoxedListIterator* it = (BoxedListIterator*)b; BoxedListIterator* it = (BoxedListIterator*)b;
......
...@@ -117,10 +117,6 @@ Box* boxStringFromCharPtr(const char* s) { ...@@ -117,10 +117,6 @@ Box* boxStringFromCharPtr(const char* s) {
return boxString(s); return boxString(s);
} }
extern "C" bool hasnext(Box* o) {
return o->cls->tpp_hasnext(o);
}
extern "C" void dump(void* p) { extern "C" void dump(void* p) {
dumpEx(p, 0); dumpEx(p, 0);
} }
......
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