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) {
assembler->UintPtrLessThan(index_var.value(), len_var.value()),
&return_false);
if (kPointerSize == kDoubleSize) {
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);
}
// Load double value or continue if it contains a double hole.
Node* element_k = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Float64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS);
CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
assembler->BranchIfFloat64Equal(element_k, search_num.value(),
&return_true, &continue_loop);
assembler->Bind(&continue_loop);
......@@ -1684,27 +1668,11 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) {
assembler->UintPtrLessThan(index_var.value(), len_var.value()),
&return_false);
if (kPointerSize == kDoubleSize) {
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);
}
// Load double value or continue if it contains a double hole.
Node* element_k = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Float64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS);
CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
assembler->Bind(&continue_loop);
index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one));
......@@ -1718,23 +1686,10 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) {
assembler->UintPtrLessThan(index_var.value(), len_var.value()),
&return_false);
if (kPointerSize == kDoubleSize) {
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),
&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);
}
// Check if the element is a double hole, but don't load it.
assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::None(), 0,
CodeStubAssembler::INTPTR_PARAMETERS, &return_true);
index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one));
assembler->Goto(&hole_loop);
......@@ -2096,27 +2051,11 @@ void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) {
assembler->UintPtrLessThan(index_var.value(), len_var.value()),
&return_not_found);
if (kPointerSize == kDoubleSize) {
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);
}
// Load double value or continue if it contains a double hole.
Node* element_k = assembler->LoadFixedDoubleArrayElement(
elements, index_var.value(), MachineType::Float64(), 0,
CodeStubAssembler::INTPTR_PARAMETERS);
CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
assembler->BranchIfFloat64Equal(element_k, search_num.value(),
&return_found, &continue_loop);
assembler->Bind(&continue_loop);
......
......@@ -1139,12 +1139,28 @@ Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement(
Node* CodeStubAssembler::LoadFixedDoubleArrayElement(
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 =
FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag;
Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_DOUBLE_ELEMENTS,
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) {
......@@ -1414,7 +1430,7 @@ void CodeStubAssembler::FillFixedArrayWithValue(
Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32);
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;
bool constant_to = ToInt32Constant(to_node, to);
int32_t from;
......@@ -2896,18 +2912,10 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
GotoUnless(UintPtrLessThan(intptr_index, length), &if_oob);
if (Is64()) {
Node* element = LoadFixedDoubleArrayElement(
elements, intptr_index, MachineType::Uint64(), 0, INTPTR_PARAMETERS);
Node* the_hole = Int64Constant(kHoleNanInt64);
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);
}
// Check if the element is a double hole, but don't load it.
LoadFixedDoubleArrayElement(elements, intptr_index, MachineType::None(), 0,
INTPTR_PARAMETERS, if_not_found);
Goto(if_found);
}
Bind(&if_isdictionary);
{
......@@ -3593,20 +3601,10 @@ void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements,
Bind(&if_fast_holey_double);
{
Comment("holey double elements");
if (kPointerSize == kDoubleSize) {
Node* raw_element = LoadFixedDoubleArrayElement(
elements, intptr_index, MachineType::Uint64(), 0, INTPTR_PARAMETERS);
Node* the_hole = Int64Constant(kHoleNanInt64);
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));
Node* value = LoadFixedDoubleArrayElement(elements, intptr_index,
MachineType::Float64(), 0,
INTPTR_PARAMETERS, if_hole);
var_double_value->Bind(value);
Goto(rebox_double);
}
......
......@@ -263,7 +263,15 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* LoadFixedDoubleArrayElement(
compiler::Node* object, compiler::Node* index, MachineType machine_type,
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
compiler::Node* LoadNativeContext(compiler::Node* context);
......
......@@ -62,6 +62,8 @@ class MachineType {
MachineRepresentation representation() const { return representation_; }
MachineSemantic semantic() const { return semantic_; }
bool IsNone() { return representation() == MachineRepresentation::kNone; }
bool IsSigned() {
return semantic() == MachineSemantic::kInt32 ||
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