[stubs] Remove dead IncStub and DecStub
R=mvstanton@chromium.org TBR=rmcilroy@chromium.org Review-Url: https://codereview.chromium.org/2608683002 Cr-Commit-Position: refs/heads/master@{#41985}
This commit is contained in:
parent
71f8c819d9
commit
21ebbd3ec2
@ -257,18 +257,6 @@ TFS_BUILTIN(StringCharCodeAt)
|
||||
|
||||
#undef TFS_BUILTIN
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Inc(Isolate* isolate) {
|
||||
IncStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Dec(Isolate* isolate) {
|
||||
DecStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags,
|
||||
PretenureFlag pretenure_flag) {
|
||||
|
@ -105,8 +105,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
|
||||
static Callable BitwiseAnd(Isolate* isolate);
|
||||
static Callable BitwiseOr(Isolate* isolate);
|
||||
static Callable BitwiseXor(Isolate* isolate);
|
||||
static Callable Inc(Isolate* isolate);
|
||||
static Callable Dec(Isolate* isolate);
|
||||
static Callable LessThan(Isolate* isolate);
|
||||
static Callable LessThanOrEqual(Isolate* isolate);
|
||||
static Callable GreaterThan(Isolate* isolate);
|
||||
|
@ -1512,150 +1512,6 @@ compiler::Node* ModulusWithFeedbackStub::Generate(
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
#define UNARY_OP_STUB(Name) \
|
||||
void Name::GenerateAssembly(compiler::CodeAssemblerState* state) const { \
|
||||
CodeStubAssembler assembler(state); \
|
||||
assembler.Return(Generate(&assembler, assembler.Parameter(0), \
|
||||
assembler.Parameter(1), assembler.Parameter(2), \
|
||||
assembler.Parameter(3))); \
|
||||
}
|
||||
UNARY_OP_STUB(IncStub)
|
||||
UNARY_OP_STUB(DecStub)
|
||||
#undef UNARY_OP_STUB
|
||||
|
||||
// static
|
||||
compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
|
||||
compiler::Node* value,
|
||||
compiler::Node* context,
|
||||
compiler::Node* type_feedback_vector,
|
||||
compiler::Node* slot_id) {
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef compiler::Node Node;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
|
||||
// Shared entry for floating point increment.
|
||||
Label do_finc(assembler), end(assembler);
|
||||
Variable var_finc_value(assembler, MachineRepresentation::kFloat64);
|
||||
|
||||
// We might need to try again due to ToNumber conversion.
|
||||
Variable value_var(assembler, MachineRepresentation::kTagged);
|
||||
Variable result_var(assembler, MachineRepresentation::kTagged);
|
||||
Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
|
||||
Variable* loop_vars[] = {&value_var, &var_type_feedback};
|
||||
Label start(assembler, 2, loop_vars);
|
||||
value_var.Bind(value);
|
||||
var_type_feedback.Bind(
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kNone));
|
||||
assembler->Goto(&start);
|
||||
assembler->Bind(&start);
|
||||
{
|
||||
value = value_var.value();
|
||||
|
||||
Label if_issmi(assembler), if_isnotsmi(assembler);
|
||||
assembler->Branch(assembler->TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
|
||||
|
||||
assembler->Bind(&if_issmi);
|
||||
{
|
||||
// Try fast Smi addition first.
|
||||
Node* one = assembler->SmiConstant(Smi::FromInt(1));
|
||||
Node* pair = assembler->IntPtrAddWithOverflow(
|
||||
assembler->BitcastTaggedToWord(value),
|
||||
assembler->BitcastTaggedToWord(one));
|
||||
Node* overflow = assembler->Projection(1, pair);
|
||||
|
||||
// Check if the Smi addition overflowed.
|
||||
Label if_overflow(assembler), if_notoverflow(assembler);
|
||||
assembler->Branch(overflow, &if_overflow, &if_notoverflow);
|
||||
|
||||
assembler->Bind(&if_notoverflow);
|
||||
var_type_feedback.Bind(assembler->Word32Or(
|
||||
var_type_feedback.value(),
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)));
|
||||
result_var.Bind(
|
||||
assembler->BitcastWordToTaggedSigned(assembler->Projection(0, pair)));
|
||||
assembler->Goto(&end);
|
||||
|
||||
assembler->Bind(&if_overflow);
|
||||
{
|
||||
var_finc_value.Bind(assembler->SmiToFloat64(value));
|
||||
assembler->Goto(&do_finc);
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&if_isnotsmi);
|
||||
{
|
||||
// Check if the value is a HeapNumber.
|
||||
Label if_valueisnumber(assembler),
|
||||
if_valuenotnumber(assembler, Label::kDeferred);
|
||||
Node* value_map = assembler->LoadMap(value);
|
||||
assembler->Branch(assembler->IsHeapNumberMap(value_map),
|
||||
&if_valueisnumber, &if_valuenotnumber);
|
||||
|
||||
assembler->Bind(&if_valueisnumber);
|
||||
{
|
||||
// Load the HeapNumber value.
|
||||
var_finc_value.Bind(assembler->LoadHeapNumberValue(value));
|
||||
assembler->Goto(&do_finc);
|
||||
}
|
||||
|
||||
assembler->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
|
||||
// only reach this path on the first pass when the feedback is kNone.
|
||||
CSA_ASSERT(assembler,
|
||||
assembler->Word32Equal(var_type_feedback.value(),
|
||||
assembler->Int32Constant(
|
||||
BinaryOperationFeedback::kNone)));
|
||||
|
||||
Label if_valueisoddball(assembler), if_valuenotoddball(assembler);
|
||||
Node* instance_type = assembler->LoadMapInstanceType(value_map);
|
||||
Node* is_oddball = assembler->Word32Equal(
|
||||
instance_type, assembler->Int32Constant(ODDBALL_TYPE));
|
||||
assembler->Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball);
|
||||
|
||||
assembler->Bind(&if_valueisoddball);
|
||||
{
|
||||
// Convert Oddball to Number and check again.
|
||||
value_var.Bind(
|
||||
assembler->LoadObjectField(value, Oddball::kToNumberOffset));
|
||||
var_type_feedback.Bind(assembler->Int32Constant(
|
||||
BinaryOperationFeedback::kNumberOrOddball));
|
||||
assembler->Goto(&start);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_valuenotoddball);
|
||||
{
|
||||
// Convert to a Number first and try again.
|
||||
Callable callable =
|
||||
CodeFactory::NonNumberToNumber(assembler->isolate());
|
||||
var_type_feedback.Bind(
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kAny));
|
||||
value_var.Bind(assembler->CallStub(callable, context, value));
|
||||
assembler->Goto(&start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&do_finc);
|
||||
{
|
||||
Node* finc_value = var_finc_value.value();
|
||||
Node* one = assembler->Float64Constant(1.0);
|
||||
Node* finc_result = assembler->Float64Add(finc_value, one);
|
||||
var_type_feedback.Bind(assembler->Word32Or(
|
||||
var_type_feedback.value(),
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
|
||||
result_var.Bind(assembler->AllocateHeapNumberWithValue(finc_result));
|
||||
assembler->Goto(&end);
|
||||
}
|
||||
|
||||
assembler->Bind(&end);
|
||||
assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
|
||||
slot_id);
|
||||
return result_var.value();
|
||||
}
|
||||
|
||||
void NumberToStringStub::GenerateAssembly(
|
||||
compiler::CodeAssemblerState* state) const {
|
||||
typedef compiler::Node Node;
|
||||
@ -1665,139 +1521,6 @@ void NumberToStringStub::GenerateAssembly(
|
||||
assembler.Return(assembler.NumberToString(context, argument));
|
||||
}
|
||||
|
||||
// static
|
||||
compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
|
||||
compiler::Node* value,
|
||||
compiler::Node* context,
|
||||
compiler::Node* type_feedback_vector,
|
||||
compiler::Node* slot_id) {
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef compiler::Node Node;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
|
||||
// Shared entry for floating point decrement.
|
||||
Label do_fdec(assembler), end(assembler);
|
||||
Variable var_fdec_value(assembler, MachineRepresentation::kFloat64);
|
||||
|
||||
// We might need to try again due to ToNumber conversion.
|
||||
Variable value_var(assembler, MachineRepresentation::kTagged);
|
||||
Variable result_var(assembler, MachineRepresentation::kTagged);
|
||||
Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
|
||||
Variable* loop_vars[] = {&value_var, &var_type_feedback};
|
||||
Label start(assembler, 2, loop_vars);
|
||||
var_type_feedback.Bind(
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kNone));
|
||||
value_var.Bind(value);
|
||||
assembler->Goto(&start);
|
||||
assembler->Bind(&start);
|
||||
{
|
||||
value = value_var.value();
|
||||
|
||||
Label if_issmi(assembler), if_isnotsmi(assembler);
|
||||
assembler->Branch(assembler->TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
|
||||
|
||||
assembler->Bind(&if_issmi);
|
||||
{
|
||||
// Try fast Smi subtraction first.
|
||||
Node* one = assembler->SmiConstant(Smi::FromInt(1));
|
||||
Node* pair = assembler->IntPtrSubWithOverflow(
|
||||
assembler->BitcastTaggedToWord(value),
|
||||
assembler->BitcastTaggedToWord(one));
|
||||
Node* overflow = assembler->Projection(1, pair);
|
||||
|
||||
// Check if the Smi subtraction overflowed.
|
||||
Label if_overflow(assembler), if_notoverflow(assembler);
|
||||
assembler->Branch(overflow, &if_overflow, &if_notoverflow);
|
||||
|
||||
assembler->Bind(&if_notoverflow);
|
||||
var_type_feedback.Bind(assembler->Word32Or(
|
||||
var_type_feedback.value(),
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)));
|
||||
result_var.Bind(
|
||||
assembler->BitcastWordToTaggedSigned(assembler->Projection(0, pair)));
|
||||
assembler->Goto(&end);
|
||||
|
||||
assembler->Bind(&if_overflow);
|
||||
{
|
||||
var_fdec_value.Bind(assembler->SmiToFloat64(value));
|
||||
assembler->Goto(&do_fdec);
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&if_isnotsmi);
|
||||
{
|
||||
// Check if the value is a HeapNumber.
|
||||
Label if_valueisnumber(assembler),
|
||||
if_valuenotnumber(assembler, Label::kDeferred);
|
||||
Node* value_map = assembler->LoadMap(value);
|
||||
assembler->Branch(assembler->IsHeapNumberMap(value_map),
|
||||
&if_valueisnumber, &if_valuenotnumber);
|
||||
|
||||
assembler->Bind(&if_valueisnumber);
|
||||
{
|
||||
// Load the HeapNumber value.
|
||||
var_fdec_value.Bind(assembler->LoadHeapNumberValue(value));
|
||||
assembler->Goto(&do_fdec);
|
||||
}
|
||||
|
||||
assembler->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
|
||||
// only reach this path on the first pass when the feedback is kNone.
|
||||
CSA_ASSERT(assembler,
|
||||
assembler->Word32Equal(var_type_feedback.value(),
|
||||
assembler->Int32Constant(
|
||||
BinaryOperationFeedback::kNone)));
|
||||
|
||||
Label if_valueisoddball(assembler), if_valuenotoddball(assembler);
|
||||
Node* instance_type = assembler->LoadMapInstanceType(value_map);
|
||||
Node* is_oddball = assembler->Word32Equal(
|
||||
instance_type, assembler->Int32Constant(ODDBALL_TYPE));
|
||||
assembler->Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball);
|
||||
|
||||
assembler->Bind(&if_valueisoddball);
|
||||
{
|
||||
// Convert Oddball to Number and check again.
|
||||
value_var.Bind(
|
||||
assembler->LoadObjectField(value, Oddball::kToNumberOffset));
|
||||
var_type_feedback.Bind(assembler->Int32Constant(
|
||||
BinaryOperationFeedback::kNumberOrOddball));
|
||||
assembler->Goto(&start);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_valuenotoddball);
|
||||
{
|
||||
// Convert to a Number first and try again.
|
||||
Callable callable =
|
||||
CodeFactory::NonNumberToNumber(assembler->isolate());
|
||||
var_type_feedback.Bind(
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kAny));
|
||||
value_var.Bind(assembler->CallStub(callable, context, value));
|
||||
assembler->Goto(&start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&do_fdec);
|
||||
{
|
||||
Node* fdec_value = var_fdec_value.value();
|
||||
Node* one = assembler->Float64Constant(1.0);
|
||||
Node* fdec_result = assembler->Float64Sub(fdec_value, one);
|
||||
var_type_feedback.Bind(assembler->Word32Or(
|
||||
var_type_feedback.value(),
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
|
||||
result_var.Bind(assembler->AllocateHeapNumberWithValue(fdec_result));
|
||||
assembler->Goto(&end);
|
||||
}
|
||||
|
||||
assembler->Bind(&end);
|
||||
assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
|
||||
slot_id);
|
||||
return result_var.value();
|
||||
}
|
||||
|
||||
// ES6 section 21.1.3.19 String.prototype.substring ( start, end )
|
||||
compiler::Node* SubStringStub::Generate(CodeStubAssembler* assembler,
|
||||
compiler::Node* string,
|
||||
|
@ -94,10 +94,8 @@ class Node;
|
||||
V(MultiplyWithFeedback) \
|
||||
V(DivideWithFeedback) \
|
||||
V(ModulusWithFeedback) \
|
||||
V(Inc) \
|
||||
V(InternalArrayNoArgumentConstructor) \
|
||||
V(InternalArraySingleArgumentConstructor) \
|
||||
V(Dec) \
|
||||
V(ElementsTransitionAndStore) \
|
||||
V(FastCloneRegExp) \
|
||||
V(FastCloneShallowArray) \
|
||||
@ -731,22 +729,6 @@ class ModulusWithFeedbackStub final : public TurboFanCodeStub {
|
||||
TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class IncStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit IncStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(CountOp);
|
||||
DEFINE_TURBOFAN_UNARY_OP_CODE_STUB_WITH_FEEDBACK(Inc, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class DecStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit DecStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(CountOp);
|
||||
DEFINE_TURBOFAN_UNARY_OP_CODE_STUB_WITH_FEEDBACK(Dec, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class StoreInterceptorStub : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit StoreInterceptorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
@ -1567,14 +1567,276 @@ void Interpreter::DoToObject(InterpreterAssembler* assembler) {
|
||||
//
|
||||
// Increments value in the accumulator by one.
|
||||
void Interpreter::DoInc(InterpreterAssembler* assembler) {
|
||||
DoUnaryOpWithFeedback<IncStub>(assembler);
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef compiler::Node Node;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
|
||||
Node* value = __ GetAccumulator();
|
||||
Node* context = __ GetContext();
|
||||
Node* slot_index = __ BytecodeOperandIdx(0);
|
||||
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
|
||||
|
||||
// Shared entry for floating point increment.
|
||||
Label do_finc(assembler), end(assembler);
|
||||
Variable var_finc_value(assembler, MachineRepresentation::kFloat64);
|
||||
|
||||
// We might need to try again due to ToNumber conversion.
|
||||
Variable value_var(assembler, MachineRepresentation::kTagged);
|
||||
Variable result_var(assembler, MachineRepresentation::kTagged);
|
||||
Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
|
||||
Variable* loop_vars[] = {&value_var, &var_type_feedback};
|
||||
Label start(assembler, 2, loop_vars);
|
||||
value_var.Bind(value);
|
||||
var_type_feedback.Bind(
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kNone));
|
||||
assembler->Goto(&start);
|
||||
assembler->Bind(&start);
|
||||
{
|
||||
value = value_var.value();
|
||||
|
||||
Label if_issmi(assembler), if_isnotsmi(assembler);
|
||||
assembler->Branch(assembler->TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
|
||||
|
||||
assembler->Bind(&if_issmi);
|
||||
{
|
||||
// Try fast Smi addition first.
|
||||
Node* one = assembler->SmiConstant(Smi::FromInt(1));
|
||||
Node* pair = assembler->IntPtrAddWithOverflow(
|
||||
assembler->BitcastTaggedToWord(value),
|
||||
assembler->BitcastTaggedToWord(one));
|
||||
Node* overflow = assembler->Projection(1, pair);
|
||||
|
||||
// Check if the Smi addition overflowed.
|
||||
Label if_overflow(assembler), if_notoverflow(assembler);
|
||||
assembler->Branch(overflow, &if_overflow, &if_notoverflow);
|
||||
|
||||
assembler->Bind(&if_notoverflow);
|
||||
var_type_feedback.Bind(assembler->Word32Or(
|
||||
var_type_feedback.value(),
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)));
|
||||
result_var.Bind(
|
||||
assembler->BitcastWordToTaggedSigned(assembler->Projection(0, pair)));
|
||||
assembler->Goto(&end);
|
||||
|
||||
assembler->Bind(&if_overflow);
|
||||
{
|
||||
var_finc_value.Bind(assembler->SmiToFloat64(value));
|
||||
assembler->Goto(&do_finc);
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&if_isnotsmi);
|
||||
{
|
||||
// Check if the value is a HeapNumber.
|
||||
Label if_valueisnumber(assembler),
|
||||
if_valuenotnumber(assembler, Label::kDeferred);
|
||||
Node* value_map = assembler->LoadMap(value);
|
||||
assembler->Branch(assembler->IsHeapNumberMap(value_map),
|
||||
&if_valueisnumber, &if_valuenotnumber);
|
||||
|
||||
assembler->Bind(&if_valueisnumber);
|
||||
{
|
||||
// Load the HeapNumber value.
|
||||
var_finc_value.Bind(assembler->LoadHeapNumberValue(value));
|
||||
assembler->Goto(&do_finc);
|
||||
}
|
||||
|
||||
assembler->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
|
||||
// only reach this path on the first pass when the feedback is kNone.
|
||||
CSA_ASSERT(assembler,
|
||||
assembler->Word32Equal(var_type_feedback.value(),
|
||||
assembler->Int32Constant(
|
||||
BinaryOperationFeedback::kNone)));
|
||||
|
||||
Label if_valueisoddball(assembler), if_valuenotoddball(assembler);
|
||||
Node* instance_type = assembler->LoadMapInstanceType(value_map);
|
||||
Node* is_oddball = assembler->Word32Equal(
|
||||
instance_type, assembler->Int32Constant(ODDBALL_TYPE));
|
||||
assembler->Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball);
|
||||
|
||||
assembler->Bind(&if_valueisoddball);
|
||||
{
|
||||
// Convert Oddball to Number and check again.
|
||||
value_var.Bind(
|
||||
assembler->LoadObjectField(value, Oddball::kToNumberOffset));
|
||||
var_type_feedback.Bind(assembler->Int32Constant(
|
||||
BinaryOperationFeedback::kNumberOrOddball));
|
||||
assembler->Goto(&start);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_valuenotoddball);
|
||||
{
|
||||
// Convert to a Number first and try again.
|
||||
Callable callable =
|
||||
CodeFactory::NonNumberToNumber(assembler->isolate());
|
||||
var_type_feedback.Bind(
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kAny));
|
||||
value_var.Bind(assembler->CallStub(callable, context, value));
|
||||
assembler->Goto(&start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&do_finc);
|
||||
{
|
||||
Node* finc_value = var_finc_value.value();
|
||||
Node* one = assembler->Float64Constant(1.0);
|
||||
Node* finc_result = assembler->Float64Add(finc_value, one);
|
||||
var_type_feedback.Bind(assembler->Word32Or(
|
||||
var_type_feedback.value(),
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
|
||||
result_var.Bind(assembler->AllocateHeapNumberWithValue(finc_result));
|
||||
assembler->Goto(&end);
|
||||
}
|
||||
|
||||
assembler->Bind(&end);
|
||||
assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
|
||||
slot_index);
|
||||
|
||||
__ SetAccumulator(result_var.value());
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
// Dec
|
||||
//
|
||||
// Decrements value in the accumulator by one.
|
||||
void Interpreter::DoDec(InterpreterAssembler* assembler) {
|
||||
DoUnaryOpWithFeedback<DecStub>(assembler);
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef compiler::Node Node;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
|
||||
Node* value = __ GetAccumulator();
|
||||
Node* context = __ GetContext();
|
||||
Node* slot_index = __ BytecodeOperandIdx(0);
|
||||
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
|
||||
|
||||
// Shared entry for floating point decrement.
|
||||
Label do_fdec(assembler), end(assembler);
|
||||
Variable var_fdec_value(assembler, MachineRepresentation::kFloat64);
|
||||
|
||||
// We might need to try again due to ToNumber conversion.
|
||||
Variable value_var(assembler, MachineRepresentation::kTagged);
|
||||
Variable result_var(assembler, MachineRepresentation::kTagged);
|
||||
Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
|
||||
Variable* loop_vars[] = {&value_var, &var_type_feedback};
|
||||
Label start(assembler, 2, loop_vars);
|
||||
var_type_feedback.Bind(
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kNone));
|
||||
value_var.Bind(value);
|
||||
assembler->Goto(&start);
|
||||
assembler->Bind(&start);
|
||||
{
|
||||
value = value_var.value();
|
||||
|
||||
Label if_issmi(assembler), if_isnotsmi(assembler);
|
||||
assembler->Branch(assembler->TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
|
||||
|
||||
assembler->Bind(&if_issmi);
|
||||
{
|
||||
// Try fast Smi subtraction first.
|
||||
Node* one = assembler->SmiConstant(Smi::FromInt(1));
|
||||
Node* pair = assembler->IntPtrSubWithOverflow(
|
||||
assembler->BitcastTaggedToWord(value),
|
||||
assembler->BitcastTaggedToWord(one));
|
||||
Node* overflow = assembler->Projection(1, pair);
|
||||
|
||||
// Check if the Smi subtraction overflowed.
|
||||
Label if_overflow(assembler), if_notoverflow(assembler);
|
||||
assembler->Branch(overflow, &if_overflow, &if_notoverflow);
|
||||
|
||||
assembler->Bind(&if_notoverflow);
|
||||
var_type_feedback.Bind(assembler->Word32Or(
|
||||
var_type_feedback.value(),
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)));
|
||||
result_var.Bind(
|
||||
assembler->BitcastWordToTaggedSigned(assembler->Projection(0, pair)));
|
||||
assembler->Goto(&end);
|
||||
|
||||
assembler->Bind(&if_overflow);
|
||||
{
|
||||
var_fdec_value.Bind(assembler->SmiToFloat64(value));
|
||||
assembler->Goto(&do_fdec);
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&if_isnotsmi);
|
||||
{
|
||||
// Check if the value is a HeapNumber.
|
||||
Label if_valueisnumber(assembler),
|
||||
if_valuenotnumber(assembler, Label::kDeferred);
|
||||
Node* value_map = assembler->LoadMap(value);
|
||||
assembler->Branch(assembler->IsHeapNumberMap(value_map),
|
||||
&if_valueisnumber, &if_valuenotnumber);
|
||||
|
||||
assembler->Bind(&if_valueisnumber);
|
||||
{
|
||||
// Load the HeapNumber value.
|
||||
var_fdec_value.Bind(assembler->LoadHeapNumberValue(value));
|
||||
assembler->Goto(&do_fdec);
|
||||
}
|
||||
|
||||
assembler->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
|
||||
// only reach this path on the first pass when the feedback is kNone.
|
||||
CSA_ASSERT(assembler,
|
||||
assembler->Word32Equal(var_type_feedback.value(),
|
||||
assembler->Int32Constant(
|
||||
BinaryOperationFeedback::kNone)));
|
||||
|
||||
Label if_valueisoddball(assembler), if_valuenotoddball(assembler);
|
||||
Node* instance_type = assembler->LoadMapInstanceType(value_map);
|
||||
Node* is_oddball = assembler->Word32Equal(
|
||||
instance_type, assembler->Int32Constant(ODDBALL_TYPE));
|
||||
assembler->Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball);
|
||||
|
||||
assembler->Bind(&if_valueisoddball);
|
||||
{
|
||||
// Convert Oddball to Number and check again.
|
||||
value_var.Bind(
|
||||
assembler->LoadObjectField(value, Oddball::kToNumberOffset));
|
||||
var_type_feedback.Bind(assembler->Int32Constant(
|
||||
BinaryOperationFeedback::kNumberOrOddball));
|
||||
assembler->Goto(&start);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_valuenotoddball);
|
||||
{
|
||||
// Convert to a Number first and try again.
|
||||
Callable callable =
|
||||
CodeFactory::NonNumberToNumber(assembler->isolate());
|
||||
var_type_feedback.Bind(
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kAny));
|
||||
value_var.Bind(assembler->CallStub(callable, context, value));
|
||||
assembler->Goto(&start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&do_fdec);
|
||||
{
|
||||
Node* fdec_value = var_fdec_value.value();
|
||||
Node* one = assembler->Float64Constant(1.0);
|
||||
Node* fdec_result = assembler->Float64Sub(fdec_value, one);
|
||||
var_type_feedback.Bind(assembler->Word32Or(
|
||||
var_type_feedback.value(),
|
||||
assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
|
||||
result_var.Bind(assembler->AllocateHeapNumberWithValue(fdec_result));
|
||||
assembler->Goto(&end);
|
||||
}
|
||||
|
||||
assembler->Bind(&end);
|
||||
assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
|
||||
slot_index);
|
||||
|
||||
__ SetAccumulator(result_var.value());
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
// LogicalNot
|
||||
|
Loading…
Reference in New Issue
Block a user