@@ -137,16 +137,6 @@ bool isPreloaded(BorrowedRef<PyFunctionObject> func) {
137137 return hir::preloaderManager ().find (func) != nullptr ;
138138}
139139
140- _PyJIT_Result tryCompile (BorrowedRef<PyFunctionObject> func) {
141- _PyJIT_Result result = compileFunction (func);
142- // Reset the function back to the interpreter if there was any non-retryable
143- // failure.
144- if (result != PYJIT_RESULT_OK && result != PYJIT_RESULT_RETRY ) {
145- func->vectorcall = getInterpretedVectorcall (func);
146- }
147- return result;
148- }
149-
150140void incrementShadowcodeCall ([[maybe_unused]] BorrowedRef<PyCodeObject> code) {
151141#if SHADOWCODE_SUPPORTED
152142 // The interpreter will only increment up to the shadowcode threshold
@@ -172,46 +162,35 @@ PyObject* forcedJitVectorcall(
172162 BorrowedRef<PyFunctionObject> func{func_obj};
173163 BorrowedRef<PyCodeObject> code{func->func_code };
174164
175- _PyJIT_Result result = tryCompile (func);
165+ _PyJIT_Result result = compileFunction (func);
176166 if (result == PYJIT_RESULT_OK ) {
177167 JIT_DCHECK (
178168 isJitCompiled (func),
179169 " JIT succeeded for function {} but it is not recognized as compiled" ,
180170 funcFullname (func));
181- } else {
182- JIT_DCHECK (
183- !isJitCompiled (func),
184- " JIT failed (error: {}) for function {} but it seems to have been "
185- " compiled" ,
186- result,
187- funcFullname (func));
171+ return func->vectorcall (func_obj, stack, nargsf, kwnames);
188172 }
189173
190- switch (result) {
191- case PYJIT_RESULT_OK :
192- return func->vectorcall (func_obj, stack, nargsf, kwnames);
193- case PYJIT_RESULT_RETRY : {
194- incrementShadowcodeCall (code);
195- auto entry = getInterpretedVectorcall (func);
196- return entry (func_obj, stack, nargsf, kwnames);
197- }
198- case PYJIT_RESULT_CANNOT_SPECIALIZE :
199- case PYJIT_RESULT_NOT_ON_JITLIST :
200- case PYJIT_NOT_INITIALIZED :
201- case PYJIT_RESULT_NO_PRELOADER :
202- case PYJIT_RESULT_UNKNOWN_ERROR :
203- case PYJIT_OVER_MAX_CODE_SIZE :
204- return func->vectorcall (func_obj, stack, nargsf, kwnames);
205- case PYJIT_RESULT_PYTHON_EXCEPTION :
206- return nullptr ;
207- default :
208- break ;
174+ auto interp_entry = getInterpretedVectorcall (func);
175+
176+ // Python errors shouldn't happen during compilation, but if they do, bubble
177+ // them up without calling the function.
178+ if (result == PYJIT_RESULT_PYTHON_EXCEPTION ) {
179+ func->vectorcall = interp_entry;
180+ return nullptr ;
209181 }
210182
211- JIT_ABORT (
212- " Unrecognized JIT result code {} for function {}" ,
213- static_cast <int >(result),
214- funcFullname (func));
183+ // Reset the function's entrypoint if it doesn't seem like there's a chance
184+ // compilation will work "soon".
185+ if (result != PYJIT_RESULT_ALREADY_SCHEDULED &&
186+ result != PYJIT_RESULT_PAUSED ) {
187+ func->vectorcall = interp_entry;
188+ }
189+
190+ // There's been some kind of compilation error, explicitly call the
191+ // interpreted entrypoint instead.
192+ incrementShadowcodeCall (code);
193+ return interp_entry (func_obj, stack, nargsf, kwnames);
215194}
216195
217196// Python function entry point when the JIT is enabled.
@@ -997,7 +976,7 @@ void compile_worker_thread() {
997976 while (BorrowedRef<> unit = getThreadedCompileContext ().nextUnit ()) {
998977 attempts++;
999978 _PyJIT_Result res = tryCompilePreloaded (unit);
1000- if (res == PYJIT_RESULT_RETRY ) {
979+ if (res == PYJIT_RESULT_ALREADY_SCHEDULED ) {
1001980 retries++;
1002981 getThreadedCompileContext ().retryUnit (unit);
1003982 }
@@ -1592,23 +1571,30 @@ PyObject* force_compile(PyObject* /* self */, PyObject* arg) {
15921571 if (func == nullptr ) {
15931572 return nullptr ;
15941573 }
1595-
15961574 if (!isJitUsable () || isJitCompiled (func)) {
15971575 Py_RETURN_FALSE;
15981576 }
15991577
1600- switch (compileFunction (func)) {
1578+ _PyJIT_Result result = compileFunction (func);
1579+ switch (result) {
16011580 case PYJIT_RESULT_OK :
16021581 Py_RETURN_TRUE;
1582+ case PYJIT_RESULT_ALREADY_SCHEDULED :
1583+ // Strange case, the function is being compiled by a different thread.
1584+ // Shouldn't happen, but don't die if it does.
1585+ Py_RETURN_FALSE;
1586+ case PYJIT_RESULT_PAUSED :
1587+ PyErr_SetString (
1588+ PyExc_RuntimeError,
1589+ " Compilation failed because the JIT was paused, but that shouldn't "
1590+ " be possible as this case was already checked" );
1591+ return nullptr ;
16031592 case PYJIT_RESULT_CANNOT_SPECIALIZE :
16041593 PyErr_SetString (PyExc_RuntimeError, " PYJIT_RESULT_CANNOT_SPECIALIZE" );
16051594 return nullptr ;
16061595 case PYJIT_RESULT_NOT_ON_JITLIST :
16071596 PyErr_SetString (PyExc_RuntimeError, " PYJIT_RESULT_NOT_ON_JITLIST" );
16081597 return nullptr ;
1609- case PYJIT_RESULT_RETRY :
1610- PyErr_SetString (PyExc_RuntimeError, " PYJIT_RESULT_RETRY" );
1611- return nullptr ;
16121598 case PYJIT_RESULT_UNKNOWN_ERROR :
16131599 PyErr_SetString (PyExc_RuntimeError, " PYJIT_RESULT_UNKNOWN_ERROR" );
16141600 return nullptr ;
@@ -1624,7 +1610,10 @@ PyObject* force_compile(PyObject* /* self */, PyObject* arg) {
16241610 case PYJIT_RESULT_PYTHON_EXCEPTION :
16251611 return nullptr ;
16261612 }
1627- PyErr_SetString (PyExc_RuntimeError, " Unhandled compilation result" );
1613+ PyErr_Format (
1614+ PyExc_RuntimeError,
1615+ " Unhandled compilation result: %d" ,
1616+ static_cast <int >(result));
16281617 return nullptr ;
16291618}
16301619
@@ -3516,7 +3505,7 @@ _PyJIT_Result compileFunction(BorrowedRef<PyFunctionObject> func) {
35163505 return PYJIT_NOT_INITIALIZED ;
35173506 }
35183507 if (isJitPaused ()) {
3519- return PYJIT_RESULT_RETRY ;
3508+ return PYJIT_RESULT_PAUSED ;
35203509 }
35213510 if (!isJitUsable ()) {
35223511 return PYJIT_RESULT_UNKNOWN_ERROR ;
@@ -3724,7 +3713,7 @@ Context::CompilationResult compilePreloaderImpl(
37243713 return {compiled, PYJIT_RESULT_OK };
37253714 }
37263715 if (!jit_ctx->addActiveCompile (key)) {
3727- return {nullptr , PYJIT_RESULT_RETRY };
3716+ return {nullptr , PYJIT_RESULT_ALREADY_SCHEDULED };
37283717 }
37293718 }
37303719
0 commit comments