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) { ...@@ -600,27 +600,17 @@ void BaselineCompiler::CallRuntime(Runtime::FunctionId function, Args... args) {
} }
// Returns into kInterpreterAccumulatorRegister // Returns into kInterpreterAccumulatorRegister
void BaselineCompiler::JumpIfToBoolean(bool do_jump_if_true, Register reg, void BaselineCompiler::JumpIfToBoolean(bool do_jump_if_true, Label* label,
Label* label, Label::Distance distance) { Label::Distance distance) {
Label end; CallBuiltin<Builtins::kToBooleanForBaselineJump>(
Label::Distance end_distance = Label::kNear; kInterpreterAccumulatorRegister);
// ToBooleanForBaselineJump returns the ToBoolean value into return reg 1, and
Label* true_label = do_jump_if_true ? label : &end; // the original value into kInterpreterAccumulatorRegister, so we don't have
Label::Distance true_distance = do_jump_if_true ? distance : end_distance; // to worry about it getting clobbered.
Label* false_label = do_jump_if_true ? &end : label; STATIC_ASSERT(kReturnRegister0 == kInterpreterAccumulatorRegister);
Label::Distance false_distance = do_jump_if_true ? end_distance : distance; __ Cmp(kReturnRegister1, Smi::FromInt(0));
__ JumpIf(do_jump_if_true ? Condition::kNotEqual : Condition::kEqual, label,
BaselineAssembler::ScratchRegisterScope scratch_scope(&basm_); distance);
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::VisitLdaZero() { void BaselineCompiler::VisitLdaZero() {
...@@ -1090,9 +1080,7 @@ void BaselineCompiler::VisitBitwiseNot() { ...@@ -1090,9 +1080,7 @@ void BaselineCompiler::VisitBitwiseNot() {
void BaselineCompiler::VisitToBooleanLogicalNot() { void BaselineCompiler::VisitToBooleanLogicalNot() {
SelectBooleanConstant(kInterpreterAccumulatorRegister, SelectBooleanConstant(kInterpreterAccumulatorRegister,
[&](Label* if_true, Label::Distance distance) { [&](Label* if_true, Label::Distance distance) {
JumpIfToBoolean(false, JumpIfToBoolean(false, if_true, distance);
kInterpreterAccumulatorRegister,
if_true, distance);
}); });
} }
...@@ -1997,16 +1985,14 @@ void BaselineCompiler::VisitJumpIfToBooleanFalseConstant() { ...@@ -1997,16 +1985,14 @@ void BaselineCompiler::VisitJumpIfToBooleanFalseConstant() {
void BaselineCompiler::VisitJumpIfToBooleanTrue() { void BaselineCompiler::VisitJumpIfToBooleanTrue() {
Label dont_jump; Label dont_jump;
JumpIfToBoolean(false, kInterpreterAccumulatorRegister, &dont_jump, JumpIfToBoolean(false, &dont_jump, Label::kNear);
Label::kNear);
UpdateInterruptBudgetAndDoInterpreterJump(); UpdateInterruptBudgetAndDoInterpreterJump();
__ Bind(&dont_jump); __ Bind(&dont_jump);
} }
void BaselineCompiler::VisitJumpIfToBooleanFalse() { void BaselineCompiler::VisitJumpIfToBooleanFalse() {
Label dont_jump; Label dont_jump;
JumpIfToBoolean(true, kInterpreterAccumulatorRegister, &dont_jump, JumpIfToBoolean(true, &dont_jump, Label::kNear);
Label::kNear);
UpdateInterruptBudgetAndDoInterpreterJump(); UpdateInterruptBudgetAndDoInterpreterJump();
__ Bind(&dont_jump); __ Bind(&dont_jump);
} }
......
...@@ -123,8 +123,8 @@ class BaselineCompiler { ...@@ -123,8 +123,8 @@ class BaselineCompiler {
void SelectBooleanConstant( void SelectBooleanConstant(
Register output, std::function<void(Label*, Label::Distance)> jump_func); Register output, std::function<void(Label*, Label::Distance)> jump_func);
// Returns ToBoolean result into kInterpreterAccumulatorRegister. // Jumps based on calling ToBoolean on kInterpreterAccumulatorRegister.
void JumpIfToBoolean(bool do_jump_if_true, Register reg, Label* label, void JumpIfToBoolean(bool do_jump_if_true, Label* label,
Label::Distance distance = Label::kFar); Label::Distance distance = Label::kFar);
// Call helpers. // Call helpers.
......
...@@ -50,6 +50,25 @@ builtin ToBoolean(input: JSAny): Boolean { ...@@ -50,6 +50,25 @@ builtin ToBoolean(input: JSAny): Boolean {
return FalseConstant(); 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): transitioning builtin ToLength(implicit context: Context)(input: JSAny):
Number { Number {
// We might need to loop once for ToNumber conversion. // 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