OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 Node* value_map_undetectable = Word32And( | 877 Node* value_map_undetectable = Word32And( |
878 value_map_bitfield, Int32Constant(1 << Map::kIsUndetectable)); | 878 value_map_bitfield, Int32Constant(1 << Map::kIsUndetectable)); |
879 | 879 |
880 // Check if the {value} is undetectable. | 880 // Check if the {value} is undetectable. |
881 Branch(Word32Equal(value_map_undetectable, Int32Constant(0)), if_true, | 881 Branch(Word32Equal(value_map_undetectable, Int32Constant(0)), if_true, |
882 if_false); | 882 if_false); |
883 } | 883 } |
884 } | 884 } |
885 } | 885 } |
886 | 886 |
887 Node* CodeStubAssembler::LoadFromFrame(int offset, MachineType rep) { | 887 compiler::Node* CodeStubAssembler::LoadFromFrame(int offset, MachineType rep) { |
888 Node* frame_pointer = LoadFramePointer(); | 888 Node* frame_pointer = LoadFramePointer(); |
889 return Load(rep, frame_pointer, IntPtrConstant(offset)); | 889 return Load(rep, frame_pointer, IntPtrConstant(offset)); |
890 } | 890 } |
891 | 891 |
892 Node* CodeStubAssembler::LoadFromParentFrame(int offset, MachineType rep) { | 892 compiler::Node* CodeStubAssembler::LoadFromParentFrame(int offset, |
| 893 MachineType rep) { |
893 Node* frame_pointer = LoadParentFramePointer(); | 894 Node* frame_pointer = LoadParentFramePointer(); |
894 return Load(rep, frame_pointer, IntPtrConstant(offset)); | 895 return Load(rep, frame_pointer, IntPtrConstant(offset)); |
895 } | 896 } |
896 | 897 |
897 Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset, | 898 Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset, |
898 MachineType rep) { | 899 MachineType rep) { |
899 return Load(rep, buffer, IntPtrConstant(offset)); | 900 return Load(rep, buffer, IntPtrConstant(offset)); |
900 } | 901 } |
901 | 902 |
902 Node* CodeStubAssembler::LoadObjectField(Node* object, int offset, | 903 Node* CodeStubAssembler::LoadObjectField(Node* object, int offset, |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 if (Heap::RootIsImmortalImmovable(root_index)) { | 1329 if (Heap::RootIsImmortalImmovable(root_index)) { |
1329 return StoreObjectFieldNoWriteBarrier(object, offset, LoadRoot(root_index)); | 1330 return StoreObjectFieldNoWriteBarrier(object, offset, LoadRoot(root_index)); |
1330 } else { | 1331 } else { |
1331 return StoreObjectField(object, offset, LoadRoot(root_index)); | 1332 return StoreObjectField(object, offset, LoadRoot(root_index)); |
1332 } | 1333 } |
1333 } | 1334 } |
1334 | 1335 |
1335 Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node, | 1336 Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node, |
1336 Node* value, | 1337 Node* value, |
1337 WriteBarrierMode barrier_mode, | 1338 WriteBarrierMode barrier_mode, |
1338 int additional_offset, | |
1339 ParameterMode parameter_mode) { | 1339 ParameterMode parameter_mode) { |
1340 DCHECK(barrier_mode == SKIP_WRITE_BARRIER || | 1340 DCHECK(barrier_mode == SKIP_WRITE_BARRIER || |
1341 barrier_mode == UPDATE_WRITE_BARRIER); | 1341 barrier_mode == UPDATE_WRITE_BARRIER); |
1342 int header_size = | 1342 Node* offset = |
1343 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag; | 1343 ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, parameter_mode, |
1344 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, | 1344 FixedArray::kHeaderSize - kHeapObjectTag); |
1345 parameter_mode, header_size); | |
1346 MachineRepresentation rep = MachineRepresentation::kTagged; | 1345 MachineRepresentation rep = MachineRepresentation::kTagged; |
1347 if (barrier_mode == SKIP_WRITE_BARRIER) { | 1346 if (barrier_mode == SKIP_WRITE_BARRIER) { |
1348 return StoreNoWriteBarrier(rep, object, offset, value); | 1347 return StoreNoWriteBarrier(rep, object, offset, value); |
1349 } else { | 1348 } else { |
1350 return Store(rep, object, offset, value); | 1349 return Store(rep, object, offset, value); |
1351 } | 1350 } |
1352 } | 1351 } |
1353 | 1352 |
1354 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( | 1353 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( |
1355 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { | 1354 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { |
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 Bind(&next_iter); | 2067 Bind(&next_iter); |
2069 Node* compare = WordNotEqual(from_offset, limit_offset); | 2068 Node* compare = WordNotEqual(from_offset, limit_offset); |
2070 Branch(compare, &decrement, &done); | 2069 Branch(compare, &decrement, &done); |
2071 } | 2070 } |
2072 | 2071 |
2073 Bind(&done); | 2072 Bind(&done); |
2074 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1); | 2073 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1); |
2075 Comment("] CopyFixedArrayElements"); | 2074 Comment("] CopyFixedArrayElements"); |
2076 } | 2075 } |
2077 | 2076 |
2078 void CodeStubAssembler::CopyStringCharacters(Node* from_string, Node* to_string, | 2077 void CodeStubAssembler::CopyStringCharacters( |
2079 Node* from_index, Node* to_index, | 2078 compiler::Node* from_string, compiler::Node* to_string, |
2080 Node* character_count, | 2079 compiler::Node* from_index, compiler::Node* to_index, |
2081 String::Encoding from_encoding, | 2080 compiler::Node* character_count, String::Encoding from_encoding, |
2082 String::Encoding to_encoding, | 2081 String::Encoding to_encoding, ParameterMode mode) { |
2083 ParameterMode mode) { | |
2084 bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING; | 2082 bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING; |
2085 bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING; | 2083 bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING; |
2086 DCHECK_IMPLIES(to_one_byte, from_one_byte); | 2084 DCHECK_IMPLIES(to_one_byte, from_one_byte); |
2087 Comment("CopyStringCharacters %s -> %s", | 2085 Comment("CopyStringCharacters %s -> %s", |
2088 from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING", | 2086 from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING", |
2089 to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING"); | 2087 to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING"); |
2090 | 2088 |
2091 ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; | 2089 ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; |
2092 ElementsKind to_kind = to_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; | 2090 ElementsKind to_kind = to_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; |
2093 STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize); | 2091 STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 // The size-check above guarantees that the |new_elements| is allocated | 2230 // The size-check above guarantees that the |new_elements| is allocated |
2233 // in new space so we can skip the write barrier. | 2231 // in new space so we can skip the write barrier. |
2234 CopyFixedArrayElements(from_kind, elements, to_kind, new_elements, capacity, | 2232 CopyFixedArrayElements(from_kind, elements, to_kind, new_elements, capacity, |
2235 new_capacity, SKIP_WRITE_BARRIER, mode); | 2233 new_capacity, SKIP_WRITE_BARRIER, mode); |
2236 | 2234 |
2237 StoreObjectField(object, JSObject::kElementsOffset, new_elements); | 2235 StoreObjectField(object, JSObject::kElementsOffset, new_elements); |
2238 Comment("] GrowElementsCapacity"); | 2236 Comment("] GrowElementsCapacity"); |
2239 return new_elements; | 2237 return new_elements; |
2240 } | 2238 } |
2241 | 2239 |
2242 void CodeStubAssembler::InitializeAllocationMemento(Node* base_allocation, | 2240 void CodeStubAssembler::InitializeAllocationMemento( |
2243 int base_allocation_size, | 2241 compiler::Node* base_allocation, int base_allocation_size, |
2244 Node* allocation_site) { | 2242 compiler::Node* allocation_site) { |
2245 StoreObjectFieldNoWriteBarrier( | 2243 StoreObjectFieldNoWriteBarrier( |
2246 base_allocation, AllocationMemento::kMapOffset + base_allocation_size, | 2244 base_allocation, AllocationMemento::kMapOffset + base_allocation_size, |
2247 HeapConstant(Handle<Map>(isolate()->heap()->allocation_memento_map()))); | 2245 HeapConstant(Handle<Map>(isolate()->heap()->allocation_memento_map()))); |
2248 StoreObjectFieldNoWriteBarrier( | 2246 StoreObjectFieldNoWriteBarrier( |
2249 base_allocation, | 2247 base_allocation, |
2250 AllocationMemento::kAllocationSiteOffset + base_allocation_size, | 2248 AllocationMemento::kAllocationSiteOffset + base_allocation_size, |
2251 allocation_site); | 2249 allocation_site); |
2252 if (FLAG_allocation_site_pretenuring) { | 2250 if (FLAG_allocation_site_pretenuring) { |
2253 Node* count = LoadObjectField(allocation_site, | 2251 Node* count = LoadObjectField(allocation_site, |
2254 AllocationSite::kPretenureCreateCountOffset); | 2252 AllocationSite::kPretenureCreateCountOffset); |
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3435 Node* const result = | 3433 Node* const result = |
3436 CallRuntime(Runtime::kStringIndexOf, context, string, pattern, from); | 3434 CallRuntime(Runtime::kStringIndexOf, context, string, pattern, from); |
3437 var_result.Bind(result); | 3435 var_result.Bind(result); |
3438 Goto(&out); | 3436 Goto(&out); |
3439 } | 3437 } |
3440 | 3438 |
3441 Bind(&out); | 3439 Bind(&out); |
3442 return var_result.value(); | 3440 return var_result.value(); |
3443 } | 3441 } |
3444 | 3442 |
3445 Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint, | 3443 Node* CodeStubAssembler::StringFromCodePoint(compiler::Node* codepoint, |
3446 UnicodeEncoding encoding) { | 3444 UnicodeEncoding encoding) { |
3447 Variable var_result(this, MachineRepresentation::kTagged); | 3445 Variable var_result(this, MachineRepresentation::kTagged); |
3448 var_result.Bind(EmptyStringConstant()); | 3446 var_result.Bind(EmptyStringConstant()); |
3449 | 3447 |
3450 Label if_isword16(this), if_isword32(this), return_result(this); | 3448 Label if_isword16(this), if_isword32(this), return_result(this); |
3451 | 3449 |
3452 Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16, | 3450 Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16, |
3453 &if_isword32); | 3451 &if_isword32); |
3454 | 3452 |
3455 Bind(&if_isword16); | 3453 Bind(&if_isword16); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3513 Bind(&runtime); | 3511 Bind(&runtime); |
3514 { | 3512 { |
3515 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input)); | 3513 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input)); |
3516 Goto(&end); | 3514 Goto(&end); |
3517 } | 3515 } |
3518 | 3516 |
3519 Bind(&end); | 3517 Bind(&end); |
3520 return var_result.value(); | 3518 return var_result.value(); |
3521 } | 3519 } |
3522 | 3520 |
3523 Node* CodeStubAssembler::NumberToString(Node* context, Node* argument) { | 3521 Node* CodeStubAssembler::NumberToString(compiler::Node* context, |
| 3522 compiler::Node* argument) { |
3524 Variable result(this, MachineRepresentation::kTagged); | 3523 Variable result(this, MachineRepresentation::kTagged); |
3525 Label runtime(this, Label::kDeferred); | 3524 Label runtime(this, Label::kDeferred); |
3526 Label smi(this); | 3525 Label smi(this); |
3527 Label done(this, &result); | 3526 Label done(this, &result); |
3528 | 3527 |
3529 // Load the number string cache. | 3528 // Load the number string cache. |
3530 Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex); | 3529 Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex); |
3531 | 3530 |
3532 // Make the hash mask from the length of the number string cache. It | 3531 // Make the hash mask from the length of the number string cache. It |
3533 // contains two elements (number and string) for each cache entry. | 3532 // contains two elements (number and string) for each cache entry. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3592 result.Bind(LoadFixedArrayElement(number_string_cache, smi_index, | 3591 result.Bind(LoadFixedArrayElement(number_string_cache, smi_index, |
3593 kPointerSize, SMI_PARAMETERS)); | 3592 kPointerSize, SMI_PARAMETERS)); |
3594 Goto(&done); | 3593 Goto(&done); |
3595 } | 3594 } |
3596 | 3595 |
3597 Bind(&done); | 3596 Bind(&done); |
3598 return result.value(); | 3597 return result.value(); |
3599 } | 3598 } |
3600 | 3599 |
3601 Node* CodeStubAssembler::ToName(Node* context, Node* value) { | 3600 Node* CodeStubAssembler::ToName(Node* context, Node* value) { |
| 3601 typedef CodeStubAssembler::Label Label; |
| 3602 typedef CodeStubAssembler::Variable Variable; |
| 3603 |
3602 Label end(this); | 3604 Label end(this); |
3603 Variable var_result(this, MachineRepresentation::kTagged); | 3605 Variable var_result(this, MachineRepresentation::kTagged); |
3604 | 3606 |
3605 Label is_number(this); | 3607 Label is_number(this); |
3606 GotoIf(TaggedIsSmi(value), &is_number); | 3608 GotoIf(TaggedIsSmi(value), &is_number); |
3607 | 3609 |
3608 Label not_name(this); | 3610 Label not_name(this); |
3609 Node* value_instance_type = LoadInstanceType(value); | 3611 Node* value_instance_type = LoadInstanceType(value); |
3610 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); | 3612 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); |
3611 GotoIf(Int32GreaterThan(value_instance_type, Int32Constant(LAST_NAME_TYPE)), | 3613 GotoIf(Int32GreaterThan(value_instance_type, Int32Constant(LAST_NAME_TYPE)), |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4027 Node* capacity = IntPtrRoundUpToPowerOfTwo32( | 4029 Node* capacity = IntPtrRoundUpToPowerOfTwo32( |
4028 WordShl(at_least_space_for, IntPtrConstant(1))); | 4030 WordShl(at_least_space_for, IntPtrConstant(1))); |
4029 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); | 4031 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); |
4030 } | 4032 } |
4031 | 4033 |
4032 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { | 4034 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { |
4033 return Select(IntPtrGreaterThanOrEqual(left, right), left, right, | 4035 return Select(IntPtrGreaterThanOrEqual(left, right), left, right, |
4034 MachineType::PointerRepresentation()); | 4036 MachineType::PointerRepresentation()); |
4035 } | 4037 } |
4036 | 4038 |
4037 template <class Dictionary> | |
4038 Node* CodeStubAssembler::GetNumberOfElements(Node* dictionary) { | |
4039 return LoadFixedArrayElement( | |
4040 dictionary, IntPtrConstant(Dictionary::kNumberOfElementsIndex), 0, | |
4041 INTPTR_PARAMETERS); | |
4042 } | |
4043 | |
4044 template <class Dictionary> | |
4045 void CodeStubAssembler::SetNumberOfElements(Node* dictionary, | |
4046 Node* num_elements_smi) { | |
4047 StoreFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex, | |
4048 num_elements_smi, SKIP_WRITE_BARRIER); | |
4049 } | |
4050 | |
4051 template <class Dictionary> | |
4052 Node* CodeStubAssembler::GetCapacity(Node* dictionary) { | |
4053 return LoadFixedArrayElement(dictionary, | |
4054 IntPtrConstant(Dictionary::kCapacityIndex), 0, | |
4055 INTPTR_PARAMETERS); | |
4056 } | |
4057 | |
4058 template <class Dictionary> | |
4059 Node* CodeStubAssembler::GetNextEnumerationIndex(Node* dictionary) { | |
4060 return LoadFixedArrayElement( | |
4061 dictionary, IntPtrConstant(Dictionary::kNextEnumerationIndexIndex), 0, | |
4062 INTPTR_PARAMETERS); | |
4063 } | |
4064 | |
4065 template <class Dictionary> | |
4066 void CodeStubAssembler::SetNextEnumerationIndex(Node* dictionary, | |
4067 Node* next_enum_index_smi) { | |
4068 StoreFixedArrayElement(dictionary, Dictionary::kNextEnumerationIndexIndex, | |
4069 next_enum_index_smi, SKIP_WRITE_BARRIER); | |
4070 } | |
4071 | |
4072 template <typename Dictionary> | 4039 template <typename Dictionary> |
4073 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, | 4040 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, |
4074 Node* unique_name, Label* if_found, | 4041 Node* unique_name, Label* if_found, |
4075 Variable* var_name_index, | 4042 Variable* var_name_index, |
4076 Label* if_not_found, | 4043 Label* if_not_found, |
4077 int inlined_probes, | 4044 int inlined_probes) { |
4078 LookupMode mode) { | |
4079 CSA_ASSERT(this, IsDictionary(dictionary)); | 4045 CSA_ASSERT(this, IsDictionary(dictionary)); |
4080 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 4046 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
4081 DCHECK_IMPLIES(mode == kFindInsertionIndex, | |
4082 inlined_probes == 0 && if_found == nullptr); | |
4083 Comment("NameDictionaryLookup"); | 4047 Comment("NameDictionaryLookup"); |
4084 | 4048 |
4085 Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary)); | 4049 Node* capacity = SmiUntag(LoadFixedArrayElement( |
| 4050 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0, |
| 4051 INTPTR_PARAMETERS)); |
4086 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); | 4052 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); |
4087 Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name)); | 4053 Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name)); |
4088 | 4054 |
4089 // See Dictionary::FirstProbe(). | 4055 // See Dictionary::FirstProbe(). |
4090 Node* count = IntPtrConstant(0); | 4056 Node* count = IntPtrConstant(0); |
4091 Node* entry = WordAnd(hash, mask); | 4057 Node* entry = WordAnd(hash, mask); |
4092 | 4058 |
4093 for (int i = 0; i < inlined_probes; i++) { | 4059 for (int i = 0; i < inlined_probes; i++) { |
4094 Node* index = EntryToIndex<Dictionary>(entry); | 4060 Node* index = EntryToIndex<Dictionary>(entry); |
4095 var_name_index->Bind(index); | 4061 var_name_index->Bind(index); |
4096 | 4062 |
4097 Node* current = | 4063 Node* current = |
4098 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); | 4064 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
4099 GotoIf(WordEqual(current, unique_name), if_found); | 4065 GotoIf(WordEqual(current, unique_name), if_found); |
4100 | 4066 |
4101 // See Dictionary::NextProbe(). | 4067 // See Dictionary::NextProbe(). |
4102 count = IntPtrConstant(i + 1); | 4068 count = IntPtrConstant(i + 1); |
4103 entry = WordAnd(IntPtrAdd(entry, count), mask); | 4069 entry = WordAnd(IntPtrAdd(entry, count), mask); |
4104 } | 4070 } |
4105 if (mode == kFindInsertionIndex) { | |
4106 // Appease the variable merging algorithm for "Goto(&loop)" below. | |
4107 var_name_index->Bind(IntPtrConstant(0)); | |
4108 } | |
4109 | 4071 |
4110 Node* undefined = UndefinedConstant(); | 4072 Node* undefined = UndefinedConstant(); |
4111 Node* the_hole = mode == kFindExisting ? nullptr : TheHoleConstant(); | |
4112 | 4073 |
4113 Variable var_count(this, MachineType::PointerRepresentation()); | 4074 Variable var_count(this, MachineType::PointerRepresentation()); |
4114 Variable var_entry(this, MachineType::PointerRepresentation()); | 4075 Variable var_entry(this, MachineType::PointerRepresentation()); |
4115 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; | 4076 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; |
4116 Label loop(this, 3, loop_vars); | 4077 Label loop(this, 3, loop_vars); |
4117 var_count.Bind(count); | 4078 var_count.Bind(count); |
4118 var_entry.Bind(entry); | 4079 var_entry.Bind(entry); |
4119 Goto(&loop); | 4080 Goto(&loop); |
4120 Bind(&loop); | 4081 Bind(&loop); |
4121 { | 4082 { |
4122 Node* count = var_count.value(); | 4083 Node* count = var_count.value(); |
4123 Node* entry = var_entry.value(); | 4084 Node* entry = var_entry.value(); |
4124 | 4085 |
4125 Node* index = EntryToIndex<Dictionary>(entry); | 4086 Node* index = EntryToIndex<Dictionary>(entry); |
4126 var_name_index->Bind(index); | 4087 var_name_index->Bind(index); |
4127 | 4088 |
4128 Node* current = | 4089 Node* current = |
4129 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); | 4090 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
4130 GotoIf(WordEqual(current, undefined), if_not_found); | 4091 GotoIf(WordEqual(current, undefined), if_not_found); |
4131 if (mode == kFindExisting) { | 4092 GotoIf(WordEqual(current, unique_name), if_found); |
4132 GotoIf(WordEqual(current, unique_name), if_found); | |
4133 } else { | |
4134 DCHECK_EQ(kFindInsertionIndex, mode); | |
4135 GotoIf(WordEqual(current, the_hole), if_not_found); | |
4136 } | |
4137 | 4093 |
4138 // See Dictionary::NextProbe(). | 4094 // See Dictionary::NextProbe(). |
4139 count = IntPtrAdd(count, IntPtrConstant(1)); | 4095 count = IntPtrAdd(count, IntPtrConstant(1)); |
4140 entry = WordAnd(IntPtrAdd(entry, count), mask); | 4096 entry = WordAnd(IntPtrAdd(entry, count), mask); |
4141 | 4097 |
4142 var_count.Bind(count); | 4098 var_count.Bind(count); |
4143 var_entry.Bind(entry); | 4099 var_entry.Bind(entry); |
4144 Goto(&loop); | 4100 Goto(&loop); |
4145 } | 4101 } |
4146 } | 4102 } |
4147 | 4103 |
4148 // Instantiate template methods to workaround GCC compilation issue. | 4104 // Instantiate template methods to workaround GCC compilation issue. |
4149 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( | 4105 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( |
4150 Node*, Node*, Label*, Variable*, Label*, int, LookupMode); | 4106 Node*, Node*, Label*, Variable*, Label*, int); |
4151 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>( | 4107 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>( |
4152 Node*, Node*, Label*, Variable*, Label*, int, LookupMode); | 4108 Node*, Node*, Label*, Variable*, Label*, int); |
4153 | 4109 |
4154 Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) { | 4110 Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) { |
4155 // See v8::internal::ComputeIntegerHash() | 4111 // See v8::internal::ComputeIntegerHash() |
4156 Node* hash = key; | 4112 Node* hash = key; |
4157 hash = Word32Xor(hash, seed); | 4113 hash = Word32Xor(hash, seed); |
4158 hash = Int32Add(Word32Xor(hash, Int32Constant(0xffffffff)), | 4114 hash = Int32Add(Word32Xor(hash, Int32Constant(0xffffffff)), |
4159 Word32Shl(hash, Int32Constant(15))); | 4115 Word32Shl(hash, Int32Constant(15))); |
4160 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12))); | 4116 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12))); |
4161 hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2))); | 4117 hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2))); |
4162 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4))); | 4118 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4))); |
4163 hash = Int32Mul(hash, Int32Constant(2057)); | 4119 hash = Int32Mul(hash, Int32Constant(2057)); |
4164 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); | 4120 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); |
4165 return Word32And(hash, Int32Constant(0x3fffffff)); | 4121 return Word32And(hash, Int32Constant(0x3fffffff)); |
4166 } | 4122 } |
4167 | 4123 |
4168 template <typename Dictionary> | 4124 template <typename Dictionary> |
4169 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, | 4125 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, |
4170 Node* intptr_index, | 4126 Node* intptr_index, |
4171 Label* if_found, | 4127 Label* if_found, |
4172 Variable* var_entry, | 4128 Variable* var_entry, |
4173 Label* if_not_found) { | 4129 Label* if_not_found) { |
4174 CSA_ASSERT(this, IsDictionary(dictionary)); | 4130 CSA_ASSERT(this, IsDictionary(dictionary)); |
4175 DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep()); | 4131 DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep()); |
4176 Comment("NumberDictionaryLookup"); | 4132 Comment("NumberDictionaryLookup"); |
4177 | 4133 |
4178 Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary)); | 4134 Node* capacity = SmiUntag(LoadFixedArrayElement( |
| 4135 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0, |
| 4136 INTPTR_PARAMETERS)); |
4179 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); | 4137 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); |
4180 | 4138 |
4181 Node* int32_seed; | 4139 Node* int32_seed; |
4182 if (Dictionary::ShapeT::UsesSeed) { | 4140 if (Dictionary::ShapeT::UsesSeed) { |
4183 int32_seed = HashSeed(); | 4141 int32_seed = HashSeed(); |
4184 } else { | 4142 } else { |
4185 int32_seed = Int32Constant(kZeroHashSeed); | 4143 int32_seed = Int32Constant(kZeroHashSeed); |
4186 } | 4144 } |
4187 Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed)); | 4145 Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed)); |
4188 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index); | 4146 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4232 // See Dictionary::NextProbe(). | 4190 // See Dictionary::NextProbe(). |
4233 count = IntPtrAdd(count, IntPtrConstant(1)); | 4191 count = IntPtrAdd(count, IntPtrConstant(1)); |
4234 entry = WordAnd(IntPtrAdd(entry, count), mask); | 4192 entry = WordAnd(IntPtrAdd(entry, count), mask); |
4235 | 4193 |
4236 var_count.Bind(count); | 4194 var_count.Bind(count); |
4237 var_entry->Bind(entry); | 4195 var_entry->Bind(entry); |
4238 Goto(&loop); | 4196 Goto(&loop); |
4239 } | 4197 } |
4240 } | 4198 } |
4241 | 4199 |
4242 template <class Dictionary> | |
4243 void CodeStubAssembler::FindInsertionEntry(Node* dictionary, Node* key, | |
4244 Variable* var_key_index) { | |
4245 UNREACHABLE(); | |
4246 } | |
4247 | |
4248 template <> | |
4249 void CodeStubAssembler::FindInsertionEntry<NameDictionary>( | |
4250 Node* dictionary, Node* key, Variable* var_key_index) { | |
4251 Label done(this); | |
4252 NameDictionaryLookup<NameDictionary>(dictionary, key, nullptr, var_key_index, | |
4253 &done, 0, kFindInsertionIndex); | |
4254 Bind(&done); | |
4255 } | |
4256 | |
4257 template <class Dictionary> | |
4258 void CodeStubAssembler::InsertEntry(Node* dictionary, Node* key, Node* value, | |
4259 Node* index, Node* enum_index) { | |
4260 // This implementation works for dictionaries with details. | |
4261 STATIC_ASSERT(Dictionary::kEntrySize == 3); | |
4262 | |
4263 StoreFixedArrayElement(dictionary, index, key, UPDATE_WRITE_BARRIER, 0, | |
4264 INTPTR_PARAMETERS); | |
4265 const int kNameToValueOffset = | |
4266 (Dictionary::kEntryValueIndex - Dictionary::kEntryKeyIndex) * | |
4267 kPointerSize; | |
4268 StoreFixedArrayElement(dictionary, index, value, UPDATE_WRITE_BARRIER, | |
4269 kNameToValueOffset, INTPTR_PARAMETERS); | |
4270 const int kInitialIndex = 0; | |
4271 PropertyDetails d(NONE, DATA, kInitialIndex, PropertyCellType::kNoCell); | |
4272 Node* details = SmiConstant(d.AsSmi()); | |
4273 if (Dictionary::kIsEnumerable) { | |
4274 enum_index = | |
4275 WordShl(enum_index, PropertyDetails::DictionaryStorageField::kShift); | |
4276 STATIC_ASSERT(kInitialIndex == 0); | |
4277 details = WordOr(details, enum_index); | |
4278 } | |
4279 const int kNameToDetailsOffset = | |
4280 (Dictionary::kEntryDetailsIndex - Dictionary::kEntryKeyIndex) * | |
4281 kPointerSize; | |
4282 StoreFixedArrayElement(dictionary, index, details, SKIP_WRITE_BARRIER, | |
4283 kNameToDetailsOffset, INTPTR_PARAMETERS); | |
4284 } | |
4285 | |
4286 template <> | |
4287 void CodeStubAssembler::InsertEntry<GlobalDictionary>(Node* dictionary, | |
4288 Node* key, Node* value, | |
4289 Node* index, | |
4290 Node* enum_index) { | |
4291 UNIMPLEMENTED(); | |
4292 } | |
4293 | |
4294 template <class Dictionary> | |
4295 void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value, | |
4296 Label* bailout) { | |
4297 Node* capacity = GetCapacity<Dictionary>(dictionary); | |
4298 Node* nof = GetNumberOfElements<Dictionary>(dictionary); | |
4299 Node* new_nof = SmiAdd(nof, SmiConstant(1)); | |
4300 // Require 33% to still be free after adding additional_elements. | |
4301 // This is a simplification of the C++ implementation's behavior, which | |
4302 // also rehashes the dictionary when there are too many deleted elements. | |
4303 // Computing "x + (x >> 1)" on a Smi x does not return a valid Smi! | |
4304 // But that's OK here because it's only used for a comparison. | |
4305 Node* required_capacity_pseudo_smi = SmiAdd(new_nof, WordShr(new_nof, 1)); | |
4306 GotoIf(UintPtrLessThan(capacity, required_capacity_pseudo_smi), bailout); | |
4307 Node* enum_index = nullptr; | |
4308 if (Dictionary::kIsEnumerable) { | |
4309 enum_index = GetNextEnumerationIndex<Dictionary>(dictionary); | |
4310 Node* new_enum_index = SmiAdd(enum_index, SmiConstant(1)); | |
4311 Node* max_enum_index = | |
4312 SmiConstant(PropertyDetails::DictionaryStorageField::kMax); | |
4313 GotoIf(UintPtrGreaterThan(new_enum_index, max_enum_index), bailout); | |
4314 | |
4315 // No more bailouts after this point. | |
4316 // Operations from here on can have side effects. | |
4317 | |
4318 SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index); | |
4319 } else { | |
4320 USE(enum_index); | |
4321 } | |
4322 SetNumberOfElements<Dictionary>(dictionary, new_nof); | |
4323 | |
4324 Variable var_key_index(this, MachineType::PointerRepresentation()); | |
4325 FindInsertionEntry<Dictionary>(dictionary, key, &var_key_index); | |
4326 InsertEntry<Dictionary>(dictionary, key, value, var_key_index.value(), | |
4327 enum_index); | |
4328 } | |
4329 | |
4330 template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*, | |
4331 Label*); | |
4332 | |
4333 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, | 4200 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, |
4334 Node* descriptors, Node* nof, | 4201 Node* descriptors, Node* nof, |
4335 Label* if_found, | 4202 Label* if_found, |
4336 Variable* var_name_index, | 4203 Variable* var_name_index, |
4337 Label* if_not_found) { | 4204 Label* if_not_found) { |
4338 Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); | 4205 Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); |
4339 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); | 4206 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); |
4340 Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor)); | 4207 Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor)); |
4341 | 4208 |
4342 BuildFastLoop( | 4209 BuildFastLoop( |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4415 if_bailout); | 4282 if_bailout); |
4416 | 4283 |
4417 Node* dictionary = LoadProperties(object); | 4284 Node* dictionary = LoadProperties(object); |
4418 var_meta_storage->Bind(dictionary); | 4285 var_meta_storage->Bind(dictionary); |
4419 | 4286 |
4420 NameDictionaryLookup<GlobalDictionary>( | 4287 NameDictionaryLookup<GlobalDictionary>( |
4421 dictionary, unique_name, if_found_global, var_name_index, if_not_found); | 4288 dictionary, unique_name, if_found_global, var_name_index, if_not_found); |
4422 } | 4289 } |
4423 } | 4290 } |
4424 | 4291 |
4425 void CodeStubAssembler::TryHasOwnProperty(Node* object, Node* map, | 4292 void CodeStubAssembler::TryHasOwnProperty(compiler::Node* object, |
4426 Node* instance_type, | 4293 compiler::Node* map, |
4427 Node* unique_name, Label* if_found, | 4294 compiler::Node* instance_type, |
4428 Label* if_not_found, | 4295 compiler::Node* unique_name, |
| 4296 Label* if_found, Label* if_not_found, |
4429 Label* if_bailout) { | 4297 Label* if_bailout) { |
4430 Comment("TryHasOwnProperty"); | 4298 Comment("TryHasOwnProperty"); |
4431 Variable var_meta_storage(this, MachineRepresentation::kTagged); | 4299 Variable var_meta_storage(this, MachineRepresentation::kTagged); |
4432 Variable var_name_index(this, MachineType::PointerRepresentation()); | 4300 Variable var_name_index(this, MachineType::PointerRepresentation()); |
4433 | 4301 |
4434 Label if_found_global(this); | 4302 Label if_found_global(this); |
4435 TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found, | 4303 TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found, |
4436 &if_found_global, &var_meta_storage, &var_name_index, | 4304 &if_found_global, &var_meta_storage, &var_name_index, |
4437 if_not_found, if_bailout); | 4305 if_not_found, if_bailout); |
4438 Bind(&if_found_global); | 4306 Bind(&if_found_global); |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5050 // Fallback to the runtime implementation. | 4918 // Fallback to the runtime implementation. |
5051 var_result.Bind( | 4919 var_result.Bind( |
5052 CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); | 4920 CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); |
5053 } | 4921 } |
5054 Goto(&return_result); | 4922 Goto(&return_result); |
5055 | 4923 |
5056 Bind(&return_result); | 4924 Bind(&return_result); |
5057 return var_result.value(); | 4925 return var_result.value(); |
5058 } | 4926 } |
5059 | 4927 |
5060 Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, | 4928 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, |
5061 ElementsKind kind, | 4929 ElementsKind kind, |
5062 ParameterMode mode, | 4930 ParameterMode mode, |
5063 int base_size) { | 4931 int base_size) { |
5064 int element_size_shift = ElementsKindToShiftSize(kind); | 4932 int element_size_shift = ElementsKindToShiftSize(kind); |
5065 int element_size = 1 << element_size_shift; | 4933 int element_size = 1 << element_size_shift; |
5066 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; | 4934 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; |
5067 intptr_t index = 0; | 4935 intptr_t index = 0; |
5068 bool constant_index = false; | 4936 bool constant_index = false; |
5069 if (mode == SMI_PARAMETERS) { | 4937 if (mode == SMI_PARAMETERS) { |
5070 element_size_shift -= kSmiShiftBits; | 4938 element_size_shift -= kSmiShiftBits; |
5071 Smi* smi_index; | 4939 Smi* smi_index; |
5072 constant_index = ToSmiConstant(index_node, smi_index); | 4940 constant_index = ToSmiConstant(index_node, smi_index); |
5073 if (constant_index) index = smi_index->value(); | 4941 if (constant_index) index = smi_index->value(); |
(...skipping 15 matching lines...) Expand all Loading... |
5089 | 4957 |
5090 Node* shifted_index = | 4958 Node* shifted_index = |
5091 (element_size_shift == 0) | 4959 (element_size_shift == 0) |
5092 ? index_node | 4960 ? index_node |
5093 : ((element_size_shift > 0) | 4961 : ((element_size_shift > 0) |
5094 ? WordShl(index_node, IntPtrConstant(element_size_shift)) | 4962 ? WordShl(index_node, IntPtrConstant(element_size_shift)) |
5095 : WordShr(index_node, IntPtrConstant(-element_size_shift))); | 4963 : WordShr(index_node, IntPtrConstant(-element_size_shift))); |
5096 return IntPtrAddFoldConstants(IntPtrConstant(base_size), shifted_index); | 4964 return IntPtrAddFoldConstants(IntPtrConstant(base_size), shifted_index); |
5097 } | 4965 } |
5098 | 4966 |
5099 Node* CodeStubAssembler::LoadTypeFeedbackVectorForStub() { | 4967 compiler::Node* CodeStubAssembler::LoadTypeFeedbackVectorForStub() { |
5100 Node* function = | 4968 Node* function = |
5101 LoadFromParentFrame(JavaScriptFrameConstants::kFunctionOffset); | 4969 LoadFromParentFrame(JavaScriptFrameConstants::kFunctionOffset); |
5102 Node* literals = LoadObjectField(function, JSFunction::kLiteralsOffset); | 4970 Node* literals = LoadObjectField(function, JSFunction::kLiteralsOffset); |
5103 return LoadObjectField(literals, LiteralsArray::kFeedbackVectorOffset); | 4971 return LoadObjectField(literals, LiteralsArray::kFeedbackVectorOffset); |
5104 } | 4972 } |
5105 | 4973 |
5106 void CodeStubAssembler::UpdateFeedback(Node* feedback, | 4974 void CodeStubAssembler::UpdateFeedback(compiler::Node* feedback, |
5107 Node* type_feedback_vector, | 4975 compiler::Node* type_feedback_vector, |
5108 Node* slot_id) { | 4976 compiler::Node* slot_id) { |
5109 // This method is used for binary op and compare feedback. These | 4977 // This method is used for binary op and compare feedback. These |
5110 // vector nodes are initialized with a smi 0, so we can simply OR | 4978 // vector nodes are initialized with a smi 0, so we can simply OR |
5111 // our new feedback in place. | 4979 // our new feedback in place. |
5112 // TODO(interpreter): Consider passing the feedback as Smi already to avoid | 4980 // TODO(interpreter): Consider passing the feedback as Smi already to avoid |
5113 // the tagging completely. | 4981 // the tagging completely. |
5114 Node* previous_feedback = | 4982 Node* previous_feedback = |
5115 LoadFixedArrayElement(type_feedback_vector, slot_id); | 4983 LoadFixedArrayElement(type_feedback_vector, slot_id); |
5116 Node* combined_feedback = SmiOr(previous_feedback, SmiFromWord32(feedback)); | 4984 Node* combined_feedback = SmiOr(previous_feedback, SmiFromWord32(feedback)); |
5117 StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, | 4985 StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, |
5118 SKIP_WRITE_BARRIER); | 4986 SKIP_WRITE_BARRIER); |
5119 } | 4987 } |
5120 | 4988 |
5121 Node* CodeStubAssembler::LoadReceiverMap(Node* receiver) { | 4989 compiler::Node* CodeStubAssembler::LoadReceiverMap(compiler::Node* receiver) { |
5122 Variable var_receiver_map(this, MachineRepresentation::kTagged); | 4990 Variable var_receiver_map(this, MachineRepresentation::kTagged); |
5123 Label load_smi_map(this, Label::kDeferred), load_receiver_map(this), | 4991 Label load_smi_map(this, Label::kDeferred), load_receiver_map(this), |
5124 if_result(this); | 4992 if_result(this); |
5125 | 4993 |
5126 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map); | 4994 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map); |
5127 Bind(&load_smi_map); | 4995 Bind(&load_smi_map); |
5128 { | 4996 { |
5129 var_receiver_map.Bind(LoadRoot(Heap::kHeapNumberMapRootIndex)); | 4997 var_receiver_map.Bind(LoadRoot(Heap::kHeapNumberMapRootIndex)); |
5130 Goto(&if_result); | 4998 Goto(&if_result); |
5131 } | 4999 } |
(...skipping 23 matching lines...) Expand all Loading... |
5155 Bind(&key_is_smi); | 5023 Bind(&key_is_smi); |
5156 { | 5024 { |
5157 var_intptr_key.Bind(SmiUntag(key)); | 5025 var_intptr_key.Bind(SmiUntag(key)); |
5158 Goto(&done); | 5026 Goto(&done); |
5159 } | 5027 } |
5160 | 5028 |
5161 Bind(&done); | 5029 Bind(&done); |
5162 return var_intptr_key.value(); | 5030 return var_intptr_key.value(); |
5163 } | 5031 } |
5164 | 5032 |
5165 void CodeStubAssembler::ExtendPropertiesBackingStore(Node* object) { | 5033 void CodeStubAssembler::ExtendPropertiesBackingStore(compiler::Node* object) { |
5166 Node* properties = LoadProperties(object); | 5034 Node* properties = LoadProperties(object); |
5167 Node* length = LoadFixedArrayBaseLength(properties); | 5035 Node* length = LoadFixedArrayBaseLength(properties); |
5168 | 5036 |
5169 ParameterMode mode = OptimalParameterMode(); | 5037 ParameterMode mode = OptimalParameterMode(); |
5170 length = UntagParameter(length, mode); | 5038 length = UntagParameter(length, mode); |
5171 | 5039 |
5172 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); | 5040 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); |
5173 Node* new_capacity = IntPtrAdd(length, delta); | 5041 Node* new_capacity = IntPtrAdd(length, delta); |
5174 | 5042 |
5175 // Grow properties array. | 5043 // Grow properties array. |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5319 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); | 5187 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); |
5320 DCHECK_EQ(Context::SlotOffset(0) + kHeapObjectTag, | 5188 DCHECK_EQ(Context::SlotOffset(0) + kHeapObjectTag, |
5321 FixedArray::OffsetOfElementAt(0)); | 5189 FixedArray::OffsetOfElementAt(0)); |
5322 if (is_load) { | 5190 if (is_load) { |
5323 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0, | 5191 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0, |
5324 INTPTR_PARAMETERS); | 5192 INTPTR_PARAMETERS); |
5325 CSA_ASSERT(this, WordNotEqual(result, TheHoleConstant())); | 5193 CSA_ASSERT(this, WordNotEqual(result, TheHoleConstant())); |
5326 var_result.Bind(result); | 5194 var_result.Bind(result); |
5327 } else { | 5195 } else { |
5328 StoreFixedArrayElement(the_context, mapped_index, value, | 5196 StoreFixedArrayElement(the_context, mapped_index, value, |
5329 UPDATE_WRITE_BARRIER, 0, INTPTR_PARAMETERS); | 5197 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS); |
5330 } | 5198 } |
5331 Goto(&end); | 5199 Goto(&end); |
5332 } | 5200 } |
5333 | 5201 |
5334 Bind(&if_unmapped); | 5202 Bind(&if_unmapped); |
5335 { | 5203 { |
5336 Node* backing_store = LoadFixedArrayElement(elements, IntPtrConstant(1), 0, | 5204 Node* backing_store = LoadFixedArrayElement(elements, IntPtrConstant(1), 0, |
5337 INTPTR_PARAMETERS); | 5205 INTPTR_PARAMETERS); |
5338 GotoIf(WordNotEqual(LoadMap(backing_store), FixedArrayMapConstant()), | 5206 GotoIf(WordNotEqual(LoadMap(backing_store), FixedArrayMapConstant()), |
5339 bailout); | 5207 bailout); |
5340 | 5208 |
5341 Node* backing_store_length = | 5209 Node* backing_store_length = |
5342 LoadAndUntagFixedArrayBaseLength(backing_store); | 5210 LoadAndUntagFixedArrayBaseLength(backing_store); |
5343 GotoIf(UintPtrGreaterThanOrEqual(key, backing_store_length), bailout); | 5211 GotoIf(UintPtrGreaterThanOrEqual(key, backing_store_length), bailout); |
5344 | 5212 |
5345 // The key falls into unmapped range. | 5213 // The key falls into unmapped range. |
5346 if (is_load) { | 5214 if (is_load) { |
5347 Node* result = | 5215 Node* result = |
5348 LoadFixedArrayElement(backing_store, key, 0, INTPTR_PARAMETERS); | 5216 LoadFixedArrayElement(backing_store, key, 0, INTPTR_PARAMETERS); |
5349 GotoIf(WordEqual(result, TheHoleConstant()), bailout); | 5217 GotoIf(WordEqual(result, TheHoleConstant()), bailout); |
5350 var_result.Bind(result); | 5218 var_result.Bind(result); |
5351 } else { | 5219 } else { |
5352 StoreFixedArrayElement(backing_store, key, value, UPDATE_WRITE_BARRIER, 0, | 5220 StoreFixedArrayElement(backing_store, key, value, UPDATE_WRITE_BARRIER, |
5353 INTPTR_PARAMETERS); | 5221 INTPTR_PARAMETERS); |
5354 } | 5222 } |
5355 Goto(&end); | 5223 Goto(&end); |
5356 } | 5224 } |
5357 | 5225 |
5358 Bind(&end); | 5226 Bind(&end); |
5359 return var_result.value(); | 5227 return var_result.value(); |
5360 } | 5228 } |
5361 | 5229 |
5362 Node* CodeStubAssembler::LoadScriptContext(Node* context, int context_index) { | 5230 Node* CodeStubAssembler::LoadScriptContext(Node* context, int context_index) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5425 return; | 5293 return; |
5426 } | 5294 } |
5427 | 5295 |
5428 WriteBarrierMode barrier_mode = | 5296 WriteBarrierMode barrier_mode = |
5429 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; | 5297 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; |
5430 if (IsFastDoubleElementsKind(kind)) { | 5298 if (IsFastDoubleElementsKind(kind)) { |
5431 // Make sure we do not store signalling NaNs into double arrays. | 5299 // Make sure we do not store signalling NaNs into double arrays. |
5432 value = Float64SilenceNaN(value); | 5300 value = Float64SilenceNaN(value); |
5433 StoreFixedDoubleArrayElement(elements, index, value, mode); | 5301 StoreFixedDoubleArrayElement(elements, index, value, mode); |
5434 } else { | 5302 } else { |
5435 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode); | 5303 StoreFixedArrayElement(elements, index, value, barrier_mode, mode); |
5436 } | 5304 } |
5437 } | 5305 } |
5438 | 5306 |
5439 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, | 5307 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, |
5440 bool is_jsarray, | 5308 bool is_jsarray, |
5441 ElementsKind elements_kind, | 5309 ElementsKind elements_kind, |
5442 KeyedAccessStoreMode store_mode, | 5310 KeyedAccessStoreMode store_mode, |
5443 Label* bailout) { | 5311 Label* bailout) { |
5444 Node* elements = LoadElements(object); | 5312 Node* elements = LoadElements(object); |
5445 if (IsFastSmiOrObjectElementsKind(elements_kind) && | 5313 if (IsFastSmiOrObjectElementsKind(elements_kind) && |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5609 length, capacity, mode, bailout); | 5477 length, capacity, mode, bailout); |
5610 | 5478 |
5611 new_elements_var.Bind(new_elements); | 5479 new_elements_var.Bind(new_elements); |
5612 Goto(&done); | 5480 Goto(&done); |
5613 } | 5481 } |
5614 | 5482 |
5615 Bind(&done); | 5483 Bind(&done); |
5616 return new_elements_var.value(); | 5484 return new_elements_var.value(); |
5617 } | 5485 } |
5618 | 5486 |
5619 void CodeStubAssembler::TransitionElementsKind(Node* object, Node* map, | 5487 void CodeStubAssembler::TransitionElementsKind( |
5620 ElementsKind from_kind, | 5488 compiler::Node* object, compiler::Node* map, ElementsKind from_kind, |
5621 ElementsKind to_kind, | 5489 ElementsKind to_kind, bool is_jsarray, Label* bailout) { |
5622 bool is_jsarray, | |
5623 Label* bailout) { | |
5624 DCHECK(!IsFastHoleyElementsKind(from_kind) || | 5490 DCHECK(!IsFastHoleyElementsKind(from_kind) || |
5625 IsFastHoleyElementsKind(to_kind)); | 5491 IsFastHoleyElementsKind(to_kind)); |
5626 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { | 5492 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { |
5627 TrapAllocationMemento(object, bailout); | 5493 TrapAllocationMemento(object, bailout); |
5628 } | 5494 } |
5629 | 5495 |
5630 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { | 5496 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { |
5631 Comment("Non-simple map transition"); | 5497 Comment("Non-simple map transition"); |
5632 Node* elements = LoadElements(object); | 5498 Node* elements = LoadElements(object); |
5633 | 5499 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5819 Node* next_site = LoadBufferObject(site_list, 0); | 5685 Node* next_site = LoadBufferObject(site_list, 0); |
5820 | 5686 |
5821 // TODO(mvstanton): This is a store to a weak pointer, which we may want to | 5687 // TODO(mvstanton): This is a store to a weak pointer, which we may want to |
5822 // mark as such in order to skip the write barrier, once we have a unified | 5688 // mark as such in order to skip the write barrier, once we have a unified |
5823 // system for weakness. For now we decided to keep it like this because having | 5689 // system for weakness. For now we decided to keep it like this because having |
5824 // an initial write barrier backed store makes this pointer strong until the | 5690 // an initial write barrier backed store makes this pointer strong until the |
5825 // next GC, and allocation sites are designed to survive several GCs anyway. | 5691 // next GC, and allocation sites are designed to survive several GCs anyway. |
5826 StoreObjectField(site, AllocationSite::kWeakNextOffset, next_site); | 5692 StoreObjectField(site, AllocationSite::kWeakNextOffset, next_site); |
5827 StoreNoWriteBarrier(MachineRepresentation::kTagged, site_list, site); | 5693 StoreNoWriteBarrier(MachineRepresentation::kTagged, site_list, site); |
5828 | 5694 |
5829 StoreFixedArrayElement(feedback_vector, slot, site, UPDATE_WRITE_BARRIER, 0, | 5695 StoreFixedArrayElement(feedback_vector, slot, site, UPDATE_WRITE_BARRIER, |
5830 CodeStubAssembler::SMI_PARAMETERS); | 5696 CodeStubAssembler::SMI_PARAMETERS); |
5831 return site; | 5697 return site; |
5832 } | 5698 } |
5833 | 5699 |
5834 Node* CodeStubAssembler::CreateWeakCellInFeedbackVector(Node* feedback_vector, | 5700 Node* CodeStubAssembler::CreateWeakCellInFeedbackVector(Node* feedback_vector, |
5835 Node* slot, | 5701 Node* slot, |
5836 Node* value) { | 5702 Node* value) { |
5837 Node* size = IntPtrConstant(WeakCell::kSize); | 5703 Node* size = IntPtrConstant(WeakCell::kSize); |
5838 Node* cell = Allocate(size, CodeStubAssembler::kPretenured); | 5704 Node* cell = Allocate(size, CodeStubAssembler::kPretenured); |
5839 | 5705 |
5840 // Initialize the WeakCell. | 5706 // Initialize the WeakCell. |
5841 StoreObjectFieldRoot(cell, WeakCell::kMapOffset, Heap::kWeakCellMapRootIndex); | 5707 StoreObjectFieldRoot(cell, WeakCell::kMapOffset, Heap::kWeakCellMapRootIndex); |
5842 StoreObjectField(cell, WeakCell::kValueOffset, value); | 5708 StoreObjectField(cell, WeakCell::kValueOffset, value); |
5843 StoreObjectFieldRoot(cell, WeakCell::kNextOffset, | 5709 StoreObjectFieldRoot(cell, WeakCell::kNextOffset, |
5844 Heap::kTheHoleValueRootIndex); | 5710 Heap::kTheHoleValueRootIndex); |
5845 | 5711 |
5846 // Store the WeakCell in the feedback vector. | 5712 // Store the WeakCell in the feedback vector. |
5847 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 0, | 5713 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
5848 CodeStubAssembler::SMI_PARAMETERS); | 5714 CodeStubAssembler::SMI_PARAMETERS); |
5849 return cell; | 5715 return cell; |
5850 } | 5716 } |
5851 | 5717 |
5852 void CodeStubAssembler::BuildFastLoop( | 5718 void CodeStubAssembler::BuildFastLoop( |
5853 const CodeStubAssembler::VariableList& vars, | 5719 const CodeStubAssembler::VariableList& vars, |
5854 MachineRepresentation index_rep, Node* start_index, Node* end_index, | 5720 MachineRepresentation index_rep, Node* start_index, Node* end_index, |
5855 std::function<void(CodeStubAssembler* assembler, Node* index)> body, | 5721 std::function<void(CodeStubAssembler* assembler, Node* index)> body, |
5856 int increment, IndexAdvanceMode mode) { | 5722 int increment, IndexAdvanceMode mode) { |
5857 Variable var(this, index_rep); | 5723 Variable var(this, index_rep); |
(...skipping 18 matching lines...) Expand all Loading... |
5876 body(this, var.value()); | 5742 body(this, var.value()); |
5877 if (mode == IndexAdvanceMode::kPost) { | 5743 if (mode == IndexAdvanceMode::kPost) { |
5878 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); | 5744 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); |
5879 } | 5745 } |
5880 Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop); | 5746 Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop); |
5881 } | 5747 } |
5882 Bind(&after_loop); | 5748 Bind(&after_loop); |
5883 } | 5749 } |
5884 | 5750 |
5885 void CodeStubAssembler::BuildFastFixedArrayForEach( | 5751 void CodeStubAssembler::BuildFastFixedArrayForEach( |
5886 Node* fixed_array, ElementsKind kind, Node* first_element_inclusive, | 5752 compiler::Node* fixed_array, ElementsKind kind, |
5887 Node* last_element_exclusive, | 5753 compiler::Node* first_element_inclusive, |
5888 std::function<void(CodeStubAssembler* assembler, Node* fixed_array, | 5754 compiler::Node* last_element_exclusive, |
5889 Node* offset)> | 5755 std::function<void(CodeStubAssembler* assembler, |
| 5756 compiler::Node* fixed_array, compiler::Node* offset)> |
5890 body, | 5757 body, |
5891 ParameterMode mode, ForEachDirection direction) { | 5758 ParameterMode mode, ForEachDirection direction) { |
5892 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize); | 5759 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize); |
5893 int32_t first_val; | 5760 int32_t first_val; |
5894 bool constant_first = ToInt32Constant(first_element_inclusive, first_val); | 5761 bool constant_first = ToInt32Constant(first_element_inclusive, first_val); |
5895 int32_t last_val; | 5762 int32_t last_val; |
5896 bool constent_last = ToInt32Constant(last_element_exclusive, last_val); | 5763 bool constent_last = ToInt32Constant(last_element_exclusive, last_val); |
5897 if (constant_first && constent_last) { | 5764 if (constant_first && constent_last) { |
5898 int delta = last_val - first_val; | 5765 int delta = last_val - first_val; |
5899 DCHECK(delta >= 0); | 5766 DCHECK(delta >= 0); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5932 MachineType::PointerRepresentation(), start, limit, | 5799 MachineType::PointerRepresentation(), start, limit, |
5933 [fixed_array, body](CodeStubAssembler* assembler, Node* offset) { | 5800 [fixed_array, body](CodeStubAssembler* assembler, Node* offset) { |
5934 body(assembler, fixed_array, offset); | 5801 body(assembler, fixed_array, offset); |
5935 }, | 5802 }, |
5936 direction == ForEachDirection::kReverse ? -increment : increment, | 5803 direction == ForEachDirection::kReverse ? -increment : increment, |
5937 direction == ForEachDirection::kReverse ? IndexAdvanceMode::kPre | 5804 direction == ForEachDirection::kReverse ? IndexAdvanceMode::kPre |
5938 : IndexAdvanceMode::kPost); | 5805 : IndexAdvanceMode::kPost); |
5939 } | 5806 } |
5940 | 5807 |
5941 void CodeStubAssembler::BranchIfNumericRelationalComparison( | 5808 void CodeStubAssembler::BranchIfNumericRelationalComparison( |
5942 RelationalComparisonMode mode, Node* lhs, Node* rhs, Label* if_true, | 5809 RelationalComparisonMode mode, compiler::Node* lhs, compiler::Node* rhs, |
5943 Label* if_false) { | 5810 Label* if_true, Label* if_false) { |
| 5811 typedef compiler::Node Node; |
| 5812 |
5944 Label end(this); | 5813 Label end(this); |
5945 Variable result(this, MachineRepresentation::kTagged); | 5814 Variable result(this, MachineRepresentation::kTagged); |
5946 | 5815 |
5947 // Shared entry for floating point comparison. | 5816 // Shared entry for floating point comparison. |
5948 Label do_fcmp(this); | 5817 Label do_fcmp(this); |
5949 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), | 5818 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), |
5950 var_fcmp_rhs(this, MachineRepresentation::kFloat64); | 5819 var_fcmp_rhs(this, MachineRepresentation::kFloat64); |
5951 | 5820 |
5952 // Check if the {lhs} is a Smi or a HeapObject. | 5821 // Check if the {lhs} is a Smi or a HeapObject. |
5953 Label if_lhsissmi(this), if_lhsisnotsmi(this); | 5822 Label if_lhsissmi(this), if_lhsisnotsmi(this); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6035 case kGreaterThan: | 5904 case kGreaterThan: |
6036 Branch(Float64GreaterThan(lhs, rhs), if_true, if_false); | 5905 Branch(Float64GreaterThan(lhs, rhs), if_true, if_false); |
6037 break; | 5906 break; |
6038 case kGreaterThanOrEqual: | 5907 case kGreaterThanOrEqual: |
6039 Branch(Float64GreaterThanOrEqual(lhs, rhs), if_true, if_false); | 5908 Branch(Float64GreaterThanOrEqual(lhs, rhs), if_true, if_false); |
6040 break; | 5909 break; |
6041 } | 5910 } |
6042 } | 5911 } |
6043 } | 5912 } |
6044 | 5913 |
6045 void CodeStubAssembler::GotoUnlessNumberLessThan(Node* lhs, Node* rhs, | 5914 void CodeStubAssembler::GotoUnlessNumberLessThan(compiler::Node* lhs, |
| 5915 compiler::Node* rhs, |
6046 Label* if_false) { | 5916 Label* if_false) { |
6047 Label if_true(this); | 5917 Label if_true(this); |
6048 BranchIfNumericRelationalComparison(kLessThan, lhs, rhs, &if_true, if_false); | 5918 BranchIfNumericRelationalComparison(kLessThan, lhs, rhs, &if_true, if_false); |
6049 Bind(&if_true); | 5919 Bind(&if_true); |
6050 } | 5920 } |
6051 | 5921 |
6052 Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode, | 5922 compiler::Node* CodeStubAssembler::RelationalComparison( |
6053 Node* lhs, Node* rhs, | 5923 RelationalComparisonMode mode, compiler::Node* lhs, compiler::Node* rhs, |
6054 Node* context) { | 5924 compiler::Node* context) { |
| 5925 typedef compiler::Node Node; |
| 5926 |
6055 Label return_true(this), return_false(this), end(this); | 5927 Label return_true(this), return_false(this), end(this); |
6056 Variable result(this, MachineRepresentation::kTagged); | 5928 Variable result(this, MachineRepresentation::kTagged); |
6057 | 5929 |
6058 // Shared entry for floating point comparison. | 5930 // Shared entry for floating point comparison. |
6059 Label do_fcmp(this); | 5931 Label do_fcmp(this); |
6060 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), | 5932 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), |
6061 var_fcmp_rhs(this, MachineRepresentation::kFloat64); | 5933 var_fcmp_rhs(this, MachineRepresentation::kFloat64); |
6062 | 5934 |
6063 // We might need to loop several times due to ToPrimitive and/or ToNumber | 5935 // We might need to loop several times due to ToPrimitive and/or ToNumber |
6064 // conversions. | 5936 // conversions. |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6365 result.Bind(BooleanConstant(false)); | 6237 result.Bind(BooleanConstant(false)); |
6366 Goto(&end); | 6238 Goto(&end); |
6367 } | 6239 } |
6368 | 6240 |
6369 Bind(&end); | 6241 Bind(&end); |
6370 return result.value(); | 6242 return result.value(); |
6371 } | 6243 } |
6372 | 6244 |
6373 namespace { | 6245 namespace { |
6374 | 6246 |
6375 void GenerateEqual_Same(CodeStubAssembler* assembler, Node* value, | 6247 void GenerateEqual_Same(CodeStubAssembler* assembler, compiler::Node* value, |
6376 CodeStubAssembler::Label* if_equal, | 6248 CodeStubAssembler::Label* if_equal, |
6377 CodeStubAssembler::Label* if_notequal) { | 6249 CodeStubAssembler::Label* if_notequal) { |
6378 // In case of abstract or strict equality checks, we need additional checks | 6250 // In case of abstract or strict equality checks, we need additional checks |
6379 // for NaN values because they are not considered equal, even if both the | 6251 // for NaN values because they are not considered equal, even if both the |
6380 // left and the right hand side reference exactly the same value. | 6252 // left and the right hand side reference exactly the same value. |
6381 // TODO(bmeurer): This seems to violate the SIMD.js specification, but it | 6253 // TODO(bmeurer): This seems to violate the SIMD.js specification, but it |
6382 // seems to be what is tested in the current SIMD.js testsuite. | 6254 // seems to be what is tested in the current SIMD.js testsuite. |
6383 | 6255 |
6384 typedef CodeStubAssembler::Label Label; | 6256 typedef CodeStubAssembler::Label Label; |
| 6257 typedef compiler::Node Node; |
6385 | 6258 |
6386 // Check if {value} is a Smi or a HeapObject. | 6259 // Check if {value} is a Smi or a HeapObject. |
6387 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); | 6260 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); |
6388 assembler->Branch(assembler->TaggedIsSmi(value), &if_valueissmi, | 6261 assembler->Branch(assembler->TaggedIsSmi(value), &if_valueissmi, |
6389 &if_valueisnotsmi); | 6262 &if_valueisnotsmi); |
6390 | 6263 |
6391 assembler->Bind(&if_valueisnotsmi); | 6264 assembler->Bind(&if_valueisnotsmi); |
6392 { | 6265 { |
6393 // Load the map of {value}. | 6266 // Load the map of {value}. |
6394 Node* value_map = assembler->LoadMap(value); | 6267 Node* value_map = assembler->LoadMap(value); |
(...skipping 14 matching lines...) Expand all Loading... |
6409 | 6282 |
6410 assembler->Bind(&if_valueisnotnumber); | 6283 assembler->Bind(&if_valueisnotnumber); |
6411 assembler->Goto(if_equal); | 6284 assembler->Goto(if_equal); |
6412 } | 6285 } |
6413 | 6286 |
6414 assembler->Bind(&if_valueissmi); | 6287 assembler->Bind(&if_valueissmi); |
6415 assembler->Goto(if_equal); | 6288 assembler->Goto(if_equal); |
6416 } | 6289 } |
6417 | 6290 |
6418 void GenerateEqual_Simd128Value_HeapObject( | 6291 void GenerateEqual_Simd128Value_HeapObject( |
6419 CodeStubAssembler* assembler, Node* lhs, Node* lhs_map, Node* rhs, | 6292 CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* lhs_map, |
6420 Node* rhs_map, CodeStubAssembler::Label* if_equal, | 6293 compiler::Node* rhs, compiler::Node* rhs_map, |
6421 CodeStubAssembler::Label* if_notequal) { | 6294 CodeStubAssembler::Label* if_equal, CodeStubAssembler::Label* if_notequal) { |
6422 assembler->BranchIfSimd128Equal(lhs, lhs_map, rhs, rhs_map, if_equal, | 6295 assembler->BranchIfSimd128Equal(lhs, lhs_map, rhs, rhs_map, if_equal, |
6423 if_notequal); | 6296 if_notequal); |
6424 } | 6297 } |
6425 | 6298 |
6426 } // namespace | 6299 } // namespace |
6427 | 6300 |
6428 // ES6 section 7.2.12 Abstract Equality Comparison | 6301 // ES6 section 7.2.12 Abstract Equality Comparison |
6429 Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs, | 6302 compiler::Node* CodeStubAssembler::Equal(ResultMode mode, compiler::Node* lhs, |
6430 Node* context) { | 6303 compiler::Node* rhs, |
| 6304 compiler::Node* context) { |
6431 // This is a slightly optimized version of Object::Equals represented as | 6305 // This is a slightly optimized version of Object::Equals represented as |
6432 // scheduled TurboFan graph utilizing the CodeStubAssembler. Whenever you | 6306 // scheduled TurboFan graph utilizing the CodeStubAssembler. Whenever you |
6433 // change something functionality wise in here, remember to update the | 6307 // change something functionality wise in here, remember to update the |
6434 // Object::Equals method as well. | 6308 // Object::Equals method as well. |
| 6309 typedef compiler::Node Node; |
6435 | 6310 |
6436 Label if_equal(this), if_notequal(this), | 6311 Label if_equal(this), if_notequal(this), |
6437 do_rhsstringtonumber(this, Label::kDeferred), end(this); | 6312 do_rhsstringtonumber(this, Label::kDeferred), end(this); |
6438 Variable result(this, MachineRepresentation::kTagged); | 6313 Variable result(this, MachineRepresentation::kTagged); |
6439 | 6314 |
6440 // Shared entry for floating point comparison. | 6315 // Shared entry for floating point comparison. |
6441 Label do_fcmp(this); | 6316 Label do_fcmp(this); |
6442 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), | 6317 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), |
6443 var_fcmp_rhs(this, MachineRepresentation::kFloat64); | 6318 var_fcmp_rhs(this, MachineRepresentation::kFloat64); |
6444 | 6319 |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6918 Bind(&if_notequal); | 6793 Bind(&if_notequal); |
6919 { | 6794 { |
6920 result.Bind(BooleanConstant(mode == kNegateResult)); | 6795 result.Bind(BooleanConstant(mode == kNegateResult)); |
6921 Goto(&end); | 6796 Goto(&end); |
6922 } | 6797 } |
6923 | 6798 |
6924 Bind(&end); | 6799 Bind(&end); |
6925 return result.value(); | 6800 return result.value(); |
6926 } | 6801 } |
6927 | 6802 |
6928 Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs, | 6803 compiler::Node* CodeStubAssembler::StrictEqual(ResultMode mode, |
6929 Node* context) { | 6804 compiler::Node* lhs, |
| 6805 compiler::Node* rhs, |
| 6806 compiler::Node* context) { |
6930 // Here's pseudo-code for the algorithm below in case of kDontNegateResult | 6807 // Here's pseudo-code for the algorithm below in case of kDontNegateResult |
6931 // mode; for kNegateResult mode we properly negate the result. | 6808 // mode; for kNegateResult mode we properly negate the result. |
6932 // | 6809 // |
6933 // if (lhs == rhs) { | 6810 // if (lhs == rhs) { |
6934 // if (lhs->IsHeapNumber()) return HeapNumber::cast(lhs)->value() != NaN; | 6811 // if (lhs->IsHeapNumber()) return HeapNumber::cast(lhs)->value() != NaN; |
6935 // return true; | 6812 // return true; |
6936 // } | 6813 // } |
6937 // if (!lhs->IsSmi()) { | 6814 // if (!lhs->IsSmi()) { |
6938 // if (lhs->IsHeapNumber()) { | 6815 // if (lhs->IsHeapNumber()) { |
6939 // if (rhs->IsSmi()) { | 6816 // if (rhs->IsSmi()) { |
(...skipping 28 matching lines...) Expand all Loading... |
6968 // return false; | 6845 // return false; |
6969 // } else { | 6846 // } else { |
6970 // if (rhs->IsHeapNumber()) { | 6847 // if (rhs->IsHeapNumber()) { |
6971 // return Smi::cast(lhs)->value() == HeapNumber::cast(rhs)->value(); | 6848 // return Smi::cast(lhs)->value() == HeapNumber::cast(rhs)->value(); |
6972 // } else { | 6849 // } else { |
6973 // return false; | 6850 // return false; |
6974 // } | 6851 // } |
6975 // } | 6852 // } |
6976 // } | 6853 // } |
6977 | 6854 |
| 6855 typedef compiler::Node Node; |
| 6856 |
6978 Label if_equal(this), if_notequal(this), end(this); | 6857 Label if_equal(this), if_notequal(this), end(this); |
6979 Variable result(this, MachineRepresentation::kTagged); | 6858 Variable result(this, MachineRepresentation::kTagged); |
6980 | 6859 |
6981 // Check if {lhs} and {rhs} refer to the same object. | 6860 // Check if {lhs} and {rhs} refer to the same object. |
6982 Label if_same(this), if_notsame(this); | 6861 Label if_same(this), if_notsame(this); |
6983 Branch(WordEqual(lhs, rhs), &if_same, &if_notsame); | 6862 Branch(WordEqual(lhs, rhs), &if_same, &if_notsame); |
6984 | 6863 |
6985 Bind(&if_same); | 6864 Bind(&if_same); |
6986 { | 6865 { |
6987 // The {lhs} and {rhs} reference the exact same value, yet we need special | 6866 // The {lhs} and {rhs} reference the exact same value, yet we need special |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7169 Goto(&end); | 7048 Goto(&end); |
7170 } | 7049 } |
7171 | 7050 |
7172 Bind(&end); | 7051 Bind(&end); |
7173 return result.value(); | 7052 return result.value(); |
7174 } | 7053 } |
7175 | 7054 |
7176 // ECMA#sec-samevalue | 7055 // ECMA#sec-samevalue |
7177 // This algorithm differs from the Strict Equality Comparison Algorithm in its | 7056 // This algorithm differs from the Strict Equality Comparison Algorithm in its |
7178 // treatment of signed zeroes and NaNs. | 7057 // treatment of signed zeroes and NaNs. |
7179 Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) { | 7058 compiler::Node* CodeStubAssembler::SameValue(compiler::Node* lhs, |
| 7059 compiler::Node* rhs, |
| 7060 compiler::Node* context) { |
7180 Variable var_result(this, MachineType::PointerRepresentation()); | 7061 Variable var_result(this, MachineType::PointerRepresentation()); |
7181 Label strict_equal(this), out(this); | 7062 Label strict_equal(this), out(this); |
7182 | 7063 |
7183 Node* const int_false = IntPtrConstant(0); | 7064 Node* const int_false = IntPtrConstant(0); |
7184 Node* const int_true = IntPtrConstant(1); | 7065 Node* const int_true = IntPtrConstant(1); |
7185 | 7066 |
7186 Label if_equal(this), if_notequal(this); | 7067 Label if_equal(this), if_notequal(this); |
7187 Branch(WordEqual(lhs, rhs), &if_equal, &if_notequal); | 7068 Branch(WordEqual(lhs, rhs), &if_equal, &if_notequal); |
7188 | 7069 |
7189 Bind(&if_equal); | 7070 Bind(&if_equal); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7253 Node* const is_equal = StrictEqual(kDontNegateResult, lhs, rhs, context); | 7134 Node* const is_equal = StrictEqual(kDontNegateResult, lhs, rhs, context); |
7254 Node* const result = WordEqual(is_equal, TrueConstant()); | 7135 Node* const result = WordEqual(is_equal, TrueConstant()); |
7255 var_result.Bind(result); | 7136 var_result.Bind(result); |
7256 Goto(&out); | 7137 Goto(&out); |
7257 } | 7138 } |
7258 | 7139 |
7259 Bind(&out); | 7140 Bind(&out); |
7260 return var_result.value(); | 7141 return var_result.value(); |
7261 } | 7142 } |
7262 | 7143 |
7263 Node* CodeStubAssembler::ForInFilter(Node* key, Node* object, Node* context) { | 7144 compiler::Node* CodeStubAssembler::ForInFilter(compiler::Node* key, |
| 7145 compiler::Node* object, |
| 7146 compiler::Node* context) { |
7264 Label return_undefined(this, Label::kDeferred), return_to_name(this), | 7147 Label return_undefined(this, Label::kDeferred), return_to_name(this), |
7265 end(this); | 7148 end(this); |
7266 | 7149 |
7267 Variable var_result(this, MachineRepresentation::kTagged); | 7150 Variable var_result(this, MachineRepresentation::kTagged); |
7268 | 7151 |
7269 Node* has_property = | 7152 Node* has_property = |
7270 HasProperty(object, key, context, Runtime::kForInHasProperty); | 7153 HasProperty(object, key, context, Runtime::kForInHasProperty); |
7271 | 7154 |
7272 Branch(WordEqual(has_property, BooleanConstant(true)), &return_to_name, | 7155 Branch(WordEqual(has_property, BooleanConstant(true)), &return_to_name, |
7273 &return_undefined); | 7156 &return_undefined); |
7274 | 7157 |
7275 Bind(&return_to_name); | 7158 Bind(&return_to_name); |
7276 { | 7159 { |
7277 var_result.Bind(ToName(context, key)); | 7160 var_result.Bind(ToName(context, key)); |
7278 Goto(&end); | 7161 Goto(&end); |
7279 } | 7162 } |
7280 | 7163 |
7281 Bind(&return_undefined); | 7164 Bind(&return_undefined); |
7282 { | 7165 { |
7283 var_result.Bind(UndefinedConstant()); | 7166 var_result.Bind(UndefinedConstant()); |
7284 Goto(&end); | 7167 Goto(&end); |
7285 } | 7168 } |
7286 | 7169 |
7287 Bind(&end); | 7170 Bind(&end); |
7288 return var_result.value(); | 7171 return var_result.value(); |
7289 } | 7172 } |
7290 | 7173 |
7291 Node* CodeStubAssembler::HasProperty( | 7174 compiler::Node* CodeStubAssembler::HasProperty( |
7292 Node* object, Node* key, Node* context, | 7175 compiler::Node* object, compiler::Node* key, compiler::Node* context, |
7293 Runtime::FunctionId fallback_runtime_function_id) { | 7176 Runtime::FunctionId fallback_runtime_function_id) { |
| 7177 typedef compiler::Node Node; |
| 7178 typedef CodeStubAssembler::Label Label; |
| 7179 typedef CodeStubAssembler::Variable Variable; |
| 7180 |
7294 Label call_runtime(this, Label::kDeferred), return_true(this), | 7181 Label call_runtime(this, Label::kDeferred), return_true(this), |
7295 return_false(this), end(this); | 7182 return_false(this), end(this); |
7296 | 7183 |
7297 CodeStubAssembler::LookupInHolder lookup_property_in_holder = | 7184 CodeStubAssembler::LookupInHolder lookup_property_in_holder = |
7298 [this, &return_true](Node* receiver, Node* holder, Node* holder_map, | 7185 [this, &return_true](Node* receiver, Node* holder, Node* holder_map, |
7299 Node* holder_instance_type, Node* unique_name, | 7186 Node* holder_instance_type, Node* unique_name, |
7300 Label* next_holder, Label* if_bailout) { | 7187 Label* next_holder, Label* if_bailout) { |
7301 TryHasOwnProperty(holder, holder_map, holder_instance_type, unique_name, | 7188 TryHasOwnProperty(holder, holder_map, holder_instance_type, unique_name, |
7302 &return_true, next_holder, if_bailout); | 7189 &return_true, next_holder, if_bailout); |
7303 }; | 7190 }; |
(...skipping 27 matching lines...) Expand all Loading... |
7331 { | 7218 { |
7332 result.Bind( | 7219 result.Bind( |
7333 CallRuntime(fallback_runtime_function_id, context, object, key)); | 7220 CallRuntime(fallback_runtime_function_id, context, object, key)); |
7334 Goto(&end); | 7221 Goto(&end); |
7335 } | 7222 } |
7336 | 7223 |
7337 Bind(&end); | 7224 Bind(&end); |
7338 return result.value(); | 7225 return result.value(); |
7339 } | 7226 } |
7340 | 7227 |
7341 Node* CodeStubAssembler::Typeof(Node* value, Node* context) { | 7228 compiler::Node* CodeStubAssembler::Typeof(compiler::Node* value, |
| 7229 compiler::Node* context) { |
7342 Variable result_var(this, MachineRepresentation::kTagged); | 7230 Variable result_var(this, MachineRepresentation::kTagged); |
7343 | 7231 |
7344 Label return_number(this, Label::kDeferred), if_oddball(this), | 7232 Label return_number(this, Label::kDeferred), if_oddball(this), |
7345 return_function(this), return_undefined(this), return_object(this), | 7233 return_function(this), return_undefined(this), return_object(this), |
7346 return_string(this), return_result(this); | 7234 return_string(this), return_result(this); |
7347 | 7235 |
7348 GotoIf(TaggedIsSmi(value), &return_number); | 7236 GotoIf(TaggedIsSmi(value), &return_number); |
7349 | 7237 |
7350 Node* map = LoadMap(value); | 7238 Node* map = LoadMap(value); |
7351 | 7239 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7424 result_var.Bind(HeapConstant(isolate()->factory()->type##_string())); \ | 7312 result_var.Bind(HeapConstant(isolate()->factory()->type##_string())); \ |
7425 Goto(&return_result); \ | 7313 Goto(&return_result); \ |
7426 } | 7314 } |
7427 SIMD128_TYPES(SIMD128_BIND_RETURN) | 7315 SIMD128_TYPES(SIMD128_BIND_RETURN) |
7428 #undef SIMD128_BIND_RETURN | 7316 #undef SIMD128_BIND_RETURN |
7429 | 7317 |
7430 Bind(&return_result); | 7318 Bind(&return_result); |
7431 return result_var.value(); | 7319 return result_var.value(); |
7432 } | 7320 } |
7433 | 7321 |
7434 Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, | 7322 compiler::Node* CodeStubAssembler::InstanceOf(compiler::Node* object, |
7435 Node* context) { | 7323 compiler::Node* callable, |
| 7324 compiler::Node* context) { |
7436 Label return_runtime(this, Label::kDeferred), end(this); | 7325 Label return_runtime(this, Label::kDeferred), end(this); |
7437 Variable result(this, MachineRepresentation::kTagged); | 7326 Variable result(this, MachineRepresentation::kTagged); |
7438 | 7327 |
7439 // Check if no one installed @@hasInstance somewhere. | 7328 // Check if no one installed @@hasInstance somewhere. |
7440 GotoUnless( | 7329 GotoUnless( |
7441 WordEqual(LoadObjectField(LoadRoot(Heap::kHasInstanceProtectorRootIndex), | 7330 WordEqual(LoadObjectField(LoadRoot(Heap::kHasInstanceProtectorRootIndex), |
7442 PropertyCell::kValueOffset), | 7331 PropertyCell::kValueOffset), |
7443 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))), | 7332 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))), |
7444 &return_runtime); | 7333 &return_runtime); |
7445 | 7334 |
7446 // Check if {callable} is a valid receiver. | 7335 // Check if {callable} is a valid receiver. |
7447 GotoIf(TaggedIsSmi(callable), &return_runtime); | 7336 GotoIf(TaggedIsSmi(callable), &return_runtime); |
7448 GotoUnless(IsCallableMap(LoadMap(callable)), &return_runtime); | 7337 GotoUnless(IsCallableMap(LoadMap(callable)), &return_runtime); |
7449 | 7338 |
7450 // Use the inline OrdinaryHasInstance directly. | 7339 // Use the inline OrdinaryHasInstance directly. |
7451 result.Bind(OrdinaryHasInstance(context, callable, object)); | 7340 result.Bind(OrdinaryHasInstance(context, callable, object)); |
7452 Goto(&end); | 7341 Goto(&end); |
7453 | 7342 |
7454 // TODO(bmeurer): Use GetPropertyStub here once available. | 7343 // TODO(bmeurer): Use GetPropertyStub here once available. |
7455 Bind(&return_runtime); | 7344 Bind(&return_runtime); |
7456 { | 7345 { |
7457 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); | 7346 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); |
7458 Goto(&end); | 7347 Goto(&end); |
7459 } | 7348 } |
7460 | 7349 |
7461 Bind(&end); | 7350 Bind(&end); |
7462 return result.value(); | 7351 return result.value(); |
7463 } | 7352 } |
7464 | 7353 |
7465 Node* CodeStubAssembler::NumberInc(Node* value) { | 7354 compiler::Node* CodeStubAssembler::NumberInc(compiler::Node* value) { |
7466 Variable var_result(this, MachineRepresentation::kTagged), | 7355 Variable var_result(this, MachineRepresentation::kTagged), |
7467 var_finc_value(this, MachineRepresentation::kFloat64); | 7356 var_finc_value(this, MachineRepresentation::kFloat64); |
7468 Label if_issmi(this), if_isnotsmi(this), do_finc(this), end(this); | 7357 Label if_issmi(this), if_isnotsmi(this), do_finc(this), end(this); |
7469 Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi); | 7358 Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi); |
7470 | 7359 |
7471 Bind(&if_issmi); | 7360 Bind(&if_issmi); |
7472 { | 7361 { |
7473 // Try fast Smi addition first. | 7362 // Try fast Smi addition first. |
7474 Node* one = SmiConstant(Smi::FromInt(1)); | 7363 Node* one = SmiConstant(Smi::FromInt(1)); |
7475 Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(value), | 7364 Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(value), |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7507 Node* one = Float64Constant(1.0); | 7396 Node* one = Float64Constant(1.0); |
7508 Node* finc_result = Float64Add(finc_value, one); | 7397 Node* finc_result = Float64Add(finc_value, one); |
7509 var_result.Bind(AllocateHeapNumberWithValue(finc_result)); | 7398 var_result.Bind(AllocateHeapNumberWithValue(finc_result)); |
7510 Goto(&end); | 7399 Goto(&end); |
7511 } | 7400 } |
7512 | 7401 |
7513 Bind(&end); | 7402 Bind(&end); |
7514 return var_result.value(); | 7403 return var_result.value(); |
7515 } | 7404 } |
7516 | 7405 |
7517 Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map, | 7406 compiler::Node* CodeStubAssembler::CreateArrayIterator( |
7518 Node* array_type, Node* context, | 7407 compiler::Node* array, compiler::Node* array_map, |
7519 IterationKind mode) { | 7408 compiler::Node* array_type, compiler::Node* context, IterationKind mode) { |
7520 int kBaseMapIndex = 0; | 7409 int kBaseMapIndex = 0; |
7521 switch (mode) { | 7410 switch (mode) { |
7522 case IterationKind::kKeys: | 7411 case IterationKind::kKeys: |
7523 kBaseMapIndex = Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX; | 7412 kBaseMapIndex = Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX; |
7524 break; | 7413 break; |
7525 case IterationKind::kValues: | 7414 case IterationKind::kValues: |
7526 kBaseMapIndex = Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX; | 7415 kBaseMapIndex = Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX; |
7527 break; | 7416 break; |
7528 case IterationKind::kEntries: | 7417 case IterationKind::kEntries: |
7529 kBaseMapIndex = Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX; | 7418 kBaseMapIndex = Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7695 LoadFixedArrayElement(LoadNativeContext(context), var_map_index.value(), | 7584 LoadFixedArrayElement(LoadNativeContext(context), var_map_index.value(), |
7696 0, CodeStubAssembler::INTPTR_PARAMETERS); | 7585 0, CodeStubAssembler::INTPTR_PARAMETERS); |
7697 var_result.Bind(AllocateJSArrayIterator(array, var_array_map.value(), map)); | 7586 var_result.Bind(AllocateJSArrayIterator(array, var_array_map.value(), map)); |
7698 Goto(&return_result); | 7587 Goto(&return_result); |
7699 } | 7588 } |
7700 | 7589 |
7701 Bind(&return_result); | 7590 Bind(&return_result); |
7702 return var_result.value(); | 7591 return var_result.value(); |
7703 } | 7592 } |
7704 | 7593 |
7705 Node* CodeStubAssembler::AllocateJSArrayIterator(Node* array, Node* array_map, | 7594 compiler::Node* CodeStubAssembler::AllocateJSArrayIterator( |
7706 Node* map) { | 7595 compiler::Node* array, compiler::Node* array_map, compiler::Node* map) { |
7707 Node* iterator = Allocate(JSArrayIterator::kSize); | 7596 Node* iterator = Allocate(JSArrayIterator::kSize); |
7708 StoreMapNoWriteBarrier(iterator, map); | 7597 StoreMapNoWriteBarrier(iterator, map); |
7709 StoreObjectFieldRoot(iterator, JSArrayIterator::kPropertiesOffset, | 7598 StoreObjectFieldRoot(iterator, JSArrayIterator::kPropertiesOffset, |
7710 Heap::kEmptyFixedArrayRootIndex); | 7599 Heap::kEmptyFixedArrayRootIndex); |
7711 StoreObjectFieldRoot(iterator, JSArrayIterator::kElementsOffset, | 7600 StoreObjectFieldRoot(iterator, JSArrayIterator::kElementsOffset, |
7712 Heap::kEmptyFixedArrayRootIndex); | 7601 Heap::kEmptyFixedArrayRootIndex); |
7713 StoreObjectFieldNoWriteBarrier(iterator, | 7602 StoreObjectFieldNoWriteBarrier(iterator, |
7714 JSArrayIterator::kIteratedObjectOffset, array); | 7603 JSArrayIterator::kIteratedObjectOffset, array); |
7715 StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset, | 7604 StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset, |
7716 SmiConstant(Smi::FromInt(0))); | 7605 SmiConstant(Smi::FromInt(0))); |
7717 StoreObjectFieldNoWriteBarrier( | 7606 StoreObjectFieldNoWriteBarrier( |
7718 iterator, JSArrayIterator::kIteratedObjectMapOffset, array_map); | 7607 iterator, JSArrayIterator::kIteratedObjectMapOffset, array_map); |
7719 return iterator; | 7608 return iterator; |
7720 } | 7609 } |
7721 | 7610 |
7722 Node* CodeStubAssembler::IsDetachedBuffer(Node* buffer) { | 7611 compiler::Node* CodeStubAssembler::IsDetachedBuffer(compiler::Node* buffer) { |
7723 CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE)); | 7612 CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE)); |
7724 | 7613 |
7725 Node* buffer_bit_field = LoadObjectField( | 7614 Node* buffer_bit_field = LoadObjectField( |
7726 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 7615 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
7727 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 7616 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); |
7728 | 7617 |
7729 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | 7618 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), |
7730 Int32Constant(0)); | 7619 Int32Constant(0)); |
7731 } | 7620 } |
7732 | 7621 |
7733 CodeStubArguments::CodeStubArguments(CodeStubAssembler* assembler, Node* argc, | 7622 CodeStubArguments::CodeStubArguments(CodeStubAssembler* assembler, |
| 7623 compiler::Node* argc, |
7734 CodeStubAssembler::ParameterMode mode) | 7624 CodeStubAssembler::ParameterMode mode) |
7735 : assembler_(assembler), | 7625 : assembler_(assembler), |
7736 argc_(argc), | 7626 argc_(argc), |
7737 arguments_(nullptr), | 7627 arguments_(nullptr), |
7738 fp_(assembler->LoadFramePointer()) { | 7628 fp_(assembler->LoadFramePointer()) { |
7739 Node* offset = assembler->ElementOffsetFromIndex( | 7629 compiler::Node* offset = assembler->ElementOffsetFromIndex( |
7740 argc_, FAST_ELEMENTS, mode, | 7630 argc_, FAST_ELEMENTS, mode, |
7741 (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kPointerSize); | 7631 (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kPointerSize); |
7742 arguments_ = assembler_->IntPtrAddFoldConstants(fp_, offset); | 7632 arguments_ = assembler_->IntPtrAddFoldConstants(fp_, offset); |
7743 if (mode == CodeStubAssembler::INTEGER_PARAMETERS) { | 7633 if (mode == CodeStubAssembler::INTEGER_PARAMETERS) { |
7744 argc_ = assembler->ChangeInt32ToIntPtr(argc_); | 7634 argc_ = assembler->ChangeInt32ToIntPtr(argc_); |
7745 } else if (mode == CodeStubAssembler::SMI_PARAMETERS) { | 7635 } else if (mode == CodeStubAssembler::SMI_PARAMETERS) { |
7746 argc_ = assembler->SmiUntag(argc_); | 7636 argc_ = assembler->SmiUntag(argc_); |
7747 } | 7637 } |
7748 } | 7638 } |
7749 | 7639 |
7750 Node* CodeStubArguments::GetReceiver() { | 7640 compiler::Node* CodeStubArguments::GetReceiver() { |
7751 return assembler_->Load(MachineType::AnyTagged(), arguments_, | 7641 return assembler_->Load(MachineType::AnyTagged(), arguments_, |
7752 assembler_->IntPtrConstant(kPointerSize)); | 7642 assembler_->IntPtrConstant(kPointerSize)); |
7753 } | 7643 } |
7754 | 7644 |
7755 Node* CodeStubArguments::AtIndex(Node* index, | 7645 compiler::Node* CodeStubArguments::AtIndex( |
7756 CodeStubAssembler::ParameterMode mode) { | 7646 compiler::Node* index, CodeStubAssembler::ParameterMode mode) { |
| 7647 typedef compiler::Node Node; |
7757 Node* negated_index = assembler_->IntPtrSubFoldConstants( | 7648 Node* negated_index = assembler_->IntPtrSubFoldConstants( |
7758 assembler_->IntPtrOrSmiConstant(0, mode), index); | 7649 assembler_->IntPtrOrSmiConstant(0, mode), index); |
7759 Node* offset = | 7650 Node* offset = |
7760 assembler_->ElementOffsetFromIndex(negated_index, FAST_ELEMENTS, mode, 0); | 7651 assembler_->ElementOffsetFromIndex(negated_index, FAST_ELEMENTS, mode, 0); |
7761 return assembler_->Load(MachineType::AnyTagged(), arguments_, offset); | 7652 return assembler_->Load(MachineType::AnyTagged(), arguments_, offset); |
7762 } | 7653 } |
7763 | 7654 |
7764 Node* CodeStubArguments::AtIndex(int index) { | 7655 compiler::Node* CodeStubArguments::AtIndex(int index) { |
7765 return AtIndex(assembler_->IntPtrConstant(index)); | 7656 return AtIndex(assembler_->IntPtrConstant(index)); |
7766 } | 7657 } |
7767 | 7658 |
7768 void CodeStubArguments::ForEach(const CodeStubAssembler::VariableList& vars, | 7659 void CodeStubArguments::ForEach(const CodeStubAssembler::VariableList& vars, |
7769 CodeStubArguments::ForEachBodyFunction body, | 7660 CodeStubArguments::ForEachBodyFunction body, |
7770 Node* first, Node* last, | 7661 compiler::Node* first, compiler::Node* last, |
7771 CodeStubAssembler::ParameterMode mode) { | 7662 CodeStubAssembler::ParameterMode mode) { |
7772 assembler_->Comment("CodeStubArguments::ForEach"); | 7663 assembler_->Comment("CodeStubArguments::ForEach"); |
7773 DCHECK_IMPLIES(first == nullptr || last == nullptr, | 7664 DCHECK_IMPLIES(first == nullptr || last == nullptr, |
7774 mode == CodeStubAssembler::INTPTR_PARAMETERS); | 7665 mode == CodeStubAssembler::INTPTR_PARAMETERS); |
7775 if (first == nullptr) { | 7666 if (first == nullptr) { |
7776 first = assembler_->IntPtrOrSmiConstant(0, mode); | 7667 first = assembler_->IntPtrOrSmiConstant(0, mode); |
7777 } | 7668 } |
7778 if (last == nullptr) { | 7669 if (last == nullptr) { |
7779 last = argc_; | 7670 last = argc_; |
7780 } | 7671 } |
7781 Node* start = assembler_->IntPtrSubFoldConstants( | 7672 compiler::Node* start = assembler_->IntPtrSubFoldConstants( |
7782 arguments_, | 7673 arguments_, |
7783 assembler_->ElementOffsetFromIndex(first, FAST_ELEMENTS, mode)); | 7674 assembler_->ElementOffsetFromIndex(first, FAST_ELEMENTS, mode)); |
7784 Node* end = assembler_->IntPtrSubFoldConstants( | 7675 compiler::Node* end = assembler_->IntPtrSubFoldConstants( |
7785 arguments_, | 7676 arguments_, |
7786 assembler_->ElementOffsetFromIndex(last, FAST_ELEMENTS, mode)); | 7677 assembler_->ElementOffsetFromIndex(last, FAST_ELEMENTS, mode)); |
7787 assembler_->BuildFastLoop( | 7678 assembler_->BuildFastLoop( |
7788 vars, MachineType::PointerRepresentation(), start, end, | 7679 vars, MachineType::PointerRepresentation(), start, end, |
7789 [body](CodeStubAssembler* assembler, Node* current) { | 7680 [body](CodeStubAssembler* assembler, compiler::Node* current) { |
7790 Node* arg = assembler->Load(MachineType::AnyTagged(), current); | 7681 Node* arg = assembler->Load(MachineType::AnyTagged(), current); |
7791 body(assembler, arg); | 7682 body(assembler, arg); |
7792 }, | 7683 }, |
7793 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); | 7684 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); |
7794 } | 7685 } |
7795 | 7686 |
7796 void CodeStubArguments::PopAndReturn(Node* value) { | 7687 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
7797 assembler_->PopAndReturn( | 7688 assembler_->PopAndReturn( |
7798 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 7689 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
7799 value); | 7690 value); |
7800 } | 7691 } |
7801 | 7692 |
7802 Node* CodeStubAssembler::IsFastElementsKind(Node* elements_kind) { | 7693 compiler::Node* CodeStubAssembler::IsFastElementsKind( |
| 7694 compiler::Node* elements_kind) { |
7803 return Uint32LessThanOrEqual(elements_kind, | 7695 return Uint32LessThanOrEqual(elements_kind, |
7804 Int32Constant(LAST_FAST_ELEMENTS_KIND)); | 7696 Int32Constant(LAST_FAST_ELEMENTS_KIND)); |
7805 } | 7697 } |
7806 | 7698 |
7807 Node* CodeStubAssembler::IsHoleyFastElementsKind(Node* elements_kind) { | 7699 compiler::Node* CodeStubAssembler::IsHoleyFastElementsKind( |
| 7700 compiler::Node* elements_kind) { |
7808 CSA_ASSERT(this, IsFastElementsKind(elements_kind)); | 7701 CSA_ASSERT(this, IsFastElementsKind(elements_kind)); |
7809 | 7702 |
7810 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); | 7703 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); |
7811 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); | 7704 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); |
7812 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); | 7705 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); |
7813 | 7706 |
7814 // Check prototype chain if receiver does not have packed elements. | 7707 // Check prototype chain if receiver does not have packed elements. |
7815 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); | 7708 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); |
7816 return Word32Equal(holey_elements, Int32Constant(1)); | 7709 return Word32Equal(holey_elements, Int32Constant(1)); |
7817 } | 7710 } |
7818 | 7711 |
7819 compiler::Node* CodeStubAssembler::IsDebugActive() { | 7712 compiler::Node* CodeStubAssembler::IsDebugActive() { |
7820 Node* is_debug_active = Load( | 7713 Node* is_debug_active = Load( |
7821 MachineType::Uint8(), | 7714 MachineType::Uint8(), |
7822 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); | 7715 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); |
7823 return WordNotEqual(is_debug_active, Int32Constant(0)); | 7716 return WordNotEqual(is_debug_active, Int32Constant(0)); |
7824 } | 7717 } |
7825 | 7718 |
7826 } // namespace internal | 7719 } // namespace internal |
7827 } // namespace v8 | 7720 } // namespace v8 |
OLD | NEW |