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 | 4 |
5 #include "src/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 using compiler::Node; | 15 using compiler::Node; |
16 | 16 |
17 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, | 17 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, |
18 const CallInterfaceDescriptor& descriptor, | 18 const CallInterfaceDescriptor& descriptor, |
19 Code::Flags flags, const char* name, | 19 Code::Flags flags, const char* name, |
20 size_t result_size) | 20 size_t result_size) |
21 : compiler::CodeAssembler(isolate, zone, descriptor, flags, name, | 21 : compiler::CodeAssembler(isolate, zone, descriptor, flags, name, |
22 result_size) {} | 22 result_size) {} |
23 | 23 |
24 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, | 24 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, |
25 int parameter_count, Code::Flags flags, | 25 int parameter_count, Code::Flags flags, |
26 const char* name) | 26 const char* name) |
27 : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {} | 27 : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {} |
28 | 28 |
29 void CodeStubAssembler::Assert(Node* condition, const char* message, | 29 void CodeStubAssembler::Assert(Node* condition) { |
30 const char* file, int line) { | |
31 #if defined(DEBUG) | 30 #if defined(DEBUG) |
32 Label ok(this); | 31 Label ok(this); |
33 Vector<char> buffer(Vector<char>::New(1024)); | 32 Comment("[ Assert"); |
34 if (message != nullptr && FLAG_code_comments) { | |
35 Comment("[ Assert: %s", message); | |
36 } else { | |
37 Comment("[ Assert "); | |
38 } | |
39 | |
40 GotoIf(condition, &ok); | 33 GotoIf(condition, &ok); |
41 if (message != nullptr) { | |
42 if (file != nullptr) { | |
43 SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line); | |
44 } else { | |
45 SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message); | |
46 } | |
47 CallRuntime( | |
48 Runtime::kGlobalPrint, SmiConstant(Smi::kZero), | |
49 HeapConstant(factory()->NewStringFromAsciiChecked(&(buffer[0])))); | |
50 } | |
51 DebugBreak(); | 34 DebugBreak(); |
52 Goto(&ok); | 35 Goto(&ok); |
53 Bind(&ok); | 36 Bind(&ok); |
54 Comment("] Assert"); | 37 Comment("] Assert"); |
55 #endif | 38 #endif |
56 } | 39 } |
57 | 40 |
58 Node* CodeStubAssembler::NoContextConstant() { return NumberConstant(0); } | 41 Node* CodeStubAssembler::NoContextConstant() { return NumberConstant(0); } |
59 | 42 |
60 #define HEAP_CONSTANT_ACCESSOR(rootName, name) \ | 43 #define HEAP_CONSTANT_ACCESSOR(rootName, name) \ |
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 Node* CodeStubAssembler::LoadMap(Node* object) { | 896 Node* CodeStubAssembler::LoadMap(Node* object) { |
914 return LoadObjectField(object, HeapObject::kMapOffset); | 897 return LoadObjectField(object, HeapObject::kMapOffset); |
915 } | 898 } |
916 | 899 |
917 Node* CodeStubAssembler::LoadInstanceType(Node* object) { | 900 Node* CodeStubAssembler::LoadInstanceType(Node* object) { |
918 return LoadMapInstanceType(LoadMap(object)); | 901 return LoadMapInstanceType(LoadMap(object)); |
919 } | 902 } |
920 | 903 |
921 void CodeStubAssembler::AssertInstanceType(Node* object, | 904 void CodeStubAssembler::AssertInstanceType(Node* object, |
922 InstanceType instance_type) { | 905 InstanceType instance_type) { |
923 CSA_ASSERT( | 906 Assert(Word32Equal(LoadInstanceType(object), Int32Constant(instance_type))); |
924 Word32Equal(LoadInstanceType(object), Int32Constant(instance_type))); | |
925 } | 907 } |
926 | 908 |
927 Node* CodeStubAssembler::LoadProperties(Node* object) { | 909 Node* CodeStubAssembler::LoadProperties(Node* object) { |
928 return LoadObjectField(object, JSObject::kPropertiesOffset); | 910 return LoadObjectField(object, JSObject::kPropertiesOffset); |
929 } | 911 } |
930 | 912 |
931 Node* CodeStubAssembler::LoadElements(Node* object) { | 913 Node* CodeStubAssembler::LoadElements(Node* object) { |
932 return LoadObjectField(object, JSObject::kElementsOffset); | 914 return LoadObjectField(object, JSObject::kElementsOffset); |
933 } | 915 } |
934 | 916 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 } | 956 } |
975 | 957 |
976 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { | 958 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { |
977 return ChangeUint32ToWord( | 959 return ChangeUint32ToWord( |
978 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8())); | 960 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8())); |
979 } | 961 } |
980 | 962 |
981 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) { | 963 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) { |
982 // See Map::GetInObjectProperties() for details. | 964 // See Map::GetInObjectProperties() for details. |
983 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); | 965 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
984 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map), | 966 Assert(Int32GreaterThanOrEqual(LoadMapInstanceType(map), |
985 Int32Constant(FIRST_JS_OBJECT_TYPE))); | 967 Int32Constant(FIRST_JS_OBJECT_TYPE))); |
986 return ChangeUint32ToWord(LoadObjectField( | 968 return ChangeUint32ToWord(LoadObjectField( |
987 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, | 969 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, |
988 MachineType::Uint8())); | 970 MachineType::Uint8())); |
989 } | 971 } |
990 | 972 |
991 Node* CodeStubAssembler::LoadMapConstructorFunctionIndex(Node* map) { | 973 Node* CodeStubAssembler::LoadMapConstructorFunctionIndex(Node* map) { |
992 // See Map::GetConstructorFunctionIndex() for details. | 974 // See Map::GetConstructorFunctionIndex() for details. |
993 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); | 975 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); |
994 CSA_ASSERT(Int32LessThanOrEqual(LoadMapInstanceType(map), | 976 Assert(Int32LessThanOrEqual(LoadMapInstanceType(map), |
995 Int32Constant(LAST_PRIMITIVE_TYPE))); | 977 Int32Constant(LAST_PRIMITIVE_TYPE))); |
996 return ChangeUint32ToWord(LoadObjectField( | 978 return ChangeUint32ToWord(LoadObjectField( |
997 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, | 979 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, |
998 MachineType::Uint8())); | 980 MachineType::Uint8())); |
999 } | 981 } |
1000 | 982 |
1001 Node* CodeStubAssembler::LoadMapConstructor(Node* map) { | 983 Node* CodeStubAssembler::LoadMapConstructor(Node* map) { |
1002 Variable result(this, MachineRepresentation::kTagged); | 984 Variable result(this, MachineRepresentation::kTagged); |
1003 result.Bind(LoadObjectField(map, Map::kConstructorOrBackPointerOffset)); | 985 result.Bind(LoadObjectField(map, Map::kConstructorOrBackPointerOffset)); |
1004 | 986 |
1005 Label done(this), loop(this, &result); | 987 Label done(this), loop(this, &result); |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1399 MachineRepresentation::kTagged); | 1381 MachineRepresentation::kTagged); |
1400 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second, | 1382 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second, |
1401 MachineRepresentation::kTagged); | 1383 MachineRepresentation::kTagged); |
1402 return result; | 1384 return result; |
1403 } | 1385 } |
1404 | 1386 |
1405 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, | 1387 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, |
1406 Node* index, Node* input) { | 1388 Node* index, Node* input) { |
1407 Node* const max_length = | 1389 Node* const max_length = |
1408 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); | 1390 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); |
1409 CSA_ASSERT(SmiLessThanOrEqual(length, max_length)); | 1391 Assert(SmiLessThanOrEqual(length, max_length)); |
1410 | 1392 |
1411 // Allocate the JSRegExpResult. | 1393 // Allocate the JSRegExpResult. |
1412 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove | 1394 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove |
1413 // unneeded store of elements. | 1395 // unneeded store of elements. |
1414 Node* const result = Allocate(JSRegExpResult::kSize); | 1396 Node* const result = Allocate(JSRegExpResult::kSize); |
1415 | 1397 |
1416 // TODO(jgruber): Store map as Heap constant? | 1398 // TODO(jgruber): Store map as Heap constant? |
1417 Node* const native_context = LoadNativeContext(context); | 1399 Node* const native_context = LoadNativeContext(context); |
1418 Node* const map = | 1400 Node* const map = |
1419 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); | 1401 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); |
(...skipping 1749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3169 Goto(&end); | 3151 Goto(&end); |
3170 } | 3152 } |
3171 } | 3153 } |
3172 | 3154 |
3173 Bind(&end); | 3155 Bind(&end); |
3174 return var_result.value(); | 3156 return var_result.value(); |
3175 } | 3157 } |
3176 | 3158 |
3177 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { | 3159 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { |
3178 // Assert input is a HeapObject (not smi or heap number) | 3160 // Assert input is a HeapObject (not smi or heap number) |
3179 CSA_ASSERT(Word32BinaryNot(TaggedIsSmi(input))); | 3161 Assert(Word32BinaryNot(TaggedIsSmi(input))); |
3180 CSA_ASSERT(Word32NotEqual(LoadMap(input), HeapNumberMapConstant())); | 3162 Assert(Word32NotEqual(LoadMap(input), HeapNumberMapConstant())); |
3181 | 3163 |
3182 // We might need to loop once here due to ToPrimitive conversions. | 3164 // We might need to loop once here due to ToPrimitive conversions. |
3183 Variable var_input(this, MachineRepresentation::kTagged); | 3165 Variable var_input(this, MachineRepresentation::kTagged); |
3184 Variable var_result(this, MachineRepresentation::kTagged); | 3166 Variable var_result(this, MachineRepresentation::kTagged); |
3185 Label loop(this, &var_input); | 3167 Label loop(this, &var_input); |
3186 Label end(this); | 3168 Label end(this); |
3187 var_input.Bind(input); | 3169 var_input.Bind(input); |
3188 Goto(&loop); | 3170 Goto(&loop); |
3189 Bind(&loop); | 3171 Bind(&loop); |
3190 { | 3172 { |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3632 | 3614 |
3633 Label if_objectisspecial(this); | 3615 Label if_objectisspecial(this); |
3634 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 3616 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
3635 GotoIf(Int32LessThanOrEqual(instance_type, | 3617 GotoIf(Int32LessThanOrEqual(instance_type, |
3636 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), | 3618 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), |
3637 &if_objectisspecial); | 3619 &if_objectisspecial); |
3638 | 3620 |
3639 Node* bit_field = LoadMapBitField(map); | 3621 Node* bit_field = LoadMapBitField(map); |
3640 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | | 3622 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | |
3641 1 << Map::kIsAccessCheckNeeded); | 3623 1 << Map::kIsAccessCheckNeeded); |
3642 CSA_ASSERT(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); | 3624 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); |
3643 | 3625 |
3644 Node* bit_field3 = LoadMapBitField3(map); | 3626 Node* bit_field3 = LoadMapBitField3(map); |
3645 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3); | 3627 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3); |
3646 Label if_isfastmap(this), if_isslowmap(this); | 3628 Label if_isfastmap(this), if_isslowmap(this); |
3647 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap); | 3629 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap); |
3648 Bind(&if_isfastmap); | 3630 Bind(&if_isfastmap); |
3649 { | 3631 { |
3650 Comment("DescriptorArrayLookup"); | 3632 Comment("DescriptorArrayLookup"); |
3651 Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bit_field3); | 3633 Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bit_field3); |
3652 // Bail out to the runtime for large numbers of own descriptors. The stub | 3634 // Bail out to the runtime for large numbers of own descriptors. The stub |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4047 { | 4029 { |
4048 Variable var_entry(this, MachineType::PointerRepresentation()); | 4030 Variable var_entry(this, MachineType::PointerRepresentation()); |
4049 Node* elements = LoadElements(object); | 4031 Node* elements = LoadElements(object); |
4050 NumberDictionaryLookup<SeededNumberDictionary>( | 4032 NumberDictionaryLookup<SeededNumberDictionary>( |
4051 elements, intptr_index, if_found, &var_entry, if_not_found); | 4033 elements, intptr_index, if_found, &var_entry, if_not_found); |
4052 } | 4034 } |
4053 Bind(&if_isfaststringwrapper); | 4035 Bind(&if_isfaststringwrapper); |
4054 { | 4036 { |
4055 AssertInstanceType(object, JS_VALUE_TYPE); | 4037 AssertInstanceType(object, JS_VALUE_TYPE); |
4056 Node* string = LoadJSValueValue(object); | 4038 Node* string = LoadJSValueValue(object); |
4057 CSA_ASSERT(IsStringInstanceType(LoadInstanceType(string))); | 4039 Assert(IsStringInstanceType(LoadInstanceType(string))); |
4058 Node* length = LoadStringLength(string); | 4040 Node* length = LoadStringLength(string); |
4059 GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found); | 4041 GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found); |
4060 Goto(&if_isobjectorsmi); | 4042 Goto(&if_isobjectorsmi); |
4061 } | 4043 } |
4062 Bind(&if_isslowstringwrapper); | 4044 Bind(&if_isslowstringwrapper); |
4063 { | 4045 { |
4064 AssertInstanceType(object, JS_VALUE_TYPE); | 4046 AssertInstanceType(object, JS_VALUE_TYPE); |
4065 Node* string = LoadJSValueValue(object); | 4047 Node* string = LoadJSValueValue(object); |
4066 CSA_ASSERT(IsStringInstanceType(LoadInstanceType(string))); | 4048 Assert(IsStringInstanceType(LoadInstanceType(string))); |
4067 Node* length = LoadStringLength(string); | 4049 Node* length = LoadStringLength(string); |
4068 GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found); | 4050 GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found); |
4069 Goto(&if_isdictionary); | 4051 Goto(&if_isdictionary); |
4070 } | 4052 } |
4071 Bind(&if_oob); | 4053 Bind(&if_oob); |
4072 { | 4054 { |
4073 // Positive OOB indices mean "not found", negative indices must be | 4055 // Positive OOB indices mean "not found", negative indices must be |
4074 // converted to property names. | 4056 // converted to property names. |
4075 GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), if_bailout); | 4057 GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), if_bailout); |
4076 Goto(if_not_found); | 4058 Goto(if_not_found); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4487 Goto(&loop); | 4469 Goto(&loop); |
4488 } | 4470 } |
4489 } | 4471 } |
4490 | 4472 |
4491 compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name, | 4473 compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name, |
4492 compiler::Node* map) { | 4474 compiler::Node* map) { |
4493 // See v8::internal::StubCache::PrimaryOffset(). | 4475 // See v8::internal::StubCache::PrimaryOffset(). |
4494 STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); | 4476 STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); |
4495 // Compute the hash of the name (use entire hash field). | 4477 // Compute the hash of the name (use entire hash field). |
4496 Node* hash_field = LoadNameHashField(name); | 4478 Node* hash_field = LoadNameHashField(name); |
4497 CSA_ASSERT(Word32Equal( | 4479 Assert(Word32Equal( |
4498 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), | 4480 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), |
4499 Int32Constant(0))); | 4481 Int32Constant(0))); |
4500 | 4482 |
4501 // Using only the low bits in 64-bit mode is unlikely to increase the | 4483 // Using only the low bits in 64-bit mode is unlikely to increase the |
4502 // risk of collision even if the heap is spread over an area larger than | 4484 // risk of collision even if the heap is spread over an area larger than |
4503 // 4Gb (and not at all if it isn't). | 4485 // 4Gb (and not at all if it isn't). |
4504 Node* hash = Int32Add(hash_field, map); | 4486 Node* hash = Int32Add(hash_field, map); |
4505 // Base the offset on a simple combination of name and map. | 4487 // Base the offset on a simple combination of name and map. |
4506 hash = Word32Xor(hash, Int32Constant(StubCache::kPrimaryMagic)); | 4488 hash = Word32Xor(hash, Int32Constant(StubCache::kPrimaryMagic)); |
4507 uint32_t mask = (StubCache::kPrimaryTableSize - 1) | 4489 uint32_t mask = (StubCache::kPrimaryTableSize - 1) |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4968 Node* validity_cell = LoadObjectField(handler, Tuple3::kValue1Offset); | 4950 Node* validity_cell = LoadObjectField(handler, Tuple3::kValue1Offset); |
4969 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); | 4951 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); |
4970 GotoIf(WordNotEqual(cell_value, | 4952 GotoIf(WordNotEqual(cell_value, |
4971 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), | 4953 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), |
4972 miss); | 4954 miss); |
4973 | 4955 |
4974 Node* holder = | 4956 Node* holder = |
4975 LoadWeakCellValue(LoadObjectField(handler, Tuple3::kValue2Offset)); | 4957 LoadWeakCellValue(LoadObjectField(handler, Tuple3::kValue2Offset)); |
4976 // The |holder| is guaranteed to be alive at this point since we passed | 4958 // The |holder| is guaranteed to be alive at this point since we passed |
4977 // both the receiver map check and the validity cell check. | 4959 // both the receiver map check and the validity cell check. |
4978 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0))); | 4960 Assert(WordNotEqual(holder, IntPtrConstant(0))); |
4979 | 4961 |
4980 Node* smi_handler = LoadObjectField(handler, Tuple3::kValue3Offset); | 4962 Node* smi_handler = LoadObjectField(handler, Tuple3::kValue3Offset); |
4981 CSA_ASSERT(TaggedIsSmi(smi_handler)); | 4963 Assert(TaggedIsSmi(smi_handler)); |
4982 | 4964 |
4983 var_holder.Bind(holder); | 4965 var_holder.Bind(holder); |
4984 var_smi_handler.Bind(smi_handler); | 4966 var_smi_handler.Bind(smi_handler); |
4985 Goto(&if_smi_handler); | 4967 Goto(&if_smi_handler); |
4986 } | 4968 } |
4987 | 4969 |
4988 // |handler| is a heap object. Must be code, call it. | 4970 // |handler| is a heap object. Must be code, call it. |
4989 Bind(&call_handler); | 4971 Bind(&call_handler); |
4990 { | 4972 { |
4991 typedef LoadWithVectorDescriptor Descriptor; | 4973 typedef LoadWithVectorDescriptor Descriptor; |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5355 | 5337 |
5356 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); | 5338 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); |
5357 Node* new_capacity = IntPtrAdd(length, delta); | 5339 Node* new_capacity = IntPtrAdd(length, delta); |
5358 | 5340 |
5359 // Grow properties array. | 5341 // Grow properties array. |
5360 ElementsKind kind = FAST_ELEMENTS; | 5342 ElementsKind kind = FAST_ELEMENTS; |
5361 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < | 5343 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < |
5362 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); | 5344 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); |
5363 // The size of a new properties backing store is guaranteed to be small | 5345 // The size of a new properties backing store is guaranteed to be small |
5364 // enough that the new backing store will be allocated in new space. | 5346 // enough that the new backing store will be allocated in new space. |
5365 CSA_ASSERT(UintPtrLessThan( | 5347 Assert(UintPtrLessThan(new_capacity, IntPtrConstant(kMaxNumberOfDescriptors + |
5366 new_capacity, | 5348 JSObject::kFieldsAdded))); |
5367 IntPtrConstant(kMaxNumberOfDescriptors + JSObject::kFieldsAdded))); | |
5368 | 5349 |
5369 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); | 5350 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); |
5370 | 5351 |
5371 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, | 5352 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, |
5372 Heap::kUndefinedValueRootIndex, mode); | 5353 Heap::kUndefinedValueRootIndex, mode); |
5373 | 5354 |
5374 // |new_properties| is guaranteed to be in new space, so we can skip | 5355 // |new_properties| is guaranteed to be in new space, so we can skip |
5375 // the write barrier. | 5356 // the write barrier. |
5376 CopyFixedArrayElements(kind, properties, new_properties, length, | 5357 CopyFixedArrayElements(kind, properties, new_properties, length, |
5377 SKIP_WRITE_BARRIER, mode); | 5358 SKIP_WRITE_BARRIER, mode); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5504 Node* adjusted_length = IntPtrSub(elements_length, intptr_two); | 5485 Node* adjusted_length = IntPtrSub(elements_length, intptr_two); |
5505 | 5486 |
5506 GotoIf(UintPtrGreaterThanOrEqual(key, adjusted_length), &if_unmapped); | 5487 GotoIf(UintPtrGreaterThanOrEqual(key, adjusted_length), &if_unmapped); |
5507 | 5488 |
5508 Node* mapped_index = LoadFixedArrayElement( | 5489 Node* mapped_index = LoadFixedArrayElement( |
5509 elements, IntPtrAdd(key, intptr_two), 0, INTPTR_PARAMETERS); | 5490 elements, IntPtrAdd(key, intptr_two), 0, INTPTR_PARAMETERS); |
5510 Branch(WordEqual(mapped_index, TheHoleConstant()), &if_unmapped, &if_mapped); | 5491 Branch(WordEqual(mapped_index, TheHoleConstant()), &if_unmapped, &if_mapped); |
5511 | 5492 |
5512 Bind(&if_mapped); | 5493 Bind(&if_mapped); |
5513 { | 5494 { |
5514 CSA_ASSERT(TaggedIsSmi(mapped_index)); | 5495 Assert(TaggedIsSmi(mapped_index)); |
5515 mapped_index = SmiUntag(mapped_index); | 5496 mapped_index = SmiUntag(mapped_index); |
5516 Node* the_context = LoadFixedArrayElement(elements, IntPtrConstant(0), 0, | 5497 Node* the_context = LoadFixedArrayElement(elements, IntPtrConstant(0), 0, |
5517 INTPTR_PARAMETERS); | 5498 INTPTR_PARAMETERS); |
5518 // Assert that we can use LoadFixedArrayElement/StoreFixedArrayElement | 5499 // Assert that we can use LoadFixedArrayElement/StoreFixedArrayElement |
5519 // methods for accessing Context. | 5500 // methods for accessing Context. |
5520 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); | 5501 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); |
5521 DCHECK_EQ(Context::SlotOffset(0) + kHeapObjectTag, | 5502 DCHECK_EQ(Context::SlotOffset(0) + kHeapObjectTag, |
5522 FixedArray::OffsetOfElementAt(0)); | 5503 FixedArray::OffsetOfElementAt(0)); |
5523 if (is_load) { | 5504 if (is_load) { |
5524 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0, | 5505 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0, |
5525 INTPTR_PARAMETERS); | 5506 INTPTR_PARAMETERS); |
5526 CSA_ASSERT(WordNotEqual(result, TheHoleConstant())); | 5507 Assert(WordNotEqual(result, TheHoleConstant())); |
5527 var_result.Bind(result); | 5508 var_result.Bind(result); |
5528 } else { | 5509 } else { |
5529 StoreFixedArrayElement(the_context, mapped_index, value, | 5510 StoreFixedArrayElement(the_context, mapped_index, value, |
5530 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS); | 5511 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS); |
5531 } | 5512 } |
5532 Goto(&end); | 5513 Goto(&end); |
5533 } | 5514 } |
5534 | 5515 |
5535 Bind(&if_unmapped); | 5516 Bind(&if_unmapped); |
5536 { | 5517 { |
(...skipping 1843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7380 | 7361 |
7381 GotoIf(IsStringInstanceType(instance_type), &return_string); | 7362 GotoIf(IsStringInstanceType(instance_type), &return_string); |
7382 | 7363 |
7383 #define SIMD128_BRANCH(TYPE, Type, type, lane_count, lane_type) \ | 7364 #define SIMD128_BRANCH(TYPE, Type, type, lane_count, lane_type) \ |
7384 Label return_##type(this); \ | 7365 Label return_##type(this); \ |
7385 Node* type##_map = HeapConstant(factory()->type##_map()); \ | 7366 Node* type##_map = HeapConstant(factory()->type##_map()); \ |
7386 GotoIf(WordEqual(map, type##_map), &return_##type); | 7367 GotoIf(WordEqual(map, type##_map), &return_##type); |
7387 SIMD128_TYPES(SIMD128_BRANCH) | 7368 SIMD128_TYPES(SIMD128_BRANCH) |
7388 #undef SIMD128_BRANCH | 7369 #undef SIMD128_BRANCH |
7389 | 7370 |
7390 CSA_ASSERT(Word32Equal(instance_type, Int32Constant(SYMBOL_TYPE))); | 7371 Assert(Word32Equal(instance_type, Int32Constant(SYMBOL_TYPE))); |
7391 result_var.Bind(HeapConstant(isolate()->factory()->symbol_string())); | 7372 result_var.Bind(HeapConstant(isolate()->factory()->symbol_string())); |
7392 Goto(&return_result); | 7373 Goto(&return_result); |
7393 | 7374 |
7394 Bind(&return_number); | 7375 Bind(&return_number); |
7395 { | 7376 { |
7396 result_var.Bind(HeapConstant(isolate()->factory()->number_string())); | 7377 result_var.Bind(HeapConstant(isolate()->factory()->number_string())); |
7397 Goto(&return_result); | 7378 Goto(&return_result); |
7398 } | 7379 } |
7399 | 7380 |
7400 Bind(&if_oddball); | 7381 Bind(&if_oddball); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7471 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); | 7452 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); |
7472 Goto(&end); | 7453 Goto(&end); |
7473 } | 7454 } |
7474 | 7455 |
7475 Bind(&end); | 7456 Bind(&end); |
7476 return result.value(); | 7457 return result.value(); |
7477 } | 7458 } |
7478 | 7459 |
7479 } // namespace internal | 7460 } // namespace internal |
7480 } // namespace v8 | 7461 } // namespace v8 |
OLD | NEW |