summaryrefslogtreecommitdiff
path: root/deps/v8/src/interpreter/interpreter-generator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/interpreter/interpreter-generator.cc')
-rw-r--r--deps/v8/src/interpreter/interpreter-generator.cc685
1 files changed, 222 insertions, 463 deletions
diff --git a/deps/v8/src/interpreter/interpreter-generator.cc b/deps/v8/src/interpreter/interpreter-generator.cc
index 2a8f3c8810..b02e024d65 100644
--- a/deps/v8/src/interpreter/interpreter-generator.cc
+++ b/deps/v8/src/interpreter/interpreter-generator.cc
@@ -179,7 +179,7 @@ class InterpreterLoadGlobalAssembler : public InterpreterAssembler {
feedback_vector, feedback_slot, &exit_point, &try_handler, &miss,
CodeStubAssembler::INTPTR_PARAMETERS);
- Bind(&done);
+ BIND(&done);
SetAccumulator(var_result.value());
Dispatch();
}
@@ -190,7 +190,7 @@ class InterpreterLoadGlobalAssembler : public InterpreterAssembler {
Variable var_result(this, MachineRepresentation::kTagged);
ExitPoint exit_point(this, &done, &var_result);
- Bind(&try_handler);
+ BIND(&try_handler);
{
Node* context = GetContext();
Node* smi_slot = SmiTag(feedback_slot);
@@ -203,7 +203,7 @@ class InterpreterLoadGlobalAssembler : public InterpreterAssembler {
&exit_point, &miss);
}
- Bind(&miss);
+ BIND(&miss);
{
Node* context = GetContext();
Node* smi_slot = SmiTag(feedback_slot);
@@ -215,7 +215,7 @@ class InterpreterLoadGlobalAssembler : public InterpreterAssembler {
accessor_asm.LoadGlobalIC_MissCase(&params, &exit_point);
}
- Bind(&done);
+ BIND(&done);
{
SetAccumulator(var_result.value());
Dispatch();
@@ -414,7 +414,7 @@ class InterpreterLookupContextSlotAssembler : public InterpreterAssembler {
}
// Slow path when we have to call out to the runtime.
- Bind(&slowpath);
+ BIND(&slowpath);
{
Node* name = LoadConstantPoolEntry(name_index);
Node* result = CallRuntime(function_id, context, name);
@@ -470,7 +470,7 @@ class InterpreterLookupGlobalAssembler : public InterpreterLoadGlobalAssembler {
}
// Slow path when we have to call out to the runtime
- Bind(&slowpath);
+ BIND(&slowpath);
{
Node* name_index = BytecodeOperandIdx(0);
Node* name = LoadConstantPoolEntry(name_index);
@@ -557,7 +557,7 @@ IGNITION_HANDLER(LdaNamedProperty, InterpreterAssembler) {
AccessorAssembler accessor_asm(state());
accessor_asm.LoadIC_BytecodeHandler(&params, &exit_point);
- Bind(&done);
+ BIND(&done);
{
SetAccumulator(var_result.value());
Dispatch();
@@ -735,7 +735,7 @@ IGNITION_HANDLER(LdaModuleVariable, InterpreterAssembler) {
Branch(IntPtrGreaterThan(cell_index, IntPtrConstant(0)), &if_export,
&if_import);
- Bind(&if_export);
+ BIND(&if_export);
{
Node* regular_exports =
LoadObjectField(module, Module::kRegularExportsOffset);
@@ -746,7 +746,7 @@ IGNITION_HANDLER(LdaModuleVariable, InterpreterAssembler) {
Goto(&end);
}
- Bind(&if_import);
+ BIND(&if_import);
{
Node* regular_imports =
LoadObjectField(module, Module::kRegularImportsOffset);
@@ -757,7 +757,7 @@ IGNITION_HANDLER(LdaModuleVariable, InterpreterAssembler) {
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
Dispatch();
}
@@ -777,7 +777,7 @@ IGNITION_HANDLER(StaModuleVariable, InterpreterAssembler) {
Branch(IntPtrGreaterThan(cell_index, IntPtrConstant(0)), &if_export,
&if_import);
- Bind(&if_export);
+ BIND(&if_export);
{
Node* regular_exports =
LoadObjectField(module, Module::kRegularExportsOffset);
@@ -788,14 +788,14 @@ IGNITION_HANDLER(StaModuleVariable, InterpreterAssembler) {
Goto(&end);
}
- Bind(&if_import);
+ BIND(&if_import);
{
// Not supported (probably never).
Abort(kUnsupportedModuleOperation);
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
Dispatch();
}
@@ -899,7 +899,7 @@ IGNITION_HANDLER(AddSmi, InterpreterAssembler) {
// {right} is known to be a Smi.
// Check if the {left} is a Smi take the fast path.
Branch(TaggedIsSmi(left), &fastpath, &slowpath);
- Bind(&fastpath);
+ BIND(&fastpath);
{
// Try fast Smi addition first.
Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(left),
@@ -909,7 +909,7 @@ IGNITION_HANDLER(AddSmi, InterpreterAssembler) {
// Check if the Smi additon overflowed.
Label if_notoverflow(this);
Branch(overflow, &slowpath, &if_notoverflow);
- Bind(&if_notoverflow);
+ BIND(&if_notoverflow);
{
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kSignedSmall),
feedback_vector, slot_index);
@@ -917,7 +917,7 @@ IGNITION_HANDLER(AddSmi, InterpreterAssembler) {
Goto(&end);
}
}
- Bind(&slowpath);
+ BIND(&slowpath);
{
Node* context = GetContext();
// TODO(ishell): pass slot as word-size value.
@@ -926,7 +926,7 @@ IGNITION_HANDLER(AddSmi, InterpreterAssembler) {
feedback_vector));
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
{
SetAccumulator(var_result.value());
Dispatch();
@@ -948,7 +948,7 @@ IGNITION_HANDLER(SubSmi, InterpreterAssembler) {
// {right} is known to be a Smi.
// Check if the {left} is a Smi take the fast path.
Branch(TaggedIsSmi(left), &fastpath, &slowpath);
- Bind(&fastpath);
+ BIND(&fastpath);
{
// Try fast Smi subtraction first.
Node* pair = IntPtrSubWithOverflow(BitcastTaggedToWord(left),
@@ -958,7 +958,7 @@ IGNITION_HANDLER(SubSmi, InterpreterAssembler) {
// Check if the Smi subtraction overflowed.
Label if_notoverflow(this);
Branch(overflow, &slowpath, &if_notoverflow);
- Bind(&if_notoverflow);
+ BIND(&if_notoverflow);
{
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kSignedSmall),
feedback_vector, slot_index);
@@ -966,7 +966,7 @@ IGNITION_HANDLER(SubSmi, InterpreterAssembler) {
Goto(&end);
}
}
- Bind(&slowpath);
+ BIND(&slowpath);
{
Node* context = GetContext();
// TODO(ishell): pass slot as word-size value.
@@ -975,7 +975,7 @@ IGNITION_HANDLER(SubSmi, InterpreterAssembler) {
feedback_vector));
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
{
SetAccumulator(var_result.value());
Dispatch();
@@ -997,7 +997,7 @@ IGNITION_HANDLER(MulSmi, InterpreterAssembler) {
// {right} is known to be a Smi.
// Check if the {left} is a Smi take the fast path.
Branch(TaggedIsSmi(left), &fastpath, &slowpath);
- Bind(&fastpath);
+ BIND(&fastpath);
{
// Both {lhs} and {rhs} are Smis. The result is not necessarily a smi,
// in case of overflow.
@@ -1008,7 +1008,7 @@ IGNITION_HANDLER(MulSmi, InterpreterAssembler) {
UpdateFeedback(feedback, feedback_vector, slot_index);
Goto(&end);
}
- Bind(&slowpath);
+ BIND(&slowpath);
{
Node* context = GetContext();
// TODO(ishell): pass slot as word-size value.
@@ -1018,7 +1018,7 @@ IGNITION_HANDLER(MulSmi, InterpreterAssembler) {
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
{
SetAccumulator(var_result.value());
Dispatch();
@@ -1040,14 +1040,14 @@ IGNITION_HANDLER(DivSmi, InterpreterAssembler) {
// {right} is known to be a Smi.
// Check if the {left} is a Smi take the fast path.
Branch(TaggedIsSmi(left), &fastpath, &slowpath);
- Bind(&fastpath);
+ BIND(&fastpath);
{
var_result.Bind(TrySmiDiv(left, right, &slowpath));
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kSignedSmall),
feedback_vector, slot_index);
Goto(&end);
}
- Bind(&slowpath);
+ BIND(&slowpath);
{
Node* context = GetContext();
// TODO(ishell): pass slot as word-size value.
@@ -1057,7 +1057,7 @@ IGNITION_HANDLER(DivSmi, InterpreterAssembler) {
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
{
SetAccumulator(var_result.value());
Dispatch();
@@ -1079,7 +1079,7 @@ IGNITION_HANDLER(ModSmi, InterpreterAssembler) {
// {right} is known to be a Smi.
// Check if the {left} is a Smi take the fast path.
Branch(TaggedIsSmi(left), &fastpath, &slowpath);
- Bind(&fastpath);
+ BIND(&fastpath);
{
// Both {lhs} and {rhs} are Smis. The result is not necessarily a smi.
var_result.Bind(SmiMod(left, right));
@@ -1089,7 +1089,7 @@ IGNITION_HANDLER(ModSmi, InterpreterAssembler) {
UpdateFeedback(feedback, feedback_vector, slot_index);
Goto(&end);
}
- Bind(&slowpath);
+ BIND(&slowpath);
{
Node* context = GetContext();
// TODO(ishell): pass slot as word-size value.
@@ -1099,7 +1099,7 @@ IGNITION_HANDLER(ModSmi, InterpreterAssembler) {
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
{
SetAccumulator(var_result.value());
Dispatch();
@@ -1172,7 +1172,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
AbortIfWordNotEqual(result_map, HeapNumberMapConstant(),
kExpectedHeapNumber);
Goto(&ok);
- Bind(&ok);
+ BIND(&ok);
}
Node* input_feedback =
@@ -1422,21 +1422,21 @@ IGNITION_HANDLER(ToNumber, InterpreterAssembler) {
Node* object_map = LoadMap(object);
Branch(IsHeapNumberMap(object_map), &if_objectisnumber, &if_objectisother);
- Bind(&if_objectissmi);
+ BIND(&if_objectissmi);
{
var_result.Bind(object);
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall));
Goto(&if_done);
}
- Bind(&if_objectisnumber);
+ BIND(&if_objectisnumber);
{
var_result.Bind(object);
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber));
Goto(&if_done);
}
- Bind(&if_objectisother);
+ BIND(&if_objectisother);
{
// Convert the {object} to a Number.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
@@ -1445,7 +1445,7 @@ IGNITION_HANDLER(ToNumber, InterpreterAssembler) {
Goto(&if_done);
}
- Bind(&if_done);
+ BIND(&if_done);
StoreRegister(var_result.value(), BytecodeOperandReg(0));
// Record the type feedback collected for {object}.
@@ -1495,14 +1495,14 @@ IGNITION_HANDLER(Inc, InterpreterAssembler) {
value_var.Bind(value);
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNone));
Goto(&start);
- Bind(&start);
+ BIND(&start);
{
value = value_var.value();
Label if_issmi(this), if_isnotsmi(this);
Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
- Bind(&if_issmi);
+ BIND(&if_issmi);
{
// Try fast Smi addition first.
Node* one = SmiConstant(Smi::FromInt(1));
@@ -1514,35 +1514,35 @@ IGNITION_HANDLER(Inc, InterpreterAssembler) {
Label if_overflow(this), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
- Bind(&if_notoverflow);
+ BIND(&if_notoverflow);
var_type_feedback.Bind(
SmiOr(var_type_feedback.value(),
SmiConstant(BinaryOperationFeedback::kSignedSmall)));
result_var.Bind(BitcastWordToTaggedSigned(Projection(0, pair)));
Goto(&end);
- Bind(&if_overflow);
+ BIND(&if_overflow);
{
var_finc_value.Bind(SmiToFloat64(value));
Goto(&do_finc);
}
}
- Bind(&if_isnotsmi);
+ BIND(&if_isnotsmi);
{
// Check if the value is a HeapNumber.
Label if_valueisnumber(this), if_valuenotnumber(this, Label::kDeferred);
Node* value_map = LoadMap(value);
Branch(IsHeapNumberMap(value_map), &if_valueisnumber, &if_valuenotnumber);
- Bind(&if_valueisnumber);
+ BIND(&if_valueisnumber);
{
// Load the HeapNumber value.
var_finc_value.Bind(LoadHeapNumberValue(value));
Goto(&do_finc);
}
- Bind(&if_valuenotnumber);
+ BIND(&if_valuenotnumber);
{
// We do not require an Or with earlier feedback here because once we
// convert the value to a number, we cannot reach this path. We can
@@ -1556,7 +1556,7 @@ IGNITION_HANDLER(Inc, InterpreterAssembler) {
Word32Equal(instance_type, Int32Constant(ODDBALL_TYPE));
Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball);
- Bind(&if_valueisoddball);
+ BIND(&if_valueisoddball);
{
// Convert Oddball to Number and check again.
value_var.Bind(LoadObjectField(value, Oddball::kToNumberOffset));
@@ -1565,7 +1565,7 @@ IGNITION_HANDLER(Inc, InterpreterAssembler) {
Goto(&start);
}
- Bind(&if_valuenotoddball);
+ BIND(&if_valuenotoddball);
{
// Convert to a Number first and try again.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
@@ -1577,7 +1577,7 @@ IGNITION_HANDLER(Inc, InterpreterAssembler) {
}
}
- Bind(&do_finc);
+ BIND(&do_finc);
{
Node* finc_value = var_finc_value.value();
Node* one = Float64Constant(1.0);
@@ -1589,7 +1589,7 @@ IGNITION_HANDLER(Inc, InterpreterAssembler) {
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index);
SetAccumulator(result_var.value());
@@ -1622,14 +1622,14 @@ IGNITION_HANDLER(Dec, InterpreterAssembler) {
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNone));
value_var.Bind(value);
Goto(&start);
- Bind(&start);
+ BIND(&start);
{
value = value_var.value();
Label if_issmi(this), if_isnotsmi(this);
Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
- Bind(&if_issmi);
+ BIND(&if_issmi);
{
// Try fast Smi subtraction first.
Node* one = SmiConstant(Smi::FromInt(1));
@@ -1641,35 +1641,35 @@ IGNITION_HANDLER(Dec, InterpreterAssembler) {
Label if_overflow(this), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
- Bind(&if_notoverflow);
+ BIND(&if_notoverflow);
var_type_feedback.Bind(
SmiOr(var_type_feedback.value(),
SmiConstant(BinaryOperationFeedback::kSignedSmall)));
result_var.Bind(BitcastWordToTaggedSigned(Projection(0, pair)));
Goto(&end);
- Bind(&if_overflow);
+ BIND(&if_overflow);
{
var_fdec_value.Bind(SmiToFloat64(value));
Goto(&do_fdec);
}
}
- Bind(&if_isnotsmi);
+ BIND(&if_isnotsmi);
{
// Check if the value is a HeapNumber.
Label if_valueisnumber(this), if_valuenotnumber(this, Label::kDeferred);
Node* value_map = LoadMap(value);
Branch(IsHeapNumberMap(value_map), &if_valueisnumber, &if_valuenotnumber);
- Bind(&if_valueisnumber);
+ BIND(&if_valueisnumber);
{
// Load the HeapNumber value.
var_fdec_value.Bind(LoadHeapNumberValue(value));
Goto(&do_fdec);
}
- Bind(&if_valuenotnumber);
+ BIND(&if_valuenotnumber);
{
// We do not require an Or with earlier feedback here because once we
// convert the value to a number, we cannot reach this path. We can
@@ -1683,7 +1683,7 @@ IGNITION_HANDLER(Dec, InterpreterAssembler) {
Word32Equal(instance_type, Int32Constant(ODDBALL_TYPE));
Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball);
- Bind(&if_valueisoddball);
+ BIND(&if_valueisoddball);
{
// Convert Oddball to Number and check again.
value_var.Bind(LoadObjectField(value, Oddball::kToNumberOffset));
@@ -1692,7 +1692,7 @@ IGNITION_HANDLER(Dec, InterpreterAssembler) {
Goto(&start);
}
- Bind(&if_valuenotoddball);
+ BIND(&if_valuenotoddball);
{
// Convert to a Number first and try again.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
@@ -1704,7 +1704,7 @@ IGNITION_HANDLER(Dec, InterpreterAssembler) {
}
}
- Bind(&do_fdec);
+ BIND(&do_fdec);
{
Node* fdec_value = var_fdec_value.value();
Node* one = Float64Constant(1.0);
@@ -1716,7 +1716,7 @@ IGNITION_HANDLER(Dec, InterpreterAssembler) {
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index);
SetAccumulator(result_var.value());
@@ -1735,17 +1735,17 @@ IGNITION_HANDLER(ToBooleanLogicalNot, InterpreterAssembler) {
Node* true_value = BooleanConstant(true);
Node* false_value = BooleanConstant(false);
BranchIfToBooleanIsTrue(value, &if_true, &if_false);
- Bind(&if_true);
+ BIND(&if_true);
{
result.Bind(false_value);
Goto(&end);
}
- Bind(&if_false);
+ BIND(&if_false);
{
result.Bind(true_value);
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
SetAccumulator(result.value());
Dispatch();
}
@@ -1761,12 +1761,12 @@ IGNITION_HANDLER(LogicalNot, InterpreterAssembler) {
Node* true_value = BooleanConstant(true);
Node* false_value = BooleanConstant(false);
Branch(WordEqual(value, true_value), &if_true, &if_false);
- Bind(&if_true);
+ BIND(&if_true);
{
result.Bind(false_value);
Goto(&end);
}
- Bind(&if_false);
+ BIND(&if_false);
{
if (FLAG_debug_code) {
AbortIfWordNotEqual(value, false_value,
@@ -1775,7 +1775,7 @@ IGNITION_HANDLER(LogicalNot, InterpreterAssembler) {
result.Bind(true_value);
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
SetAccumulator(result.value());
Dispatch();
}
@@ -1800,8 +1800,8 @@ IGNITION_HANDLER(DeletePropertyStrict, InterpreterAssembler) {
Node* object = LoadRegister(reg_index);
Node* key = GetAccumulator();
Node* context = GetContext();
- Node* result =
- CallRuntime(Runtime::kDeleteProperty_Strict, context, object, key);
+ Node* result = CallBuiltin(Builtins::kDeleteProperty, context, object, key,
+ SmiConstant(STRICT));
SetAccumulator(result);
Dispatch();
}
@@ -1815,8 +1815,8 @@ IGNITION_HANDLER(DeletePropertySloppy, InterpreterAssembler) {
Node* object = LoadRegister(reg_index);
Node* key = GetAccumulator();
Node* context = GetContext();
- Node* result =
- CallRuntime(Runtime::kDeleteProperty_Sloppy, context, object, key);
+ Node* result = CallBuiltin(Builtins::kDeleteProperty, context, object, key,
+ SmiConstant(SLOPPY));
SetAccumulator(result);
Dispatch();
}
@@ -2124,313 +2124,41 @@ class InterpreterCompareOpAssembler : public InterpreterAssembler {
Node* lhs = LoadRegister(reg_index);
Node* rhs = GetAccumulator();
Node* context = GetContext();
- Node* slot_index = BytecodeOperandIdx(1);
- Node* feedback_vector = LoadFeedbackVector();
-
- Variable var_result(this, MachineRepresentation::kTagged),
- var_fcmp_lhs(this, MachineRepresentation::kFloat64),
- var_fcmp_rhs(this, MachineRepresentation::kFloat64),
- non_number_value(this, MachineRepresentation::kTagged),
- maybe_smi_value(this, MachineRepresentation::kTagged);
- Label lhs_is_not_smi(this), do_fcmp(this), slow_path(this),
- fast_path_dispatch(this);
-
- GotoIf(TaggedIsNotSmi(lhs), &lhs_is_not_smi);
- {
- Label rhs_is_not_smi(this);
- GotoIf(TaggedIsNotSmi(rhs), &rhs_is_not_smi);
- {
- Comment("Do integer comparison");
- UpdateFeedback(SmiConstant(CompareOperationFeedback::kSignedSmall),
- feedback_vector, slot_index);
- Node* result;
- switch (compare_op) {
- case Token::LT:
- result = SelectBooleanConstant(SmiLessThan(lhs, rhs));
- break;
- case Token::LTE:
- result = SelectBooleanConstant(SmiLessThanOrEqual(lhs, rhs));
- break;
- case Token::GT:
- result = SelectBooleanConstant(SmiLessThan(rhs, lhs));
- break;
- case Token::GTE:
- result = SelectBooleanConstant(SmiLessThanOrEqual(rhs, lhs));
- break;
- case Token::EQ:
- case Token::EQ_STRICT:
- result = SelectBooleanConstant(WordEqual(lhs, rhs));
- break;
- default:
- UNREACHABLE();
- }
- var_result.Bind(result);
- Goto(&fast_path_dispatch);
- }
-
- Bind(&rhs_is_not_smi);
- {
- Node* rhs_map = LoadMap(rhs);
- Label rhs_is_not_number(this);
- GotoIfNot(IsHeapNumberMap(rhs_map), &rhs_is_not_number);
-
- Comment("Convert lhs to float and load HeapNumber value from rhs");
- var_fcmp_lhs.Bind(SmiToFloat64(lhs));
- var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs));
- Goto(&do_fcmp);
-
- Bind(&rhs_is_not_number);
- {
- non_number_value.Bind(rhs);
- maybe_smi_value.Bind(lhs);
- Goto(&slow_path);
- }
- }
- }
-
- Bind(&lhs_is_not_smi);
- {
- Label rhs_is_not_smi(this), lhs_is_not_number(this),
- rhs_is_not_number(this);
-
- Node* lhs_map = LoadMap(lhs);
- GotoIfNot(IsHeapNumberMap(lhs_map), &lhs_is_not_number);
-
- GotoIfNot(TaggedIsSmi(rhs), &rhs_is_not_smi);
- Comment("Convert rhs to double and load HeapNumber value from lhs");
- var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(SmiToFloat64(rhs));
- Goto(&do_fcmp);
-
- Bind(&rhs_is_not_smi);
- {
- Node* rhs_map = LoadMap(rhs);
- GotoIfNot(IsHeapNumberMap(rhs_map), &rhs_is_not_number);
-
- Comment("Load HeapNumber values from lhs and rhs");
- var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs));
- Goto(&do_fcmp);
- }
-
- Bind(&lhs_is_not_number);
- {
- non_number_value.Bind(lhs);
- maybe_smi_value.Bind(rhs);
- Goto(&slow_path);
- }
-
- Bind(&rhs_is_not_number);
- {
- non_number_value.Bind(rhs);
- maybe_smi_value.Bind(lhs);
- Goto(&slow_path);
- }
- }
-
- Bind(&do_fcmp);
- {
- Comment("Do floating point comparison");
- Node* lhs_float = var_fcmp_lhs.value();
- Node* rhs_float = var_fcmp_rhs.value();
- UpdateFeedback(SmiConstant(CompareOperationFeedback::kNumber),
- feedback_vector, slot_index);
-
- // Perform a fast floating point comparison.
- Node* result;
- switch (compare_op) {
- case Token::LT:
- result = SelectBooleanConstant(Float64LessThan(lhs_float, rhs_float));
- break;
- case Token::LTE:
- result = SelectBooleanConstant(
- Float64LessThanOrEqual(lhs_float, rhs_float));
- break;
- case Token::GT:
- result =
- SelectBooleanConstant(Float64GreaterThan(lhs_float, rhs_float));
- break;
- case Token::GTE:
- result = SelectBooleanConstant(
- Float64GreaterThanOrEqual(lhs_float, rhs_float));
- break;
- case Token::EQ:
- case Token::EQ_STRICT: {
- Label check_nan(this);
- var_result.Bind(BooleanConstant(false));
- Branch(Float64Equal(lhs_float, rhs_float), &check_nan,
- &fast_path_dispatch);
- Bind(&check_nan);
- result = SelectBooleanConstant(Float64Equal(lhs_float, lhs_float));
- } break;
- default:
- UNREACHABLE();
- }
- var_result.Bind(result);
- Goto(&fast_path_dispatch);
- }
-
- Bind(&fast_path_dispatch);
- {
- SetAccumulator(var_result.value());
- Dispatch();
+ Variable var_type_feedback(this, MachineRepresentation::kTagged);
+ Node* result;
+ switch (compare_op) {
+ case Token::EQ:
+ result = Equal(lhs, rhs, context, &var_type_feedback);
+ break;
+ case Token::EQ_STRICT:
+ result = StrictEqual(lhs, rhs, &var_type_feedback);
+ break;
+ case Token::LT:
+ result = RelationalComparison(CodeStubAssembler::kLessThan, lhs, rhs,
+ context, &var_type_feedback);
+ break;
+ case Token::GT:
+ result = RelationalComparison(CodeStubAssembler::kGreaterThan, lhs, rhs,
+ context, &var_type_feedback);
+ break;
+ case Token::LTE:
+ result = RelationalComparison(CodeStubAssembler::kLessThanOrEqual, lhs,
+ rhs, context, &var_type_feedback);
+ break;
+ case Token::GTE:
+ result = RelationalComparison(CodeStubAssembler::kGreaterThanOrEqual,
+ lhs, rhs, context, &var_type_feedback);
+ break;
+ default:
+ UNREACHABLE();
}
- // Marking a block with more than one predecessor causes register allocator
- // to fail (v8:5998). Add a dummy block as a workaround.
- Label slow_path_deferred(this, Label::kDeferred);
- Bind(&slow_path);
- Goto(&slow_path_deferred);
-
- Bind(&slow_path_deferred);
- {
- // When we reach here, one of the operands is not a Smi / HeapNumber and
- // the other operand could be of any type. The cases where both of them
- // are HeapNumbers / Smis are handled earlier.
- Comment("Collect feedback for non HeapNumber cases.");
- Label update_feedback_and_do_compare(this);
- Variable var_type_feedback(this, MachineRepresentation::kTaggedSigned);
- var_type_feedback.Bind(SmiConstant(CompareOperationFeedback::kAny));
-
- if (Token::IsOrderedRelationalCompareOp(compare_op)) {
- Label check_for_oddball(this);
- // Check for NumberOrOddball feedback.
- Node* non_number_instance_type =
- LoadInstanceType(non_number_value.value());
- GotoIf(
- Word32Equal(non_number_instance_type, Int32Constant(ODDBALL_TYPE)),
- &check_for_oddball);
-
- // Check for string feedback.
- GotoIfNot(IsStringInstanceType(non_number_instance_type),
- &update_feedback_and_do_compare);
-
- GotoIf(TaggedIsSmi(maybe_smi_value.value()),
- &update_feedback_and_do_compare);
-
- Node* maybe_smi_instance_type =
- LoadInstanceType(maybe_smi_value.value());
- GotoIfNot(IsStringInstanceType(maybe_smi_instance_type),
- &update_feedback_and_do_compare);
-
- var_type_feedback.Bind(SmiConstant(CompareOperationFeedback::kString));
- Goto(&update_feedback_and_do_compare);
-
- Bind(&check_for_oddball);
- {
- Label compare_with_oddball_feedback(this);
- GotoIf(TaggedIsSmi(maybe_smi_value.value()),
- &compare_with_oddball_feedback);
-
- Node* maybe_smi_instance_type =
- LoadInstanceType(maybe_smi_value.value());
- GotoIf(Word32Equal(maybe_smi_instance_type,
- Int32Constant(HEAP_NUMBER_TYPE)),
- &compare_with_oddball_feedback);
-
- Branch(
- Word32Equal(maybe_smi_instance_type, Int32Constant(ODDBALL_TYPE)),
- &compare_with_oddball_feedback, &update_feedback_and_do_compare);
-
- Bind(&compare_with_oddball_feedback);
- {
- var_type_feedback.Bind(
- SmiConstant(CompareOperationFeedback::kNumberOrOddball));
- Goto(&update_feedback_and_do_compare);
- }
- }
- } else {
- Label not_string(this), both_are_strings(this);
-
- DCHECK(Token::IsEqualityOp(compare_op));
-
- // If one of them is a Smi and the other is not a number, record "Any"
- // feedback. Equality comparisons do not need feedback about oddballs.
- GotoIf(TaggedIsSmi(maybe_smi_value.value()),
- &update_feedback_and_do_compare);
-
- Node* maybe_smi_instance_type =
- LoadInstanceType(maybe_smi_value.value());
- Node* non_number_instance_type =
- LoadInstanceType(non_number_value.value());
- GotoIfNot(IsStringInstanceType(maybe_smi_instance_type), &not_string);
-
- // If one value is string and other isn't record "Any" feedback.
- Branch(IsStringInstanceType(non_number_instance_type),
- &both_are_strings, &update_feedback_and_do_compare);
-
- Bind(&both_are_strings);
- {
- Node* operand1_feedback = SelectSmiConstant(
- Word32Equal(Word32And(maybe_smi_instance_type,
- Int32Constant(kIsNotInternalizedMask)),
- Int32Constant(kInternalizedTag)),
- CompareOperationFeedback::kInternalizedString,
- CompareOperationFeedback::kString);
-
- Node* operand2_feedback = SelectSmiConstant(
- Word32Equal(Word32And(non_number_instance_type,
- Int32Constant(kIsNotInternalizedMask)),
- Int32Constant(kInternalizedTag)),
- CompareOperationFeedback::kInternalizedString,
- CompareOperationFeedback::kString);
-
- var_type_feedback.Bind(SmiOr(operand1_feedback, operand2_feedback));
- Goto(&update_feedback_and_do_compare);
- }
-
- Bind(&not_string);
- {
- // Check if both operands are of type JSReceiver.
- GotoIfNot(IsJSReceiverInstanceType(maybe_smi_instance_type),
- &update_feedback_and_do_compare);
-
- GotoIfNot(IsJSReceiverInstanceType(non_number_instance_type),
- &update_feedback_and_do_compare);
-
- var_type_feedback.Bind(
- SmiConstant(CompareOperationFeedback::kReceiver));
- Goto(&update_feedback_and_do_compare);
- }
- }
-
- Bind(&update_feedback_and_do_compare);
- {
- Comment("Do the full compare operation");
- UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index);
- Node* result;
- switch (compare_op) {
- case Token::EQ:
- result = Equal(lhs, rhs, context);
- break;
- case Token::EQ_STRICT:
- result = StrictEqual(lhs, rhs);
- break;
- case Token::LT:
- result = RelationalComparison(CodeStubAssembler::kLessThan, lhs,
- rhs, context);
- break;
- case Token::GT:
- result = RelationalComparison(CodeStubAssembler::kGreaterThan, lhs,
- rhs, context);
- break;
- case Token::LTE:
- result = RelationalComparison(CodeStubAssembler::kLessThanOrEqual,
- lhs, rhs, context);
- break;
- case Token::GTE:
- result = RelationalComparison(
- CodeStubAssembler::kGreaterThanOrEqual, lhs, rhs, context);
- break;
- default:
- UNREACHABLE();
- }
- var_result.Bind(result);
- SetAccumulator(var_result.value());
- Dispatch();
- }
- }
+ Node* slot_index = BytecodeOperandIdx(1);
+ Node* feedback_vector = LoadFeedbackVector();
+ UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index);
+ SetAccumulator(result);
+ Dispatch();
}
};
@@ -2543,7 +2271,7 @@ IGNITION_HANDLER(TestUndetectable, InterpreterAssembler) {
SetAccumulator(result);
Goto(&end);
- Bind(&end);
+ BIND(&end);
Dispatch();
}
@@ -2594,37 +2322,37 @@ IGNITION_HANDLER(TestTypeOf, InterpreterAssembler) {
Switch(literal_flag, &abort, cases, labels, arraysize(cases));
- Bind(&abort);
+ BIND(&abort);
{
Comment("Abort");
Abort(BailoutReason::kUnexpectedTestTypeofLiteralFlag);
Goto(&if_false);
}
- Bind(&if_number);
+ BIND(&if_number);
{
Comment("IfNumber");
GotoIfNumber(object, &if_true);
Goto(&if_false);
}
- Bind(&if_string);
+ BIND(&if_string);
{
Comment("IfString");
GotoIf(TaggedIsSmi(object), &if_false);
Branch(IsString(object), &if_true, &if_false);
}
- Bind(&if_symbol);
+ BIND(&if_symbol);
{
Comment("IfSymbol");
GotoIf(TaggedIsSmi(object), &if_false);
Branch(IsSymbol(object), &if_true, &if_false);
}
- Bind(&if_boolean);
+ BIND(&if_boolean);
{
Comment("IfBoolean");
GotoIf(WordEqual(object, BooleanConstant(true)), &if_true);
Branch(WordEqual(object, BooleanConstant(false)), &if_true, &if_false);
}
- Bind(&if_undefined);
+ BIND(&if_undefined);
{
Comment("IfUndefined");
GotoIf(TaggedIsSmi(object), &if_false);
@@ -2636,7 +2364,7 @@ IGNITION_HANDLER(TestTypeOf, InterpreterAssembler) {
Branch(Word32Equal(undetectable_bit, Int32Constant(0)), &if_false,
&if_true);
}
- Bind(&if_function);
+ BIND(&if_function);
{
Comment("IfFunction");
GotoIf(TaggedIsSmi(object), &if_false);
@@ -2649,7 +2377,7 @@ IGNITION_HANDLER(TestTypeOf, InterpreterAssembler) {
Int32Constant(1 << Map::kIsCallable)),
&if_true, &if_false);
}
- Bind(&if_object);
+ BIND(&if_object);
{
Comment("IfObject");
GotoIf(TaggedIsSmi(object), &if_false);
@@ -2667,29 +2395,29 @@ IGNITION_HANDLER(TestTypeOf, InterpreterAssembler) {
Branch(Word32Equal(callable_undetectable, Int32Constant(0)), &if_true,
&if_false);
}
- Bind(&if_other);
+ BIND(&if_other);
{
// Typeof doesn't return any other string value.
Goto(&if_false);
}
- Bind(&if_false);
+ BIND(&if_false);
{
SetAccumulator(BooleanConstant(false));
Goto(&end);
}
- Bind(&if_true);
+ BIND(&if_true);
{
SetAccumulator(BooleanConstant(true));
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
Dispatch();
}
// Jump <imm>
//
-// Jump by number of bytes represented by the immediate operand |imm|.
+// Jump by the number of bytes represented by the immediate operand |imm|.
IGNITION_HANDLER(Jump, InterpreterAssembler) {
Node* relative_jump = BytecodeOperandUImmWord(0);
Jump(relative_jump);
@@ -2697,7 +2425,8 @@ IGNITION_HANDLER(Jump, InterpreterAssembler) {
// JumpConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool.
IGNITION_HANDLER(JumpConstant, InterpreterAssembler) {
Node* index = BytecodeOperandIdx(0);
Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
@@ -2706,7 +2435,7 @@ IGNITION_HANDLER(JumpConstant, InterpreterAssembler) {
// JumpIfTrue <imm>
//
-// Jump by number of bytes represented by an immediate operand if the
+// Jump by the number of bytes represented by an immediate operand if the
// accumulator contains true. This only works for boolean inputs, and
// will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfTrue, InterpreterAssembler) {
@@ -2720,9 +2449,9 @@ IGNITION_HANDLER(JumpIfTrue, InterpreterAssembler) {
// JumpIfTrueConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the accumulator contains true. This only works for boolean inputs, and
-// will misbehave if passed arbitrary input values.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the accumulator contains true. This only works for boolean inputs,
+// and will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfTrueConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
@@ -2735,7 +2464,7 @@ IGNITION_HANDLER(JumpIfTrueConstant, InterpreterAssembler) {
// JumpIfFalse <imm>
//
-// Jump by number of bytes represented by an immediate operand if the
+// Jump by the number of bytes represented by an immediate operand if the
// accumulator contains false. This only works for boolean inputs, and
// will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfFalse, InterpreterAssembler) {
@@ -2749,9 +2478,9 @@ IGNITION_HANDLER(JumpIfFalse, InterpreterAssembler) {
// JumpIfFalseConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the accumulator contains false. This only works for boolean inputs, and
-// will misbehave if passed arbitrary input values.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the accumulator contains false. This only works for boolean inputs,
+// and will misbehave if passed arbitrary input values.
IGNITION_HANDLER(JumpIfFalseConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
@@ -2764,71 +2493,71 @@ IGNITION_HANDLER(JumpIfFalseConstant, InterpreterAssembler) {
// JumpIfToBooleanTrue <imm>
//
-// Jump by number of bytes represented by an immediate operand if the object
+// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is true when the object is cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanTrue, InterpreterAssembler) {
Node* value = GetAccumulator();
Node* relative_jump = BytecodeOperandUImmWord(0);
Label if_true(this), if_false(this);
BranchIfToBooleanIsTrue(value, &if_true, &if_false);
- Bind(&if_true);
+ BIND(&if_true);
Jump(relative_jump);
- Bind(&if_false);
+ BIND(&if_false);
Dispatch();
}
// JumpIfToBooleanTrueConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the object referenced by the accumulator is true when the object is cast
-// to boolean.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the object referenced by the accumulator is true when the object is
+// cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanTrueConstant, InterpreterAssembler) {
Node* value = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
Label if_true(this), if_false(this);
BranchIfToBooleanIsTrue(value, &if_true, &if_false);
- Bind(&if_true);
+ BIND(&if_true);
Jump(relative_jump);
- Bind(&if_false);
+ BIND(&if_false);
Dispatch();
}
// JumpIfToBooleanFalse <imm>
//
-// Jump by number of bytes represented by an immediate operand if the object
+// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is false when the object is cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanFalse, InterpreterAssembler) {
Node* value = GetAccumulator();
Node* relative_jump = BytecodeOperandUImmWord(0);
Label if_true(this), if_false(this);
BranchIfToBooleanIsTrue(value, &if_true, &if_false);
- Bind(&if_true);
+ BIND(&if_true);
Dispatch();
- Bind(&if_false);
+ BIND(&if_false);
Jump(relative_jump);
}
// JumpIfToBooleanFalseConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the object referenced by the accumulator is false when the object is cast
-// to boolean.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the object referenced by the accumulator is false when the object is
+// cast to boolean.
IGNITION_HANDLER(JumpIfToBooleanFalseConstant, InterpreterAssembler) {
Node* value = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
Node* relative_jump = LoadAndUntagConstantPoolEntry(index);
Label if_true(this), if_false(this);
BranchIfToBooleanIsTrue(value, &if_true, &if_false);
- Bind(&if_true);
+ BIND(&if_true);
Dispatch();
- Bind(&if_false);
+ BIND(&if_false);
Jump(relative_jump);
}
// JumpIfNull <imm>
//
-// Jump by number of bytes represented by an immediate operand if the object
+// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the null constant.
IGNITION_HANDLER(JumpIfNull, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@@ -2839,8 +2568,8 @@ IGNITION_HANDLER(JumpIfNull, InterpreterAssembler) {
// JumpIfNullConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the object referenced by the accumulator is the null constant.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the object referenced by the accumulator is the null constant.
IGNITION_HANDLER(JumpIfNullConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* null_value = HeapConstant(isolate()->factory()->null_value());
@@ -2851,7 +2580,7 @@ IGNITION_HANDLER(JumpIfNullConstant, InterpreterAssembler) {
// JumpIfNotNull <imm>
//
-// Jump by number of bytes represented by an immediate operand if the object
+// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is not the null constant.
IGNITION_HANDLER(JumpIfNotNull, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@@ -2862,8 +2591,8 @@ IGNITION_HANDLER(JumpIfNotNull, InterpreterAssembler) {
// JumpIfNotNullConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the object referenced by the accumulator is not the null constant.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the object referenced by the accumulator is not the null constant.
IGNITION_HANDLER(JumpIfNotNullConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* null_value = HeapConstant(isolate()->factory()->null_value());
@@ -2874,7 +2603,7 @@ IGNITION_HANDLER(JumpIfNotNullConstant, InterpreterAssembler) {
// JumpIfUndefined <imm>
//
-// Jump by number of bytes represented by an immediate operand if the object
+// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the undefined constant.
IGNITION_HANDLER(JumpIfUndefined, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@@ -2885,8 +2614,8 @@ IGNITION_HANDLER(JumpIfUndefined, InterpreterAssembler) {
// JumpIfUndefinedConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the object referenced by the accumulator is the undefined constant.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the object referenced by the accumulator is the undefined constant.
IGNITION_HANDLER(JumpIfUndefinedConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
@@ -2897,7 +2626,7 @@ IGNITION_HANDLER(JumpIfUndefinedConstant, InterpreterAssembler) {
// JumpIfNotUndefined <imm>
//
-// Jump by number of bytes represented by an immediate operand if the object
+// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is not the undefined constant.
IGNITION_HANDLER(JumpIfNotUndefined, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@@ -2908,8 +2637,9 @@ IGNITION_HANDLER(JumpIfNotUndefined, InterpreterAssembler) {
// JumpIfNotUndefinedConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the object referenced by the accumulator is not the undefined constant.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the object referenced by the accumulator is not the undefined
+// constant.
IGNITION_HANDLER(JumpIfNotUndefinedConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* undefined_value = HeapConstant(isolate()->factory()->undefined_value());
@@ -2920,7 +2650,7 @@ IGNITION_HANDLER(JumpIfNotUndefinedConstant, InterpreterAssembler) {
// JumpIfJSReceiver <imm>
//
-// Jump by number of bytes represented by an immediate operand if the object
+// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is a JSReceiver.
IGNITION_HANDLER(JumpIfJSReceiver, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@@ -2929,19 +2659,19 @@ IGNITION_HANDLER(JumpIfJSReceiver, InterpreterAssembler) {
Label if_object(this), if_notobject(this, Label::kDeferred), if_notsmi(this);
Branch(TaggedIsSmi(accumulator), &if_notobject, &if_notsmi);
- Bind(&if_notsmi);
+ BIND(&if_notsmi);
Branch(IsJSReceiver(accumulator), &if_object, &if_notobject);
- Bind(&if_object);
+ BIND(&if_object);
Jump(relative_jump);
- Bind(&if_notobject);
+ BIND(&if_notobject);
Dispatch();
}
// JumpIfJSReceiverConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool if
-// the object referenced by the accumulator is a JSReceiver.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the object referenced by the accumulator is a JSReceiver.
IGNITION_HANDLER(JumpIfJSReceiverConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* index = BytecodeOperandIdx(0);
@@ -2950,19 +2680,19 @@ IGNITION_HANDLER(JumpIfJSReceiverConstant, InterpreterAssembler) {
Label if_object(this), if_notobject(this), if_notsmi(this);
Branch(TaggedIsSmi(accumulator), &if_notobject, &if_notsmi);
- Bind(&if_notsmi);
+ BIND(&if_notsmi);
Branch(IsJSReceiver(accumulator), &if_object, &if_notobject);
- Bind(&if_object);
+ BIND(&if_object);
Jump(relative_jump);
- Bind(&if_notobject);
+ BIND(&if_notobject);
Dispatch();
}
// JumpIfNotHole <imm>
//
-// Jump by number of bytes represented by an immediate operand if the object
+// Jump by the number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the hole.
IGNITION_HANDLER(JumpIfNotHole, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
@@ -2973,8 +2703,8 @@ IGNITION_HANDLER(JumpIfNotHole, InterpreterAssembler) {
// JumpIfNotHoleConstant <idx>
//
-// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
-// if the object referenced by the accumulator is the hole constant.
+// Jump by the number of bytes in the Smi in the |idx| entry in the constant
+// pool if the object referenced by the accumulator is the hole constant.
IGNITION_HANDLER(JumpIfNotHoleConstant, InterpreterAssembler) {
Node* accumulator = GetAccumulator();
Node* the_hole_value = HeapConstant(isolate()->factory()->the_hole_value());
@@ -2985,7 +2715,7 @@ IGNITION_HANDLER(JumpIfNotHoleConstant, InterpreterAssembler) {
// JumpLoop <imm> <loop_depth>
//
-// Jump by number of bytes represented by the immediate operand |imm|. Also
+// Jump by the number of bytes represented by the immediate operand |imm|. Also
// performs a loop nesting check and potentially triggers OSR in case the
// current OSR level matches (or exceeds) the specified |loop_depth|.
IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
@@ -2999,10 +2729,10 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
Node* condition = Int32GreaterThanOrEqual(loop_depth, osr_level);
Branch(condition, &ok, &osr_armed);
- Bind(&ok);
+ BIND(&ok);
JumpBackward(relative_jump);
- Bind(&osr_armed);
+ BIND(&osr_armed);
{
Callable callable = CodeFactory::InterpreterOnStackReplacement(isolate());
Node* target = HeapConstant(callable.code());
@@ -3012,6 +2742,37 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) {
}
}
+// SwitchOnSmiNoFeedback <table_start> <table_length> <case_value_base>
+//
+// Jump by the number of bytes defined by a Smi in a table in the constant pool,
+// where the table starts at |table_start| and has |table_length| entries.
+// The table is indexed by the accumulator, minus |case_value_base|. If the
+// case_value falls outside of the table |table_length|, fall-through to the
+// next bytecode.
+IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) {
+ Node* acc = GetAccumulator();
+ Node* table_start = BytecodeOperandIdx(0);
+ Node* table_length = BytecodeOperandUImmWord(1);
+ Node* case_value_base = BytecodeOperandImmIntPtr(2);
+
+ Label fall_through(this);
+
+ // The accumulator must be a Smi.
+ // TODO(leszeks): Add a bytecode with type feedback that allows other
+ // accumulator values.
+ CSA_ASSERT(this, TaggedIsSmi(acc));
+
+ Node* case_value = IntPtrSub(SmiUntag(acc), case_value_base);
+ GotoIf(IntPtrLessThan(case_value, IntPtrConstant(0)), &fall_through);
+ GotoIf(IntPtrGreaterThanOrEqual(case_value, table_length), &fall_through);
+ Node* entry = IntPtrAdd(table_start, case_value);
+ Node* relative_jump = LoadAndUntagConstantPoolEntry(entry);
+ Jump(relative_jump);
+
+ BIND(&fall_through);
+ Dispatch();
+}
+
// CreateRegExpLiteral <pattern_idx> <literal_idx> <flags>
//
// Creates a regular expression literal for literal index <literal_idx> with
@@ -3045,7 +2806,7 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
IsSetWord32<CreateArrayLiteralFlags::FastShallowCloneBit>(bytecode_flags),
&fast_shallow_clone, &call_runtime);
- Bind(&fast_shallow_clone);
+ BIND(&fast_shallow_clone);
{
ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitFastCloneShallowArray(
@@ -3054,7 +2815,7 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
Dispatch();
}
- Bind(&call_runtime);
+ BIND(&call_runtime);
{
Node* flags_raw = DecodeWordFromWord32<CreateArrayLiteralFlags::FlagsBits>(
bytecode_flags);
@@ -3079,23 +2840,21 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
// Check if we can do a fast clone or have to call the runtime.
Label if_fast_clone(this), if_not_fast_clone(this, Label::kDeferred);
- Node* fast_clone_properties_count = DecodeWordFromWord32<
- CreateObjectLiteralFlags::FastClonePropertiesCountBits>(bytecode_flags);
- Branch(WordNotEqual(fast_clone_properties_count, IntPtrConstant(0)),
+ Branch(IsSetWord32<CreateObjectLiteralFlags::FastCloneSupportedBit>(
+ bytecode_flags),
&if_fast_clone, &if_not_fast_clone);
- Bind(&if_fast_clone);
+ BIND(&if_fast_clone);
{
// If we can do a fast clone do the fast-path in FastCloneShallowObjectStub.
ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitFastCloneShallowObject(
- &if_not_fast_clone, closure, literal_index,
- fast_clone_properties_count);
+ &if_not_fast_clone, closure, literal_index);
StoreRegister(result, BytecodeOperandReg(3));
Dispatch();
}
- Bind(&if_not_fast_clone);
+ BIND(&if_not_fast_clone);
{
// If we can't do a fast clone, call into the runtime.
Node* index = BytecodeOperandIdx(0);
@@ -3135,7 +2894,7 @@ IGNITION_HANDLER(CreateClosure, InterpreterAssembler) {
shared, feedback_vector, vector_index, context));
Dispatch();
- Bind(&call_runtime);
+ BIND(&call_runtime);
{
Node* tenured_raw =
DecodeWordFromWord32<CreateClosureFlags::PretenuredBit>(flags);
@@ -3249,7 +3008,7 @@ IGNITION_HANDLER(CreateMappedArguments, InterpreterAssembler) {
Node* compare = Word32And(compiler_hints, duplicate_parameters_bit);
Branch(compare, &if_duplicate_parameters, &if_not_duplicate_parameters);
- Bind(&if_not_duplicate_parameters);
+ BIND(&if_not_duplicate_parameters);
{
ArgumentsBuiltinsAssembler constructor_assembler(state());
Node* result =
@@ -3258,7 +3017,7 @@ IGNITION_HANDLER(CreateMappedArguments, InterpreterAssembler) {
Dispatch();
}
- Bind(&if_duplicate_parameters);
+ BIND(&if_duplicate_parameters);
{
Node* result =
CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure);
@@ -3301,10 +3060,10 @@ IGNITION_HANDLER(StackCheck, InterpreterAssembler) {
Node* interrupt = StackCheckTriggeredInterrupt();
Branch(interrupt, &stack_check_interrupt, &ok);
- Bind(&ok);
+ BIND(&ok);
Dispatch();
- Bind(&stack_check_interrupt);
+ BIND(&stack_check_interrupt);
{
Node* context = GetContext();
CallRuntime(Runtime::kStackGuard, context);
@@ -3427,7 +3186,7 @@ IGNITION_HANDLER(ForInPrepare, InterpreterForInPrepareAssembler) {
cache_length);
Dispatch();
- Bind(&call_runtime);
+ BIND(&call_runtime);
{
Node* result_triple =
CallRuntime(Runtime::kForInPrepare, context, receiver);
@@ -3438,7 +3197,7 @@ IGNITION_HANDLER(ForInPrepare, InterpreterForInPrepareAssembler) {
cache_length);
Dispatch();
}
- Bind(&nothing_to_iterate);
+ BIND(&nothing_to_iterate);
{
// Receiver is null or undefined or descriptors are zero length.
Node* zero = SmiConstant(0);
@@ -3468,13 +3227,13 @@ IGNITION_HANDLER(ForInNext, InterpreterAssembler) {
Label if_fast(this), if_slow(this, Label::kDeferred);
Node* receiver_map = LoadMap(receiver);
Branch(WordEqual(receiver_map, cache_type), &if_fast, &if_slow);
- Bind(&if_fast);
+ BIND(&if_fast);
{
// Enum cache in use for {receiver}, the {key} is definitely valid.
SetAccumulator(key);
Dispatch();
}
- Bind(&if_slow);
+ BIND(&if_slow);
{
// Record the fact that we hit the for-in slow path.
Node* vector_index = BytecodeOperandIdx(3);
@@ -3505,17 +3264,17 @@ IGNITION_HANDLER(ForInContinue, InterpreterAssembler) {
// Check if {index} is at {cache_length} already.
Label if_true(this), if_false(this), end(this);
Branch(WordEqual(index, cache_length), &if_true, &if_false);
- Bind(&if_true);
+ BIND(&if_true);
{
SetAccumulator(BooleanConstant(false));
Goto(&end);
}
- Bind(&if_false);
+ BIND(&if_false);
{
SetAccumulator(BooleanConstant(true));
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
Dispatch();
}
@@ -3574,7 +3333,7 @@ IGNITION_HANDLER(SuspendGenerator, InterpreterAssembler) {
STATIC_ASSERT(LastStepAction == StepIn);
Node* step_next = Int32Constant(StepNext);
Branch(Int32LessThanOrEqual(step_next, step_action), &if_stepping, &ok);
- Bind(&ok);
+ BIND(&ok);
Node* array =
LoadObjectField(generator, JSGeneratorObject::kRegisterFileOffset);
@@ -3598,7 +3357,7 @@ IGNITION_HANDLER(SuspendGenerator, InterpreterAssembler) {
static_cast<int>(SuspendFlags::kAsyncGeneratorAwait))),
&if_asyncgeneratorawait, &if_notasyncgeneratorawait);
- Bind(&if_notasyncgeneratorawait);
+ BIND(&if_notasyncgeneratorawait);
{
// For ordinary yields (and for AwaitExpressions in Async Functions, which
// are implemented as ordinary yields), it is safe to write over the
@@ -3608,7 +3367,7 @@ IGNITION_HANDLER(SuspendGenerator, InterpreterAssembler) {
Goto(&merge);
}
- Bind(&if_asyncgeneratorawait);
+ BIND(&if_asyncgeneratorawait);
{
// An AwaitExpression in an Async Generator requires writing to the
// [await_input_or_debug_pos] field.
@@ -3619,10 +3378,10 @@ IGNITION_HANDLER(SuspendGenerator, InterpreterAssembler) {
Goto(&merge);
}
- Bind(&merge);
+ BIND(&merge);
Dispatch();
- Bind(&if_stepping);
+ BIND(&if_stepping);
{
Node* context = GetContext();
CallRuntime(Runtime::kDebugRecordGenerator, context, generator);