Commit ff06760b authored by ishell's avatar ishell Committed by Commit bot

[stubs] CSA::LoadFixedDoubleArrayElement() is now able to do a hole check.

Review-Url: https://codereview.chromium.org/2321543003
Cr-Commit-Position: refs/heads/master@{#39280}
parent b0a7738a
...@@ -1648,27 +1648,11 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) { ...@@ -1648,27 +1648,11 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) {
assembler->UintPtrLessThan(index_var.value(), len_var.value()), assembler->UintPtrLessThan(index_var.value(), len_var.value()),
&return_false); &return_false);
if (kPointerSize == kDoubleSize) { // Load double value or continue if it contains a double hole.
Node* element = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Uint64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS);
Node* the_hole = assembler->Int64Constant(kHoleNanInt64);
assembler->GotoIf(assembler->Word64Equal(element, the_hole),
&continue_loop);
} else {
Node* element_upper = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Uint32(),
kIeeeDoubleExponentWordOffset,
CodeStubAssembler::INTPTR_PARAMETERS);
assembler->GotoIf(
assembler->Word32Equal(element_upper,
assembler->Int32Constant(kHoleNanUpper32)),
&continue_loop);
}
Node* element_k = assembler->LoadFixedDoubleArrayElement( Node* element_k = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Float64(), 0, elements, index_var.value(), MachineType::Float64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS); CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
assembler->BranchIfFloat64Equal(element_k, search_num.value(), assembler->BranchIfFloat64Equal(element_k, search_num.value(),
&return_true, &continue_loop); &return_true, &continue_loop);
assembler->Bind(&continue_loop); assembler->Bind(&continue_loop);
...@@ -1684,27 +1668,11 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) { ...@@ -1684,27 +1668,11 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) {
assembler->UintPtrLessThan(index_var.value(), len_var.value()), assembler->UintPtrLessThan(index_var.value(), len_var.value()),
&return_false); &return_false);
if (kPointerSize == kDoubleSize) { // Load double value or continue if it contains a double hole.
Node* element = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Uint64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS);
Node* the_hole = assembler->Int64Constant(kHoleNanInt64);
assembler->GotoIf(assembler->Word64Equal(element, the_hole),
&continue_loop);
} else {
Node* element_upper = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Uint32(),
kIeeeDoubleExponentWordOffset,
CodeStubAssembler::INTPTR_PARAMETERS);
assembler->GotoIf(
assembler->Word32Equal(element_upper,
assembler->Int32Constant(kHoleNanUpper32)),
&continue_loop);
}
Node* element_k = assembler->LoadFixedDoubleArrayElement( Node* element_k = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Float64(), 0, elements, index_var.value(), MachineType::Float64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS); CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
assembler->Bind(&continue_loop); assembler->Bind(&continue_loop);
index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one));
...@@ -1718,23 +1686,10 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) { ...@@ -1718,23 +1686,10 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) {
assembler->UintPtrLessThan(index_var.value(), len_var.value()), assembler->UintPtrLessThan(index_var.value(), len_var.value()),
&return_false); &return_false);
if (kPointerSize == kDoubleSize) { // Check if the element is a double hole, but don't load it.
Node* element = assembler->LoadFixedDoubleArrayElement( assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Uint64(), 0, elements, index_var.value(), MachineType::None(), 0,
CodeStubAssembler::INTPTR_PARAMETERS); CodeStubAssembler::INTPTR_PARAMETERS, &return_true);
Node* the_hole = assembler->Int64Constant(kHoleNanInt64);
assembler->GotoIf(assembler->Word64Equal(element, the_hole),
&return_true);
} else {
Node* element_upper = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Uint32(),
kIeeeDoubleExponentWordOffset,
CodeStubAssembler::INTPTR_PARAMETERS);
assembler->GotoIf(
assembler->Word32Equal(element_upper,
assembler->Int32Constant(kHoleNanUpper32)),
&return_true);
}
index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one));
assembler->Goto(&hole_loop); assembler->Goto(&hole_loop);
...@@ -2096,27 +2051,11 @@ void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) { ...@@ -2096,27 +2051,11 @@ void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) {
assembler->UintPtrLessThan(index_var.value(), len_var.value()), assembler->UintPtrLessThan(index_var.value(), len_var.value()),
&return_not_found); &return_not_found);
if (kPointerSize == kDoubleSize) { // Load double value or continue if it contains a double hole.
Node* element = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Uint64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS);
Node* the_hole = assembler->Int64Constant(kHoleNanInt64);
assembler->GotoIf(assembler->Word64Equal(element, the_hole),
&continue_loop);
} else {
Node* element_upper = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Uint32(),
kIeeeDoubleExponentWordOffset,
CodeStubAssembler::INTPTR_PARAMETERS);
assembler->GotoIf(
assembler->Word32Equal(element_upper,
assembler->Int32Constant(kHoleNanUpper32)),
&continue_loop);
}
Node* element_k = assembler->LoadFixedDoubleArrayElement( Node* element_k = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Float64(), 0, elements, index_var.value(), MachineType::Float64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS); CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
assembler->BranchIfFloat64Equal(element_k, search_num.value(), assembler->BranchIfFloat64Equal(element_k, search_num.value(),
&return_found, &continue_loop); &return_found, &continue_loop);
assembler->Bind(&continue_loop); assembler->Bind(&continue_loop);
......
...@@ -1139,12 +1139,28 @@ Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement( ...@@ -1139,12 +1139,28 @@ Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement(
Node* CodeStubAssembler::LoadFixedDoubleArrayElement( Node* CodeStubAssembler::LoadFixedDoubleArrayElement(
Node* object, Node* index_node, MachineType machine_type, Node* object, Node* index_node, MachineType machine_type,
int additional_offset, ParameterMode parameter_mode) { int additional_offset, ParameterMode parameter_mode, Label* if_hole) {
int32_t header_size = int32_t header_size =
FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag; FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag;
Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_DOUBLE_ELEMENTS, Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_DOUBLE_ELEMENTS,
parameter_mode, header_size); parameter_mode, header_size);
return Load(machine_type, object, offset); return LoadDoubleWithHoleCheck(object, offset, if_hole, machine_type);
}
Node* CodeStubAssembler::LoadDoubleWithHoleCheck(Node* base, Node* offset,
Label* if_hole,
MachineType machine_type) {
if (if_hole) {
Node* element_upper =
Load(MachineType::Uint32(), base,
IntPtrAdd(offset, IntPtrConstant(kIeeeDoubleExponentWordOffset)));
GotoIf(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), if_hole);
}
if (machine_type.IsNone()) {
// This means the actual value is not needed.
return nullptr;
}
return Load(machine_type, base, offset);
} }
Node* CodeStubAssembler::LoadNativeContext(Node* context) { Node* CodeStubAssembler::LoadNativeContext(Node* context) {
...@@ -1414,7 +1430,7 @@ void CodeStubAssembler::FillFixedArrayWithValue( ...@@ -1414,7 +1430,7 @@ void CodeStubAssembler::FillFixedArrayWithValue(
Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32); Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32);
Node* value = LoadRoot(value_root_index); Node* value = LoadRoot(value_root_index);
int const first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag;
int32_t to; int32_t to;
bool constant_to = ToInt32Constant(to_node, to); bool constant_to = ToInt32Constant(to_node, to);
int32_t from; int32_t from;
...@@ -2896,18 +2912,10 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, ...@@ -2896,18 +2912,10 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
GotoUnless(UintPtrLessThan(intptr_index, length), &if_oob); GotoUnless(UintPtrLessThan(intptr_index, length), &if_oob);
if (Is64()) { // Check if the element is a double hole, but don't load it.
Node* element = LoadFixedDoubleArrayElement( LoadFixedDoubleArrayElement(elements, intptr_index, MachineType::None(), 0,
elements, intptr_index, MachineType::Uint64(), 0, INTPTR_PARAMETERS); INTPTR_PARAMETERS, if_not_found);
Node* the_hole = Int64Constant(kHoleNanInt64); Goto(if_found);
Branch(Word64Equal(element, the_hole), if_not_found, if_found);
} else {
Node* element_upper = LoadFixedDoubleArrayElement(
elements, intptr_index, MachineType::Uint32(),
kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS);
Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)),
if_not_found, if_found);
}
} }
Bind(&if_isdictionary); Bind(&if_isdictionary);
{ {
...@@ -3593,20 +3601,10 @@ void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements, ...@@ -3593,20 +3601,10 @@ void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements,
Bind(&if_fast_holey_double); Bind(&if_fast_holey_double);
{ {
Comment("holey double elements"); Comment("holey double elements");
if (kPointerSize == kDoubleSize) { Node* value = LoadFixedDoubleArrayElement(elements, intptr_index,
Node* raw_element = LoadFixedDoubleArrayElement( MachineType::Float64(), 0,
elements, intptr_index, MachineType::Uint64(), 0, INTPTR_PARAMETERS); INTPTR_PARAMETERS, if_hole);
Node* the_hole = Int64Constant(kHoleNanInt64); var_double_value->Bind(value);
GotoIf(Word64Equal(raw_element, the_hole), if_hole);
} else {
Node* element_upper = LoadFixedDoubleArrayElement(
elements, intptr_index, MachineType::Uint32(),
kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS);
GotoIf(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)),
if_hole);
}
var_double_value->Bind(LoadFixedDoubleArrayElement(
elements, intptr_index, MachineType::Float64(), 0, INTPTR_PARAMETERS));
Goto(rebox_double); Goto(rebox_double);
} }
......
...@@ -263,7 +263,15 @@ class CodeStubAssembler : public compiler::CodeAssembler { ...@@ -263,7 +263,15 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* LoadFixedDoubleArrayElement( compiler::Node* LoadFixedDoubleArrayElement(
compiler::Node* object, compiler::Node* index, MachineType machine_type, compiler::Node* object, compiler::Node* index, MachineType machine_type,
int additional_offset = 0, int additional_offset = 0,
ParameterMode parameter_mode = INTEGER_PARAMETERS); ParameterMode parameter_mode = INTEGER_PARAMETERS,
Label* if_hole = nullptr);
// Load Float64 value by |base| + |offset| address. If the value is a double
// hole then jump to |if_hole|. If |machine_type| is None then only the hole
// check is generated.
compiler::Node* LoadDoubleWithHoleCheck(
compiler::Node* base, compiler::Node* offset, Label* if_hole,
MachineType machine_type = MachineType::Float64());
// Context manipulation // Context manipulation
compiler::Node* LoadNativeContext(compiler::Node* context); compiler::Node* LoadNativeContext(compiler::Node* context);
......
...@@ -62,6 +62,8 @@ class MachineType { ...@@ -62,6 +62,8 @@ class MachineType {
MachineRepresentation representation() const { return representation_; } MachineRepresentation representation() const { return representation_; }
MachineSemantic semantic() const { return semantic_; } MachineSemantic semantic() const { return semantic_; }
bool IsNone() { return representation() == MachineRepresentation::kNone; }
bool IsSigned() { bool IsSigned() {
return semantic() == MachineSemantic::kInt32 || return semantic() == MachineSemantic::kInt32 ||
semantic() == MachineSemantic::kInt64; semantic() == MachineSemantic::kInt64;
......
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