Commit 486925b4 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[sparkplug] Add custom builtin for ToBoolean

Add a special builtin performing a ToBoolean operation for jumps in
baseline code, which

   a) returns the original value as the first return value, to avoid
      needing to save it in the caller, and
   b) returns the true/false value as a Smi, to make the baseline-side
      comparison a cheap comparison against zero.

This reduces JumpIfToBoolean (on x64) from ~40 to ~30 bytes.

Bug: v8:11420
Change-Id: Idee51405b1e450cdd11ccb45ed82ddbc9119ae74
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2854654
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Patrick Thier <pthier@chromium.org>
Reviewed-by: 's avatarPatrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74239}
parent d057c823
......@@ -600,27 +600,17 @@ void BaselineCompiler::CallRuntime(Runtime::FunctionId function, Args... args) {
}
// Returns into kInterpreterAccumulatorRegister
void BaselineCompiler::JumpIfToBoolean(bool do_jump_if_true, Register reg,
Label* label, Label::Distance distance) {
Label end;
Label::Distance end_distance = Label::kNear;
Label* true_label = do_jump_if_true ? label : &end;
Label::Distance true_distance = do_jump_if_true ? distance : end_distance;
Label* false_label = do_jump_if_true ? &end : label;
Label::Distance false_distance = do_jump_if_true ? end_distance : distance;
BaselineAssembler::ScratchRegisterScope scratch_scope(&basm_);
Register to_boolean = scratch_scope.AcquireScratch();
{
SaveAccumulatorScope accumulator_scope(&basm_);
CallBuiltin<Builtins::kToBoolean>(reg);
__ Move(to_boolean, kInterpreterAccumulatorRegister);
}
__ JumpIfRoot(to_boolean, RootIndex::kTrueValue, true_label, true_distance);
if (false_label != &end) __ Jump(false_label, false_distance);
__ Bind(&end);
void BaselineCompiler::JumpIfToBoolean(bool do_jump_if_true, Label* label,
Label::Distance distance) {
CallBuiltin<Builtins::kToBooleanForBaselineJump>(
kInterpreterAccumulatorRegister);
// ToBooleanForBaselineJump returns the ToBoolean value into return reg 1, and
// the original value into kInterpreterAccumulatorRegister, so we don't have
// to worry about it getting clobbered.
STATIC_ASSERT(kReturnRegister0 == kInterpreterAccumulatorRegister);
__ Cmp(kReturnRegister1, Smi::FromInt(0));
__ JumpIf(do_jump_if_true ? Condition::kNotEqual : Condition::kEqual, label,
distance);
}
void BaselineCompiler::VisitLdaZero() {
......@@ -1090,9 +1080,7 @@ void BaselineCompiler::VisitBitwiseNot() {
void BaselineCompiler::VisitToBooleanLogicalNot() {
SelectBooleanConstant(kInterpreterAccumulatorRegister,
[&](Label* if_true, Label::Distance distance) {
JumpIfToBoolean(false,
kInterpreterAccumulatorRegister,
if_true, distance);
JumpIfToBoolean(false, if_true, distance);
});
}
......@@ -1997,16 +1985,14 @@ void BaselineCompiler::VisitJumpIfToBooleanFalseConstant() {
void BaselineCompiler::VisitJumpIfToBooleanTrue() {
Label dont_jump;
JumpIfToBoolean(false, kInterpreterAccumulatorRegister, &dont_jump,
Label::kNear);
JumpIfToBoolean(false, &dont_jump, Label::kNear);
UpdateInterruptBudgetAndDoInterpreterJump();
__ Bind(&dont_jump);
}
void BaselineCompiler::VisitJumpIfToBooleanFalse() {
Label dont_jump;
JumpIfToBoolean(true, kInterpreterAccumulatorRegister, &dont_jump,
Label::kNear);
JumpIfToBoolean(true, &dont_jump, Label::kNear);
UpdateInterruptBudgetAndDoInterpreterJump();
__ Bind(&dont_jump);
}
......
......@@ -123,8 +123,8 @@ class BaselineCompiler {
void SelectBooleanConstant(
Register output, std::function<void(Label*, Label::Distance)> jump_func);
// Returns ToBoolean result into kInterpreterAccumulatorRegister.
void JumpIfToBoolean(bool do_jump_if_true, Register reg, Label* label,
// Jumps based on calling ToBoolean on kInterpreterAccumulatorRegister.
void JumpIfToBoolean(bool do_jump_if_true, Label* label,
Label::Distance distance = Label::kFar);
// Call helpers.
......
......@@ -50,6 +50,25 @@ builtin ToBoolean(input: JSAny): Boolean {
return FalseConstant();
}
struct ToBooleanForBaselineJumpResult {
value: JSAny;
is_to_boolean: Smi;
}
// ToBoolean for baseline code jumps, which
// a) returns the original value as the first return value, to avoid needing
// to save it in the caller, and
// b) returns the true/false value as a Smi, to make the baseline-side
// comparison cheaper.
builtin ToBooleanForBaselineJump(input: JSAny): ToBooleanForBaselineJumpResult {
try {
BranchIfToBooleanIsTrue(input) otherwise IsTrue, IsFalse;
} label IsTrue {
return ToBooleanForBaselineJumpResult{value: input, is_to_boolean: 1};
} label IsFalse {
return ToBooleanForBaselineJumpResult{value: input, is_to_boolean: 0};
}
}
transitioning builtin ToLength(implicit context: Context)(input: JSAny):
Number {
// We might need to loop once for ToNumber conversion.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment