Chromium Code Reviews| Index: src/code-stub-assembler.cc |
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
| index 56d3700fdb8195a2af57eb8c24ef08153d246dd6..61f237140574e6fd61e138f144a0e2aa6fa2d96b 100644 |
| --- a/src/code-stub-assembler.cc |
| +++ b/src/code-stub-assembler.cc |
| @@ -2256,45 +2256,36 @@ void CodeStubAssembler::Use(Label* label) { |
| void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, |
| Variable* var_index, Label* if_keyisunique, |
| Label* if_bailout) { |
| - DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep()); |
| + DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); |
| Comment("TryToName"); |
| - Label if_keyissmi(this), if_keyisnotsmi(this); |
| - Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); |
| - Bind(&if_keyissmi); |
| - { |
| - // Negative smi keys are named properties. Handle in the runtime. |
| - GotoUnless(WordIsPositiveSmi(key), if_bailout); |
| - |
| - var_index->Bind(SmiToWord32(key)); |
| - Goto(if_keyisindex); |
| - } |
| - |
| - Bind(&if_keyisnotsmi); |
| + Label if_hascachedindex(this), if_keyisnotindex(this); |
| + // Handle Smi and HeapNumber keys. |
| + var_index->Bind(TryToIntptr(key, &if_keyisnotindex)); |
| + Goto(if_keyisindex); |
| + Bind(&if_keyisnotindex); |
| Node* key_instance_type = LoadInstanceType(key); |
| // Symbols are unique. |
| GotoIf(Word32Equal(key_instance_type, Int32Constant(SYMBOL_TYPE)), |
| if_keyisunique); |
| - |
| - Label if_keyisinternalized(this); |
| - Node* bits = |
| - WordAnd(key_instance_type, |
| - Int32Constant(kIsNotStringMask | kIsNotInternalizedMask)); |
| - Branch(Word32Equal(bits, Int32Constant(kStringTag | kInternalizedTag)), |
| - &if_keyisinternalized, if_bailout); |
| - Bind(&if_keyisinternalized); |
| - |
| - // Check whether the key is an array index passed in as string. Handle |
| - // uniform with smi keys if so. |
| - // TODO(verwaest): Also support non-internalized strings. |
| + // Miss if |key| is not a String. |
| + GotoIf( |
| + Int32GreaterThan(key_instance_type, Int32Constant(LAST_UNIQUE_NAME_TYPE)), |
|
Igor Sheludko
2016/09/01 14:31:30
It looks like we are missing FIRST_STRING_TYPE and
Jakob Kummerow
2016/09/05 13:15:54
Done.
|
| + if_bailout); |
| + // |key| is a String. Check if it has a cached array index. |
| Node* hash = LoadNameHashField(key); |
| - Node* bit = Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask)); |
| - GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_keyisunique); |
| - // Key is an index. Check if it is small enough to be encoded in the |
| - // hash_field. Handle too big array index in runtime. |
| - bit = Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask)); |
| - GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_bailout); |
| + Node* contains_index = |
| + Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask)); |
| + GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex); |
|
Igor Sheludko
2016/09/01 14:31:30
What if the hash field is not computed yet? We can
Igor Sheludko
2016/09/01 15:52:17
Ignore this comment. We set the hash field of a ne
Jakob Kummerow
2016/09/05 13:15:54
Acknowledged. It's also what the handwritten Keyed
|
| + // No cached array index; check if |key| is internalized. |
| + STATIC_ASSERT(kNotInternalizedTag != 0); |
| + Node* not_internalized = |
| + Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); |
| + GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); |
| + Goto(if_keyisunique); |
| + |
| + Bind(&if_hascachedindex); |
| var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash)); |
| Goto(if_keyisindex); |
| } |
| @@ -2406,7 +2397,7 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* key, |
| seed = Int32Constant(kZeroHashSeed); |
| } |
| Node* hash = ComputeIntegerHash(key, seed); |
| - Node* key_as_float64 = ChangeUint32ToFloat64(key); |
| + Node* key_as_float64 = RoundIntPtrToFloat64(key); |
| // See Dictionary::FirstProbe(). |
| Node* count = Int32Constant(0); |
| @@ -2435,8 +2426,8 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* key, |
| Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi); |
| Bind(&if_currentissmi); |
| { |
| - Node* current_value = SmiToWord32(current); |
| - Branch(Word32Equal(current_value, key), if_found, &next_probe); |
| + Node* current_value = SmiUntag(current); |
| + Branch(WordEqual(current_value, key), if_found, &next_probe); |
| } |
| Bind(&if_currentisnotsmi); |
| { |
| @@ -2829,7 +2820,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
| // TODO(verwaest): Support other elements kinds as well. |
| Label if_isobjectorsmi(this), if_isdouble(this), if_isdictionary(this), |
| - if_isfaststringwrapper(this), if_isslowstringwrapper(this); |
| + if_isfaststringwrapper(this), if_isslowstringwrapper(this), if_oob(this); |
| // clang-format off |
| int32_t values[] = { |
| // Handled by {if_isobjectorsmi}. |
| @@ -2864,9 +2855,10 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
| Node* elements = LoadElements(object); |
| Node* length = LoadAndUntagFixedArrayBaseLength(elements); |
| - GotoUnless(Uint32LessThan(index, length), if_not_found); |
| + GotoUnless(UintPtrLessThan(index, length), &if_oob); |
| - Node* element = LoadFixedArrayElement(elements, index); |
| + Node* element = |
| + LoadFixedArrayElement(elements, index, 0, INTPTR_PARAMETERS); |
| Node* the_hole = TheHoleConstant(); |
| Branch(WordEqual(element, the_hole), if_not_found, if_found); |
| } |
| @@ -2875,17 +2867,17 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
| Node* elements = LoadElements(object); |
| Node* length = LoadAndUntagFixedArrayBaseLength(elements); |
| - GotoUnless(Uint32LessThan(index, length), if_not_found); |
| + GotoUnless(UintPtrLessThan(index, length), &if_oob); |
| if (kPointerSize == kDoubleSize) { |
| - Node* element = |
| - LoadFixedDoubleArrayElement(elements, index, MachineType::Uint64()); |
| + Node* element = LoadFixedDoubleArrayElement( |
| + elements, 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, index, MachineType::Uint32(), |
| - kIeeeDoubleExponentWordOffset); |
| + Node* element_upper = LoadFixedDoubleArrayElement( |
| + elements, index, MachineType::Uint32(), kIeeeDoubleExponentWordOffset, |
| + INTPTR_PARAMETERS); |
| Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), |
| if_not_found, if_found); |
| } |
| @@ -2904,7 +2896,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
| Assert(Int32LessThan(LoadInstanceType(string), |
| Int32Constant(FIRST_NONSTRING_TYPE))); |
| Node* length = LoadStringLength(string); |
| - GotoIf(Uint32LessThan(index, SmiToWord32(length)), if_found); |
| + GotoIf(UintPtrLessThan(index, SmiUntag(length)), if_found); |
| Goto(&if_isobjectorsmi); |
| } |
| Bind(&if_isslowstringwrapper); |
| @@ -2914,9 +2906,16 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
| Assert(Int32LessThan(LoadInstanceType(string), |
| Int32Constant(FIRST_NONSTRING_TYPE))); |
| Node* length = LoadStringLength(string); |
| - GotoIf(Uint32LessThan(index, SmiToWord32(length)), if_found); |
| + GotoIf(UintPtrLessThan(index, SmiUntag(length)), if_found); |
| Goto(&if_isdictionary); |
| } |
| + Bind(&if_oob); |
| + { |
| + // Positive OOB indices mean "not found", negative indices must be |
| + // converted to property names. |
| + GotoIf(IntPtrLessThan(index, IntPtrConstant(0)), if_bailout); |
| + Goto(if_not_found); |
| + } |
| } |
| // Instantiate template methods to workaround GCC compilation issue. |
| @@ -2946,7 +2945,7 @@ void CodeStubAssembler::TryPrototypeChainLookup( |
| Bind(&if_objectisreceiver); |
| } |
| - Variable var_index(this, MachineRepresentation::kWord32); |
| + Variable var_index(this, MachineType::PointerRepresentation()); |
| Label if_keyisindex(this), if_iskeyunique(this); |
| TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); |
| @@ -3178,15 +3177,19 @@ compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, |
| int element_size_shift = is_double ? kDoubleSizeLog2 : kPointerSizeLog2; |
| int element_size = 1 << element_size_shift; |
| int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; |
| - int32_t index = 0; |
| + intptr_t index = 0; |
| bool constant_index = false; |
| if (mode == SMI_PARAMETERS) { |
| element_size_shift -= kSmiShiftBits; |
| - intptr_t temp = 0; |
| - constant_index = ToIntPtrConstant(index_node, temp); |
| - index = temp >> kSmiShiftBits; |
| + constant_index = ToIntPtrConstant(index_node, index); |
| + index = index >> kSmiShiftBits; |
| + } else if (mode == INTEGER_PARAMETERS) { |
| + int32_t temp = 0; |
| + constant_index = ToInt32Constant(index_node, temp); |
| + index = static_cast<intptr_t>(temp); |
| } else { |
| - constant_index = ToInt32Constant(index_node, index); |
| + DCHECK(mode == INTPTR_PARAMETERS); |
| + constant_index = ToIntPtrConstant(index_node, index); |
| } |
| if (constant_index) { |
| return IntPtrConstant(base_size + element_size * index); |
| @@ -3540,16 +3543,13 @@ void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements, |
| Bind(&if_fast_packed); |
| { |
| Comment("fast packed elements"); |
| - // TODO(jkummerow): The Load*Element helpers add movsxlq instructions |
| - // on x64 which we don't need here, because |key| is an IntPtr already. |
| - // Do something about that. |
| - Return(LoadFixedArrayElement(elements, key)); |
| + Return(LoadFixedArrayElement(elements, key, 0, INTPTR_PARAMETERS)); |
| } |
| Bind(&if_fast_holey); |
| { |
| Comment("fast holey elements"); |
| - Node* element = LoadFixedArrayElement(elements, key); |
| + Node* element = LoadFixedArrayElement(elements, key, 0, INTPTR_PARAMETERS); |
| GotoIf(WordEqual(element, TheHoleConstant()), if_hole); |
| Return(element); |
| } |
| @@ -3557,8 +3557,8 @@ void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements, |
| Bind(&if_fast_double); |
| { |
| Comment("packed double elements"); |
| - var_double_value->Bind( |
| - LoadFixedDoubleArrayElement(elements, key, MachineType::Float64())); |
| + var_double_value->Bind(LoadFixedDoubleArrayElement( |
| + elements, key, MachineType::Float64(), 0, INTPTR_PARAMETERS)); |
| Goto(rebox_double); |
| } |
| @@ -3566,18 +3566,19 @@ void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements, |
| { |
| Comment("holey double elements"); |
| if (kPointerSize == kDoubleSize) { |
| - Node* raw_element = |
| - LoadFixedDoubleArrayElement(elements, key, MachineType::Uint64()); |
| + Node* raw_element = LoadFixedDoubleArrayElement( |
| + elements, key, MachineType::Uint64(), 0, INTPTR_PARAMETERS); |
| Node* the_hole = Int64Constant(kHoleNanInt64); |
| GotoIf(Word64Equal(raw_element, the_hole), if_hole); |
| } else { |
| Node* element_upper = LoadFixedDoubleArrayElement( |
| - elements, key, MachineType::Uint32(), kIeeeDoubleExponentWordOffset); |
| + elements, key, MachineType::Uint32(), kIeeeDoubleExponentWordOffset, |
| + INTPTR_PARAMETERS); |
| GotoIf(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), |
| if_hole); |
| } |
| - var_double_value->Bind( |
| - LoadFixedDoubleArrayElement(elements, key, MachineType::Float64())); |
| + var_double_value->Bind(LoadFixedDoubleArrayElement( |
| + elements, key, MachineType::Float64(), 0, INTPTR_PARAMETERS)); |
| Goto(rebox_double); |
| } |
| @@ -3934,9 +3935,9 @@ void CodeStubAssembler::KeyedLoadIC(const LoadICParameters* p) { |
| void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| Variable var_index(this, MachineType::PointerRepresentation()); |
| - Label if_index(this), if_key_is_not_number(this), if_index_name(this), |
| - if_unique_name(this), if_element_hole(this), if_oob(this), slow(this), |
| - stub_cache_miss(this), if_property_dictionary(this); |
| + Label if_index(this), if_unique_name(this), if_element_hole(this), |
| + if_oob(this), slow(this), stub_cache_miss(this), |
| + if_property_dictionary(this); |
| Node* receiver = p->receiver; |
| GotoIf(WordIsSmi(receiver), &slow); |
| @@ -3948,43 +3949,8 @@ void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), |
| &slow); |
| - // Check what kind of key we have. |
| Node* key = p->name; |
| - var_index.Bind(TryToIntptr(key, &if_key_is_not_number)); |
| - Goto(&if_index); |
| - |
| - Node* hash = nullptr; |
| - // TODO(jkummerow): Unify this with CodeStubAssembler::TryToName(). |
| - Bind(&if_key_is_not_number); |
| - { |
| - Node* key_map = LoadMap(key); |
| - Node* key_instance_type = LoadMapInstanceType(key_map); |
| - // Jump to the runtime if key is neither String nor Symbol. |
| - GotoIf(Int32GreaterThan(key_instance_type, |
| - Int32Constant(LAST_UNIQUE_NAME_TYPE)), |
| - &slow); |
| - // Symbols are always unique names. |
| - GotoIf(Word32Equal(key_instance_type, Int32Constant(LAST_UNIQUE_NAME_TYPE)), |
| - &if_unique_name); |
| - // |key| is a String. Check if it has a cached array index. |
| - hash = LoadNameHashField(key); |
| - Node* contains_index = |
| - Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask)); |
| - GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_index_name); |
| - // Otherwise, jump to the runtime if the string is not internalized. |
| - STATIC_ASSERT(kNotInternalizedTag != 0); |
| - Node* not_internalized = |
| - Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); |
| - GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), &slow); |
| - Goto(&if_unique_name); |
| - } |
| - |
| - Bind(&if_index_name); |
| - { |
| - Comment("string key with cached array index"); |
| - var_index.Bind(BitFieldDecode<String::ArrayIndexValueBits>(hash)); |
| - Goto(&if_index); |
| - } |
| + TryToName(key, &if_index, &var_index, &if_unique_name, &slow); |
| Bind(&if_index); |
| { |