OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 518 |
519 Bind(&return_result); | 519 Bind(&return_result); |
520 return var_result.value(); | 520 return var_result.value(); |
521 } | 521 } |
522 | 522 |
523 Node* CodeStubAssembler::TaggedIsSmi(Node* a) { | 523 Node* CodeStubAssembler::TaggedIsSmi(Node* a) { |
524 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), | 524 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), |
525 IntPtrConstant(0)); | 525 IntPtrConstant(0)); |
526 } | 526 } |
527 | 527 |
| 528 Node* CodeStubAssembler::TaggedIsNotSmi(Node* a) { |
| 529 return WordNotEqual( |
| 530 WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), |
| 531 IntPtrConstant(0)); |
| 532 } |
| 533 |
528 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { | 534 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { |
529 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), | 535 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), |
530 IntPtrConstant(0)); | 536 IntPtrConstant(0)); |
531 } | 537 } |
532 | 538 |
533 Node* CodeStubAssembler::WordIsWordAligned(Node* word) { | 539 Node* CodeStubAssembler::WordIsWordAligned(Node* word) { |
534 return WordEqual(IntPtrConstant(0), | 540 return WordEqual(IntPtrConstant(0), |
535 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1))); | 541 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1))); |
536 } | 542 } |
537 | 543 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 | 652 |
647 void CodeStubAssembler::BranchIfJSObject(Node* object, Label* if_true, | 653 void CodeStubAssembler::BranchIfJSObject(Node* object, Label* if_true, |
648 Label* if_false) { | 654 Label* if_false) { |
649 GotoIf(TaggedIsSmi(object), if_false); | 655 GotoIf(TaggedIsSmi(object), if_false); |
650 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); | 656 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
651 Branch(Int32GreaterThanOrEqual(LoadInstanceType(object), | 657 Branch(Int32GreaterThanOrEqual(LoadInstanceType(object), |
652 Int32Constant(FIRST_JS_OBJECT_TYPE)), | 658 Int32Constant(FIRST_JS_OBJECT_TYPE)), |
653 if_true, if_false); | 659 if_true, if_false); |
654 } | 660 } |
655 | 661 |
656 void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context, | 662 void CodeStubAssembler::BranchIfFastJSArray( |
657 Label* if_true, Label* if_false) { | 663 Node* object, Node* context, CodeStubAssembler::FastJSArrayAccessMode mode, |
| 664 Label* if_true, Label* if_false) { |
658 // Bailout if receiver is a Smi. | 665 // Bailout if receiver is a Smi. |
659 GotoIf(TaggedIsSmi(object), if_false); | 666 GotoIf(TaggedIsSmi(object), if_false); |
660 | 667 |
661 Node* map = LoadMap(object); | 668 Node* map = LoadMap(object); |
662 | 669 |
663 // Bailout if instance type is not JS_ARRAY_TYPE. | 670 // Bailout if instance type is not JS_ARRAY_TYPE. |
664 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), | 671 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), |
665 if_false); | 672 if_false); |
666 | 673 |
667 Node* elements_kind = LoadMapElementsKind(map); | 674 Node* elements_kind = LoadMapElementsKind(map); |
668 | 675 |
669 // Bailout if receiver has slow elements. | 676 // Bailout if receiver has slow elements. |
670 GotoUnless(IsFastElementsKind(elements_kind), if_false); | 677 GotoUnless(IsFastElementsKind(elements_kind), if_false); |
671 | 678 |
672 // Check prototype chain if receiver does not have packed elements. | 679 // Check prototype chain if receiver does not have packed elements. |
673 GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true); | 680 if (mode == FastJSArrayAccessMode::INBOUNDS_READ) { |
674 | 681 GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true); |
| 682 } |
675 BranchIfPrototypesHaveNoElements(map, if_true, if_false); | 683 BranchIfPrototypesHaveNoElements(map, if_true, if_false); |
676 } | 684 } |
677 | 685 |
678 Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, | 686 Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, |
679 AllocationFlags flags, | 687 AllocationFlags flags, |
680 Node* top_address, | 688 Node* top_address, |
681 Node* limit_address) { | 689 Node* limit_address) { |
682 Node* top = Load(MachineType::Pointer(), top_address); | 690 Node* top = Load(MachineType::Pointer(), top_address); |
683 Node* limit = Load(MachineType::Pointer(), limit_address); | 691 Node* limit = Load(MachineType::Pointer(), limit_address); |
684 | 692 |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1354 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( | 1362 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( |
1355 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { | 1363 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { |
1356 CSA_ASSERT(this, IsFixedDoubleArray(object)); | 1364 CSA_ASSERT(this, IsFixedDoubleArray(object)); |
1357 Node* offset = | 1365 Node* offset = |
1358 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, | 1366 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, |
1359 FixedArray::kHeaderSize - kHeapObjectTag); | 1367 FixedArray::kHeaderSize - kHeapObjectTag); |
1360 MachineRepresentation rep = MachineRepresentation::kFloat64; | 1368 MachineRepresentation rep = MachineRepresentation::kFloat64; |
1361 return StoreNoWriteBarrier(rep, object, offset, value); | 1369 return StoreNoWriteBarrier(rep, object, offset, value); |
1362 } | 1370 } |
1363 | 1371 |
| 1372 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context, |
| 1373 Node* array, |
| 1374 CodeStubArguments& args, |
| 1375 Variable& arg_index, |
| 1376 Label* bailout) { |
| 1377 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); |
| 1378 Label pre_bailout(this); |
| 1379 Label success(this); |
| 1380 Variable elements(this, MachineRepresentation::kTagged); |
| 1381 ParameterMode mode = OptimalParameterMode(); |
| 1382 Variable length(this, OptimalParameterRepresentation()); |
| 1383 length.Bind(UntagParameter(LoadJSArrayLength(array), mode)); |
| 1384 elements.Bind(LoadElements(array)); |
| 1385 Node* capacity = |
| 1386 UntagParameter(LoadFixedArrayBaseLength(elements.value()), mode); |
| 1387 |
| 1388 // Resize the capacity of the fixed array if it doesn't fit. |
| 1389 Label fits(this, &elements); |
| 1390 Node* first = arg_index.value(); |
| 1391 Node* growth = IntPtrSubFoldConstants(args.GetLength(), first); |
| 1392 Node* new_length = IntPtrAdd( |
| 1393 mode == INTPTR_PARAMETERS ? growth : SmiTag(growth), length.value()); |
| 1394 GotoUnless(IntPtrGreaterThanOrEqual(new_length, capacity), &fits); |
| 1395 Node* new_capacity = CalculateNewElementsCapacity( |
| 1396 IntPtrAdd(new_length, IntPtrOrSmiConstant(1, mode)), mode); |
| 1397 elements.Bind(GrowElementsCapacity(array, elements.value(), kind, kind, |
| 1398 capacity, new_capacity, mode, |
| 1399 &pre_bailout)); |
| 1400 Goto(&fits); |
| 1401 Bind(&fits); |
| 1402 |
| 1403 // Push each argument onto the end of the array now that there is enough |
| 1404 // capacity. |
| 1405 CodeStubAssembler::VariableList push_vars({&length, &elements}, zone()); |
| 1406 args.ForEach( |
| 1407 push_vars, |
| 1408 [kind, mode, &length, &elements, &pre_bailout]( |
| 1409 CodeStubAssembler* assembler, Node* arg) { |
| 1410 if (IsFastSmiElementsKind(kind)) { |
| 1411 assembler->GotoIf(assembler->TaggedIsNotSmi(arg), &pre_bailout); |
| 1412 } else if (IsFastDoubleElementsKind(kind)) { |
| 1413 assembler->GotoIfNotNumber(arg, &pre_bailout); |
| 1414 } |
| 1415 if (IsFastDoubleElementsKind(kind)) { |
| 1416 Node* double_value = assembler->ChangeNumberToFloat64(arg); |
| 1417 assembler->StoreFixedDoubleArrayElement( |
| 1418 elements.value(), length.value(), |
| 1419 assembler->Float64SilenceNaN(double_value), mode); |
| 1420 } else { |
| 1421 WriteBarrierMode barrier_mode = IsFastSmiElementsKind(kind) |
| 1422 ? SKIP_WRITE_BARRIER |
| 1423 : UPDATE_WRITE_BARRIER; |
| 1424 assembler->StoreFixedArrayElement(elements.value(), length.value(), |
| 1425 arg, barrier_mode, 0, mode); |
| 1426 } |
| 1427 assembler->Increment(length, 1, mode); |
| 1428 }, |
| 1429 first, nullptr); |
| 1430 length.Bind(TagParameter(length.value(), mode)); |
| 1431 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length.value()); |
| 1432 Goto(&success); |
| 1433 |
| 1434 Bind(&pre_bailout); |
| 1435 length.Bind(TagParameter(length.value(), mode)); |
| 1436 Node* diff = SmiSub(length.value(), LoadJSArrayLength(array)); |
| 1437 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length.value()); |
| 1438 arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff))); |
| 1439 Goto(bailout); |
| 1440 |
| 1441 Bind(&success); |
| 1442 return length.value(); |
| 1443 } |
| 1444 |
1364 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { | 1445 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { |
1365 Node* result = Allocate(HeapNumber::kSize, kNone); | 1446 Node* result = Allocate(HeapNumber::kSize, kNone); |
1366 Heap::RootListIndex heap_map_index = | 1447 Heap::RootListIndex heap_map_index = |
1367 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex | 1448 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex |
1368 : Heap::kMutableHeapNumberMapRootIndex; | 1449 : Heap::kMutableHeapNumberMapRootIndex; |
1369 Node* map = LoadRoot(heap_map_index); | 1450 Node* map = LoadRoot(heap_map_index); |
1370 StoreMapNoWriteBarrier(result, map); | 1451 StoreMapNoWriteBarrier(result, map); |
1371 return result; | 1452 return result; |
1372 } | 1453 } |
1373 | 1454 |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2123 to_index_smi == from_index_smi)); | 2204 to_index_smi == from_index_smi)); |
2124 BuildFastLoop(vars, MachineType::PointerRepresentation(), from_offset, | 2205 BuildFastLoop(vars, MachineType::PointerRepresentation(), from_offset, |
2125 limit_offset, | 2206 limit_offset, |
2126 [from_string, to_string, ¤t_to_offset, to_increment, type, | 2207 [from_string, to_string, ¤t_to_offset, to_increment, type, |
2127 rep, index_same](CodeStubAssembler* assembler, Node* offset) { | 2208 rep, index_same](CodeStubAssembler* assembler, Node* offset) { |
2128 Node* value = assembler->Load(type, from_string, offset); | 2209 Node* value = assembler->Load(type, from_string, offset); |
2129 assembler->StoreNoWriteBarrier( | 2210 assembler->StoreNoWriteBarrier( |
2130 rep, to_string, | 2211 rep, to_string, |
2131 index_same ? offset : current_to_offset.value(), value); | 2212 index_same ? offset : current_to_offset.value(), value); |
2132 if (!index_same) { | 2213 if (!index_same) { |
2133 current_to_offset.Bind(assembler->IntPtrAdd( | 2214 assembler->Increment(current_to_offset, to_increment); |
2134 current_to_offset.value(), | |
2135 assembler->IntPtrConstant(to_increment))); | |
2136 } | 2215 } |
2137 }, | 2216 }, |
2138 from_increment, IndexAdvanceMode::kPost); | 2217 from_increment, IndexAdvanceMode::kPost); |
2139 } | 2218 } |
2140 | 2219 |
2141 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, | 2220 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, |
2142 Node* offset, | 2221 Node* offset, |
2143 ElementsKind from_kind, | 2222 ElementsKind from_kind, |
2144 ElementsKind to_kind, | 2223 ElementsKind to_kind, |
2145 Label* if_hole) { | 2224 Label* if_hole) { |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2547 { | 2626 { |
2548 // The {value} is a Smi, convert it to a String. | 2627 // The {value} is a Smi, convert it to a String. |
2549 Callable callable = CodeFactory::NumberToString(isolate()); | 2628 Callable callable = CodeFactory::NumberToString(isolate()); |
2550 var_value.Bind(CallStub(callable, context, value)); | 2629 var_value.Bind(CallStub(callable, context, value)); |
2551 Goto(&if_valueisstring); | 2630 Goto(&if_valueisstring); |
2552 } | 2631 } |
2553 Bind(&if_valueisstring); | 2632 Bind(&if_valueisstring); |
2554 return var_value.value(); | 2633 return var_value.value(); |
2555 } | 2634 } |
2556 | 2635 |
| 2636 Node* CodeStubAssembler::ChangeNumberToFloat64(compiler::Node* value) { |
| 2637 Variable result(this, MachineRepresentation::kFloat64); |
| 2638 Label smi(this); |
| 2639 Label done(this, &result); |
| 2640 GotoIf(TaggedIsSmi(value), &smi); |
| 2641 result.Bind( |
| 2642 LoadObjectField(value, HeapNumber::kValueOffset, MachineType::Float64())); |
| 2643 Goto(&done); |
| 2644 |
| 2645 Bind(&smi); |
| 2646 { |
| 2647 result.Bind(ChangeInt32ToFloat64(SmiUntag(value))); |
| 2648 Goto(&done); |
| 2649 } |
| 2650 |
| 2651 Bind(&done); |
| 2652 return result.value(); |
| 2653 } |
| 2654 |
2557 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, | 2655 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, |
2558 PrimitiveType primitive_type, | 2656 PrimitiveType primitive_type, |
2559 char const* method_name) { | 2657 char const* method_name) { |
2560 // We might need to loop once due to JSValue unboxing. | 2658 // We might need to loop once due to JSValue unboxing. |
2561 Variable var_value(this, MachineRepresentation::kTagged); | 2659 Variable var_value(this, MachineRepresentation::kTagged); |
2562 Label loop(this, &var_value), done_loop(this), | 2660 Label loop(this, &var_value), done_loop(this), |
2563 done_throw(this, Label::kDeferred); | 2661 done_throw(this, Label::kDeferred); |
2564 var_value.Bind(value); | 2662 var_value.Bind(value); |
2565 Goto(&loop); | 2663 Goto(&loop); |
2566 Bind(&loop); | 2664 Bind(&loop); |
(...skipping 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3959 void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { | 4057 void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { |
3960 DCHECK(delta > 0); | 4058 DCHECK(delta > 0); |
3961 if (FLAG_native_code_counters && counter->Enabled()) { | 4059 if (FLAG_native_code_counters && counter->Enabled()) { |
3962 Node* counter_address = ExternalConstant(ExternalReference(counter)); | 4060 Node* counter_address = ExternalConstant(ExternalReference(counter)); |
3963 Node* value = Load(MachineType::Int32(), counter_address); | 4061 Node* value = Load(MachineType::Int32(), counter_address); |
3964 value = Int32Sub(value, Int32Constant(delta)); | 4062 value = Int32Sub(value, Int32Constant(delta)); |
3965 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); | 4063 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); |
3966 } | 4064 } |
3967 } | 4065 } |
3968 | 4066 |
| 4067 void CodeStubAssembler::Increment(Variable& variable, int value, |
| 4068 ParameterMode mode) { |
| 4069 DCHECK_IMPLIES(mode == INTPTR_PARAMETERS, |
| 4070 variable.rep() == MachineType::PointerRepresentation()); |
| 4071 DCHECK_IMPLIES(mode == SMI_PARAMETERS, |
| 4072 variable.rep() == MachineRepresentation::kTagged || |
| 4073 variable.rep() == MachineRepresentation::kTaggedSigned); |
| 4074 variable.Bind(IntPtrAdd(variable.value(), IntPtrOrSmiConstant(value, mode))); |
| 4075 } |
| 4076 |
3969 void CodeStubAssembler::Use(Label* label) { | 4077 void CodeStubAssembler::Use(Label* label) { |
3970 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); | 4078 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); |
3971 } | 4079 } |
3972 | 4080 |
3973 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, | 4081 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, |
3974 Variable* var_index, Label* if_keyisunique, | 4082 Variable* var_index, Label* if_keyisunique, |
3975 Label* if_bailout) { | 4083 Label* if_bailout) { |
3976 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); | 4084 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); |
3977 Comment("TryToName"); | 4085 Comment("TryToName"); |
3978 | 4086 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4119 | 4227 |
4120 Variable var_count(this, MachineType::PointerRepresentation()); | 4228 Variable var_count(this, MachineType::PointerRepresentation()); |
4121 Variable var_entry(this, MachineType::PointerRepresentation()); | 4229 Variable var_entry(this, MachineType::PointerRepresentation()); |
4122 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; | 4230 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; |
4123 Label loop(this, 3, loop_vars); | 4231 Label loop(this, 3, loop_vars); |
4124 var_count.Bind(count); | 4232 var_count.Bind(count); |
4125 var_entry.Bind(entry); | 4233 var_entry.Bind(entry); |
4126 Goto(&loop); | 4234 Goto(&loop); |
4127 Bind(&loop); | 4235 Bind(&loop); |
4128 { | 4236 { |
4129 Node* count = var_count.value(); | |
4130 Node* entry = var_entry.value(); | 4237 Node* entry = var_entry.value(); |
4131 | 4238 |
4132 Node* index = EntryToIndex<Dictionary>(entry); | 4239 Node* index = EntryToIndex<Dictionary>(entry); |
4133 var_name_index->Bind(index); | 4240 var_name_index->Bind(index); |
4134 | 4241 |
4135 Node* current = | 4242 Node* current = |
4136 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); | 4243 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
4137 GotoIf(WordEqual(current, undefined), if_not_found); | 4244 GotoIf(WordEqual(current, undefined), if_not_found); |
4138 if (mode == kFindExisting) { | 4245 if (mode == kFindExisting) { |
4139 GotoIf(WordEqual(current, unique_name), if_found); | 4246 GotoIf(WordEqual(current, unique_name), if_found); |
4140 } else { | 4247 } else { |
4141 DCHECK_EQ(kFindInsertionIndex, mode); | 4248 DCHECK_EQ(kFindInsertionIndex, mode); |
4142 GotoIf(WordEqual(current, the_hole), if_not_found); | 4249 GotoIf(WordEqual(current, the_hole), if_not_found); |
4143 } | 4250 } |
4144 | 4251 |
4145 // See Dictionary::NextProbe(). | 4252 // See Dictionary::NextProbe(). |
4146 count = IntPtrAdd(count, IntPtrConstant(1)); | 4253 Increment(var_count); |
4147 entry = WordAnd(IntPtrAdd(entry, count), mask); | 4254 entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask); |
4148 | 4255 |
4149 var_count.Bind(count); | |
4150 var_entry.Bind(entry); | 4256 var_entry.Bind(entry); |
4151 Goto(&loop); | 4257 Goto(&loop); |
4152 } | 4258 } |
4153 } | 4259 } |
4154 | 4260 |
4155 // Instantiate template methods to workaround GCC compilation issue. | 4261 // Instantiate template methods to workaround GCC compilation issue. |
4156 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( | 4262 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( |
4157 Node*, Node*, Label*, Variable*, Label*, int, LookupMode); | 4263 Node*, Node*, Label*, Variable*, Label*, int, LookupMode); |
4158 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>( | 4264 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>( |
4159 Node*, Node*, Label*, Variable*, Label*, int, LookupMode); | 4265 Node*, Node*, Label*, Variable*, Label*, int, LookupMode); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4202 Node* the_hole = TheHoleConstant(); | 4308 Node* the_hole = TheHoleConstant(); |
4203 | 4309 |
4204 Variable var_count(this, MachineType::PointerRepresentation()); | 4310 Variable var_count(this, MachineType::PointerRepresentation()); |
4205 Variable* loop_vars[] = {&var_count, var_entry}; | 4311 Variable* loop_vars[] = {&var_count, var_entry}; |
4206 Label loop(this, 2, loop_vars); | 4312 Label loop(this, 2, loop_vars); |
4207 var_count.Bind(count); | 4313 var_count.Bind(count); |
4208 var_entry->Bind(entry); | 4314 var_entry->Bind(entry); |
4209 Goto(&loop); | 4315 Goto(&loop); |
4210 Bind(&loop); | 4316 Bind(&loop); |
4211 { | 4317 { |
4212 Node* count = var_count.value(); | |
4213 Node* entry = var_entry->value(); | 4318 Node* entry = var_entry->value(); |
4214 | 4319 |
4215 Node* index = EntryToIndex<Dictionary>(entry); | 4320 Node* index = EntryToIndex<Dictionary>(entry); |
4216 Node* current = | 4321 Node* current = |
4217 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); | 4322 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
4218 GotoIf(WordEqual(current, undefined), if_not_found); | 4323 GotoIf(WordEqual(current, undefined), if_not_found); |
4219 Label next_probe(this); | 4324 Label next_probe(this); |
4220 { | 4325 { |
4221 Label if_currentissmi(this), if_currentisnotsmi(this); | 4326 Label if_currentissmi(this), if_currentisnotsmi(this); |
4222 Branch(TaggedIsSmi(current), &if_currentissmi, &if_currentisnotsmi); | 4327 Branch(TaggedIsSmi(current), &if_currentissmi, &if_currentisnotsmi); |
4223 Bind(&if_currentissmi); | 4328 Bind(&if_currentissmi); |
4224 { | 4329 { |
4225 Node* current_value = SmiUntag(current); | 4330 Node* current_value = SmiUntag(current); |
4226 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe); | 4331 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe); |
4227 } | 4332 } |
4228 Bind(&if_currentisnotsmi); | 4333 Bind(&if_currentisnotsmi); |
4229 { | 4334 { |
4230 GotoIf(WordEqual(current, the_hole), &next_probe); | 4335 GotoIf(WordEqual(current, the_hole), &next_probe); |
4231 // Current must be the Number. | 4336 // Current must be the Number. |
4232 Node* current_value = LoadHeapNumberValue(current); | 4337 Node* current_value = LoadHeapNumberValue(current); |
4233 Branch(Float64Equal(current_value, key_as_float64), if_found, | 4338 Branch(Float64Equal(current_value, key_as_float64), if_found, |
4234 &next_probe); | 4339 &next_probe); |
4235 } | 4340 } |
4236 } | 4341 } |
4237 | 4342 |
4238 Bind(&next_probe); | 4343 Bind(&next_probe); |
4239 // See Dictionary::NextProbe(). | 4344 // See Dictionary::NextProbe(). |
4240 count = IntPtrAdd(count, IntPtrConstant(1)); | 4345 Increment(var_count); |
4241 entry = WordAnd(IntPtrAdd(entry, count), mask); | 4346 entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask); |
4242 | 4347 |
4243 var_count.Bind(count); | |
4244 var_entry->Bind(entry); | 4348 var_entry->Bind(entry); |
4245 Goto(&loop); | 4349 Goto(&loop); |
4246 } | 4350 } |
4247 } | 4351 } |
4248 | 4352 |
4249 template <class Dictionary> | 4353 template <class Dictionary> |
4250 void CodeStubAssembler::FindInsertionEntry(Node* dictionary, Node* key, | 4354 void CodeStubAssembler::FindInsertionEntry(Node* dictionary, Node* key, |
4251 Variable* var_key_index) { | 4355 Variable* var_key_index) { |
4252 UNREACHABLE(); | 4356 UNREACHABLE(); |
4253 } | 4357 } |
(...skipping 1641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5895 // loop that helps turbofan generate better code. If there's only a single | 5999 // loop that helps turbofan generate better code. If there's only a single |
5896 // check, then the CodeStubAssembler forces it to be at the beginning of the | 6000 // check, then the CodeStubAssembler forces it to be at the beginning of the |
5897 // loop requiring a backwards branch at the end of the loop (it's not possible | 6001 // loop requiring a backwards branch at the end of the loop (it's not possible |
5898 // to force the loop header check at the end of the loop and branch forward to | 6002 // to force the loop header check at the end of the loop and branch forward to |
5899 // it from the pre-header). The extra branch is slower in the case that the | 6003 // it from the pre-header). The extra branch is slower in the case that the |
5900 // loop actually iterates. | 6004 // loop actually iterates. |
5901 Branch(WordEqual(var.value(), end_index), &after_loop, &loop); | 6005 Branch(WordEqual(var.value(), end_index), &after_loop, &loop); |
5902 Bind(&loop); | 6006 Bind(&loop); |
5903 { | 6007 { |
5904 if (mode == IndexAdvanceMode::kPre) { | 6008 if (mode == IndexAdvanceMode::kPre) { |
5905 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); | 6009 Increment(var, increment); |
5906 } | 6010 } |
5907 body(this, var.value()); | 6011 body(this, var.value()); |
5908 if (mode == IndexAdvanceMode::kPost) { | 6012 if (mode == IndexAdvanceMode::kPost) { |
5909 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); | 6013 Increment(var, increment); |
5910 } | 6014 } |
5911 Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop); | 6015 Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop); |
5912 } | 6016 } |
5913 Bind(&after_loop); | 6017 Bind(&after_loop); |
5914 } | 6018 } |
5915 | 6019 |
5916 void CodeStubAssembler::BuildFastFixedArrayForEach( | 6020 void CodeStubAssembler::BuildFastFixedArrayForEach( |
5917 Node* fixed_array, ElementsKind kind, Node* first_element_inclusive, | 6021 Node* fixed_array, ElementsKind kind, Node* first_element_inclusive, |
5918 Node* last_element_exclusive, | 6022 Node* last_element_exclusive, |
5919 std::function<void(CodeStubAssembler* assembler, Node* fixed_array, | 6023 std::function<void(CodeStubAssembler* assembler, Node* fixed_array, |
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7538 Node* one = Float64Constant(1.0); | 7642 Node* one = Float64Constant(1.0); |
7539 Node* finc_result = Float64Add(finc_value, one); | 7643 Node* finc_result = Float64Add(finc_value, one); |
7540 var_result.Bind(AllocateHeapNumberWithValue(finc_result)); | 7644 var_result.Bind(AllocateHeapNumberWithValue(finc_result)); |
7541 Goto(&end); | 7645 Goto(&end); |
7542 } | 7646 } |
7543 | 7647 |
7544 Bind(&end); | 7648 Bind(&end); |
7545 return var_result.value(); | 7649 return var_result.value(); |
7546 } | 7650 } |
7547 | 7651 |
| 7652 void CodeStubAssembler::GotoIfNotNumber(Node* input, Label* is_not_number) { |
| 7653 Label is_number(this); |
| 7654 GotoIf(TaggedIsSmi(input), &is_number); |
| 7655 Node* input_map = LoadMap(input); |
| 7656 Branch(IsHeapNumberMap(input_map), &is_number, is_not_number); |
| 7657 Bind(&is_number); |
| 7658 } |
| 7659 |
| 7660 void CodeStubAssembler::GotoIfNumber(Node* input, Label* is_number) { |
| 7661 GotoIf(TaggedIsSmi(input), is_number); |
| 7662 Node* input_map = LoadMap(input); |
| 7663 GotoIf(IsHeapNumberMap(input_map), is_number); |
| 7664 } |
| 7665 |
7548 Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map, | 7666 Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map, |
7549 Node* array_type, Node* context, | 7667 Node* array_type, Node* context, |
7550 IterationKind mode) { | 7668 IterationKind mode) { |
7551 int kBaseMapIndex = 0; | 7669 int kBaseMapIndex = 0; |
7552 switch (mode) { | 7670 switch (mode) { |
7553 case IterationKind::kKeys: | 7671 case IterationKind::kKeys: |
7554 kBaseMapIndex = Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX; | 7672 kBaseMapIndex = Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX; |
7555 break; | 7673 break; |
7556 case IterationKind::kValues: | 7674 case IterationKind::kValues: |
7557 kBaseMapIndex = Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX; | 7675 kBaseMapIndex = Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7594 // the receiver is a TypedArray or not. | 7712 // the receiver is a TypedArray or not. |
7595 | 7713 |
7596 Label if_istypedarray(this), if_isgeneric(this); | 7714 Label if_istypedarray(this), if_isgeneric(this); |
7597 | 7715 |
7598 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 7716 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
7599 &if_istypedarray, &if_isgeneric); | 7717 &if_istypedarray, &if_isgeneric); |
7600 | 7718 |
7601 Bind(&if_isgeneric); | 7719 Bind(&if_isgeneric); |
7602 { | 7720 { |
7603 Label if_isfast(this), if_isslow(this); | 7721 Label if_isfast(this), if_isslow(this); |
7604 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 7722 BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ, |
| 7723 &if_isfast, &if_isslow); |
7605 | 7724 |
7606 Bind(&if_isfast); | 7725 Bind(&if_isfast); |
7607 { | 7726 { |
7608 var_map_index.Bind( | 7727 var_map_index.Bind( |
7609 IntPtrConstant(Context::FAST_ARRAY_KEY_ITERATOR_MAP_INDEX)); | 7728 IntPtrConstant(Context::FAST_ARRAY_KEY_ITERATOR_MAP_INDEX)); |
7610 var_array_map.Bind(array_map); | 7729 var_array_map.Bind(array_map); |
7611 Goto(&allocate_iterator); | 7730 Goto(&allocate_iterator); |
7612 } | 7731 } |
7613 | 7732 |
7614 Bind(&if_isslow); | 7733 Bind(&if_isslow); |
(...skipping 13 matching lines...) Expand all Loading... |
7628 Goto(&allocate_iterator); | 7747 Goto(&allocate_iterator); |
7629 } | 7748 } |
7630 } else { | 7749 } else { |
7631 Label if_istypedarray(this), if_isgeneric(this); | 7750 Label if_istypedarray(this), if_isgeneric(this); |
7632 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 7751 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
7633 &if_istypedarray, &if_isgeneric); | 7752 &if_istypedarray, &if_isgeneric); |
7634 | 7753 |
7635 Bind(&if_isgeneric); | 7754 Bind(&if_isgeneric); |
7636 { | 7755 { |
7637 Label if_isfast(this), if_isslow(this); | 7756 Label if_isfast(this), if_isslow(this); |
7638 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 7757 BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ, |
| 7758 &if_isfast, &if_isslow); |
7639 | 7759 |
7640 Bind(&if_isfast); | 7760 Bind(&if_isfast); |
7641 { | 7761 { |
7642 Label if_ispacked(this), if_isholey(this); | 7762 Label if_ispacked(this), if_isholey(this); |
7643 Node* elements_kind = LoadMapElementsKind(array_map); | 7763 Node* elements_kind = LoadMapElementsKind(array_map); |
7644 Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey, | 7764 Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey, |
7645 &if_ispacked); | 7765 &if_ispacked); |
7646 | 7766 |
7647 Bind(&if_isholey); | 7767 Bind(&if_isholey); |
7648 { | 7768 { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7771 argc_, FAST_ELEMENTS, mode, | 7891 argc_, FAST_ELEMENTS, mode, |
7772 (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kPointerSize); | 7892 (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kPointerSize); |
7773 arguments_ = assembler_->IntPtrAddFoldConstants(fp_, offset); | 7893 arguments_ = assembler_->IntPtrAddFoldConstants(fp_, offset); |
7774 if (mode == CodeStubAssembler::INTEGER_PARAMETERS) { | 7894 if (mode == CodeStubAssembler::INTEGER_PARAMETERS) { |
7775 argc_ = assembler->ChangeInt32ToIntPtr(argc_); | 7895 argc_ = assembler->ChangeInt32ToIntPtr(argc_); |
7776 } else if (mode == CodeStubAssembler::SMI_PARAMETERS) { | 7896 } else if (mode == CodeStubAssembler::SMI_PARAMETERS) { |
7777 argc_ = assembler->SmiUntag(argc_); | 7897 argc_ = assembler->SmiUntag(argc_); |
7778 } | 7898 } |
7779 } | 7899 } |
7780 | 7900 |
7781 Node* CodeStubArguments::GetReceiver() { | 7901 Node* CodeStubArguments::GetReceiver() const { |
7782 return assembler_->Load(MachineType::AnyTagged(), arguments_, | 7902 return assembler_->Load(MachineType::AnyTagged(), arguments_, |
7783 assembler_->IntPtrConstant(kPointerSize)); | 7903 assembler_->IntPtrConstant(kPointerSize)); |
7784 } | 7904 } |
7785 | 7905 |
7786 Node* CodeStubArguments::AtIndex(Node* index, | 7906 Node* CodeStubArguments::AtIndex(Node* index, |
7787 CodeStubAssembler::ParameterMode mode) { | 7907 CodeStubAssembler::ParameterMode mode) const { |
| 7908 typedef compiler::Node Node; |
7788 Node* negated_index = assembler_->IntPtrSubFoldConstants( | 7909 Node* negated_index = assembler_->IntPtrSubFoldConstants( |
7789 assembler_->IntPtrOrSmiConstant(0, mode), index); | 7910 assembler_->IntPtrOrSmiConstant(0, mode), index); |
7790 Node* offset = | 7911 Node* offset = |
7791 assembler_->ElementOffsetFromIndex(negated_index, FAST_ELEMENTS, mode, 0); | 7912 assembler_->ElementOffsetFromIndex(negated_index, FAST_ELEMENTS, mode, 0); |
7792 return assembler_->Load(MachineType::AnyTagged(), arguments_, offset); | 7913 return assembler_->Load(MachineType::AnyTagged(), arguments_, offset); |
7793 } | 7914 } |
7794 | 7915 |
7795 Node* CodeStubArguments::AtIndex(int index) { | 7916 Node* CodeStubArguments::AtIndex(int index) const { |
7796 return AtIndex(assembler_->IntPtrConstant(index)); | 7917 return AtIndex(assembler_->IntPtrConstant(index)); |
7797 } | 7918 } |
7798 | 7919 |
7799 void CodeStubArguments::ForEach(const CodeStubAssembler::VariableList& vars, | 7920 void CodeStubArguments::ForEach(const CodeStubAssembler::VariableList& vars, |
7800 CodeStubArguments::ForEachBodyFunction body, | 7921 CodeStubArguments::ForEachBodyFunction body, |
7801 Node* first, Node* last, | 7922 Node* first, Node* last, |
7802 CodeStubAssembler::ParameterMode mode) { | 7923 CodeStubAssembler::ParameterMode mode) { |
7803 assembler_->Comment("CodeStubArguments::ForEach"); | 7924 assembler_->Comment("CodeStubArguments::ForEach"); |
7804 DCHECK_IMPLIES(first == nullptr || last == nullptr, | 7925 DCHECK_IMPLIES(first == nullptr || last == nullptr, |
7805 mode == CodeStubAssembler::INTPTR_PARAMETERS); | 7926 mode == CodeStubAssembler::INTPTR_PARAMETERS); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7849 | 7970 |
7850 Node* CodeStubAssembler::IsDebugActive() { | 7971 Node* CodeStubAssembler::IsDebugActive() { |
7851 Node* is_debug_active = Load( | 7972 Node* is_debug_active = Load( |
7852 MachineType::Uint8(), | 7973 MachineType::Uint8(), |
7853 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); | 7974 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); |
7854 return WordNotEqual(is_debug_active, Int32Constant(0)); | 7975 return WordNotEqual(is_debug_active, Int32Constant(0)); |
7855 } | 7976 } |
7856 | 7977 |
7857 } // namespace internal | 7978 } // namespace internal |
7858 } // namespace v8 | 7979 } // namespace v8 |
OLD | NEW |