diff --git a/crates/oxc_minifier/src/peephole/fold_constants.rs b/crates/oxc_minifier/src/peephole/fold_constants.rs index d07b21076f..8a88c22e54 100644 --- a/crates/oxc_minifier/src/peephole/fold_constants.rs +++ b/crates/oxc_minifier/src/peephole/fold_constants.rs @@ -143,22 +143,11 @@ impl<'a> PeepholeOptimizations { } return Some(logical_expr.left.take_in(ctx)); } else if !left.may_have_side_effects(ctx) { - let should_keep_indirect_access = - Self::should_keep_indirect_access(&logical_expr.right, ctx); - // (true && o.f) => (0, o.f) - if should_keep_indirect_access { - return Some(Expression::new_sequence_expression( - logical_expr.span, - [ - Expression::new_numeric_literal( - logical_expr.left.span(), - 0.0, - None, - NumberBase::Decimal, - ctx, - ), - logical_expr.right.take_in(ctx), - ], + // `(true && o.f)` => `(0, o.f)` + if Self::should_keep_indirect_access(&logical_expr.right, ctx) { + return Some(Self::preserve_indirect_access( + logical_expr.left.span(), + logical_expr.right.take_in(ctx), ctx, )); } @@ -214,27 +203,16 @@ impl<'a> PeepholeOptimizations { match left_val { ValueType::Null | ValueType::Undefined => { Some(if left.may_have_side_effects(ctx) { - // e.g. `(a(), null) ?? 1` => `(a(), null, 1)` + // `(a(), null) ?? 1` => `(a(), null, 1)` let expressions = [logical_expr.left.take_in(ctx), logical_expr.right.take_in(ctx)]; Expression::new_sequence_expression(logical_expr.span, expressions, ctx) } else { - let should_keep_indirect_access = - Self::should_keep_indirect_access(&logical_expr.right, ctx); - // (null ?? o.f) => (0, o.f) - if should_keep_indirect_access { - return Some(Expression::new_sequence_expression( - logical_expr.span, - [ - Expression::new_numeric_literal( - logical_expr.left.span(), - 0.0, - None, - NumberBase::Decimal, - ctx, - ), - logical_expr.right.take_in(ctx), - ], + // `(null ?? o.f)` => `(0, o.f)` + if Self::should_keep_indirect_access(&logical_expr.right, ctx) { + return Some(Self::preserve_indirect_access( + logical_expr.left.span(), + logical_expr.right.take_in(ctx), ctx, )); } @@ -247,22 +225,11 @@ impl<'a> PeepholeOptimizations { | ValueType::String | ValueType::Boolean | ValueType::Object => { - let should_keep_indirect_access = - Self::should_keep_indirect_access(&logical_expr.left, ctx); - // (o.f ?? something) => (0, o.f) - if should_keep_indirect_access { - return Some(Expression::new_sequence_expression( - logical_expr.span, - [ - Expression::new_numeric_literal( - logical_expr.right.span(), - 0.0, - None, - NumberBase::Decimal, - ctx, - ), - logical_expr.left.take_in(ctx), - ], + // `(o.f ?? something)` => `(0, o.f)` + if Self::should_keep_indirect_access(&logical_expr.left, ctx) { + return Some(Self::preserve_indirect_access( + logical_expr.right.span(), + logical_expr.left.take_in(ctx), ctx, )); } diff --git a/crates/oxc_minifier/src/peephole/remove_dead_code.rs b/crates/oxc_minifier/src/peephole/remove_dead_code.rs index ed6dbe0111..e12bbc6d71 100644 --- a/crates/oxc_minifier/src/peephole/remove_dead_code.rs +++ b/crates/oxc_minifier/src/peephole/remove_dead_code.rs @@ -428,44 +428,28 @@ impl<'a> PeepholeOptimizations { pub fn try_fold_conditional_expression(expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) { let Expression::ConditionalExpression(e) = expr else { return }; let Some(v) = e.test.evaluate_value_to_boolean(ctx) else { return }; - let new_expr = if e.test.may_have_side_effects(ctx) { - // "(a, true) ? b : c" => "a, b" - Expression::new_sequence_expression( - e.span, - [ - { - let mut test = e.test.take_in(ctx); - Self::remove_unused_expression(&mut test, ctx); - test - }, - if v { e.consequent.take_in(ctx) } else { e.alternate.take_in(ctx) }, - ], - ctx, - ) - } else { - let result_expr = if v { e.consequent.take_in(ctx) } else { e.alternate.take_in(ctx) }; - let should_keep_as_sequence_expr = Self::should_keep_indirect_access(&result_expr, ctx); - // "(1 ? a.b : 0)()" => "(0, a.b)()" - if should_keep_as_sequence_expr { - Expression::new_sequence_expression( - e.span, - [ - Expression::new_numeric_literal( - e.span, - 0.0, - None, - NumberBase::Decimal, - ctx, - ), - result_expr, - ], - ctx, - ) + + ctx.drop_expression(if v { &e.alternate } else { &e.consequent }); + ctx.replace_expression_with(expr, |e, ctx| { + let Expression::ConditionalExpression(e) = e else { + unreachable!(); + }; + let mut e = e.unbox(); + let result_expr = if v { e.consequent } else { e.alternate }; + + if Self::remove_unused_expression(&mut e.test, ctx) { + ctx.drop_expression(&e.test); + // `(1 ? a.b : 0)()` => `(0, a.b)()` + if Self::should_keep_indirect_access(&result_expr, ctx) { + Self::preserve_indirect_access(e.span, result_expr, ctx) + } else { + result_expr + } } else { - result_expr + // `(a, true) ? b : c` => `a, b` + Expression::new_sequence_expression(e.span, [e.test, result_expr], ctx) } - }; - ctx.replace_expression(expr, new_expr); + }); } pub fn remove_sequence_expression(expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) { @@ -720,7 +704,7 @@ impl<'a> PeepholeOptimizations { ctx: &TraverseCtx<'a>, ) -> Expression<'a> { Expression::new_sequence_expression( - span, + span.merge(expr.span()), [Expression::new_numeric_literal(span, 0.0, None, NumberBase::Decimal, ctx), expr], ctx, ) diff --git a/crates/oxc_minifier/src/peephole/substitute_alternate_syntax.rs b/crates/oxc_minifier/src/peephole/substitute_alternate_syntax.rs index 5ae9d53e28..daab273cea 100644 --- a/crates/oxc_minifier/src/peephole/substitute_alternate_syntax.rs +++ b/crates/oxc_minifier/src/peephole/substitute_alternate_syntax.rs @@ -1542,14 +1542,7 @@ impl<'a> PeepholeOptimizations { return; }; - let new_callee = Expression::new_sequence_expression( - span, - [ - Expression::new_numeric_literal(span, 0.0, None, NumberBase::Decimal, ctx), - arg_expr.take_in(ctx), - ], - ctx, - ); + let new_callee = Self::preserve_indirect_access(span, arg_expr.take_in(ctx), ctx); ctx.replace_expression(&mut expr.callee, new_callee); } diff --git a/tasks/track_memory_allocations/allocs_minifier.yaml b/tasks/track_memory_allocations/allocs_minifier.yaml index a541005820..ab178cb5d2 100644 --- a/tasks/track_memory_allocations/allocs_minifier.yaml +++ b/tasks/track_memory_allocations/allocs_minifier.yaml @@ -49,7 +49,7 @@ antd.js: sys deallocs: 860 sys alloc bytes: 29976375 # 29.98 MB sys peak growth: 19934749 # 19.93 MB - arena allocs: 187032 + arena allocs: 187025 arena reallocs: 63323 arena size: 43370040 # 43.37 MB @@ -71,6 +71,6 @@ kitchen-sink.tsx: sys deallocs: 1854 sys alloc bytes: 5304692 # 5.30 MB sys peak growth: 3707457 # 3.71 MB - arena allocs: 31944 + arena allocs: 31927 arena reallocs: 12185 arena size: 8688104 # 8.69 MB