@@ -88,6 +88,7 @@ dummy_func(
88
88
inst (RESUME , (-- )) {
89
89
if (cframe .use_tracing == 0 ) {
90
90
next_instr = _PyCode_Tier2Warmup (frame , next_instr );
91
+ DISPATCH ();
91
92
}
92
93
// GO_TO_INSTRUCTION(RESUME_QUICK);
93
94
assert (frame == cframe .current_frame );
@@ -3294,57 +3295,80 @@ dummy_func(
3294
3295
// Tier 2 instructions
3295
3296
// Type propagator assumes this doesn't affect type context
3296
3297
inst (BB_BRANCH , (unused /10 -- )) {
3297
- _Py_CODEUNIT * t2_nextinstr = NULL ;
3298
3298
_PyBBBranchCache * cache = (_PyBBBranchCache * )next_instr ;
3299
+ _PyTier2BBMetadata * meta = NULL ;
3299
3300
_Py_CODEUNIT * tier1_fallback = NULL ;
3300
3301
if (BB_TEST_IS_SUCCESSOR (frame )) {
3301
- // Rewrite self
3302
- _py_set_opcode (next_instr - 1 , BB_BRANCH_IF_FLAG_UNSET );
3303
3302
// Generate consequent.
3304
- t2_nextinstr = _PyTier2_GenerateNextBB (
3303
+ meta = _PyTier2_GenerateNextBB (
3305
3304
frame , cache -> bb_id_tagged , next_instr - 1 ,
3306
3305
0 , & tier1_fallback , frame -> bb_test );
3307
- if (t2_nextinstr == NULL ) {
3306
+ if (meta == NULL ) {
3308
3307
// Fall back to tier 1.
3309
3308
next_instr = tier1_fallback ;
3310
3309
DISPATCH ();
3311
3310
}
3311
+ // Rewrite self
3312
+ _py_set_opcode (next_instr - 1 , BB_BRANCH_IF_FLAG_UNSET );
3313
+ memcpy (cache -> consequent_trace , & meta -> machine_code , sizeof (uint64_t ));
3312
3314
}
3313
3315
else {
3314
- // Rewrite self
3315
- _py_set_opcode (next_instr - 1 , BB_BRANCH_IF_FLAG_SET );
3316
3316
// Generate alternative.
3317
- t2_nextinstr = _PyTier2_GenerateNextBB (
3317
+ meta = _PyTier2_GenerateNextBB (
3318
3318
frame , cache -> bb_id_tagged , next_instr - 1 ,
3319
3319
oparg , & tier1_fallback , frame -> bb_test );
3320
- if (t2_nextinstr == NULL ) {
3320
+ if (meta == NULL ) {
3321
3321
// Fall back to tier 1.
3322
- next_instr = tier1_fallback + oparg ;
3322
+ next_instr = tier1_fallback ;
3323
3323
DISPATCH ();
3324
3324
}
3325
+ // Rewrite self
3326
+ _py_set_opcode (next_instr - 1 , BB_BRANCH_IF_FLAG_SET );
3327
+ memcpy (cache -> alternative_trace , & meta -> machine_code , sizeof (uint64_t ));
3325
3328
}
3326
- Py_ssize_t forward_jump = t2_nextinstr - next_instr ;
3329
+ Py_ssize_t forward_jump = meta -> tier2_start - next_instr ;
3327
3330
assert ((uint16_t )forward_jump == forward_jump );
3328
3331
cache -> successor_jumpby = (uint16_t )forward_jump ;
3329
- next_instr = t2_nextinstr ;
3330
- DISPATCH ();
3332
+ next_instr = meta -> tier2_start ;
3333
+ // Could not generate machine code, fall back to tier 2 instructions.
3334
+ if (meta -> machine_code == NULL ) {
3335
+ DISPATCH ();
3336
+ }
3337
+ // The following code is partially adapted from Brandt Bucher's https://github.com/brandtbucher/cpython/blob/justin/Python/bytecodes.c#L2175
3338
+ _PyJITReturnCode status = ((_PyJITFunction )(meta -> machine_code ))(tstate , frame , stack_pointer , next_instr );
3339
+ frame = cframe .current_frame ;
3340
+ next_instr = frame -> prev_instr ;
3341
+ stack_pointer = _PyFrame_GetStackPointer (frame );
3342
+ switch (status ) {
3343
+ case _JUSTIN_RETURN_DEOPT :
3344
+ NEXTOPARG ();
3345
+ opcode = _PyOpcode_Deopt [opcode ];
3346
+ DISPATCH_GOTO ();
3347
+ case _JUSTIN_RETURN_OK :
3348
+ DISPATCH ();
3349
+ case _JUSTIN_RETURN_GOTO_ERROR :
3350
+ goto error ;
3351
+ }
3352
+ //Py_UNREACHABLE();
3331
3353
}
3332
3354
3333
3355
inst (BB_BRANCH_IF_FLAG_UNSET , (unused /10 -- )) {
3334
3356
if (!BB_TEST_IS_SUCCESSOR (frame )) {
3335
3357
_Py_CODEUNIT * curr = next_instr - 1 ;
3336
- _Py_CODEUNIT * t2_nextinstr = NULL ;
3358
+ _PyTier2BBMetadata * meta = NULL ;
3337
3359
_PyBBBranchCache * cache = (_PyBBBranchCache * )next_instr ;
3338
3360
_Py_CODEUNIT * tier1_fallback = NULL ;
3339
3361
3340
- t2_nextinstr = _PyTier2_GenerateNextBB (
3362
+ meta = _PyTier2_GenerateNextBB (
3341
3363
frame , cache -> bb_id_tagged , next_instr - 1 ,
3342
3364
oparg , & tier1_fallback , frame -> bb_test );
3343
- if (t2_nextinstr == NULL ) {
3365
+ if (meta == NULL ) {
3344
3366
// Fall back to tier 1.
3345
3367
next_instr = tier1_fallback ;
3346
3368
}
3347
- next_instr = t2_nextinstr ;
3369
+ else {
3370
+ next_instr = meta -> tier2_start ;
3371
+ }
3348
3372
3349
3373
// Rewrite self
3350
3374
_PyTier2_RewriteForwardJump (curr , next_instr );
@@ -3368,18 +3392,21 @@ dummy_func(
3368
3392
inst (BB_BRANCH_IF_FLAG_SET , (unused /10 -- )) {
3369
3393
if (BB_TEST_IS_SUCCESSOR (frame )) {
3370
3394
_Py_CODEUNIT * curr = next_instr - 1 ;
3395
+ _PyTier2BBMetadata * meta = NULL ;
3371
3396
_Py_CODEUNIT * t2_nextinstr = NULL ;
3372
3397
_PyBBBranchCache * cache = (_PyBBBranchCache * )next_instr ;
3373
3398
_Py_CODEUNIT * tier1_fallback = NULL ;
3374
- t2_nextinstr = _PyTier2_GenerateNextBB (
3399
+ meta = _PyTier2_GenerateNextBB (
3375
3400
frame , cache -> bb_id_tagged , next_instr - 1 ,
3376
3401
// v We generate from the tier1 consequent BB, so offset (oparg) is 0.
3377
3402
0 , & tier1_fallback , frame -> bb_test );
3378
- if (t2_nextinstr == NULL ) {
3403
+ if (meta == NULL ) {
3379
3404
// Fall back to tier 1.
3380
3405
next_instr = tier1_fallback ;
3381
3406
}
3382
- next_instr = t2_nextinstr ;
3407
+ else {
3408
+ next_instr = meta -> tier2_start ;
3409
+ }
3383
3410
3384
3411
// Rewrite self
3385
3412
_PyTier2_RewriteForwardJump (curr , next_instr );
0 commit comments