mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-01 21:59:07 +00:00
LibJS/Bytecode: Round constant operands of bitwise binary expressions
This helps some of the Cloudflare Turnstile stuff run faster, since they are deliberately screwing with JS engines by asking us to do a bunch of bitwise operations on e.g 65535.56 By rounding such values in bytecode generation, the interpreter can stay on the happy path while executing, and finish quite a bit faster.
This commit is contained in:
parent
ca8dc8f61f
commit
448f837d38
Notes:
sideshowbarker
2024-07-18 02:47:59 +09:00
Author: https://github.com/awesomekling
Commit: 448f837d38
Pull-request: https://github.com/SerenityOS/serenity/pull/24276
Reviewed-by: https://github.com/Hendiadyoin1
Reviewed-by: https://github.com/shannonbooth
1 changed files with 52 additions and 2 deletions
|
@ -90,9 +90,59 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> BinaryExpression::gener
|
|||
return dst;
|
||||
}
|
||||
|
||||
auto lhs = TRY(m_lhs->generate_bytecode(generator)).value();
|
||||
auto rhs = TRY(m_rhs->generate_bytecode(generator)).value();
|
||||
// OPTIMIZATION: If LHS and/or RHS are numeric literals, we make sure they are converted to i32/u32
|
||||
// as appropriate, to avoid having to perform these conversions at runtime.
|
||||
|
||||
auto get_left_side = [&](Expression const& side) -> CodeGenerationErrorOr<Optional<ScopedOperand>> {
|
||||
switch (m_op) {
|
||||
case BinaryOp::BitwiseAnd:
|
||||
case BinaryOp::BitwiseOr:
|
||||
case BinaryOp::BitwiseXor:
|
||||
case BinaryOp::LeftShift:
|
||||
case BinaryOp::RightShift:
|
||||
case BinaryOp::UnsignedRightShift:
|
||||
// LHS will always be converted to i32 for these ops.
|
||||
if (side.is_numeric_literal()) {
|
||||
auto value = MUST(static_cast<NumericLiteral const&>(side).value().to_i32(generator.vm()));
|
||||
return generator.add_constant(Value(value));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return side.generate_bytecode(generator);
|
||||
};
|
||||
|
||||
auto get_right_side = [&](Expression const& side) -> CodeGenerationErrorOr<Optional<ScopedOperand>> {
|
||||
switch (m_op) {
|
||||
case BinaryOp::BitwiseAnd:
|
||||
case BinaryOp::BitwiseOr:
|
||||
case BinaryOp::BitwiseXor:
|
||||
// RHS will always be converted to i32 for these ops.
|
||||
if (side.is_numeric_literal()) {
|
||||
auto value = MUST(static_cast<NumericLiteral const&>(side).value().to_i32(generator.vm()));
|
||||
return generator.add_constant(Value(value));
|
||||
}
|
||||
break;
|
||||
case BinaryOp::LeftShift:
|
||||
case BinaryOp::RightShift:
|
||||
case BinaryOp::UnsignedRightShift:
|
||||
// RHS will always be converted to u32 for these ops.
|
||||
if (side.is_numeric_literal()) {
|
||||
auto value = MUST(static_cast<NumericLiteral const&>(side).value().to_u32(generator.vm()));
|
||||
return generator.add_constant(Value(value));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return side.generate_bytecode(generator);
|
||||
};
|
||||
|
||||
auto lhs = TRY(get_left_side(*m_lhs)).value();
|
||||
auto rhs = TRY(get_right_side(*m_rhs)).value();
|
||||
auto dst = choose_dst(generator, preferred_dst);
|
||||
switch (m_op) {
|
||||
case BinaryOp::Addition:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue