Chromium Code Reviews| Index: src/code-stubs.cc |
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc |
| index 06b7afcaeb28cd90b182e374225ab9a66dfa030a..16315f25f57fc0c01b57ef42d9d93d39592267bc 100644 |
| --- a/src/code-stubs.cc |
| +++ b/src/code-stubs.cc |
| @@ -1491,13 +1491,38 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_valuenotnumber); |
| { |
| - // 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); |
| + 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)); |
| + // We do not require an Or with earlier feedback here because once we |
|
Leszek Swirski
2016/10/20 09:40:15
One last thing: can we move this assert outside of
mythria
2016/10/20 11:38:09
Done.
|
| + // convert the value to a number, we cannot reach this path. We can |
| + // only reach this path on the first pass. |
| + assembler->Assert(assembler->Word32Equal( |
| + var_type_feedback.value(), |
| + assembler->Int32Constant(BinaryOperationFeedback::kNone))); |
| + 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); |
| + } |
| } |
| } |
| } |
| @@ -1601,13 +1626,38 @@ compiler::Node* DecStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_valuenotnumber); |
| { |
| - // 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); |
| + 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)); |
| + // 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. |
| + assembler->Assert(assembler->Word32Equal( |
| + var_type_feedback.value(), |
| + assembler->Int32Constant(BinaryOperationFeedback::kNone))); |
| + 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); |
| + } |
| } |
| } |
| } |