| 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 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1559 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value, |  1559 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value, | 
|  1560                                                      MutableMode mode) { |  1560                                                      MutableMode mode) { | 
|  1561   Node* result = AllocateHeapNumber(mode); |  1561   Node* result = AllocateHeapNumber(mode); | 
|  1562   StoreHeapNumberValue(result, value); |  1562   StoreHeapNumberValue(result, value); | 
|  1563   return result; |  1563   return result; | 
|  1564 } |  1564 } | 
|  1565  |  1565  | 
|  1566 Node* CodeStubAssembler::AllocateSeqOneByteString(int length, |  1566 Node* CodeStubAssembler::AllocateSeqOneByteString(int length, | 
|  1567                                                   AllocationFlags flags) { |  1567                                                   AllocationFlags flags) { | 
|  1568   Comment("AllocateSeqOneByteString"); |  1568   Comment("AllocateSeqOneByteString"); | 
|  1569   if (length == 0) { |  | 
|  1570     return LoadRoot(Heap::kempty_stringRootIndex); |  | 
|  1571   } |  | 
|  1572   Node* result = Allocate(SeqOneByteString::SizeFor(length), flags); |  1569   Node* result = Allocate(SeqOneByteString::SizeFor(length), flags); | 
|  1573   DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); |  1570   DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); | 
|  1574   StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); |  1571   StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); | 
|  1575   StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, |  1572   StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, | 
|  1576                                  SmiConstant(Smi::FromInt(length))); |  1573                                  SmiConstant(Smi::FromInt(length))); | 
|  1577   // Initialize both used and unused parts of hash field slot at once. |  1574   // Initialize both used and unused parts of hash field slot at once. | 
|  1578   StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, |  1575   StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, | 
|  1579                                  IntPtrConstant(String::kEmptyHashField), |  1576                                  IntPtrConstant(String::kEmptyHashField), | 
|  1580                                  MachineType::PointerRepresentation()); |  1577                                  MachineType::PointerRepresentation()); | 
|  1581   return result; |  1578   return result; | 
|  1582 } |  1579 } | 
|  1583  |  1580  | 
|  1584 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length, |  1581 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length, | 
|  1585                                                   ParameterMode mode, |  1582                                                   ParameterMode mode, | 
|  1586                                                   AllocationFlags flags) { |  1583                                                   AllocationFlags flags) { | 
|  1587   Comment("AllocateSeqOneByteString"); |  1584   Comment("AllocateSeqOneByteString"); | 
|  1588   Variable var_result(this, MachineRepresentation::kTagged); |  1585   Variable var_result(this, MachineRepresentation::kTagged); | 
|  1589  |  1586  | 
|  1590   // Compute the SeqOneByteString size and check if it fits into new space. |  1587   // Compute the SeqOneByteString size and check if it fits into new space. | 
|  1591   Label if_lengthiszero(this), if_sizeissmall(this), |  1588   Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred), | 
|  1592       if_notsizeissmall(this, Label::kDeferred), if_join(this); |  1589       if_join(this); | 
|  1593   GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero); |  | 
|  1594  |  | 
|  1595   Node* raw_size = GetArrayAllocationSize( |  1590   Node* raw_size = GetArrayAllocationSize( | 
|  1596       length, UINT8_ELEMENTS, mode, |  1591       length, UINT8_ELEMENTS, mode, | 
|  1597       SeqOneByteString::kHeaderSize + kObjectAlignmentMask); |  1592       SeqOneByteString::kHeaderSize + kObjectAlignmentMask); | 
|  1598   Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); |  1593   Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); | 
|  1599   Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), |  1594   Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), | 
|  1600          &if_sizeissmall, &if_notsizeissmall); |  1595          &if_sizeissmall, &if_notsizeissmall); | 
|  1601  |  1596  | 
|  1602   Bind(&if_sizeissmall); |  1597   Bind(&if_sizeissmall); | 
|  1603   { |  1598   { | 
|  1604     // Just allocate the SeqOneByteString in new space. |  1599     // Just allocate the SeqOneByteString in new space. | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  1617  |  1612  | 
|  1618   Bind(&if_notsizeissmall); |  1613   Bind(&if_notsizeissmall); | 
|  1619   { |  1614   { | 
|  1620     // We might need to allocate in large object space, go to the runtime. |  1615     // We might need to allocate in large object space, go to the runtime. | 
|  1621     Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context, |  1616     Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context, | 
|  1622                                ParameterToTagged(length, mode)); |  1617                                ParameterToTagged(length, mode)); | 
|  1623     var_result.Bind(result); |  1618     var_result.Bind(result); | 
|  1624     Goto(&if_join); |  1619     Goto(&if_join); | 
|  1625   } |  1620   } | 
|  1626  |  1621  | 
|  1627   Bind(&if_lengthiszero); |  | 
|  1628   { |  | 
|  1629     var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex)); |  | 
|  1630     Goto(&if_join); |  | 
|  1631   } |  | 
|  1632  |  | 
|  1633   Bind(&if_join); |  1622   Bind(&if_join); | 
|  1634   return var_result.value(); |  1623   return var_result.value(); | 
|  1635 } |  1624 } | 
|  1636  |  1625  | 
|  1637 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length, |  1626 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length, | 
|  1638                                                   AllocationFlags flags) { |  1627                                                   AllocationFlags flags) { | 
|  1639   Comment("AllocateSeqTwoByteString"); |  1628   Comment("AllocateSeqTwoByteString"); | 
|  1640   if (length == 0) { |  | 
|  1641     return LoadRoot(Heap::kempty_stringRootIndex); |  | 
|  1642   } |  | 
|  1643   Node* result = Allocate(SeqTwoByteString::SizeFor(length), flags); |  1629   Node* result = Allocate(SeqTwoByteString::SizeFor(length), flags); | 
|  1644   DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex)); |  1630   DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex)); | 
|  1645   StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex); |  1631   StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex); | 
|  1646   StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, |  1632   StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, | 
|  1647                                  SmiConstant(Smi::FromInt(length))); |  1633                                  SmiConstant(Smi::FromInt(length))); | 
|  1648   // Initialize both used and unused parts of hash field slot at once. |  1634   // Initialize both used and unused parts of hash field slot at once. | 
|  1649   StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, |  1635   StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, | 
|  1650                                  IntPtrConstant(String::kEmptyHashField), |  1636                                  IntPtrConstant(String::kEmptyHashField), | 
|  1651                                  MachineType::PointerRepresentation()); |  1637                                  MachineType::PointerRepresentation()); | 
|  1652   return result; |  1638   return result; | 
|  1653 } |  1639 } | 
|  1654  |  1640  | 
|  1655 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length, |  1641 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length, | 
|  1656                                                   ParameterMode mode, |  1642                                                   ParameterMode mode, | 
|  1657                                                   AllocationFlags flags) { |  1643                                                   AllocationFlags flags) { | 
|  1658   Comment("AllocateSeqTwoByteString"); |  1644   Comment("AllocateSeqTwoByteString"); | 
|  1659   Variable var_result(this, MachineRepresentation::kTagged); |  1645   Variable var_result(this, MachineRepresentation::kTagged); | 
|  1660  |  1646  | 
|  1661   // Compute the SeqTwoByteString size and check if it fits into new space. |  1647   // Compute the SeqTwoByteString size and check if it fits into new space. | 
|  1662   Label if_lengthiszero(this), if_sizeissmall(this), |  1648   Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred), | 
|  1663       if_notsizeissmall(this, Label::kDeferred), if_join(this); |  1649       if_join(this); | 
|  1664   GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero); |  | 
|  1665  |  | 
|  1666   Node* raw_size = GetArrayAllocationSize( |  1650   Node* raw_size = GetArrayAllocationSize( | 
|  1667       length, UINT16_ELEMENTS, mode, |  1651       length, UINT16_ELEMENTS, mode, | 
|  1668       SeqOneByteString::kHeaderSize + kObjectAlignmentMask); |  1652       SeqOneByteString::kHeaderSize + kObjectAlignmentMask); | 
|  1669   Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); |  1653   Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); | 
|  1670   Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), |  1654   Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), | 
|  1671          &if_sizeissmall, &if_notsizeissmall); |  1655          &if_sizeissmall, &if_notsizeissmall); | 
|  1672  |  1656  | 
|  1673   Bind(&if_sizeissmall); |  1657   Bind(&if_sizeissmall); | 
|  1674   { |  1658   { | 
|  1675     // Just allocate the SeqTwoByteString in new space. |  1659     // Just allocate the SeqTwoByteString in new space. | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  1690   Bind(&if_notsizeissmall); |  1674   Bind(&if_notsizeissmall); | 
|  1691   { |  1675   { | 
|  1692     // We might need to allocate in large object space, go to the runtime. |  1676     // We might need to allocate in large object space, go to the runtime. | 
|  1693     Node* result = |  1677     Node* result = | 
|  1694         CallRuntime(Runtime::kAllocateSeqTwoByteString, context, |  1678         CallRuntime(Runtime::kAllocateSeqTwoByteString, context, | 
|  1695                     mode == SMI_PARAMETERS ? length : SmiFromWord(length)); |  1679                     mode == SMI_PARAMETERS ? length : SmiFromWord(length)); | 
|  1696     var_result.Bind(result); |  1680     var_result.Bind(result); | 
|  1697     Goto(&if_join); |  1681     Goto(&if_join); | 
|  1698   } |  1682   } | 
|  1699  |  1683  | 
|  1700   Bind(&if_lengthiszero); |  | 
|  1701   { |  | 
|  1702     var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex)); |  | 
|  1703     Goto(&if_join); |  | 
|  1704   } |  | 
|  1705  |  | 
|  1706   Bind(&if_join); |  1684   Bind(&if_join); | 
|  1707   return var_result.value(); |  1685   return var_result.value(); | 
|  1708 } |  1686 } | 
|  1709  |  1687  | 
|  1710 Node* CodeStubAssembler::AllocateSlicedString( |  1688 Node* CodeStubAssembler::AllocateSlicedString( | 
|  1711     Heap::RootListIndex map_root_index, Node* length, Node* parent, |  1689     Heap::RootListIndex map_root_index, Node* length, Node* parent, | 
|  1712     Node* offset) { |  1690     Node* offset) { | 
|  1713   CSA_ASSERT(this, TaggedIsSmi(length)); |  1691   CSA_ASSERT(this, TaggedIsSmi(length)); | 
|  1714   Node* result = Allocate(SlicedString::kSize); |  1692   Node* result = Allocate(SlicedString::kSize); | 
|  1715   DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); |  1693   DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); | 
| (...skipping 1442 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3158             // The {string} might be compressed, call the runtime. |  3136             // The {string} might be compressed, call the runtime. | 
|  3159             var_result.Bind(SmiToWord32( |  3137             var_result.Bind(SmiToWord32( | 
|  3160                 CallRuntime(Runtime::kExternalStringGetChar, |  3138                 CallRuntime(Runtime::kExternalStringGetChar, | 
|  3161                             NoContextConstant(), string, SmiTag(index)))); |  3139                             NoContextConstant(), string, SmiTag(index)))); | 
|  3162             Goto(&done_loop); |  3140             Goto(&done_loop); | 
|  3163           } |  3141           } | 
|  3164         } |  3142         } | 
|  3165  |  3143  | 
|  3166         Bind(&if_stringisnotexternal); |  3144         Bind(&if_stringisnotexternal); | 
|  3167         { |  3145         { | 
|  3168           Label if_stringissliced(this), if_stringisthin(this); |  3146           // The {string} is a SlicedString, continue with its parent. | 
|  3169           Branch( |  3147           Node* string_offset = | 
|  3170               Word32Equal(Word32And(string_instance_type, |  3148               LoadAndUntagObjectField(string, SlicedString::kOffsetOffset); | 
|  3171                                     Int32Constant(kStringRepresentationMask)), |  3149           Node* string_parent = | 
|  3172                           Int32Constant(kSlicedStringTag)), |  3150               LoadObjectField(string, SlicedString::kParentOffset); | 
|  3173               &if_stringissliced, &if_stringisthin); |  3151           var_index.Bind(IntPtrAdd(index, string_offset)); | 
|  3174           Bind(&if_stringissliced); |  3152           var_string.Bind(string_parent); | 
|  3175           { |  3153           Goto(&loop); | 
|  3176             // The {string} is a SlicedString, continue with its parent. |  | 
|  3177             Node* string_offset = |  | 
|  3178                 LoadAndUntagObjectField(string, SlicedString::kOffsetOffset); |  | 
|  3179             Node* string_parent = |  | 
|  3180                 LoadObjectField(string, SlicedString::kParentOffset); |  | 
|  3181             var_index.Bind(IntPtrAdd(index, string_offset)); |  | 
|  3182             var_string.Bind(string_parent); |  | 
|  3183             Goto(&loop); |  | 
|  3184           } |  | 
|  3185           Bind(&if_stringisthin); |  | 
|  3186           { |  | 
|  3187             // The {string} is a ThinString, continue with its actual value. |  | 
|  3188             var_string.Bind(LoadObjectField(string, ThinString::kActualOffset)); |  | 
|  3189             Goto(&loop); |  | 
|  3190           } |  | 
|  3191         } |  3154         } | 
|  3192       } |  3155       } | 
|  3193     } |  3156     } | 
|  3194   } |  3157   } | 
|  3195  |  3158  | 
|  3196   Bind(&done_loop); |  3159   Bind(&done_loop); | 
|  3197   return var_result.value(); |  3160   return var_result.value(); | 
|  3198 } |  3161 } | 
|  3199  |  3162  | 
|  3200 Node* CodeStubAssembler::StringFromCharCode(Node* code) { |  3163 Node* CodeStubAssembler::StringFromCharCode(Node* code) { | 
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3356  |  3319  | 
|  3357   Label single_char(this); |  3320   Label single_char(this); | 
|  3358   GotoIf(SmiEqual(substr_length, SmiConstant(Smi::FromInt(1))), &single_char); |  3321   GotoIf(SmiEqual(substr_length, SmiConstant(Smi::FromInt(1))), &single_char); | 
|  3359  |  3322  | 
|  3360   // TODO(jgruber): Add an additional case for substring of length == 0? |  3323   // TODO(jgruber): Add an additional case for substring of length == 0? | 
|  3361  |  3324  | 
|  3362   // Deal with different string types: update the index if necessary |  3325   // Deal with different string types: update the index if necessary | 
|  3363   // and put the underlying string into var_string. |  3326   // and put the underlying string into var_string. | 
|  3364  |  3327  | 
|  3365   // If the string is not indirect, it can only be sequential or external. |  3328   // If the string is not indirect, it can only be sequential or external. | 
|  3366   STATIC_ASSERT(kIsIndirectStringMask == |  3329   STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag)); | 
|  3367                 (kSlicedStringTag & kConsStringTag & kThinStringTag)); |  | 
|  3368   STATIC_ASSERT(kIsIndirectStringMask != 0); |  3330   STATIC_ASSERT(kIsIndirectStringMask != 0); | 
|  3369   Label underlying_unpacked(this); |  3331   Label underlying_unpacked(this); | 
|  3370   GotoIf(Word32Equal( |  3332   GotoIf(Word32Equal( | 
|  3371              Word32And(instance_type, Int32Constant(kIsIndirectStringMask)), |  3333              Word32And(instance_type, Int32Constant(kIsIndirectStringMask)), | 
|  3372              Int32Constant(0)), |  3334              Int32Constant(0)), | 
|  3373          &underlying_unpacked); |  3335          &underlying_unpacked); | 
|  3374  |  3336  | 
|  3375   // The subject string is a sliced, cons, or thin string. |  3337   // The subject string is either a sliced or cons string. | 
|  3376  |  3338  | 
|  3377   Label sliced_string(this), thin_or_sliced(this); |  3339   Label sliced_string(this); | 
|  3378   Node* representation = |  3340   GotoIf(Word32NotEqual( | 
|  3379       Word32And(instance_type, Int32Constant(kStringRepresentationMask)); |  3341              Word32And(instance_type, Int32Constant(kSlicedNotConsMask)), | 
|  3380   GotoIf(Word32NotEqual(representation, Int32Constant(kConsStringTag)), |  3342              Int32Constant(0)), | 
|  3381          &thin_or_sliced); |  3343          &sliced_string); | 
|  3382  |  3344  | 
|  3383   // Cons string.  Check whether it is flat, then fetch first part. |  3345   // Cons string.  Check whether it is flat, then fetch first part. | 
|  3384   // Flat cons strings have an empty second part. |  3346   // Flat cons strings have an empty second part. | 
|  3385   { |  3347   { | 
|  3386     GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset), |  3348     GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset), | 
|  3387                         EmptyStringConstant()), |  3349                         EmptyStringConstant()), | 
|  3388            &runtime); |  3350            &runtime); | 
|  3389  |  3351  | 
|  3390     Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset); |  3352     Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset); | 
|  3391     var_string.Bind(first_string_part); |  3353     var_string.Bind(first_string_part); | 
|  3392     var_instance_type.Bind(LoadInstanceType(first_string_part)); |  3354     var_instance_type.Bind(LoadInstanceType(first_string_part)); | 
|  3393  |  3355  | 
|  3394     Goto(&underlying_unpacked); |  3356     Goto(&underlying_unpacked); | 
|  3395   } |  3357   } | 
|  3396  |  3358  | 
|  3397   Bind(&thin_or_sliced); |  | 
|  3398   { |  | 
|  3399     GotoIf(Word32Equal(representation, Int32Constant(kSlicedStringTag)), |  | 
|  3400            &sliced_string); |  | 
|  3401     Node* actual_string = LoadObjectField(string, ThinString::kActualOffset); |  | 
|  3402     var_string.Bind(actual_string); |  | 
|  3403     var_instance_type.Bind(LoadInstanceType(actual_string)); |  | 
|  3404     Goto(&underlying_unpacked); |  | 
|  3405   } |  | 
|  3406  |  | 
|  3407   Bind(&sliced_string); |  3359   Bind(&sliced_string); | 
|  3408   { |  3360   { | 
|  3409     // Fetch parent and correct start index by offset. |  3361     // Fetch parent and correct start index by offset. | 
|  3410     Node* sliced_offset = LoadObjectField(string, SlicedString::kOffsetOffset); |  3362     Node* sliced_offset = LoadObjectField(string, SlicedString::kOffsetOffset); | 
|  3411     var_from.Bind(SmiAdd(from, sliced_offset)); |  3363     var_from.Bind(SmiAdd(from, sliced_offset)); | 
|  3412  |  3364  | 
|  3413     Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset); |  3365     Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset); | 
|  3414     var_string.Bind(slice_parent); |  3366     var_string.Bind(slice_parent); | 
|  3415  |  3367  | 
|  3416     Node* slice_parent_instance_type = LoadInstanceType(slice_parent); |  3368     Node* slice_parent_instance_type = LoadInstanceType(slice_parent); | 
| (...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4353   variable.Bind( |  4305   variable.Bind( | 
|  4354       IntPtrOrSmiAdd(variable.value(), IntPtrOrSmiConstant(value, mode), mode)); |  4306       IntPtrOrSmiAdd(variable.value(), IntPtrOrSmiConstant(value, mode), mode)); | 
|  4355 } |  4307 } | 
|  4356  |  4308  | 
|  4357 void CodeStubAssembler::Use(Label* label) { |  4309 void CodeStubAssembler::Use(Label* label) { | 
|  4358   GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); |  4310   GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); | 
|  4359 } |  4311 } | 
|  4360  |  4312  | 
|  4361 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, |  4313 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, | 
|  4362                                   Variable* var_index, Label* if_keyisunique, |  4314                                   Variable* var_index, Label* if_keyisunique, | 
|  4363                                   Variable* var_unique, Label* if_bailout) { |  4315                                   Label* if_bailout) { | 
|  4364   DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); |  4316   DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); | 
|  4365   DCHECK_EQ(MachineRepresentation::kTagged, var_unique->rep()); |  | 
|  4366   Comment("TryToName"); |  4317   Comment("TryToName"); | 
|  4367  |  4318  | 
|  4368   Label if_hascachedindex(this), if_keyisnotindex(this), if_thinstring(this); |  4319   Label if_hascachedindex(this), if_keyisnotindex(this); | 
|  4369   // Handle Smi and HeapNumber keys. |  4320   // Handle Smi and HeapNumber keys. | 
|  4370   var_index->Bind(TryToIntptr(key, &if_keyisnotindex)); |  4321   var_index->Bind(TryToIntptr(key, &if_keyisnotindex)); | 
|  4371   Goto(if_keyisindex); |  4322   Goto(if_keyisindex); | 
|  4372  |  4323  | 
|  4373   Bind(&if_keyisnotindex); |  4324   Bind(&if_keyisnotindex); | 
|  4374   Node* key_map = LoadMap(key); |  4325   Node* key_map = LoadMap(key); | 
|  4375   var_unique->Bind(key); |  | 
|  4376   // Symbols are unique. |  4326   // Symbols are unique. | 
|  4377   GotoIf(IsSymbolMap(key_map), if_keyisunique); |  4327   GotoIf(IsSymbolMap(key_map), if_keyisunique); | 
|  4378   Node* key_instance_type = LoadMapInstanceType(key_map); |  4328   Node* key_instance_type = LoadMapInstanceType(key_map); | 
|  4379   // Miss if |key| is not a String. |  4329   // Miss if |key| is not a String. | 
|  4380   STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); |  4330   STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); | 
|  4381   GotoUnless(IsStringInstanceType(key_instance_type), if_bailout); |  4331   GotoUnless(IsStringInstanceType(key_instance_type), if_bailout); | 
|  4382   // |key| is a String. Check if it has a cached array index. |  4332   // |key| is a String. Check if it has a cached array index. | 
|  4383   Node* hash = LoadNameHashField(key); |  4333   Node* hash = LoadNameHashField(key); | 
|  4384   Node* contains_index = |  4334   Node* contains_index = | 
|  4385       Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask)); |  4335       Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask)); | 
|  4386   GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex); |  4336   GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex); | 
|  4387   // No cached array index. If the string knows that it contains an index, |  4337   // No cached array index. If the string knows that it contains an index, | 
|  4388   // then it must be an uncacheable index. Handle this case in the runtime. |  4338   // then it must be an uncacheable index. Handle this case in the runtime. | 
|  4389   Node* not_an_index = |  4339   Node* not_an_index = | 
|  4390       Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask)); |  4340       Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask)); | 
|  4391   GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout); |  4341   GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout); | 
|  4392   // Check if we have a ThinString. |  | 
|  4393   GotoIf(Word32Equal(key_instance_type, Int32Constant(THIN_STRING_TYPE)), |  | 
|  4394          &if_thinstring); |  | 
|  4395   GotoIf( |  | 
|  4396       Word32Equal(key_instance_type, Int32Constant(THIN_ONE_BYTE_STRING_TYPE)), |  | 
|  4397       &if_thinstring); |  | 
|  4398   // Finally, check if |key| is internalized. |  4342   // Finally, check if |key| is internalized. | 
|  4399   STATIC_ASSERT(kNotInternalizedTag != 0); |  4343   STATIC_ASSERT(kNotInternalizedTag != 0); | 
|  4400   Node* not_internalized = |  4344   Node* not_internalized = | 
|  4401       Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); |  4345       Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); | 
|  4402   GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); |  4346   GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); | 
|  4403   Goto(if_keyisunique); |  4347   Goto(if_keyisunique); | 
|  4404  |  4348  | 
|  4405   Bind(&if_thinstring); |  | 
|  4406   var_unique->Bind(LoadObjectField(key, ThinString::kActualOffset)); |  | 
|  4407   Goto(if_keyisunique); |  | 
|  4408  |  | 
|  4409   Bind(&if_hascachedindex); |  4349   Bind(&if_hascachedindex); | 
|  4410   var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash)); |  4350   var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash)); | 
|  4411   Goto(if_keyisindex); |  4351   Goto(if_keyisindex); | 
|  4412 } |  4352 } | 
|  4413  |  4353  | 
|  4414 template <typename Dictionary> |  4354 template <typename Dictionary> | 
|  4415 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { |  4355 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { | 
|  4416   Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); |  4356   Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); | 
|  4417   return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + |  4357   return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + | 
|  4418                                                field_index)); |  4358                                                field_index)); | 
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5248     Label if_objectisreceiver(this); |  5188     Label if_objectisreceiver(this); | 
|  5249     STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |  5189     STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | 
|  5250     STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE); |  5190     STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE); | 
|  5251     Branch( |  5191     Branch( | 
|  5252         Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)), |  5192         Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)), | 
|  5253         &if_objectisreceiver, if_bailout); |  5193         &if_objectisreceiver, if_bailout); | 
|  5254     Bind(&if_objectisreceiver); |  5194     Bind(&if_objectisreceiver); | 
|  5255   } |  5195   } | 
|  5256  |  5196  | 
|  5257   Variable var_index(this, MachineType::PointerRepresentation()); |  5197   Variable var_index(this, MachineType::PointerRepresentation()); | 
|  5258   Variable var_unique(this, MachineRepresentation::kTagged); |  | 
|  5259  |  5198  | 
|  5260   Label if_keyisindex(this), if_iskeyunique(this); |  5199   Label if_keyisindex(this), if_iskeyunique(this); | 
|  5261   TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_unique, |  5200   TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); | 
|  5262             if_bailout); |  | 
|  5263  |  5201  | 
|  5264   Bind(&if_iskeyunique); |  5202   Bind(&if_iskeyunique); | 
|  5265   { |  5203   { | 
|  5266     Variable var_holder(this, MachineRepresentation::kTagged); |  5204     Variable var_holder(this, MachineRepresentation::kTagged); | 
|  5267     Variable var_holder_map(this, MachineRepresentation::kTagged); |  5205     Variable var_holder_map(this, MachineRepresentation::kTagged); | 
|  5268     Variable var_holder_instance_type(this, MachineRepresentation::kWord32); |  5206     Variable var_holder_instance_type(this, MachineRepresentation::kWord32); | 
|  5269  |  5207  | 
|  5270     Variable* merged_variables[] = {&var_holder, &var_holder_map, |  5208     Variable* merged_variables[] = {&var_holder, &var_holder_map, | 
|  5271                                     &var_holder_instance_type}; |  5209                                     &var_holder_instance_type}; | 
|  5272     Label loop(this, arraysize(merged_variables), merged_variables); |  5210     Label loop(this, arraysize(merged_variables), merged_variables); | 
|  5273     var_holder.Bind(receiver); |  5211     var_holder.Bind(receiver); | 
|  5274     var_holder_map.Bind(map); |  5212     var_holder_map.Bind(map); | 
|  5275     var_holder_instance_type.Bind(instance_type); |  5213     var_holder_instance_type.Bind(instance_type); | 
|  5276     Goto(&loop); |  5214     Goto(&loop); | 
|  5277     Bind(&loop); |  5215     Bind(&loop); | 
|  5278     { |  5216     { | 
|  5279       Node* holder_map = var_holder_map.value(); |  5217       Node* holder_map = var_holder_map.value(); | 
|  5280       Node* holder_instance_type = var_holder_instance_type.value(); |  5218       Node* holder_instance_type = var_holder_instance_type.value(); | 
|  5281  |  5219  | 
|  5282       Label next_proto(this); |  5220       Label next_proto(this); | 
|  5283       lookup_property_in_holder(receiver, var_holder.value(), holder_map, |  5221       lookup_property_in_holder(receiver, var_holder.value(), holder_map, | 
|  5284                                 holder_instance_type, var_unique.value(), |  5222                                 holder_instance_type, key, &next_proto, | 
|  5285                                 &next_proto, if_bailout); |  5223                                 if_bailout); | 
|  5286       Bind(&next_proto); |  5224       Bind(&next_proto); | 
|  5287  |  5225  | 
|  5288       // Bailout if it can be an integer indexed exotic case. |  5226       // Bailout if it can be an integer indexed exotic case. | 
|  5289       GotoIf( |  5227       GotoIf( | 
|  5290           Word32Equal(holder_instance_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |  5228           Word32Equal(holder_instance_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 
|  5291           if_bailout); |  5229           if_bailout); | 
|  5292  |  5230  | 
|  5293       Node* proto = LoadMapPrototype(holder_map); |  5231       Node* proto = LoadMapPrototype(holder_map); | 
|  5294  |  5232  | 
|  5295       Label if_not_null(this); |  5233       Label if_not_null(this); | 
| (...skipping 3110 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  8406   StoreObjectFieldNoWriteBarrier(result, |  8344   StoreObjectFieldNoWriteBarrier(result, | 
|  8407                                  PromiseReactionJobInfo::kDebugNameOffset, |  8345                                  PromiseReactionJobInfo::kDebugNameOffset, | 
|  8408                                  SmiConstant(kDebugNotActive)); |  8346                                  SmiConstant(kDebugNotActive)); | 
|  8409   StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset, |  8347   StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset, | 
|  8410                                  context); |  8348                                  context); | 
|  8411   return result; |  8349   return result; | 
|  8412 } |  8350 } | 
|  8413  |  8351  | 
|  8414 }  // namespace internal |  8352 }  // namespace internal | 
|  8415 }  // namespace v8 |  8353 }  // namespace v8 | 
| OLD | NEW |