Chromium Code Reviews| Index: src/compiler/change-lowering.cc |
| diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc |
| index 317439bbc00a6e964a05cdd08e30ebaefebdd80d..8552cdf7921b6c5bd62e4d7bbd7091008d5e5eb8 100644 |
| --- a/src/compiler/change-lowering.cc |
| +++ b/src/compiler/change-lowering.cc |
| @@ -151,7 +151,78 @@ Reduction ChangeLowering::ChangeBoolToBit(Node* value) { |
| Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { |
| - return Replace(AllocateHeapNumberWithValue(value, control)); |
| + Type* const value_type = NodeProperties::GetType(value); |
| + Node* const value32 = graph()->NewNode( |
| + machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value); |
| + // TODO(bmeurer): This fast case must be disabled until we kill the asm.js |
| + // support in the generic JavaScript pipeline, because LoadBuffer is lying |
| + // about its result. |
| + // if (value_type->Is(Type::Signed32())) { |
| + // return ChangeInt32ToTagged(value32, control); |
| + // } |
| + Node* check_same = graph()->NewNode( |
| + machine()->Float64Equal(), value, |
| + graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); |
| + Node* branch_same = graph()->NewNode(common()->Branch(), check_same, control); |
| + |
| + Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_same); |
| + Node* vsmi; |
| + Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same); |
| + Node* vbox; |
| + |
| + // We only need to check for -0 if the {value} can potentially contain -0. |
| + if (value_type->Maybe(Type::MinusZero())) { |
| + Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, |
| + jsgraph()->Int32Constant(0)); |
| + Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| + check_zero, if_smi); |
| + |
| + Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); |
| + Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); |
| + |
| + // In case of 0, we need to check the high bits for the IEEE -0 pattern. |
| + Node* check_negative = graph()->NewNode( |
| + machine()->Int32LessThan(), |
| + graph()->NewNode(machine()->Float64ExtractHighWord32(), value), |
| + jsgraph()->Int32Constant(0)); |
| + Node* branch_negative = graph()->NewNode( |
| + common()->Branch(BranchHint::kFalse), check_negative, if_zero); |
| + |
| + Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative); |
| + Node* if_notnegative = |
| + graph()->NewNode(common()->IfFalse(), branch_negative); |
| + |
| + // We need to create a box for negative 0. |
| + if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative); |
| + if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative); |
| + } |
| + |
| + // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit |
| + // machines we need to deal with potential overflow and fallback to boxing. |
| + if (machine()->Is64() || value_type->Is(Type::SignedSmall())) { |
| + vsmi = ChangeInt32ToSmi(value32); |
| + } else { |
| + Node* smi_tag = |
| + graph()->NewNode(machine()->Int32AddWithOverflow(), value32, value32); |
| + |
| + Node* check_ovf = graph()->NewNode(common()->Projection(1), smi_tag); |
| + Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| + check_ovf, if_smi); |
| + |
| + Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf); |
| + if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box); |
| + |
| + if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf); |
| + vsmi = graph()->NewNode(common()->Projection(0), smi_tag); |
| + } |
| + |
| + // Allocate the box for the {value}. |
| + vbox = AllocateHeapNumberWithValue(value, if_box); |
| + |
| + control = graph()->NewNode(common()->Merge(2), if_smi, if_box); |
| + value = |
| + graph()->NewNode(common()->Phi(kMachAnyTagged, 2), vsmi, vbox, control); |
| + return Replace(value); |
|
Jarin
2015/10/27 15:17:03
Just wondering - is there a reason to not use sele
Benedikt Meurer
2015/10/27 16:16:18
Allocate requires a control input.
|
| } |