Commit 349c4d4b authored by Marius Wachtler's avatar Marius Wachtler

always_use_version support CAPI and CXX

parent 2974bf34
...@@ -1970,13 +1970,13 @@ static const slotdef* update_one_slot(BoxedClass* type, const slotdef* p) noexce ...@@ -1970,13 +1970,13 @@ static const slotdef* update_one_slot(BoxedClass* type, const slotdef* p) noexce
sanity checks. I'll buy the first person to sanity checks. I'll buy the first person to
point out a bug in this reasoning a beer. */ point out a bug in this reasoning a beer. */
} else if (offset == offsetof(BoxedClass, tp_descr_get) && descr->cls == function_cls } else if (offset == offsetof(BoxedClass, tp_descr_get) && descr->cls == function_cls
&& static_cast<BoxedFunction*>(descr)->md->always_use_version) { && !static_cast<BoxedFunction*>(descr)->md->always_use_version.empty()) {
CompiledFunction* cf = static_cast<BoxedFunction*>(descr)->md->always_use_version; auto md = static_cast<BoxedFunction*>(descr)->md;
if (cf->exception_style == CXX) { if (md->always_use_version.get<CAPI>())
type->tpp_descr_get = (descrgetfunc)cf->code; specific = md->always_use_version.get<CAPI>();
else {
type->tpp_descr_get = (descrgetfunc)md->always_use_version.get<CXX>()->code;
specific = (void*)slot_tp_tpp_descr_get; specific = (void*)slot_tp_tpp_descr_get;
} else {
specific = cf->code;
} }
} else if (descr == Py_None && ptr == (void**)&type->tp_hash) { } else if (descr == Py_None && ptr == (void**)&type->tp_hash) {
/* We specifically allow __hash__ to be set to None /* We specifically allow __hash__ to be set to None
......
...@@ -47,7 +47,6 @@ FunctionMetadata::FunctionMetadata(int num_args, bool takes_varargs, bool takes_ ...@@ -47,7 +47,6 @@ FunctionMetadata::FunctionMetadata(int num_args, bool takes_varargs, bool takes_
takes_kwargs(takes_kwargs), takes_kwargs(takes_kwargs),
source(std::move(source)), source(std::move(source)),
param_names(this->source->ast, this->source->getInternedStrings()), param_names(this->source->ast, this->source->getInternedStrings()),
always_use_version(NULL),
times_interpreted(0), times_interpreted(0),
internal_callable(NULL, NULL) { internal_callable(NULL, NULL) {
} }
...@@ -59,7 +58,6 @@ FunctionMetadata::FunctionMetadata(int num_args, bool takes_varargs, bool takes_ ...@@ -59,7 +58,6 @@ FunctionMetadata::FunctionMetadata(int num_args, bool takes_varargs, bool takes_
takes_kwargs(takes_kwargs), takes_kwargs(takes_kwargs),
source(nullptr), source(nullptr),
param_names(param_names), param_names(param_names),
always_use_version(NULL),
times_interpreted(0), times_interpreted(0),
internal_callable(NULL, NULL) { internal_callable(NULL, NULL) {
} }
...@@ -81,9 +79,12 @@ void FunctionMetadata::addVersion(CompiledFunction* compiled) { ...@@ -81,9 +79,12 @@ void FunctionMetadata::addVersion(CompiledFunction* compiled) {
if (compiled->entry_descriptor == NULL) { if (compiled->entry_descriptor == NULL) {
bool could_have_speculations = (source.get() != NULL); bool could_have_speculations = (source.get() != NULL);
if (!could_have_speculations && versions.size() == 0 && compiled->effort == EffortLevel::MAXIMAL if (!could_have_speculations && compiled->effort == EffortLevel::MAXIMAL && compiled->spec->accepts_all_inputs
&& compiled->spec->accepts_all_inputs && compiled->spec->boxed_return_value) && compiled->spec->boxed_return_value
always_use_version = compiled; && (versions.size() == 0 || (versions.size() == 1 && !always_use_version.empty()))) {
always_use_version.get(compiled->exception_style) = compiled;
} else
assert(always_use_version.empty());
assert(compiled->spec->arg_types.size() == numReceivedArgs()); assert(compiled->spec->arg_types.size() == numReceivedArgs());
versions.push_back(compiled); versions.push_back(compiled);
......
...@@ -648,7 +648,7 @@ void CompiledFunction::speculationFailed() { ...@@ -648,7 +648,7 @@ void CompiledFunction::speculationFailed() {
FunctionMetadata* md = this->md; FunctionMetadata* md = this->md;
assert(md); assert(md);
assert(this != md->always_use_version); assert(this != md->always_use_version.get(exception_style));
bool found = false; bool found = false;
for (int i = 0; i < md->versions.size(); i++) { for (int i = 0; i < md->versions.size(); i++) {
......
...@@ -95,19 +95,22 @@ public: ...@@ -95,19 +95,22 @@ public:
ExceptionSwitchable() : capi_val(), cxx_val() {} ExceptionSwitchable() : capi_val(), cxx_val() {}
ExceptionSwitchable(T capi_val, T cxx_val) : capi_val(std::move(capi_val)), cxx_val(std::move(cxx_val)) {} ExceptionSwitchable(T capi_val, T cxx_val) : capi_val(std::move(capi_val)), cxx_val(std::move(cxx_val)) {}
template <ExceptionStyle S> T get() { template <ExceptionStyle S> T& get() {
if (S == CAPI) if (S == CAPI)
return capi_val; return capi_val;
else else
return cxx_val; return cxx_val;
} }
T get(ExceptionStyle S) { T& get(ExceptionStyle S) {
if (S == CAPI) if (S == CAPI)
return capi_val; return capi_val;
else else
return cxx_val; return cxx_val;
} }
bool empty() const { return !capi_val && !cxx_val; }
void clear() { *this = ExceptionSwitchable<T>(); }
}; };
template <typename R, typename... Args> template <typename R, typename... Args>
...@@ -470,7 +473,8 @@ public: ...@@ -470,7 +473,8 @@ public:
FunctionList FunctionList
versions; // any compiled versions along with their type parameters; in order from most preferred to least versions; // any compiled versions along with their type parameters; in order from most preferred to least
CompiledFunction* always_use_version; // if this version is set, always use it (for unboxed cases) ExceptionSwitchable<CompiledFunction*>
always_use_version; // if this version is set, always use it (for unboxed cases)
std::unordered_map<const OSREntryDescriptor*, CompiledFunction*> osr_versions; std::unordered_map<const OSREntryDescriptor*, CompiledFunction*> osr_versions;
// Profiling counter: // Profiling counter:
......
...@@ -3959,12 +3959,20 @@ static inline RewriterVar* getArg(int idx, _CallRewriteArgsBase* rewrite_args) { ...@@ -3959,12 +3959,20 @@ static inline RewriterVar* getArg(int idx, _CallRewriteArgsBase* rewrite_args) {
} }
static StatCounter slowpath_pickversion("slowpath_pickversion"); static StatCounter slowpath_pickversion("slowpath_pickversion");
static CompiledFunction* pickVersion(FunctionMetadata* f, ExceptionStyle S, int num_output_args, Box* oarg1, Box* oarg2, template <ExceptionStyle S>
Box* oarg3, Box** oargs) { static CompiledFunction* pickVersion(FunctionMetadata* f, int num_output_args, Box* oarg1, Box* oarg2, Box* oarg3,
Box** oargs) {
LOCK_REGION(codegen_rwlock.asWrite()); LOCK_REGION(codegen_rwlock.asWrite());
if (f->always_use_version && f->always_use_version->exception_style == S) // if always_use_version is set use it even if the exception style does not match.
return f->always_use_version; // But prefer using the correct style if both are available
if (f->always_use_version.get(S))
return f->always_use_version.get(S);
ExceptionStyle other = S == CAPI ? CXX : CAPI;
if (f->always_use_version.get(other))
return f->always_use_version.get(other);
slowpath_pickversion.log(); slowpath_pickversion.log();
CompiledFunction* best_nonexcmatch = NULL; CompiledFunction* best_nonexcmatch = NULL;
...@@ -4845,7 +4853,7 @@ Box* callCLFunc(FunctionMetadata* md, CallRewriteArgs* rewrite_args, int num_out ...@@ -4845,7 +4853,7 @@ Box* callCLFunc(FunctionMetadata* md, CallRewriteArgs* rewrite_args, int num_out
rewrite_args = NULL; rewrite_args = NULL;
} }
CompiledFunction* chosen_cf = pickVersion(md, S, num_output_args, oarg1, oarg2, oarg3, oargs); CompiledFunction* chosen_cf = pickVersion<S>(md, num_output_args, oarg1, oarg2, oarg3, oargs);
if (!chosen_cf) { if (!chosen_cf) {
if (rewrite_args) { if (rewrite_args) {
......
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