diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt index ae90beb..29d618a 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt @@ -3604,6 +3604,12 @@ class BytecodeCompiler( } SlotType.OBJ -> { if (objOp == null) return null + if (isExactNonNullSlotClassOrTemp(rhs.slot, ObjInt.type)) { + val right = allocSlot() + builder.emit(Opcode.UNBOX_INT_OBJ, rhs.slot, right) + builder.emit(intOp, out, right, out) + return CompiledValue(out, SlotType.INT) + } val leftObj = allocSlot() builder.emit(Opcode.BOX_OBJ, out, leftObj) updateSlotType(leftObj, SlotType.OBJ) @@ -3629,6 +3635,12 @@ class BytecodeCompiler( } SlotType.OBJ -> { if (objOp == null) return null + if (isExactNonNullSlotClassOrTemp(rhs.slot, ObjReal.type)) { + val right = allocSlot() + builder.emit(Opcode.UNBOX_REAL_OBJ, rhs.slot, right) + builder.emit(realOp, out, right, out) + return CompiledValue(out, SlotType.REAL) + } val leftObj = allocSlot() builder.emit(Opcode.BOX_OBJ, out, leftObj) updateSlotType(leftObj, SlotType.OBJ) diff --git a/notes/fast_ops_optimizations_plan.md b/notes/fast_ops_optimizations_plan.md index 05a7aa3..77454be 100644 --- a/notes/fast_ops_optimizations_plan.md +++ b/notes/fast_ops_optimizations_plan.md @@ -19,5 +19,6 @@ Candidates (not started) 5) String ops (done) - Mark GET_INDEX results as stable only for closed ObjString elements to enable fast compares. - MixedCompareBenchmarkTest: 247 ms -> 240 ms. -6) Box/unbox audit - - Identify remaining BOX_OBJ / OBJ_TO_* in inner loops and eliminate when safe. +6) Box/unbox audit (done) + - Unbox ObjInt/ObjReal in assign-op when target is INT/REAL to avoid boxing + obj ops. + - MixedCompareBenchmarkTest: 240 ms -> 234 ms.