Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/code-stub-assembler.cc

Issue 2446073002: [stubs] Add more assertions in the CodeStubAssembler (Closed)
Patch Set: rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698