Commit 86427f32 authored by Marius Wachtler's avatar Marius Wachtler Committed by Boxiang Sun

BST: remove pointer to FunctionDef and ClassDef and the code object pointer

Replace it with a index into a table of definitions and code objects

This also now frees much more code objects early because they get proper refcounted now
parent f1599afc
...@@ -478,7 +478,7 @@ private: ...@@ -478,7 +478,7 @@ private:
} }
void visit_makeclass(BST_MakeClass* mkclass) override { void visit_makeclass(BST_MakeClass* mkclass) override {
BST_ClassDef* node = mkclass->class_def; auto* node = bst_cast<BST_ClassDef>(getCodeConstants().getFuncOrClass(mkclass->index_class_def).first);
for (int i = 0; i < node->num_decorator; ++i) { for (int i = 0; i < node->num_decorator; ++i) {
getType(node->decorator[i]); getType(node->decorator[i]);
...@@ -504,7 +504,7 @@ private: ...@@ -504,7 +504,7 @@ private:
} }
void visit_makefunction(BST_MakeFunction* mkfn) override { void visit_makefunction(BST_MakeFunction* mkfn) override {
BST_FunctionDef* node = mkfn->function_def; auto* node = bst_cast<BST_FunctionDef>(getCodeConstants().getFuncOrClass(mkfn->index_func_def).first);
for (int i = 0; i < node->num_defaults + node->num_decorator; ++i) { for (int i = 0; i < node->num_defaults + node->num_decorator; ++i) {
getType(node->elts[i]); getType(node->elts[i]);
......
...@@ -74,7 +74,7 @@ public: ...@@ -74,7 +74,7 @@ public:
static Box* executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, BST_stmt* start_at); static Box* executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, BST_stmt* start_at);
private: private:
Value createFunction(BST_FunctionDef* node); Value createFunction(BST_FunctionDef* node, BoxedCode* node_code);
Value doBinOp(BST_stmt* node, Value left, Value right, int op, BinExpType exp_type); Value doBinOp(BST_stmt* node, Value left, Value right, int op, BinExpType exp_type);
void doStore(int vreg, STOLEN(Value) value); void doStore(int vreg, STOLEN(Value) value);
void doStoreArg(BST_Name* name, STOLEN(Value) value); void doStoreArg(BST_Name* name, STOLEN(Value) value);
...@@ -1125,8 +1125,7 @@ Value ASTInterpreter::visit_return(BST_Return* node) { ...@@ -1125,8 +1125,7 @@ Value ASTInterpreter::visit_return(BST_Return* node) {
return s; return s;
} }
Value ASTInterpreter::createFunction(BST_FunctionDef* node) { Value ASTInterpreter::createFunction(BST_FunctionDef* node, BoxedCode* code) {
BoxedCode* code = node->code;
assert(code); assert(code);
std::vector<Box*> defaults; std::vector<Box*> defaults;
...@@ -1206,14 +1205,15 @@ Value ASTInterpreter::createFunction(BST_FunctionDef* node) { ...@@ -1206,14 +1205,15 @@ Value ASTInterpreter::createFunction(BST_FunctionDef* node) {
} }
Value ASTInterpreter::visit_makeFunction(BST_MakeFunction* mkfn) { Value ASTInterpreter::visit_makeFunction(BST_MakeFunction* mkfn) {
BST_FunctionDef* node = mkfn->function_def; auto func_entry = getCodeConstants().getFuncOrClass(mkfn->index_func_def);
auto node = bst_cast<BST_FunctionDef>(func_entry.first);
std::vector<Value> decorators; std::vector<Value> decorators;
decorators.reserve(node->num_decorator); decorators.reserve(node->num_decorator);
for (int i = 0; i < node->num_decorator; ++i) for (int i = 0; i < node->num_decorator; ++i)
decorators.push_back(getVReg(node->elts[i])); decorators.push_back(getVReg(node->elts[i]));
Value func = createFunction(node); Value func = createFunction(node, func_entry.second);
for (int i = decorators.size() - 1; i >= 0; i--) { for (int i = decorators.size() - 1; i >= 0; i--) {
func.o = runtimeCall(autoDecref(decorators[i].o), ArgPassSpec(1), autoDecref(func.o), 0, 0, 0, 0); func.o = runtimeCall(autoDecref(decorators[i].o), ArgPassSpec(1), autoDecref(func.o), 0, 0, 0, 0);
...@@ -1228,8 +1228,9 @@ Value ASTInterpreter::visit_makeFunction(BST_MakeFunction* mkfn) { ...@@ -1228,8 +1228,9 @@ Value ASTInterpreter::visit_makeFunction(BST_MakeFunction* mkfn) {
Value ASTInterpreter::visit_makeClass(BST_MakeClass* mkclass) { Value ASTInterpreter::visit_makeClass(BST_MakeClass* mkclass) {
abortJITing(); abortJITing();
BST_ClassDef* node = mkclass->class_def;
auto class_entry = getCodeConstants().getFuncOrClass(mkclass->index_class_def);
auto node = bst_cast<BST_ClassDef>(class_entry.first);
BoxedTuple* bases_tuple = (BoxedTuple*)getVReg(node->vreg_bases_tuple).o; BoxedTuple* bases_tuple = (BoxedTuple*)getVReg(node->vreg_bases_tuple).o;
assert(bases_tuple->cls == tuple_cls); assert(bases_tuple->cls == tuple_cls);
...@@ -1241,7 +1242,7 @@ Value ASTInterpreter::visit_makeClass(BST_MakeClass* mkclass) { ...@@ -1241,7 +1242,7 @@ Value ASTInterpreter::visit_makeClass(BST_MakeClass* mkclass) {
decorators.push_back(getVReg(node->decorator[i]).o); decorators.push_back(getVReg(node->decorator[i]).o);
} }
BoxedCode* code = node->code; BoxedCode* code = class_entry.second;
assert(code); assert(code);
const ScopingResults& scope_info = code->source->scoping; const ScopingResults& scope_info = code->source->scoping;
......
...@@ -1488,8 +1488,8 @@ private: ...@@ -1488,8 +1488,8 @@ private:
} }
CompilerVariable* evalMakeClass(BST_MakeClass* mkclass, const UnwindInfo& unw_info) { CompilerVariable* evalMakeClass(BST_MakeClass* mkclass, const UnwindInfo& unw_info) {
assert(mkclass->type == BST_TYPE::MakeClass && mkclass->class_def->type == BST_TYPE::ClassDef); auto class_entry = irstate->getCodeConstants().getFuncOrClass(mkclass->index_class_def);
BST_ClassDef* node = mkclass->class_def; BST_ClassDef* node = bst_cast<BST_ClassDef>(class_entry.first);
CompilerVariable* _bases_tuple = evalVReg(node->vreg_bases_tuple); CompilerVariable* _bases_tuple = evalVReg(node->vreg_bases_tuple);
ConcreteCompilerVariable* bases_tuple = _bases_tuple->makeConverted(emitter, _bases_tuple->getBoxType()); ConcreteCompilerVariable* bases_tuple = _bases_tuple->makeConverted(emitter, _bases_tuple->getBoxType());
...@@ -1499,7 +1499,7 @@ private: ...@@ -1499,7 +1499,7 @@ private:
decorators.push_back(evalVReg(node->decorator[i])); decorators.push_back(evalVReg(node->decorator[i]));
} }
BoxedCode* code = node->code; BoxedCode* code = class_entry.second;
assert(code); assert(code);
const ScopingResults& scope_info = code->source->scoping; const ScopingResults& scope_info = code->source->scoping;
...@@ -1542,8 +1542,7 @@ private: ...@@ -1542,8 +1542,7 @@ private:
return cls; return cls;
} }
CompilerVariable* _createFunction(BST_FunctionDef* node, const UnwindInfo& unw_info) { CompilerVariable* _createFunction(BST_FunctionDef* node, BoxedCode* code, const UnwindInfo& unw_info) {
BoxedCode* code = node->code;
assert(code); assert(code);
std::vector<ConcreteCompilerVariable*> defaults; std::vector<ConcreteCompilerVariable*> defaults;
...@@ -1572,13 +1571,15 @@ private: ...@@ -1572,13 +1571,15 @@ private:
} }
CompilerVariable* evalMakeFunction(BST_MakeFunction* mkfn, const UnwindInfo& unw_info) { CompilerVariable* evalMakeFunction(BST_MakeFunction* mkfn, const UnwindInfo& unw_info) {
BST_FunctionDef* node = mkfn->function_def; auto func_entry = irstate->getCodeConstants().getFuncOrClass(mkfn->index_func_def);
BST_FunctionDef* node = bst_cast<BST_FunctionDef>(func_entry.first);
std::vector<CompilerVariable*> decorators; std::vector<CompilerVariable*> decorators;
for (int i = 0; i < node->num_decorator; ++i) { for (int i = 0; i < node->num_decorator; ++i) {
decorators.push_back(evalVReg(node->elts[i])); decorators.push_back(evalVReg(node->elts[i]));
} }
CompilerVariable* func = _createFunction(node, unw_info); CompilerVariable* func = _createFunction(node, func_entry.second, unw_info);
for (int i = decorators.size() - 1; i >= 0; i--) { for (int i = decorators.size() - 1; i >= 0; i--) {
func = decorators[i]->call(emitter, getOpInfoForNode(node, unw_info), ArgPassSpec(1), { func }, NULL); func = decorators[i]->call(emitter, getOpInfoForNode(node, unw_info), ArgPassSpec(1), { func }, NULL);
......
...@@ -710,7 +710,7 @@ void BST_MakeFunction::accept(BSTVisitor* v) { ...@@ -710,7 +710,7 @@ void BST_MakeFunction::accept(BSTVisitor* v) {
if (skip) if (skip)
return; return;
function_def->accept(v); bst_cast<BST_FunctionDef>(v->getCodeConstants().getFuncOrClass(index_func_def).first)->accept(v);
v->visit_vreg(&vreg_dst, true); v->visit_vreg(&vreg_dst, true);
} }
...@@ -723,7 +723,7 @@ void BST_MakeClass::accept(BSTVisitor* v) { ...@@ -723,7 +723,7 @@ void BST_MakeClass::accept(BSTVisitor* v) {
if (skip) if (skip)
return; return;
class_def->accept(v); bst_cast<BST_ClassDef>(v->getCodeConstants().getFuncOrClass(index_class_def).first)->accept(v);
v->visit_vreg(&vreg_dst, true); v->visit_vreg(&vreg_dst, true);
} }
......
...@@ -404,8 +404,6 @@ public: ...@@ -404,8 +404,6 @@ public:
class BST_ClassDef : public BST_stmt { class BST_ClassDef : public BST_stmt {
public: public:
BoxedCode* code;
InternedString name; InternedString name;
int vreg_bases_tuple; int vreg_bases_tuple;
const int num_decorator; const int num_decorator;
...@@ -471,8 +469,6 @@ class BST_FunctionDef : public BST_stmt { ...@@ -471,8 +469,6 @@ class BST_FunctionDef : public BST_stmt {
public: public:
InternedString name; // if the name is not set this is a lambda InternedString name; // if the name is not set this is a lambda
BoxedCode* code;
const int num_decorator; const int num_decorator;
const int num_defaults; const int num_defaults;
...@@ -563,18 +559,20 @@ public: ...@@ -563,18 +559,20 @@ public:
class BST_MakeFunction : public BST_stmt_with_dest { class BST_MakeFunction : public BST_stmt_with_dest {
public: public:
BST_FunctionDef* function_def; const int index_func_def;
BST_MakeFunction(BST_FunctionDef* fd) : BST_stmt_with_dest(BST_TYPE::MakeFunction, fd->lineno), function_def(fd) {} BST_MakeFunction(BST_FunctionDef* fd, int index_func_def)
: BST_stmt_with_dest(BST_TYPE::MakeFunction, fd->lineno), index_func_def(index_func_def) {}
BSTNODE(MakeFunction) BSTNODE(MakeFunction)
}; };
class BST_MakeClass : public BST_stmt_with_dest { class BST_MakeClass : public BST_stmt_with_dest {
public: public:
BST_ClassDef* class_def; const int index_class_def;
BST_MakeClass(BST_ClassDef* cd) : BST_stmt_with_dest(BST_TYPE::MakeClass, cd->lineno), class_def(cd) {} BST_MakeClass(BST_ClassDef* cd, int index_class_def)
: BST_stmt_with_dest(BST_TYPE::MakeClass, cd->lineno), index_class_def(index_class_def) {}
BSTNODE(MakeClass) BSTNODE(MakeClass)
}; };
......
// Copyright (c) 2014-2016 Dropbox, Inc. // Copyright (c) 2014-2016 Dropbox, Inc.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
...@@ -1294,13 +1294,8 @@ private: ...@@ -1294,13 +1294,8 @@ private:
static BoxedString* gen_name = getStaticString("<generator>"); static BoxedString* gen_name = getStaticString("<generator>");
BoxedCode* code = cfgizer->runRecursively(new_body, gen_name, node->lineno, genexp_args, node); BoxedCode* code = cfgizer->runRecursively(new_body, gen_name, node->lineno, genexp_args, node);
// XXX bad! this should be tracked ex through co_consts
// cur_code->co_consts.push_back(def->code)
constants.push_back(code);
BST_FunctionDef* func = BST_FunctionDef::create(0, 0); BST_FunctionDef* func = BST_FunctionDef::create(0, 0);
func->code = code; BST_MakeFunction* mkfunc = new BST_MakeFunction(func, code_constants.addFuncOrClass(func, code));
BST_MakeFunction* mkfunc = new BST_MakeFunction(func);
TmpValue func_var_name = pushBackCreateDst(mkfunc); TmpValue func_var_name = pushBackCreateDst(mkfunc);
return makeCall(func_var_name, { first }); return makeCall(func_var_name, { first });
...@@ -1357,13 +1352,8 @@ private: ...@@ -1357,13 +1352,8 @@ private:
static BoxedString* comp_name = getStaticString("<comperehension>"); static BoxedString* comp_name = getStaticString("<comperehension>");
BoxedCode* code = cfgizer->runRecursively(new_body, comp_name, node->lineno, args, node); BoxedCode* code = cfgizer->runRecursively(new_body, comp_name, node->lineno, args, node);
// XXX bad! this should be tracked ex through co_consts
// cur_code->co_consts.push_back(def->code)
constants.push_back(code);
BST_FunctionDef* func = BST_FunctionDef::create(0, 0); BST_FunctionDef* func = BST_FunctionDef::create(0, 0);
func->code = code; BST_MakeFunction* mkfunc = new BST_MakeFunction(func, code_constants.addFuncOrClass(func, code));
BST_MakeFunction* mkfunc = new BST_MakeFunction(func);
TmpValue func_var_name = pushBackCreateDst(mkfunc); TmpValue func_var_name = pushBackCreateDst(mkfunc);
return makeCall(func_var_name, { first }); return makeCall(func_var_name, { first });
...@@ -1415,12 +1405,9 @@ private: ...@@ -1415,12 +1405,9 @@ private:
} }
auto name = getStaticString("<lambda>"); auto name = getStaticString("<lambda>");
bdef->code = cfgizer->runRecursively({ stmt }, name, node->lineno, node->args, node); auto* code = cfgizer->runRecursively({ stmt }, name, node->lineno, node->args, node);
// XXX bad! this should be tracked ex through co_consts auto mkfn = new BST_MakeFunction(bdef, code_constants.addFuncOrClass(bdef, code));
// cur_code->co_consts.push_back(def->code)
constants.push_back(bdef->code);
auto mkfn = new BST_MakeFunction(bdef);
return pushBackCreateDst(mkfn); return pushBackCreateDst(mkfn);
} }
...@@ -1813,12 +1800,8 @@ public: ...@@ -1813,12 +1800,8 @@ public:
TmpValue bases_name = pushBackCreateDst(bases); TmpValue bases_name = pushBackCreateDst(bases);
unmapExpr(bases_name, &def->vreg_bases_tuple); unmapExpr(bases_name, &def->vreg_bases_tuple);
def->code = cfgizer->runRecursively(node->body, node->name.getBox(), node->lineno, NULL, node); auto* code = cfgizer->runRecursively(node->body, node->name.getBox(), node->lineno, NULL, node);
// XXX bad! this should be tracked ex through co_consts auto mkclass = new BST_MakeClass(def, code_constants.addFuncOrClass(def, code));
// cur_code->co_consts.push_back(def->code)
constants.push_back(def->code);
auto mkclass = new BST_MakeClass(def);
auto tmp = pushBackCreateDst(mkclass); auto tmp = pushBackCreateDst(mkclass);
pushAssign(TmpValue(scoping->mangleName(def->name), node->lineno), tmp); pushAssign(TmpValue(scoping->mangleName(def->name), node->lineno), tmp);
...@@ -1839,12 +1822,8 @@ public: ...@@ -1839,12 +1822,8 @@ public:
unmapExpr(remapExpr(node->args->defaults[i]), &def->elts[node->decorator_list.size() + i]); unmapExpr(remapExpr(node->args->defaults[i]), &def->elts[node->decorator_list.size() + i]);
} }
def->code = cfgizer->runRecursively(node->body, node->name.getBox(), node->lineno, node->args, node); auto* code = cfgizer->runRecursively(node->body, node->name.getBox(), node->lineno, node->args, node);
// XXX bad! this should be tracked ex through co_consts auto mkfunc = new BST_MakeFunction(def, code_constants.addFuncOrClass(def, code));
// cur_code->co_consts.push_back(def->code)
constants.push_back(def->code);
auto mkfunc = new BST_MakeFunction(def);
auto tmp = pushBackCreateDst(mkfunc); auto tmp = pushBackCreateDst(mkfunc);
pushAssign(TmpValue(scoping->mangleName(def->name), node->lineno), tmp); pushAssign(TmpValue(scoping->mangleName(def->name), node->lineno), tmp);
......
...@@ -4055,6 +4055,10 @@ BORROWED(BoxedFloat*) CodeConstants::getFloatConstant(double d) const { ...@@ -4055,6 +4055,10 @@ BORROWED(BoxedFloat*) CodeConstants::getFloatConstant(double d) const {
void CodeConstants::dealloc() const { void CodeConstants::dealloc() const {
decrefArray(owned_refs.data(), owned_refs.size()); decrefArray(owned_refs.data(), owned_refs.size());
owned_refs.clear(); owned_refs.clear();
for (auto&& e : funcs_and_classes) {
Py_DECREF(e.second);
}
funcs_and_classes.clear();
} }
#ifndef Py_REF_DEBUG #ifndef Py_REF_DEBUG
......
...@@ -1079,6 +1079,8 @@ private: ...@@ -1079,6 +1079,8 @@ private:
// all objects we need to decref when the code object dies // all objects we need to decref when the code object dies
mutable std::vector<Box*> owned_refs; mutable std::vector<Box*> owned_refs;
mutable std::vector<std::pair<BST_stmt*, BoxedCode*>> funcs_and_classes;
// Note: DenseMap doesn't work here since we don't prevent the tombstone/empty // Note: DenseMap doesn't work here since we don't prevent the tombstone/empty
// keys from reaching it. // keys from reaching it.
mutable std::unordered_map<int64_t, BoxedInt*> int_constants; mutable std::unordered_map<int64_t, BoxedInt*> int_constants;
...@@ -1105,6 +1107,14 @@ public: ...@@ -1105,6 +1107,14 @@ public:
BORROWED(BoxedInt*) getIntConstant(int64_t n) const; BORROWED(BoxedInt*) getIntConstant(int64_t n) const;
BORROWED(BoxedFloat*) getFloatConstant(double d) const; BORROWED(BoxedFloat*) getFloatConstant(double d) const;
std::pair<BST_stmt*, BORROWED(BoxedCode*)> getFuncOrClass(int constant) const {
return funcs_and_classes[constant];
}
int addFuncOrClass(BST_stmt* stmt, STOLEN(BoxedCode*) code) {
funcs_and_classes.emplace_back(stmt, code);
return funcs_and_classes.size() - 1;
}
void dealloc() const; void dealloc() const;
}; };
......
...@@ -25,6 +25,18 @@ protected: ...@@ -25,6 +25,18 @@ protected:
} }
}; };
static BoxedCode* getCodeObjectOfFirstMakeFunction(BoxedCode* module_code) {
BoxedCode* code = NULL;
for (BST_stmt* stmt : module_code->source->cfg->blocks[0]->body) {
if (stmt->type != BST_TYPE::MakeFunction)
continue;
code = module_code->code_constants.getFuncOrClass(bst_cast<BST_MakeFunction>(stmt)->index_func_def).second;
break;
}
assert(code);
return code;
}
// this test use functions (VRegInfo::getVReg) which are only available in a debug build // this test use functions (VRegInfo::getVReg) which are only available in a debug build
#ifndef NDEBUG #ifndef NDEBUG
TEST_F(AnalysisTest, augassign) { TEST_F(AnalysisTest, augassign) {
...@@ -52,16 +64,10 @@ TEST_F(AnalysisTest, augassign) { ...@@ -52,16 +64,10 @@ TEST_F(AnalysisTest, augassign) {
ParamNames param_names(args, *module->interned_strings.get()); ParamNames param_names(args, *module->interned_strings.get());
// Hack to get at the cfg: // Hack to get at the cfg:
CFG* cfg = NULL; BoxedCode* code = getCodeObjectOfFirstMakeFunction(module_code);
for (BST_stmt* stmt : module_code->source->cfg->blocks[0]->body) { CFG* cfg = code->source->cfg;
if (stmt->type != BST_TYPE::MakeFunction)
continue;
cfg = bst_cast<BST_MakeFunction>(stmt)->function_def->code->source->cfg;
break;
}
assert(cfg);
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg, module_code->code_constants); std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg, code->code_constants);
auto&& vregs = cfg->getVRegInfo(); auto&& vregs = cfg->getVRegInfo();
//cfg->print(); //cfg->print();
...@@ -96,14 +102,7 @@ void doOsrTest(bool is_osr, bool i_maybe_undefined) { ...@@ -96,14 +102,7 @@ void doOsrTest(bool is_osr, bool i_maybe_undefined) {
auto module_code = computeAllCFGs(module, true, future_flags, boxString(fn), main_module); auto module_code = computeAllCFGs(module, true, future_flags, boxString(fn), main_module);
// Hack to get at the cfg: // Hack to get at the cfg:
BoxedCode* code = NULL; BoxedCode* code = getCodeObjectOfFirstMakeFunction(module_code);
for (BST_stmt* stmt : module_code->source->cfg->blocks[0]->body) {
if (stmt->type != BST_TYPE::MakeFunction)
continue;
code = bst_cast<BST_MakeFunction>(stmt)->function_def->code;
break;
}
assert(code);
CFG* cfg = code->source->cfg; CFG* cfg = code->source->cfg;
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg, module_code->code_constants); std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg, module_code->code_constants);
......
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