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 #include "src/ic/handler-configuration.h" | 8 #include "src/ic/handler-configuration.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 } | 1006 } |
1007 | 1007 |
1008 Node* CodeStubAssembler::LoadProperties(Node* object) { | 1008 Node* CodeStubAssembler::LoadProperties(Node* object) { |
1009 return LoadObjectField(object, JSObject::kPropertiesOffset); | 1009 return LoadObjectField(object, JSObject::kPropertiesOffset); |
1010 } | 1010 } |
1011 | 1011 |
1012 Node* CodeStubAssembler::LoadElements(Node* object) { | 1012 Node* CodeStubAssembler::LoadElements(Node* object) { |
1013 return LoadObjectField(object, JSObject::kElementsOffset); | 1013 return LoadObjectField(object, JSObject::kElementsOffset); |
1014 } | 1014 } |
1015 | 1015 |
1016 Node* CodeStubAssembler::LoadJSArrayLength(compiler::Node* array) { | 1016 Node* CodeStubAssembler::LoadJSArrayLength(Node* array) { |
| 1017 CSA_ASSERT(IsJSArray(array)); |
1017 return LoadObjectField(array, JSArray::kLengthOffset); | 1018 return LoadObjectField(array, JSArray::kLengthOffset); |
1018 } | 1019 } |
1019 | 1020 |
1020 Node* CodeStubAssembler::LoadFixedArrayBaseLength(compiler::Node* array) { | 1021 Node* CodeStubAssembler::LoadFixedArrayBaseLength(Node* array) { |
1021 return LoadObjectField(array, FixedArrayBase::kLengthOffset); | 1022 return LoadObjectField(array, FixedArrayBase::kLengthOffset); |
1022 } | 1023 } |
1023 | 1024 |
1024 Node* CodeStubAssembler::LoadAndUntagFixedArrayBaseLength(Node* array) { | 1025 Node* CodeStubAssembler::LoadAndUntagFixedArrayBaseLength(Node* array) { |
1025 return LoadAndUntagObjectField(array, FixedArrayBase::kLengthOffset); | 1026 return LoadAndUntagObjectField(array, FixedArrayBase::kLengthOffset); |
1026 } | 1027 } |
1027 | 1028 |
1028 Node* CodeStubAssembler::LoadMapBitField(Node* map) { | 1029 Node* CodeStubAssembler::LoadMapBitField(Node* map) { |
| 1030 CSA_SLOW_ASSERT(IsMap(map)); |
1029 return LoadObjectField(map, Map::kBitFieldOffset, MachineType::Uint8()); | 1031 return LoadObjectField(map, Map::kBitFieldOffset, MachineType::Uint8()); |
1030 } | 1032 } |
1031 | 1033 |
1032 Node* CodeStubAssembler::LoadMapBitField2(Node* map) { | 1034 Node* CodeStubAssembler::LoadMapBitField2(Node* map) { |
| 1035 CSA_SLOW_ASSERT(IsMap(map)); |
1033 return LoadObjectField(map, Map::kBitField2Offset, MachineType::Uint8()); | 1036 return LoadObjectField(map, Map::kBitField2Offset, MachineType::Uint8()); |
1034 } | 1037 } |
1035 | 1038 |
1036 Node* CodeStubAssembler::LoadMapBitField3(Node* map) { | 1039 Node* CodeStubAssembler::LoadMapBitField3(Node* map) { |
| 1040 CSA_SLOW_ASSERT(IsMap(map)); |
1037 return LoadObjectField(map, Map::kBitField3Offset, MachineType::Uint32()); | 1041 return LoadObjectField(map, Map::kBitField3Offset, MachineType::Uint32()); |
1038 } | 1042 } |
1039 | 1043 |
1040 Node* CodeStubAssembler::LoadMapInstanceType(Node* map) { | 1044 Node* CodeStubAssembler::LoadMapInstanceType(Node* map) { |
1041 return LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint8()); | 1045 return LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint8()); |
1042 } | 1046 } |
1043 | 1047 |
1044 Node* CodeStubAssembler::LoadMapElementsKind(Node* map) { | 1048 Node* CodeStubAssembler::LoadMapElementsKind(Node* map) { |
| 1049 CSA_SLOW_ASSERT(IsMap(map)); |
1045 Node* bit_field2 = LoadMapBitField2(map); | 1050 Node* bit_field2 = LoadMapBitField2(map); |
1046 return DecodeWord32<Map::ElementsKindBits>(bit_field2); | 1051 return DecodeWord32<Map::ElementsKindBits>(bit_field2); |
1047 } | 1052 } |
1048 | 1053 |
1049 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { | 1054 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { |
| 1055 CSA_SLOW_ASSERT(IsMap(map)); |
1050 return LoadObjectField(map, Map::kDescriptorsOffset); | 1056 return LoadObjectField(map, Map::kDescriptorsOffset); |
1051 } | 1057 } |
1052 | 1058 |
1053 Node* CodeStubAssembler::LoadMapPrototype(Node* map) { | 1059 Node* CodeStubAssembler::LoadMapPrototype(Node* map) { |
| 1060 CSA_SLOW_ASSERT(IsMap(map)); |
1054 return LoadObjectField(map, Map::kPrototypeOffset); | 1061 return LoadObjectField(map, Map::kPrototypeOffset); |
1055 } | 1062 } |
1056 | 1063 |
1057 Node* CodeStubAssembler::LoadMapPrototypeInfo(Node* map, | 1064 Node* CodeStubAssembler::LoadMapPrototypeInfo(Node* map, |
1058 Label* if_no_proto_info) { | 1065 Label* if_no_proto_info) { |
| 1066 CSA_ASSERT(IsMap(map)); |
1059 Node* prototype_info = | 1067 Node* prototype_info = |
1060 LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset); | 1068 LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset); |
1061 GotoIf(TaggedIsSmi(prototype_info), if_no_proto_info); | 1069 GotoIf(TaggedIsSmi(prototype_info), if_no_proto_info); |
1062 GotoUnless(WordEqual(LoadMap(prototype_info), | 1070 GotoUnless(WordEqual(LoadMap(prototype_info), |
1063 LoadRoot(Heap::kPrototypeInfoMapRootIndex)), | 1071 LoadRoot(Heap::kPrototypeInfoMapRootIndex)), |
1064 if_no_proto_info); | 1072 if_no_proto_info); |
1065 return prototype_info; | 1073 return prototype_info; |
1066 } | 1074 } |
1067 | 1075 |
1068 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { | 1076 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { |
| 1077 CSA_SLOW_ASSERT(IsMap(map)); |
1069 return ChangeUint32ToWord( | 1078 return ChangeUint32ToWord( |
1070 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8())); | 1079 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8())); |
1071 } | 1080 } |
1072 | 1081 |
1073 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) { | 1082 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) { |
| 1083 CSA_SLOW_ASSERT(IsMap(map)); |
1074 // See Map::GetInObjectProperties() for details. | 1084 // See Map::GetInObjectProperties() for details. |
1075 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); | 1085 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
1076 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map), | 1086 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map), |
1077 Int32Constant(FIRST_JS_OBJECT_TYPE))); | 1087 Int32Constant(FIRST_JS_OBJECT_TYPE))); |
1078 return ChangeUint32ToWord(LoadObjectField( | 1088 return ChangeUint32ToWord(LoadObjectField( |
1079 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, | 1089 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, |
1080 MachineType::Uint8())); | 1090 MachineType::Uint8())); |
1081 } | 1091 } |
1082 | 1092 |
1083 Node* CodeStubAssembler::LoadMapConstructorFunctionIndex(Node* map) { | 1093 Node* CodeStubAssembler::LoadMapConstructorFunctionIndex(Node* map) { |
| 1094 CSA_SLOW_ASSERT(IsMap(map)); |
1084 // See Map::GetConstructorFunctionIndex() for details. | 1095 // See Map::GetConstructorFunctionIndex() for details. |
1085 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); | 1096 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); |
1086 CSA_ASSERT(Int32LessThanOrEqual(LoadMapInstanceType(map), | 1097 CSA_ASSERT(Int32LessThanOrEqual(LoadMapInstanceType(map), |
1087 Int32Constant(LAST_PRIMITIVE_TYPE))); | 1098 Int32Constant(LAST_PRIMITIVE_TYPE))); |
1088 return ChangeUint32ToWord(LoadObjectField( | 1099 return ChangeUint32ToWord(LoadObjectField( |
1089 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, | 1100 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, |
1090 MachineType::Uint8())); | 1101 MachineType::Uint8())); |
1091 } | 1102 } |
1092 | 1103 |
1093 Node* CodeStubAssembler::LoadMapConstructor(Node* map) { | 1104 Node* CodeStubAssembler::LoadMapConstructor(Node* map) { |
| 1105 CSA_SLOW_ASSERT(IsMap(map)); |
1094 Variable result(this, MachineRepresentation::kTagged); | 1106 Variable result(this, MachineRepresentation::kTagged); |
1095 result.Bind(LoadObjectField(map, Map::kConstructorOrBackPointerOffset)); | 1107 result.Bind(LoadObjectField(map, Map::kConstructorOrBackPointerOffset)); |
1096 | 1108 |
1097 Label done(this), loop(this, &result); | 1109 Label done(this), loop(this, &result); |
1098 Goto(&loop); | 1110 Goto(&loop); |
1099 Bind(&loop); | 1111 Bind(&loop); |
1100 { | 1112 { |
1101 GotoIf(TaggedIsSmi(result.value()), &done); | 1113 GotoIf(TaggedIsSmi(result.value()), &done); |
1102 Node* is_map_type = | 1114 Node* is_map_type = |
1103 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); | 1115 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); |
1104 GotoUnless(is_map_type, &done); | 1116 GotoUnless(is_map_type, &done); |
1105 result.Bind( | 1117 result.Bind( |
1106 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); | 1118 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); |
1107 Goto(&loop); | 1119 Goto(&loop); |
1108 } | 1120 } |
1109 Bind(&done); | 1121 Bind(&done); |
1110 return result.value(); | 1122 return result.value(); |
1111 } | 1123 } |
1112 | 1124 |
1113 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { | |
1114 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | |
1115 Node* bit_field = LoadMapBitField(map); | |
1116 uint32_t mask = | |
1117 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; | |
1118 // Interceptors or access checks imply special receiver. | |
1119 CSA_ASSERT( | |
1120 Select(IsSetWord32(bit_field, mask), is_special, Int32Constant(1))); | |
1121 return is_special; | |
1122 } | |
1123 | |
1124 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { | |
1125 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | |
1126 return Int32LessThanOrEqual(instance_type, | |
1127 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); | |
1128 } | |
1129 | |
1130 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { | |
1131 Node* bit_field3 = LoadMapBitField3(map); | |
1132 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), | |
1133 Int32Constant(0)); | |
1134 } | |
1135 | |
1136 Node* CodeStubAssembler::LoadNameHashField(Node* name) { | 1125 Node* CodeStubAssembler::LoadNameHashField(Node* name) { |
| 1126 CSA_ASSERT(IsName(name)); |
1137 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); | 1127 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); |
1138 } | 1128 } |
1139 | 1129 |
1140 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { | 1130 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { |
1141 Node* hash_field = LoadNameHashField(name); | 1131 Node* hash_field = LoadNameHashField(name); |
1142 if (if_hash_not_computed != nullptr) { | 1132 if (if_hash_not_computed != nullptr) { |
1143 GotoIf(Word32Equal( | 1133 GotoIf(Word32Equal( |
1144 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), | 1134 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), |
1145 Int32Constant(0)), | 1135 Int32Constant(0)), |
1146 if_hash_not_computed); | 1136 if_hash_not_computed); |
1147 } | 1137 } |
1148 return Word32Shr(hash_field, Int32Constant(Name::kHashShift)); | 1138 return Word32Shr(hash_field, Int32Constant(Name::kHashShift)); |
1149 } | 1139 } |
1150 | 1140 |
1151 Node* CodeStubAssembler::LoadStringLength(Node* object) { | 1141 Node* CodeStubAssembler::LoadStringLength(Node* object) { |
| 1142 CSA_ASSERT(IsString(object)); |
1152 return LoadObjectField(object, String::kLengthOffset); | 1143 return LoadObjectField(object, String::kLengthOffset); |
1153 } | 1144 } |
1154 | 1145 |
1155 Node* CodeStubAssembler::LoadJSValueValue(Node* object) { | 1146 Node* CodeStubAssembler::LoadJSValueValue(Node* object) { |
| 1147 CSA_ASSERT(IsJSValue(object)); |
1156 return LoadObjectField(object, JSValue::kValueOffset); | 1148 return LoadObjectField(object, JSValue::kValueOffset); |
1157 } | 1149 } |
1158 | 1150 |
| 1151 Node* CodeStubAssembler::LoadWeakCellValueUnchecked(Node* weak_cell) { |
| 1152 // TODO(ishell): fix callers. |
| 1153 return LoadObjectField(weak_cell, WeakCell::kValueOffset); |
| 1154 } |
| 1155 |
1159 Node* CodeStubAssembler::LoadWeakCellValue(Node* weak_cell, Label* if_cleared) { | 1156 Node* CodeStubAssembler::LoadWeakCellValue(Node* weak_cell, Label* if_cleared) { |
1160 Node* value = LoadObjectField(weak_cell, WeakCell::kValueOffset); | 1157 CSA_ASSERT(IsWeakCell(weak_cell)); |
| 1158 Node* value = LoadWeakCellValueUnchecked(weak_cell); |
1161 if (if_cleared != nullptr) { | 1159 if (if_cleared != nullptr) { |
1162 GotoIf(WordEqual(value, IntPtrConstant(0)), if_cleared); | 1160 GotoIf(WordEqual(value, IntPtrConstant(0)), if_cleared); |
1163 } | 1161 } |
1164 return value; | 1162 return value; |
1165 } | 1163 } |
1166 | 1164 |
1167 Node* CodeStubAssembler::LoadFixedArrayElement(Node* object, Node* index_node, | 1165 Node* CodeStubAssembler::LoadFixedArrayElement(Node* object, Node* index_node, |
1168 int additional_offset, | 1166 int additional_offset, |
1169 ParameterMode parameter_mode) { | 1167 ParameterMode parameter_mode) { |
1170 int32_t header_size = | 1168 int32_t header_size = |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1227 if (Is64()) { | 1225 if (Is64()) { |
1228 return Load(MachineType::Int32(), object, offset); | 1226 return Load(MachineType::Int32(), object, offset); |
1229 } else { | 1227 } else { |
1230 return SmiToWord32(Load(MachineType::AnyTagged(), object, offset)); | 1228 return SmiToWord32(Load(MachineType::AnyTagged(), object, offset)); |
1231 } | 1229 } |
1232 } | 1230 } |
1233 | 1231 |
1234 Node* CodeStubAssembler::LoadFixedDoubleArrayElement( | 1232 Node* CodeStubAssembler::LoadFixedDoubleArrayElement( |
1235 Node* object, Node* index_node, MachineType machine_type, | 1233 Node* object, Node* index_node, MachineType machine_type, |
1236 int additional_offset, ParameterMode parameter_mode, Label* if_hole) { | 1234 int additional_offset, ParameterMode parameter_mode, Label* if_hole) { |
| 1235 CSA_ASSERT(IsFixedDoubleArray(object)); |
1237 int32_t header_size = | 1236 int32_t header_size = |
1238 FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag; | 1237 FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag; |
1239 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_DOUBLE_ELEMENTS, | 1238 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_DOUBLE_ELEMENTS, |
1240 parameter_mode, header_size); | 1239 parameter_mode, header_size); |
1241 return LoadDoubleWithHoleCheck(object, offset, if_hole, machine_type); | 1240 return LoadDoubleWithHoleCheck(object, offset, if_hole, machine_type); |
1242 } | 1241 } |
1243 | 1242 |
1244 Node* CodeStubAssembler::LoadDoubleWithHoleCheck(Node* base, Node* offset, | 1243 Node* CodeStubAssembler::LoadDoubleWithHoleCheck(Node* base, Node* offset, |
1245 Label* if_hole, | 1244 Label* if_hole, |
1246 MachineType machine_type) { | 1245 MachineType machine_type) { |
(...skipping 30 matching lines...) Expand all Loading... |
1277 return Store(MachineRepresentation::kTagged, context, IntPtrConstant(offset), | 1276 return Store(MachineRepresentation::kTagged, context, IntPtrConstant(offset), |
1278 value); | 1277 value); |
1279 } | 1278 } |
1280 | 1279 |
1281 Node* CodeStubAssembler::LoadNativeContext(Node* context) { | 1280 Node* CodeStubAssembler::LoadNativeContext(Node* context) { |
1282 return LoadContextElement(context, Context::NATIVE_CONTEXT_INDEX); | 1281 return LoadContextElement(context, Context::NATIVE_CONTEXT_INDEX); |
1283 } | 1282 } |
1284 | 1283 |
1285 Node* CodeStubAssembler::LoadJSArrayElementsMap(ElementsKind kind, | 1284 Node* CodeStubAssembler::LoadJSArrayElementsMap(ElementsKind kind, |
1286 Node* native_context) { | 1285 Node* native_context) { |
| 1286 CSA_ASSERT(IsNativeContext(native_context)); |
1287 return LoadFixedArrayElement(native_context, | 1287 return LoadFixedArrayElement(native_context, |
1288 IntPtrConstant(Context::ArrayMapIndex(kind))); | 1288 IntPtrConstant(Context::ArrayMapIndex(kind))); |
1289 } | 1289 } |
1290 | 1290 |
1291 Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) { | 1291 Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) { |
1292 return StoreObjectFieldNoWriteBarrier(object, HeapNumber::kValueOffset, value, | 1292 return StoreObjectFieldNoWriteBarrier(object, HeapNumber::kValueOffset, value, |
1293 MachineRepresentation::kFloat64); | 1293 MachineRepresentation::kFloat64); |
1294 } | 1294 } |
1295 | 1295 |
1296 Node* CodeStubAssembler::StoreObjectField( | 1296 Node* CodeStubAssembler::StoreObjectField( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 MachineRepresentation rep = MachineRepresentation::kTagged; | 1352 MachineRepresentation rep = MachineRepresentation::kTagged; |
1353 if (barrier_mode == SKIP_WRITE_BARRIER) { | 1353 if (barrier_mode == SKIP_WRITE_BARRIER) { |
1354 return StoreNoWriteBarrier(rep, object, offset, value); | 1354 return StoreNoWriteBarrier(rep, object, offset, value); |
1355 } else { | 1355 } else { |
1356 return Store(rep, object, offset, value); | 1356 return Store(rep, object, offset, value); |
1357 } | 1357 } |
1358 } | 1358 } |
1359 | 1359 |
1360 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( | 1360 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( |
1361 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { | 1361 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { |
| 1362 CSA_ASSERT(IsFixedDoubleArray(object)); |
1362 Node* offset = | 1363 Node* offset = |
1363 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, | 1364 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, |
1364 FixedArray::kHeaderSize - kHeapObjectTag); | 1365 FixedArray::kHeaderSize - kHeapObjectTag); |
1365 MachineRepresentation rep = MachineRepresentation::kFloat64; | 1366 MachineRepresentation rep = MachineRepresentation::kFloat64; |
1366 return StoreNoWriteBarrier(rep, object, offset, value); | 1367 return StoreNoWriteBarrier(rep, object, offset, value); |
1367 } | 1368 } |
1368 | 1369 |
1369 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { | 1370 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { |
1370 Node* result = Allocate(HeapNumber::kSize, kNone); | 1371 Node* result = Allocate(HeapNumber::kSize, kNone); |
1371 Heap::RootListIndex heap_map_index = | 1372 Heap::RootListIndex heap_map_index = |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 CallRuntime(Runtime::kAllocateSeqTwoByteString, context, | 1497 CallRuntime(Runtime::kAllocateSeqTwoByteString, context, |
1497 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); | 1498 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); |
1498 var_result.Bind(result); | 1499 var_result.Bind(result); |
1499 Goto(&if_join); | 1500 Goto(&if_join); |
1500 } | 1501 } |
1501 | 1502 |
1502 Bind(&if_join); | 1503 Bind(&if_join); |
1503 return var_result.value(); | 1504 return var_result.value(); |
1504 } | 1505 } |
1505 | 1506 |
1506 Node* CodeStubAssembler::AllocateSlicedOneByteString(Node* length, Node* parent, | 1507 Node* CodeStubAssembler::AllocateSlicedString( |
1507 Node* offset) { | 1508 Heap::RootListIndex map_root_index, Node* length, Node* parent, |
| 1509 Node* offset) { |
| 1510 CSA_ASSERT(TaggedIsSmi(length)); |
1508 Node* result = Allocate(SlicedString::kSize); | 1511 Node* result = Allocate(SlicedString::kSize); |
1509 Node* map = LoadRoot(Heap::kSlicedOneByteStringMapRootIndex); | 1512 Node* map = LoadRoot(map_root_index); |
| 1513 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); |
1510 StoreMapNoWriteBarrier(result, map); | 1514 StoreMapNoWriteBarrier(result, map); |
1511 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length, | 1515 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length, |
1512 MachineRepresentation::kTagged); | 1516 MachineRepresentation::kTagged); |
1513 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset, | 1517 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset, |
1514 Int32Constant(String::kEmptyHashField), | 1518 Int32Constant(String::kEmptyHashField), |
1515 MachineRepresentation::kWord32); | 1519 MachineRepresentation::kWord32); |
1516 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent, | 1520 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent, |
1517 MachineRepresentation::kTagged); | 1521 MachineRepresentation::kTagged); |
1518 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset, | 1522 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset, |
1519 MachineRepresentation::kTagged); | 1523 MachineRepresentation::kTagged); |
1520 return result; | 1524 return result; |
1521 } | 1525 } |
1522 | 1526 |
| 1527 Node* CodeStubAssembler::AllocateSlicedOneByteString(Node* length, Node* parent, |
| 1528 Node* offset) { |
| 1529 return AllocateSlicedString(Heap::kSlicedOneByteStringMapRootIndex, length, |
| 1530 parent, offset); |
| 1531 } |
| 1532 |
1523 Node* CodeStubAssembler::AllocateSlicedTwoByteString(Node* length, Node* parent, | 1533 Node* CodeStubAssembler::AllocateSlicedTwoByteString(Node* length, Node* parent, |
1524 Node* offset) { | 1534 Node* offset) { |
1525 CSA_ASSERT(TaggedIsSmi(length)); | 1535 return AllocateSlicedString(Heap::kSlicedStringMapRootIndex, length, parent, |
1526 Node* result = Allocate(SlicedString::kSize); | 1536 offset); |
1527 Node* map = LoadRoot(Heap::kSlicedStringMapRootIndex); | |
1528 StoreMapNoWriteBarrier(result, map); | |
1529 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length, | |
1530 MachineRepresentation::kTagged); | |
1531 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset, | |
1532 Int32Constant(String::kEmptyHashField), | |
1533 MachineRepresentation::kWord32); | |
1534 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent, | |
1535 MachineRepresentation::kTagged); | |
1536 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset, | |
1537 MachineRepresentation::kTagged); | |
1538 return result; | |
1539 } | 1537 } |
1540 | 1538 |
1541 Node* CodeStubAssembler::AllocateOneByteConsString(Node* length, Node* first, | 1539 Node* CodeStubAssembler::AllocateConsString(Heap::RootListIndex map_root_index, |
1542 Node* second, | 1540 Node* length, Node* first, |
1543 AllocationFlags flags) { | 1541 Node* second, |
| 1542 AllocationFlags flags) { |
1544 CSA_ASSERT(TaggedIsSmi(length)); | 1543 CSA_ASSERT(TaggedIsSmi(length)); |
1545 Node* result = Allocate(ConsString::kSize, flags); | 1544 Node* result = Allocate(ConsString::kSize, flags); |
1546 Node* map = LoadRoot(Heap::kConsOneByteStringMapRootIndex); | 1545 Node* map = LoadRoot(map_root_index); |
1547 DCHECK(Heap::RootIsImmortalImmovable(Heap::kConsOneByteStringMapRootIndex)); | 1546 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); |
1548 StoreMapNoWriteBarrier(result, map); | 1547 StoreMapNoWriteBarrier(result, map); |
1549 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, | 1548 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, |
1550 MachineRepresentation::kTagged); | 1549 MachineRepresentation::kTagged); |
1551 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset, | 1550 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset, |
1552 Int32Constant(String::kEmptyHashField), | 1551 Int32Constant(String::kEmptyHashField), |
1553 MachineRepresentation::kWord32); | 1552 MachineRepresentation::kWord32); |
1554 bool const new_space = !(flags & kPretenured); | 1553 bool const new_space = !(flags & kPretenured); |
1555 if (new_space) { | 1554 if (new_space) { |
1556 StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first, | 1555 StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first, |
1557 MachineRepresentation::kTagged); | 1556 MachineRepresentation::kTagged); |
1558 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second, | 1557 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second, |
1559 MachineRepresentation::kTagged); | 1558 MachineRepresentation::kTagged); |
1560 } else { | 1559 } else { |
1561 StoreObjectField(result, ConsString::kFirstOffset, first); | 1560 StoreObjectField(result, ConsString::kFirstOffset, first); |
1562 StoreObjectField(result, ConsString::kSecondOffset, second); | 1561 StoreObjectField(result, ConsString::kSecondOffset, second); |
1563 } | 1562 } |
1564 return result; | 1563 return result; |
1565 } | 1564 } |
1566 | 1565 |
| 1566 Node* CodeStubAssembler::AllocateOneByteConsString(Node* length, Node* first, |
| 1567 Node* second, |
| 1568 AllocationFlags flags) { |
| 1569 return AllocateConsString(Heap::kConsOneByteStringMapRootIndex, length, first, |
| 1570 second, flags); |
| 1571 } |
| 1572 |
1567 Node* CodeStubAssembler::AllocateTwoByteConsString(Node* length, Node* first, | 1573 Node* CodeStubAssembler::AllocateTwoByteConsString(Node* length, Node* first, |
1568 Node* second, | 1574 Node* second, |
1569 AllocationFlags flags) { | 1575 AllocationFlags flags) { |
1570 CSA_ASSERT(TaggedIsSmi(length)); | 1576 return AllocateConsString(Heap::kConsStringMapRootIndex, length, first, |
1571 Node* result = Allocate(ConsString::kSize, flags); | 1577 second, flags); |
1572 Node* map = LoadRoot(Heap::kConsStringMapRootIndex); | |
1573 DCHECK(Heap::RootIsImmortalImmovable(Heap::kConsStringMapRootIndex)); | |
1574 StoreMapNoWriteBarrier(result, map); | |
1575 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, | |
1576 MachineRepresentation::kTagged); | |
1577 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset, | |
1578 Int32Constant(String::kEmptyHashField), | |
1579 MachineRepresentation::kWord32); | |
1580 bool const new_space = !(flags & kPretenured); | |
1581 if (new_space) { | |
1582 StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first, | |
1583 MachineRepresentation::kTagged); | |
1584 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second, | |
1585 MachineRepresentation::kTagged); | |
1586 } else { | |
1587 StoreObjectField(result, ConsString::kFirstOffset, first); | |
1588 StoreObjectField(result, ConsString::kSecondOffset, second); | |
1589 } | |
1590 return result; | |
1591 } | 1578 } |
1592 | 1579 |
1593 Node* CodeStubAssembler::NewConsString(Node* context, Node* length, Node* left, | 1580 Node* CodeStubAssembler::NewConsString(Node* context, Node* length, Node* left, |
1594 Node* right, AllocationFlags flags) { | 1581 Node* right, AllocationFlags flags) { |
1595 CSA_ASSERT(TaggedIsSmi(length)); | 1582 CSA_ASSERT(TaggedIsSmi(length)); |
1596 // Added string can be a cons string. | 1583 // Added string can be a cons string. |
1597 Comment("Allocating ConsString"); | 1584 Comment("Allocating ConsString"); |
1598 Node* left_instance_type = LoadInstanceType(left); | 1585 Node* left_instance_type = LoadInstanceType(left); |
1599 Node* right_instance_type = LoadInstanceType(right); | 1586 Node* right_instance_type = LoadInstanceType(right); |
1600 | 1587 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1733 kHeapObjectTag)); | 1720 kHeapObjectTag)); |
1734 Node* end_address = IntPtrAdd( | 1721 Node* end_address = IntPtrAdd( |
1735 result, | 1722 result, |
1736 IntPtrSubFoldConstants(store_size, IntPtrConstant(kHeapObjectTag))); | 1723 IntPtrSubFoldConstants(store_size, IntPtrConstant(kHeapObjectTag))); |
1737 StoreFieldsNoWriteBarrier(start_address, end_address, filler); | 1724 StoreFieldsNoWriteBarrier(start_address, end_address, filler); |
1738 return result; | 1725 return result; |
1739 } | 1726 } |
1740 | 1727 |
1741 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, | 1728 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, |
1742 Node* elements) { | 1729 Node* elements) { |
| 1730 CSA_ASSERT(IsMap(map)); |
1743 Node* size = | 1731 Node* size = |
1744 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); | 1732 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); |
1745 CSA_ASSERT(IsRegularHeapObjectSize(size)); | 1733 CSA_ASSERT(IsRegularHeapObjectSize(size)); |
1746 Node* object = Allocate(size); | 1734 Node* object = Allocate(size); |
1747 StoreMapNoWriteBarrier(object, map); | 1735 StoreMapNoWriteBarrier(object, map); |
1748 InitializeJSObjectFromMap(object, map, size, properties, elements); | 1736 InitializeJSObjectFromMap(object, map, size, properties, elements); |
1749 return object; | 1737 return object; |
1750 } | 1738 } |
1751 | 1739 |
1752 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, | 1740 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1885 : IntPtrConstant(0), | 1873 : IntPtrConstant(0), |
1886 capacity, Heap::kTheHoleValueRootIndex, capacity_mode); | 1874 capacity, Heap::kTheHoleValueRootIndex, capacity_mode); |
1887 | 1875 |
1888 return array; | 1876 return array; |
1889 } | 1877 } |
1890 | 1878 |
1891 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, | 1879 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, |
1892 Node* capacity_node, | 1880 Node* capacity_node, |
1893 ParameterMode mode, | 1881 ParameterMode mode, |
1894 AllocationFlags flags) { | 1882 AllocationFlags flags) { |
| 1883 CSA_ASSERT(IntPtrGreaterThan(capacity_node, IntPtrOrSmiConstant(0, mode))); |
1895 Node* total_size = GetFixedArrayAllocationSize(capacity_node, kind, mode); | 1884 Node* total_size = GetFixedArrayAllocationSize(capacity_node, kind, mode); |
1896 | 1885 |
1897 // Allocate both array and elements object, and initialize the JSArray. | 1886 // Allocate both array and elements object, and initialize the JSArray. |
1898 Node* array = Allocate(total_size, flags); | 1887 Node* array = Allocate(total_size, flags); |
1899 Heap* heap = isolate()->heap(); | 1888 Heap* heap = isolate()->heap(); |
1900 Handle<Map> map(IsFastDoubleElementsKind(kind) | 1889 Handle<Map> map(IsFastDoubleElementsKind(kind) |
1901 ? heap->fixed_double_array_map() | 1890 ? heap->fixed_double_array_map() |
1902 : heap->fixed_array_map()); | 1891 : heap->fixed_array_map()); |
1903 if (flags & kPretenured) { | 1892 if (flags & kPretenured) { |
1904 StoreObjectField(array, JSObject::kMapOffset, HeapConstant(map)); | 1893 StoreObjectField(array, JSObject::kMapOffset, HeapConstant(map)); |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2631 Runtime::kThrowIncompatibleMethodReceiver, context, | 2620 Runtime::kThrowIncompatibleMethodReceiver, context, |
2632 HeapConstant(factory()->NewStringFromAsciiChecked(method_name, TENURED)), | 2621 HeapConstant(factory()->NewStringFromAsciiChecked(method_name, TENURED)), |
2633 value); | 2622 value); |
2634 var_value_map.Bind(UndefinedConstant()); | 2623 var_value_map.Bind(UndefinedConstant()); |
2635 Goto(&out); // Never reached. | 2624 Goto(&out); // Never reached. |
2636 | 2625 |
2637 Bind(&out); | 2626 Bind(&out); |
2638 return var_value_map.value(); | 2627 return var_value_map.value(); |
2639 } | 2628 } |
2640 | 2629 |
| 2630 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { |
| 2631 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
| 2632 Node* bit_field = LoadMapBitField(map); |
| 2633 uint32_t mask = |
| 2634 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
| 2635 // Interceptors or access checks imply special receiver. |
| 2636 CSA_ASSERT( |
| 2637 Select(IsSetWord32(bit_field, mask), is_special, Int32Constant(1))); |
| 2638 return is_special; |
| 2639 } |
| 2640 |
| 2641 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { |
| 2642 CSA_SLOW_ASSERT(IsMap(map)); |
| 2643 Node* bit_field3 = LoadMapBitField3(map); |
| 2644 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), |
| 2645 Int32Constant(0)); |
| 2646 } |
| 2647 |
| 2648 Node* CodeStubAssembler::IsCallableMap(Node* map) { |
| 2649 CSA_ASSERT(IsMap(map)); |
| 2650 return Word32NotEqual( |
| 2651 Word32And(LoadMapBitField(map), Int32Constant(1 << Map::kIsCallable)), |
| 2652 Int32Constant(0)); |
| 2653 } |
| 2654 |
| 2655 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
| 2656 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
| 2657 return Int32LessThanOrEqual(instance_type, |
| 2658 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); |
| 2659 } |
| 2660 |
2641 Node* CodeStubAssembler::IsStringInstanceType(Node* instance_type) { | 2661 Node* CodeStubAssembler::IsStringInstanceType(Node* instance_type) { |
2642 STATIC_ASSERT(INTERNALIZED_STRING_TYPE == FIRST_TYPE); | 2662 STATIC_ASSERT(INTERNALIZED_STRING_TYPE == FIRST_TYPE); |
2643 return Int32LessThan(instance_type, Int32Constant(FIRST_NONSTRING_TYPE)); | 2663 return Int32LessThan(instance_type, Int32Constant(FIRST_NONSTRING_TYPE)); |
2644 } | 2664 } |
2645 | 2665 |
2646 Node* CodeStubAssembler::IsJSReceiverInstanceType(Node* instance_type) { | 2666 Node* CodeStubAssembler::IsJSReceiverInstanceType(Node* instance_type) { |
2647 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | 2667 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
2648 return Int32GreaterThanOrEqual(instance_type, | 2668 return Int32GreaterThanOrEqual(instance_type, |
2649 Int32Constant(FIRST_JS_RECEIVER_TYPE)); | 2669 Int32Constant(FIRST_JS_RECEIVER_TYPE)); |
2650 } | 2670 } |
2651 | 2671 |
2652 Node* CodeStubAssembler::IsCallableMap(Node* map) { | 2672 Node* CodeStubAssembler::IsJSReceiver(Node* object) { |
2653 return Word32NotEqual( | 2673 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
2654 Word32And(LoadMapBitField(map), Int32Constant(1 << Map::kIsCallable)), | 2674 return IsJSReceiverInstanceType(LoadInstanceType(object)); |
2655 Int32Constant(0)); | 2675 } |
| 2676 |
| 2677 Node* CodeStubAssembler::IsJSObject(Node* object) { |
| 2678 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
| 2679 return Int32GreaterThanOrEqual(LoadInstanceType(object), |
| 2680 Int32Constant(FIRST_JS_RECEIVER_TYPE)); |
| 2681 } |
| 2682 |
| 2683 Node* CodeStubAssembler::IsMap(Node* map) { |
| 2684 return HasInstanceType(map, MAP_TYPE); |
| 2685 } |
| 2686 |
| 2687 Node* CodeStubAssembler::IsJSValue(Node* map) { |
| 2688 return HasInstanceType(map, JS_VALUE_TYPE); |
| 2689 } |
| 2690 |
| 2691 Node* CodeStubAssembler::IsJSArray(Node* object) { |
| 2692 return HasInstanceType(object, JS_ARRAY_TYPE); |
| 2693 } |
| 2694 |
| 2695 Node* CodeStubAssembler::IsWeakCell(Node* object) { |
| 2696 return HasInstanceType(object, WEAK_CELL_TYPE); |
| 2697 } |
| 2698 |
| 2699 Node* CodeStubAssembler::IsName(Node* object) { |
| 2700 return Int32LessThanOrEqual(LoadInstanceType(object), |
| 2701 Int32Constant(LAST_NAME_TYPE)); |
| 2702 } |
| 2703 |
| 2704 Node* CodeStubAssembler::IsString(Node* object) { |
| 2705 return Int32LessThanOrEqual(LoadInstanceType(object), |
| 2706 Int32Constant(FIRST_NONSTRING_TYPE)); |
| 2707 } |
| 2708 |
| 2709 Node* CodeStubAssembler::IsNativeContext(Node* object) { |
| 2710 return WordEqual(LoadMap(object), LoadRoot(Heap::kNativeContextMapRootIndex)); |
| 2711 } |
| 2712 |
| 2713 Node* CodeStubAssembler::IsFixedDoubleArray(Node* object) { |
| 2714 return WordEqual(LoadMap(object), FixedDoubleArrayMapConstant()); |
| 2715 } |
| 2716 |
| 2717 Node* CodeStubAssembler::IsHashTable(Node* object) { |
| 2718 return WordEqual(LoadMap(object), LoadRoot(Heap::kHashTableMapRootIndex)); |
| 2719 } |
| 2720 |
| 2721 Node* CodeStubAssembler::IsDictionary(Node* object) { |
| 2722 return WordOr(IsHashTable(object), IsUnseededNumberDictionary(object)); |
| 2723 } |
| 2724 |
| 2725 Node* CodeStubAssembler::IsUnseededNumberDictionary(Node* object) { |
| 2726 return WordEqual(LoadMap(object), |
| 2727 LoadRoot(Heap::kUnseededNumberDictionaryMapRootIndex)); |
2656 } | 2728 } |
2657 | 2729 |
2658 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index) { | 2730 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index) { |
| 2731 CSA_ASSERT(IsString(string)); |
2659 // Translate the {index} into a Word. | 2732 // Translate the {index} into a Word. |
2660 index = SmiToWord(index); | 2733 index = SmiToWord(index); |
2661 | 2734 |
2662 // We may need to loop in case of cons or sliced strings. | 2735 // We may need to loop in case of cons or sliced strings. |
2663 Variable var_index(this, MachineType::PointerRepresentation()); | 2736 Variable var_index(this, MachineType::PointerRepresentation()); |
2664 Variable var_result(this, MachineRepresentation::kWord32); | 2737 Variable var_result(this, MachineRepresentation::kWord32); |
2665 Variable var_string(this, MachineRepresentation::kTagged); | 2738 Variable var_string(this, MachineRepresentation::kTagged); |
2666 Variable* loop_vars[] = {&var_index, &var_string}; | 2739 Variable* loop_vars[] = {&var_index, &var_string}; |
2667 Label done_loop(this, &var_result), loop(this, 2, loop_vars); | 2740 Label done_loop(this, &var_result), loop(this, 2, loop_vars); |
2668 var_string.Bind(string); | 2741 var_string.Bind(string); |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3260 IncrementCounter(counters->string_add_native(), 1); | 3333 IncrementCounter(counters->string_add_native(), 1); |
3261 Goto(&done); | 3334 Goto(&done); |
3262 } | 3335 } |
3263 | 3336 |
3264 Bind(&done); | 3337 Bind(&done); |
3265 return result.value(); | 3338 return result.value(); |
3266 } | 3339 } |
3267 | 3340 |
3268 Node* CodeStubAssembler::StringIndexOfChar(Node* context, Node* string, | 3341 Node* CodeStubAssembler::StringIndexOfChar(Node* context, Node* string, |
3269 Node* needle_char, Node* from) { | 3342 Node* needle_char, Node* from) { |
| 3343 CSA_ASSERT(IsString(string)); |
3270 Variable var_result(this, MachineRepresentation::kTagged); | 3344 Variable var_result(this, MachineRepresentation::kTagged); |
3271 | 3345 |
3272 Label out(this), runtime(this, Label::kDeferred); | 3346 Label out(this), runtime(this, Label::kDeferred); |
3273 | 3347 |
3274 // Let runtime handle non-one-byte {needle_char}. | 3348 // Let runtime handle non-one-byte {needle_char}. |
3275 | 3349 |
3276 Node* const one_byte_char_mask = IntPtrConstant(0xFF); | 3350 Node* const one_byte_char_mask = IntPtrConstant(0xFF); |
3277 GotoUnless(WordEqual(WordAnd(needle_char, one_byte_char_mask), needle_char), | 3351 GotoUnless(WordEqual(WordAnd(needle_char, one_byte_char_mask), needle_char), |
3278 &runtime); | 3352 &runtime); |
3279 | 3353 |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3689 { | 3763 { |
3690 result.Bind(CallRuntime(Runtime::kToString, context, input)); | 3764 result.Bind(CallRuntime(Runtime::kToString, context, input)); |
3691 Goto(&done); | 3765 Goto(&done); |
3692 } | 3766 } |
3693 | 3767 |
3694 Bind(&done); | 3768 Bind(&done); |
3695 return result.value(); | 3769 return result.value(); |
3696 } | 3770 } |
3697 | 3771 |
3698 Node* CodeStubAssembler::FlattenString(Node* string) { | 3772 Node* CodeStubAssembler::FlattenString(Node* string) { |
| 3773 CSA_ASSERT(IsString(string)); |
3699 Variable var_result(this, MachineRepresentation::kTagged); | 3774 Variable var_result(this, MachineRepresentation::kTagged); |
3700 var_result.Bind(string); | 3775 var_result.Bind(string); |
3701 | 3776 |
3702 Node* instance_type = LoadInstanceType(string); | 3777 Node* instance_type = LoadInstanceType(string); |
3703 | 3778 |
3704 // Check if the {string} is not a ConsString (i.e. already flat). | 3779 // Check if the {string} is not a ConsString (i.e. already flat). |
3705 Label is_cons(this, Label::kDeferred), is_flat_in_cons(this), end(this); | 3780 Label is_cons(this, Label::kDeferred), is_flat_in_cons(this), end(this); |
3706 { | 3781 { |
3707 GotoUnless(Word32Equal(Word32And(instance_type, | 3782 GotoUnless(Word32Equal(Word32And(instance_type, |
3708 Int32Constant(kStringRepresentationMask)), | 3783 Int32Constant(kStringRepresentationMask)), |
(...skipping 18 matching lines...) Expand all Loading... |
3727 { | 3802 { |
3728 var_result.Bind(LoadObjectField(string, ConsString::kFirstOffset)); | 3803 var_result.Bind(LoadObjectField(string, ConsString::kFirstOffset)); |
3729 Goto(&end); | 3804 Goto(&end); |
3730 } | 3805 } |
3731 | 3806 |
3732 Bind(&end); | 3807 Bind(&end); |
3733 return var_result.value(); | 3808 return var_result.value(); |
3734 } | 3809 } |
3735 | 3810 |
3736 Node* CodeStubAssembler::JSReceiverToPrimitive(Node* context, Node* input) { | 3811 Node* CodeStubAssembler::JSReceiverToPrimitive(Node* context, Node* input) { |
3737 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
3738 Label if_isreceiver(this, Label::kDeferred), if_isnotreceiver(this); | 3812 Label if_isreceiver(this, Label::kDeferred), if_isnotreceiver(this); |
3739 Variable result(this, MachineRepresentation::kTagged); | 3813 Variable result(this, MachineRepresentation::kTagged); |
3740 Label done(this, &result); | 3814 Label done(this, &result); |
3741 | 3815 |
3742 GotoIf(TaggedIsSmi(input), &if_isnotreceiver); | 3816 BranchIfJSReceiver(input, &if_isreceiver, &if_isnotreceiver); |
3743 | |
3744 Node* map = LoadMap(input); | |
3745 Node* instance_type = LoadMapInstanceType(map); | |
3746 Branch(IsJSReceiverInstanceType(instance_type), &if_isreceiver, | |
3747 &if_isnotreceiver); | |
3748 | 3817 |
3749 Bind(&if_isreceiver); | 3818 Bind(&if_isreceiver); |
3750 { | 3819 { |
3751 // Convert {input} to a primitive first passing Number hint. | 3820 // Convert {input} to a primitive first passing Number hint. |
3752 Callable callable = CodeFactory::NonPrimitiveToPrimitive(isolate()); | 3821 Callable callable = CodeFactory::NonPrimitiveToPrimitive(isolate()); |
3753 result.Bind(CallStub(callable, context, input)); | 3822 result.Bind(CallStub(callable, context, input)); |
3754 Goto(&done); | 3823 Goto(&done); |
3755 } | 3824 } |
3756 | 3825 |
3757 Bind(&if_isnotreceiver); | 3826 Bind(&if_isnotreceiver); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3927 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { | 3996 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { |
3928 return Select(IntPtrGreaterThanOrEqual(left, right), left, right); | 3997 return Select(IntPtrGreaterThanOrEqual(left, right), left, right); |
3929 } | 3998 } |
3930 | 3999 |
3931 template <typename Dictionary> | 4000 template <typename Dictionary> |
3932 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, | 4001 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, |
3933 Node* unique_name, Label* if_found, | 4002 Node* unique_name, Label* if_found, |
3934 Variable* var_name_index, | 4003 Variable* var_name_index, |
3935 Label* if_not_found, | 4004 Label* if_not_found, |
3936 int inlined_probes) { | 4005 int inlined_probes) { |
| 4006 CSA_ASSERT(IsDictionary(dictionary)); |
3937 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 4007 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
3938 Comment("NameDictionaryLookup"); | 4008 Comment("NameDictionaryLookup"); |
3939 | 4009 |
3940 Node* capacity = SmiUntag(LoadFixedArrayElement( | 4010 Node* capacity = SmiUntag(LoadFixedArrayElement( |
3941 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0, | 4011 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0, |
3942 INTPTR_PARAMETERS)); | 4012 INTPTR_PARAMETERS)); |
3943 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); | 4013 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); |
3944 Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name)); | 4014 Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name)); |
3945 | 4015 |
3946 // See Dictionary::FirstProbe(). | 4016 // See Dictionary::FirstProbe(). |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4011 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); | 4081 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); |
4012 return Word32And(hash, Int32Constant(0x3fffffff)); | 4082 return Word32And(hash, Int32Constant(0x3fffffff)); |
4013 } | 4083 } |
4014 | 4084 |
4015 template <typename Dictionary> | 4085 template <typename Dictionary> |
4016 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, | 4086 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, |
4017 Node* intptr_index, | 4087 Node* intptr_index, |
4018 Label* if_found, | 4088 Label* if_found, |
4019 Variable* var_entry, | 4089 Variable* var_entry, |
4020 Label* if_not_found) { | 4090 Label* if_not_found) { |
| 4091 CSA_ASSERT(IsDictionary(dictionary)); |
4021 DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep()); | 4092 DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep()); |
4022 Comment("NumberDictionaryLookup"); | 4093 Comment("NumberDictionaryLookup"); |
4023 | 4094 |
4024 Node* capacity = SmiUntag(LoadFixedArrayElement( | 4095 Node* capacity = SmiUntag(LoadFixedArrayElement( |
4025 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0, | 4096 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0, |
4026 INTPTR_PARAMETERS)); | 4097 INTPTR_PARAMETERS)); |
4027 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); | 4098 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); |
4028 | 4099 |
4029 Node* int32_seed; | 4100 Node* int32_seed; |
4030 if (Dictionary::ShapeT::UsesSeed) { | 4101 if (Dictionary::ShapeT::UsesSeed) { |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4313 Bind(&done); | 4384 Bind(&done); |
4314 | 4385 |
4315 Comment("] LoadPropertyFromFastObject"); | 4386 Comment("] LoadPropertyFromFastObject"); |
4316 } | 4387 } |
4317 | 4388 |
4318 void CodeStubAssembler::LoadPropertyFromNameDictionary(Node* dictionary, | 4389 void CodeStubAssembler::LoadPropertyFromNameDictionary(Node* dictionary, |
4319 Node* name_index, | 4390 Node* name_index, |
4320 Variable* var_details, | 4391 Variable* var_details, |
4321 Variable* var_value) { | 4392 Variable* var_value) { |
4322 Comment("LoadPropertyFromNameDictionary"); | 4393 Comment("LoadPropertyFromNameDictionary"); |
4323 | 4394 CSA_ASSERT(IsDictionary(dictionary)); |
4324 const int name_to_details_offset = | 4395 const int name_to_details_offset = |
4325 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) * | 4396 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) * |
4326 kPointerSize; | 4397 kPointerSize; |
4327 const int name_to_value_offset = | 4398 const int name_to_value_offset = |
4328 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * | 4399 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * |
4329 kPointerSize; | 4400 kPointerSize; |
4330 | 4401 |
4331 Node* details = LoadAndUntagToWord32FixedArrayElement(dictionary, name_index, | 4402 Node* details = LoadAndUntagToWord32FixedArrayElement(dictionary, name_index, |
4332 name_to_details_offset); | 4403 name_to_details_offset); |
4333 | 4404 |
4334 var_details->Bind(details); | 4405 var_details->Bind(details); |
4335 var_value->Bind( | 4406 var_value->Bind( |
4336 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset)); | 4407 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset)); |
4337 | 4408 |
4338 Comment("] LoadPropertyFromNameDictionary"); | 4409 Comment("] LoadPropertyFromNameDictionary"); |
4339 } | 4410 } |
4340 | 4411 |
4341 void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary, | 4412 void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary, |
4342 Node* name_index, | 4413 Node* name_index, |
4343 Variable* var_details, | 4414 Variable* var_details, |
4344 Variable* var_value, | 4415 Variable* var_value, |
4345 Label* if_deleted) { | 4416 Label* if_deleted) { |
4346 Comment("[ LoadPropertyFromGlobalDictionary"); | 4417 Comment("[ LoadPropertyFromGlobalDictionary"); |
| 4418 CSA_ASSERT(IsDictionary(dictionary)); |
4347 | 4419 |
4348 const int name_to_value_offset = | 4420 const int name_to_value_offset = |
4349 (GlobalDictionary::kEntryValueIndex - GlobalDictionary::kEntryKeyIndex) * | 4421 (GlobalDictionary::kEntryValueIndex - GlobalDictionary::kEntryKeyIndex) * |
4350 kPointerSize; | 4422 kPointerSize; |
4351 | 4423 |
4352 Node* property_cell = | 4424 Node* property_cell = |
4353 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset); | 4425 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset); |
4354 | 4426 |
4355 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); | 4427 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); |
4356 GotoIf(WordEqual(value, TheHoleConstant()), if_deleted); | 4428 GotoIf(WordEqual(value, TheHoleConstant()), if_deleted); |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4891 var_receiver_map.Bind(LoadMap(receiver)); | 4963 var_receiver_map.Bind(LoadMap(receiver)); |
4892 Goto(&if_result); | 4964 Goto(&if_result); |
4893 } | 4965 } |
4894 Bind(&if_result); | 4966 Bind(&if_result); |
4895 return var_receiver_map.value(); | 4967 return var_receiver_map.value(); |
4896 } | 4968 } |
4897 | 4969 |
4898 compiler::Node* CodeStubAssembler::TryMonomorphicCase( | 4970 compiler::Node* CodeStubAssembler::TryMonomorphicCase( |
4899 compiler::Node* slot, compiler::Node* vector, compiler::Node* receiver_map, | 4971 compiler::Node* slot, compiler::Node* vector, compiler::Node* receiver_map, |
4900 Label* if_handler, Variable* var_handler, Label* if_miss) { | 4972 Label* if_handler, Variable* var_handler, Label* if_miss) { |
| 4973 Comment("TryMonomorphicCase"); |
4901 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); | 4974 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); |
4902 | 4975 |
4903 // TODO(ishell): add helper class that hides offset computations for a series | 4976 // TODO(ishell): add helper class that hides offset computations for a series |
4904 // of loads. | 4977 // of loads. |
4905 int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag; | 4978 int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag; |
4906 // Adding |header_size| with a separate IntPtrAdd rather than passing it | 4979 // Adding |header_size| with a separate IntPtrAdd rather than passing it |
4907 // into ElementOffsetFromIndex() allows it to be folded into a single | 4980 // into ElementOffsetFromIndex() allows it to be folded into a single |
4908 // [base, index, offset] indirect memory access on x64. | 4981 // [base, index, offset] indirect memory access on x64. |
4909 Node* offset = | 4982 Node* offset = |
4910 ElementOffsetFromIndex(slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS); | 4983 ElementOffsetFromIndex(slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS); |
4911 Node* feedback = Load(MachineType::AnyTagged(), vector, | 4984 Node* feedback = Load(MachineType::AnyTagged(), vector, |
4912 IntPtrAdd(offset, IntPtrConstant(header_size))); | 4985 IntPtrAdd(offset, IntPtrConstant(header_size))); |
4913 | 4986 |
4914 // Try to quickly handle the monomorphic case without knowing for sure | 4987 // Try to quickly handle the monomorphic case without knowing for sure |
4915 // if we have a weak cell in feedback. We do know it's safe to look | 4988 // if we have a weak cell in feedback. We do know it's safe to look |
4916 // at WeakCell::kValueOffset. | 4989 // at WeakCell::kValueOffset. |
4917 GotoIf(WordNotEqual(receiver_map, LoadWeakCellValue(feedback)), if_miss); | 4990 GotoIf(WordNotEqual(receiver_map, LoadWeakCellValueUnchecked(feedback)), |
| 4991 if_miss); |
4918 | 4992 |
4919 Node* handler = | 4993 Node* handler = |
4920 Load(MachineType::AnyTagged(), vector, | 4994 Load(MachineType::AnyTagged(), vector, |
4921 IntPtrAdd(offset, IntPtrConstant(header_size + kPointerSize))); | 4995 IntPtrAdd(offset, IntPtrConstant(header_size + kPointerSize))); |
4922 | 4996 |
4923 var_handler->Bind(handler); | 4997 var_handler->Bind(handler); |
4924 Goto(if_handler); | 4998 Goto(if_handler); |
4925 return feedback; | 4999 return feedback; |
4926 } | 5000 } |
4927 | 5001 |
4928 void CodeStubAssembler::HandlePolymorphicCase( | 5002 void CodeStubAssembler::HandlePolymorphicCase( |
4929 compiler::Node* receiver_map, compiler::Node* feedback, Label* if_handler, | 5003 compiler::Node* receiver_map, compiler::Node* feedback, Label* if_handler, |
4930 Variable* var_handler, Label* if_miss, int unroll_count) { | 5004 Variable* var_handler, Label* if_miss, int unroll_count) { |
| 5005 Comment("HandlePolymorphicCase"); |
4931 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); | 5006 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); |
4932 | 5007 |
4933 // Iterate {feedback} array. | 5008 // Iterate {feedback} array. |
4934 const int kEntrySize = 2; | 5009 const int kEntrySize = 2; |
4935 | 5010 |
4936 for (int i = 0; i < unroll_count; i++) { | 5011 for (int i = 0; i < unroll_count; i++) { |
4937 Label next_entry(this); | 5012 Label next_entry(this); |
4938 Node* cached_map = LoadWeakCellValue(LoadFixedArrayElement( | 5013 Node* cached_map = LoadWeakCellValue(LoadFixedArrayElement( |
4939 feedback, IntPtrConstant(i * kEntrySize), 0, INTPTR_PARAMETERS)); | 5014 feedback, IntPtrConstant(i * kEntrySize), 0, INTPTR_PARAMETERS)); |
4940 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); | 5015 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); |
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6676 } | 6751 } |
6677 Bind(&no_memento_found); | 6752 Bind(&no_memento_found); |
6678 Comment("] TrapAllocationMemento"); | 6753 Comment("] TrapAllocationMemento"); |
6679 } | 6754 } |
6680 | 6755 |
6681 Node* CodeStubAssembler::PageFromAddress(Node* address) { | 6756 Node* CodeStubAssembler::PageFromAddress(Node* address) { |
6682 return WordAnd(address, IntPtrConstant(~Page::kPageAlignmentMask)); | 6757 return WordAnd(address, IntPtrConstant(~Page::kPageAlignmentMask)); |
6683 } | 6758 } |
6684 | 6759 |
6685 Node* CodeStubAssembler::EnumLength(Node* map) { | 6760 Node* CodeStubAssembler::EnumLength(Node* map) { |
| 6761 CSA_ASSERT(IsMap(map)); |
6686 Node* bitfield_3 = LoadMapBitField3(map); | 6762 Node* bitfield_3 = LoadMapBitField3(map); |
6687 Node* enum_length = DecodeWordFromWord32<Map::EnumLengthBits>(bitfield_3); | 6763 Node* enum_length = DecodeWordFromWord32<Map::EnumLengthBits>(bitfield_3); |
6688 return SmiTag(enum_length); | 6764 return SmiTag(enum_length); |
6689 } | 6765 } |
6690 | 6766 |
6691 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, | 6767 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, |
6692 Label* use_runtime) { | 6768 Label* use_runtime) { |
6693 Variable current_js_object(this, MachineRepresentation::kTagged); | 6769 Variable current_js_object(this, MachineRepresentation::kTagged); |
6694 current_js_object.Bind(receiver); | 6770 current_js_object.Bind(receiver); |
6695 | 6771 |
(...skipping 1878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8574 Node* buffer_bit_field = LoadObjectField( | 8650 Node* buffer_bit_field = LoadObjectField( |
8575 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 8651 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
8576 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 8652 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); |
8577 | 8653 |
8578 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | 8654 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), |
8579 Int32Constant(0)); | 8655 Int32Constant(0)); |
8580 } | 8656 } |
8581 | 8657 |
8582 } // namespace internal | 8658 } // namespace internal |
8583 } // namespace v8 | 8659 } // namespace v8 |
OLD | NEW |