@@ -654,10 +654,20 @@ fn gen_guard_block_param_proxy(jit: &JITState, asm: &mut Assembler, level: u32,
654654}
655655
656656fn gen_guard_not_frozen ( jit : & JITState , asm : & mut Assembler , recv : Opnd , state : & FrameState ) -> Opnd {
657- let ret = asm_ccall ! ( asm, rb_obj_frozen_p, recv) ;
658- asm_comment ! ( asm, "side-exit if rb_obj_frozen_p returns Qtrue" ) ;
659- asm. cmp ( ret, Qtrue . into ( ) ) ;
660- asm. je ( side_exit ( jit, state, GuardNotFrozen ) ) ;
657+ let side_exit = side_exit ( jit, state, GuardNotFrozen ) ;
658+ let recv = asm. load ( recv) ;
659+ // Side-exit if recv is false
660+ assert_eq ! ( Qfalse . as_i64( ) , 0 ) ;
661+ asm. test ( recv, recv) ;
662+ asm. jz ( side_exit. clone ( ) ) ;
663+ // Side-exit if recv is immediate
664+ asm. test ( recv, ( RUBY_IMMEDIATE_MASK as u64 ) . into ( ) ) ;
665+ asm. jnz ( side_exit. clone ( ) ) ;
666+ // It's a heap object, so check the frozen flag
667+ let flags = asm. load ( Opnd :: mem ( 64 , recv, RUBY_OFFSET_RBASIC_FLAGS ) ) ;
668+ asm. test ( flags, ( RUBY_FL_FREEZE as u64 ) . into ( ) ) ;
669+ // Side-exit if frozen
670+ asm. jnz ( side_exit. clone ( ) ) ;
661671 recv
662672}
663673
0 commit comments