OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 #include "src/ic/handler-configuration.h" | 8 #include "src/ic/handler-configuration.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
520 | 520 |
521 Bind(&return_result); | 521 Bind(&return_result); |
522 return var_result.value(); | 522 return var_result.value(); |
523 } | 523 } |
524 | 524 |
525 Node* CodeStubAssembler::TaggedIsSmi(Node* a) { | 525 Node* CodeStubAssembler::TaggedIsSmi(Node* a) { |
526 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), | 526 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), |
527 IntPtrConstant(0)); | 527 IntPtrConstant(0)); |
528 } | 528 } |
529 | 529 |
530 Node* CodeStubAssembler::TaggedIsNotSmi(Node* a) { | |
531 return WordNotEqual( | |
532 WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), | |
533 IntPtrConstant(0)); | |
534 } | |
535 | |
530 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { | 536 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { |
531 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), | 537 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), |
532 IntPtrConstant(0)); | 538 IntPtrConstant(0)); |
533 } | 539 } |
534 | 540 |
535 Node* CodeStubAssembler::WordIsWordAligned(Node* word) { | 541 Node* CodeStubAssembler::WordIsWordAligned(Node* word) { |
536 return WordEqual(IntPtrConstant(0), | 542 return WordEqual(IntPtrConstant(0), |
537 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1))); | 543 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1))); |
538 } | 544 } |
539 | 545 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
648 | 654 |
649 void CodeStubAssembler::BranchIfJSObject(Node* object, Label* if_true, | 655 void CodeStubAssembler::BranchIfJSObject(Node* object, Label* if_true, |
650 Label* if_false) { | 656 Label* if_false) { |
651 GotoIf(TaggedIsSmi(object), if_false); | 657 GotoIf(TaggedIsSmi(object), if_false); |
652 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); | 658 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
653 Branch(Int32GreaterThanOrEqual(LoadInstanceType(object), | 659 Branch(Int32GreaterThanOrEqual(LoadInstanceType(object), |
654 Int32Constant(FIRST_JS_OBJECT_TYPE)), | 660 Int32Constant(FIRST_JS_OBJECT_TYPE)), |
655 if_true, if_false); | 661 if_true, if_false); |
656 } | 662 } |
657 | 663 |
658 void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context, | 664 void CodeStubAssembler::BranchIfFastJSArray( |
659 Label* if_true, Label* if_false) { | 665 Node* object, Node* context, CodeStubAssembler::FastJSArrayAccessMode mode, |
666 Label* if_true, Label* if_false) { | |
660 // Bailout if receiver is a Smi. | 667 // Bailout if receiver is a Smi. |
661 GotoIf(TaggedIsSmi(object), if_false); | 668 GotoIf(TaggedIsSmi(object), if_false); |
662 | 669 |
663 Node* map = LoadMap(object); | 670 Node* map = LoadMap(object); |
664 | 671 |
665 // Bailout if instance type is not JS_ARRAY_TYPE. | 672 // Bailout if instance type is not JS_ARRAY_TYPE. |
666 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), | 673 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), |
667 if_false); | 674 if_false); |
668 | 675 |
669 Node* elements_kind = LoadMapElementsKind(map); | 676 Node* elements_kind = LoadMapElementsKind(map); |
670 | 677 |
671 // Bailout if receiver has slow elements. | 678 // Bailout if receiver has slow elements. |
672 GotoUnless(IsFastElementsKind(elements_kind), if_false); | 679 GotoUnless(IsFastElementsKind(elements_kind), if_false); |
673 | 680 |
674 // Check prototype chain if receiver does not have packed elements. | 681 // Check prototype chain if receiver does not have packed elements. |
675 GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true); | 682 if (mode == FastJSArrayAccessMode::INBOUNDS_READ) { |
676 | 683 GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true); |
684 } | |
677 BranchIfPrototypesHaveNoElements(map, if_true, if_false); | 685 BranchIfPrototypesHaveNoElements(map, if_true, if_false); |
678 } | 686 } |
679 | 687 |
680 Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, | 688 Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, |
681 AllocationFlags flags, | 689 AllocationFlags flags, |
682 Node* top_address, | 690 Node* top_address, |
683 Node* limit_address) { | 691 Node* limit_address) { |
684 Node* top = Load(MachineType::Pointer(), top_address); | 692 Node* top = Load(MachineType::Pointer(), top_address); |
685 Node* limit = Load(MachineType::Pointer(), limit_address); | 693 Node* limit = Load(MachineType::Pointer(), limit_address); |
686 | 694 |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1355 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( | 1363 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( |
1356 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { | 1364 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { |
1357 CSA_ASSERT(this, IsFixedDoubleArray(object)); | 1365 CSA_ASSERT(this, IsFixedDoubleArray(object)); |
1358 Node* offset = | 1366 Node* offset = |
1359 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, | 1367 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, |
1360 FixedArray::kHeaderSize - kHeapObjectTag); | 1368 FixedArray::kHeaderSize - kHeapObjectTag); |
1361 MachineRepresentation rep = MachineRepresentation::kFloat64; | 1369 MachineRepresentation rep = MachineRepresentation::kFloat64; |
1362 return StoreNoWriteBarrier(rep, object, offset, value); | 1370 return StoreNoWriteBarrier(rep, object, offset, value); |
1363 } | 1371 } |
1364 | 1372 |
1373 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context, | |
1374 Node* array, | |
1375 CodeStubArguments& args, | |
1376 Variable& arg_index, | |
1377 Label* bailout) { | |
1378 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); | |
1379 Label pre_bailout(this); | |
1380 Label success(this); | |
1381 Variable elements(this, MachineRepresentation::kTagged); | |
1382 ParameterMode mode = OptimalParameterMode(); | |
1383 Variable capacity(this, OptimalParameterRepresentation()); | |
1384 Variable length(this, OptimalParameterRepresentation()); | |
1385 length.Bind(UntagParameter(LoadJSArrayLength(array), mode)); | |
1386 elements.Bind(LoadElements(array)); | |
1387 capacity.Bind( | |
Jakob Kummerow
2016/11/23 17:17:06
I think |capacity| could simply be a Node*, I see
danno
2016/11/29 14:39:59
Done.
| |
1388 UntagParameter(LoadFixedArrayBaseLength(elements.value()), mode)); | |
1389 | |
1390 // Resize the capacity of the fixed array if it doesn't fit. | |
1391 CodeStubAssembler::VariableList grow_vars({&capacity, &elements}, zone()); | |
1392 Label fits(this, grow_vars); | |
1393 Node* first = arg_index.value(); | |
1394 Node* growth = IntPtrSubFoldConstants(args.GetLength(), first); | |
1395 Node* new_length = IntPtrAdd( | |
1396 mode == INTPTR_PARAMETERS ? growth : SmiTag(growth), length.value()); | |
1397 GotoUnless(IntPtrGreaterThanOrEqual(new_length, capacity.value()), &fits); | |
1398 Node* new_capacity = CalculateNewElementsCapacity( | |
1399 IntPtrAdd(new_length, IntPtrOrSmiConstant(1, mode)), mode); | |
1400 elements.Bind(GrowElementsCapacity(array, elements.value(), kind, kind, | |
1401 capacity.value(), new_capacity, mode, | |
1402 &pre_bailout)); | |
1403 Goto(&fits); | |
1404 Bind(&fits); | |
1405 | |
1406 // Push each argument onto the end of the array now that there is enough | |
1407 // capacity. | |
1408 CodeStubAssembler::VariableList push_vars({&length, &elements}, zone()); | |
1409 args.ForEach( | |
1410 push_vars, | |
1411 [kind, array, context, mode, &length, &elements, &pre_bailout]( | |
Jakob Kummerow
2016/11/23 17:17:06
nit: |array| and |context| appear to be unused, dr
danno
2016/11/29 14:39:59
Done.
| |
1412 CodeStubAssembler* assembler, Node* arg) { | |
1413 if (IsFastSmiElementsKind(kind)) { | |
1414 assembler->GotoUnless(assembler->TaggedIsSmi(arg), &pre_bailout); | |
Jakob Kummerow
2016/11/23 17:17:05
nit: now that you have TaggedIsNotSmi, you could u
danno
2016/11/29 14:39:59
Done.
| |
1415 } else if (IsFastDoubleElementsKind(kind)) { | |
1416 assembler->GotoIfNotNumber(arg, &pre_bailout); | |
1417 } | |
1418 if (IsFastDoubleElementsKind(kind)) { | |
1419 assembler->StoreFixedDoubleArrayElement( | |
1420 elements.value(), length.value(), | |
1421 assembler->ChangeNumberToFloat64(arg), mode); | |
1422 } else { | |
1423 WriteBarrierMode barrier_mode = IsFastSmiElementsKind(kind) | |
1424 ? SKIP_WRITE_BARRIER | |
1425 : UPDATE_WRITE_BARRIER; | |
1426 assembler->StoreFixedArrayElement(elements.value(), length.value(), | |
1427 arg, barrier_mode, mode); | |
1428 } | |
1429 assembler->Increment(length, 1, mode); | |
1430 }, | |
1431 first, nullptr); | |
1432 length.Bind(TagParameter(length.value(), mode)); | |
1433 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length.value()); | |
1434 Goto(&success); | |
1435 | |
1436 Bind(&pre_bailout); | |
1437 length.Bind(TagParameter(length.value(), mode)); | |
1438 Node* diff = SmiSub(length.value(), LoadJSArrayLength(array)); | |
1439 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length.value()); | |
1440 arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff))); | |
1441 Goto(bailout); | |
1442 | |
1443 Bind(&success); | |
1444 return length.value(); | |
1445 } | |
1446 | |
1365 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { | 1447 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { |
1366 Node* result = Allocate(HeapNumber::kSize, kNone); | 1448 Node* result = Allocate(HeapNumber::kSize, kNone); |
1367 Heap::RootListIndex heap_map_index = | 1449 Heap::RootListIndex heap_map_index = |
1368 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex | 1450 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex |
1369 : Heap::kMutableHeapNumberMapRootIndex; | 1451 : Heap::kMutableHeapNumberMapRootIndex; |
1370 Node* map = LoadRoot(heap_map_index); | 1452 Node* map = LoadRoot(heap_map_index); |
1371 StoreMapNoWriteBarrier(result, map); | 1453 StoreMapNoWriteBarrier(result, map); |
1372 return result; | 1454 return result; |
1373 } | 1455 } |
1374 | 1456 |
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2123 to_index_smi == from_index_smi)); | 2205 to_index_smi == from_index_smi)); |
2124 BuildFastLoop(vars, MachineType::PointerRepresentation(), from_offset, | 2206 BuildFastLoop(vars, MachineType::PointerRepresentation(), from_offset, |
2125 limit_offset, | 2207 limit_offset, |
2126 [from_string, to_string, ¤t_to_offset, to_increment, type, | 2208 [from_string, to_string, ¤t_to_offset, to_increment, type, |
2127 rep, index_same](CodeStubAssembler* assembler, Node* offset) { | 2209 rep, index_same](CodeStubAssembler* assembler, Node* offset) { |
2128 Node* value = assembler->Load(type, from_string, offset); | 2210 Node* value = assembler->Load(type, from_string, offset); |
2129 assembler->StoreNoWriteBarrier( | 2211 assembler->StoreNoWriteBarrier( |
2130 rep, to_string, | 2212 rep, to_string, |
2131 index_same ? offset : current_to_offset.value(), value); | 2213 index_same ? offset : current_to_offset.value(), value); |
2132 if (!index_same) { | 2214 if (!index_same) { |
2133 current_to_offset.Bind(assembler->IntPtrAdd( | 2215 assembler->Increment(current_to_offset, to_increment, |
2134 current_to_offset.value(), | 2216 INTPTR_PARAMETERS); |
Jakob Kummerow
2016/11/23 17:17:05
nit: INTPTR_PARAMETERS is the default, no need to
danno
2016/11/29 14:39:59
Done.
| |
2135 assembler->IntPtrConstant(to_increment))); | |
2136 } | 2217 } |
2137 }, | 2218 }, |
2138 from_increment, IndexAdvanceMode::kPost); | 2219 from_increment, IndexAdvanceMode::kPost); |
2139 } | 2220 } |
2140 | 2221 |
2141 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, | 2222 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, |
2142 Node* offset, | 2223 Node* offset, |
2143 ElementsKind from_kind, | 2224 ElementsKind from_kind, |
2144 ElementsKind to_kind, | 2225 ElementsKind to_kind, |
2145 Label* if_hole) { | 2226 Label* if_hole) { |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2547 { | 2628 { |
2548 // The {value} is a Smi, convert it to a String. | 2629 // The {value} is a Smi, convert it to a String. |
2549 Callable callable = CodeFactory::NumberToString(isolate()); | 2630 Callable callable = CodeFactory::NumberToString(isolate()); |
2550 var_value.Bind(CallStub(callable, context, value)); | 2631 var_value.Bind(CallStub(callable, context, value)); |
2551 Goto(&if_valueisstring); | 2632 Goto(&if_valueisstring); |
2552 } | 2633 } |
2553 Bind(&if_valueisstring); | 2634 Bind(&if_valueisstring); |
2554 return var_value.value(); | 2635 return var_value.value(); |
2555 } | 2636 } |
2556 | 2637 |
2638 Node* CodeStubAssembler::ChangeNumberToFloat64(compiler::Node* value) { | |
2639 Variable result(this, MachineRepresentation::kFloat64); | |
2640 Label smi(this); | |
2641 Label done(this, &result); | |
2642 GotoIf(TaggedIsSmi(value), &smi); | |
2643 result.Bind( | |
2644 LoadObjectField(value, HeapNumber::kValueOffset, MachineType::Float64())); | |
Jakob Kummerow
2016/11/23 17:17:05
This doesn't canonicalize the hole NaN. Use Float6
danno
2016/11/29 14:39:59
Done.
| |
2645 Goto(&done); | |
2646 | |
2647 Bind(&smi); | |
2648 { | |
2649 result.Bind(ChangeInt32ToFloat64(SmiUntag(value))); | |
2650 Goto(&done); | |
2651 } | |
2652 | |
2653 Bind(&done); | |
2654 return result.value(); | |
2655 } | |
2656 | |
2557 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, | 2657 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, |
2558 PrimitiveType primitive_type, | 2658 PrimitiveType primitive_type, |
2559 char const* method_name) { | 2659 char const* method_name) { |
2560 // We might need to loop once due to JSValue unboxing. | 2660 // We might need to loop once due to JSValue unboxing. |
2561 Variable var_value(this, MachineRepresentation::kTagged); | 2661 Variable var_value(this, MachineRepresentation::kTagged); |
2562 Label loop(this, &var_value), done_loop(this), | 2662 Label loop(this, &var_value), done_loop(this), |
2563 done_throw(this, Label::kDeferred); | 2663 done_throw(this, Label::kDeferred); |
2564 var_value.Bind(value); | 2664 var_value.Bind(value); |
2565 Goto(&loop); | 2665 Goto(&loop); |
2566 Bind(&loop); | 2666 Bind(&loop); |
(...skipping 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3963 void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { | 4063 void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { |
3964 DCHECK(delta > 0); | 4064 DCHECK(delta > 0); |
3965 if (FLAG_native_code_counters && counter->Enabled()) { | 4065 if (FLAG_native_code_counters && counter->Enabled()) { |
3966 Node* counter_address = ExternalConstant(ExternalReference(counter)); | 4066 Node* counter_address = ExternalConstant(ExternalReference(counter)); |
3967 Node* value = Load(MachineType::Int32(), counter_address); | 4067 Node* value = Load(MachineType::Int32(), counter_address); |
3968 value = Int32Sub(value, Int32Constant(delta)); | 4068 value = Int32Sub(value, Int32Constant(delta)); |
3969 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); | 4069 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); |
3970 } | 4070 } |
3971 } | 4071 } |
3972 | 4072 |
4073 void CodeStubAssembler::Increment(Variable& variable, int value, | |
4074 ParameterMode mode) { | |
4075 DCHECK_IMPLIES(mode == INTPTR_PARAMETERS, | |
4076 variable.rep() == MachineType::PointerRepresentation()); | |
4077 DCHECK_IMPLIES(mode == SMI_PARAMETERS, | |
4078 variable.rep() == MachineRepresentation::kTagged || | |
4079 variable.rep() == MachineRepresentation::kTaggedSigned); | |
4080 variable.Bind(IntPtrAdd(variable.value(), IntPtrOrSmiConstant(value, mode))); | |
4081 } | |
4082 | |
3973 void CodeStubAssembler::Use(Label* label) { | 4083 void CodeStubAssembler::Use(Label* label) { |
3974 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); | 4084 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); |
3975 } | 4085 } |
3976 | 4086 |
3977 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, | 4087 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, |
3978 Variable* var_index, Label* if_keyisunique, | 4088 Variable* var_index, Label* if_keyisunique, |
3979 Label* if_bailout) { | 4089 Label* if_bailout) { |
3980 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); | 4090 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); |
3981 Comment("TryToName"); | 4091 Comment("TryToName"); |
3982 | 4092 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4073 | 4183 |
4074 Variable var_count(this, MachineType::PointerRepresentation()); | 4184 Variable var_count(this, MachineType::PointerRepresentation()); |
4075 Variable var_entry(this, MachineType::PointerRepresentation()); | 4185 Variable var_entry(this, MachineType::PointerRepresentation()); |
4076 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; | 4186 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; |
4077 Label loop(this, 3, loop_vars); | 4187 Label loop(this, 3, loop_vars); |
4078 var_count.Bind(count); | 4188 var_count.Bind(count); |
4079 var_entry.Bind(entry); | 4189 var_entry.Bind(entry); |
4080 Goto(&loop); | 4190 Goto(&loop); |
4081 Bind(&loop); | 4191 Bind(&loop); |
4082 { | 4192 { |
4083 Node* count = var_count.value(); | |
4084 Node* entry = var_entry.value(); | 4193 Node* entry = var_entry.value(); |
4085 | 4194 |
4086 Node* index = EntryToIndex<Dictionary>(entry); | 4195 Node* index = EntryToIndex<Dictionary>(entry); |
4087 var_name_index->Bind(index); | 4196 var_name_index->Bind(index); |
4088 | 4197 |
4089 Node* current = | 4198 Node* current = |
4090 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); | 4199 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
4091 GotoIf(WordEqual(current, undefined), if_not_found); | 4200 GotoIf(WordEqual(current, undefined), if_not_found); |
4092 GotoIf(WordEqual(current, unique_name), if_found); | 4201 GotoIf(WordEqual(current, unique_name), if_found); |
4093 | 4202 |
4094 // See Dictionary::NextProbe(). | 4203 // See Dictionary::NextProbe(). |
4095 count = IntPtrAdd(count, IntPtrConstant(1)); | 4204 Increment(var_count); |
4096 entry = WordAnd(IntPtrAdd(entry, count), mask); | 4205 entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask); |
4097 | 4206 |
4098 var_count.Bind(count); | |
4099 var_entry.Bind(entry); | 4207 var_entry.Bind(entry); |
4100 Goto(&loop); | 4208 Goto(&loop); |
4101 } | 4209 } |
4102 } | 4210 } |
4103 | 4211 |
4104 // Instantiate template methods to workaround GCC compilation issue. | 4212 // Instantiate template methods to workaround GCC compilation issue. |
4105 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( | 4213 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( |
4106 Node*, Node*, Label*, Variable*, Label*, int); | 4214 Node*, Node*, Label*, Variable*, Label*, int); |
4107 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>( | 4215 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>( |
4108 Node*, Node*, Label*, Variable*, Label*, int); | 4216 Node*, Node*, Label*, Variable*, Label*, int); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4153 Node* the_hole = TheHoleConstant(); | 4261 Node* the_hole = TheHoleConstant(); |
4154 | 4262 |
4155 Variable var_count(this, MachineType::PointerRepresentation()); | 4263 Variable var_count(this, MachineType::PointerRepresentation()); |
4156 Variable* loop_vars[] = {&var_count, var_entry}; | 4264 Variable* loop_vars[] = {&var_count, var_entry}; |
4157 Label loop(this, 2, loop_vars); | 4265 Label loop(this, 2, loop_vars); |
4158 var_count.Bind(count); | 4266 var_count.Bind(count); |
4159 var_entry->Bind(entry); | 4267 var_entry->Bind(entry); |
4160 Goto(&loop); | 4268 Goto(&loop); |
4161 Bind(&loop); | 4269 Bind(&loop); |
4162 { | 4270 { |
4163 Node* count = var_count.value(); | |
4164 Node* entry = var_entry->value(); | 4271 Node* entry = var_entry->value(); |
4165 | 4272 |
4166 Node* index = EntryToIndex<Dictionary>(entry); | 4273 Node* index = EntryToIndex<Dictionary>(entry); |
4167 Node* current = | 4274 Node* current = |
4168 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); | 4275 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
4169 GotoIf(WordEqual(current, undefined), if_not_found); | 4276 GotoIf(WordEqual(current, undefined), if_not_found); |
4170 Label next_probe(this); | 4277 Label next_probe(this); |
4171 { | 4278 { |
4172 Label if_currentissmi(this), if_currentisnotsmi(this); | 4279 Label if_currentissmi(this), if_currentisnotsmi(this); |
4173 Branch(TaggedIsSmi(current), &if_currentissmi, &if_currentisnotsmi); | 4280 Branch(TaggedIsSmi(current), &if_currentissmi, &if_currentisnotsmi); |
4174 Bind(&if_currentissmi); | 4281 Bind(&if_currentissmi); |
4175 { | 4282 { |
4176 Node* current_value = SmiUntag(current); | 4283 Node* current_value = SmiUntag(current); |
4177 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe); | 4284 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe); |
4178 } | 4285 } |
4179 Bind(&if_currentisnotsmi); | 4286 Bind(&if_currentisnotsmi); |
4180 { | 4287 { |
4181 GotoIf(WordEqual(current, the_hole), &next_probe); | 4288 GotoIf(WordEqual(current, the_hole), &next_probe); |
4182 // Current must be the Number. | 4289 // Current must be the Number. |
4183 Node* current_value = LoadHeapNumberValue(current); | 4290 Node* current_value = LoadHeapNumberValue(current); |
4184 Branch(Float64Equal(current_value, key_as_float64), if_found, | 4291 Branch(Float64Equal(current_value, key_as_float64), if_found, |
4185 &next_probe); | 4292 &next_probe); |
4186 } | 4293 } |
4187 } | 4294 } |
4188 | 4295 |
4189 Bind(&next_probe); | 4296 Bind(&next_probe); |
4190 // See Dictionary::NextProbe(). | 4297 // See Dictionary::NextProbe(). |
4191 count = IntPtrAdd(count, IntPtrConstant(1)); | 4298 Increment(var_count); |
4192 entry = WordAnd(IntPtrAdd(entry, count), mask); | 4299 entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask); |
4193 | 4300 |
4194 var_count.Bind(count); | |
4195 var_entry->Bind(entry); | 4301 var_entry->Bind(entry); |
4196 Goto(&loop); | 4302 Goto(&loop); |
4197 } | 4303 } |
4198 } | 4304 } |
4199 | 4305 |
4200 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, | 4306 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, |
4201 Node* descriptors, Node* nof, | 4307 Node* descriptors, Node* nof, |
4202 Label* if_found, | 4308 Label* if_found, |
4203 Variable* var_name_index, | 4309 Variable* var_name_index, |
4204 Label* if_not_found) { | 4310 Label* if_not_found) { |
(...skipping 3035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7240 // loop that helps turbofan generate better code. If there's only a single | 7346 // loop that helps turbofan generate better code. If there's only a single |
7241 // check, then the CodeStubAssembler forces it to be at the beginning of the | 7347 // check, then the CodeStubAssembler forces it to be at the beginning of the |
7242 // loop requiring a backwards branch at the end of the loop (it's not possible | 7348 // loop requiring a backwards branch at the end of the loop (it's not possible |
7243 // to force the loop header check at the end of the loop and branch forward to | 7349 // to force the loop header check at the end of the loop and branch forward to |
7244 // it from the pre-header). The extra branch is slower in the case that the | 7350 // it from the pre-header). The extra branch is slower in the case that the |
7245 // loop actually iterates. | 7351 // loop actually iterates. |
7246 Branch(WordEqual(var.value(), end_index), &after_loop, &loop); | 7352 Branch(WordEqual(var.value(), end_index), &after_loop, &loop); |
7247 Bind(&loop); | 7353 Bind(&loop); |
7248 { | 7354 { |
7249 if (mode == IndexAdvanceMode::kPre) { | 7355 if (mode == IndexAdvanceMode::kPre) { |
7250 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); | 7356 Increment(var, increment); |
7251 } | 7357 } |
7252 body(this, var.value()); | 7358 body(this, var.value()); |
7253 if (mode == IndexAdvanceMode::kPost) { | 7359 if (mode == IndexAdvanceMode::kPost) { |
7254 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); | 7360 Increment(var, increment); |
7255 } | 7361 } |
7256 Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop); | 7362 Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop); |
7257 } | 7363 } |
7258 Bind(&after_loop); | 7364 Bind(&after_loop); |
7259 } | 7365 } |
7260 | 7366 |
7261 void CodeStubAssembler::BuildFastFixedArrayForEach( | 7367 void CodeStubAssembler::BuildFastFixedArrayForEach( |
7262 compiler::Node* fixed_array, ElementsKind kind, | 7368 compiler::Node* fixed_array, ElementsKind kind, |
7263 compiler::Node* first_element_inclusive, | 7369 compiler::Node* first_element_inclusive, |
7264 compiler::Node* last_element_exclusive, | 7370 compiler::Node* last_element_exclusive, |
(...skipping 1641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8906 Node* one = Float64Constant(1.0); | 9012 Node* one = Float64Constant(1.0); |
8907 Node* finc_result = Float64Add(finc_value, one); | 9013 Node* finc_result = Float64Add(finc_value, one); |
8908 var_result.Bind(AllocateHeapNumberWithValue(finc_result)); | 9014 var_result.Bind(AllocateHeapNumberWithValue(finc_result)); |
8909 Goto(&end); | 9015 Goto(&end); |
8910 } | 9016 } |
8911 | 9017 |
8912 Bind(&end); | 9018 Bind(&end); |
8913 return var_result.value(); | 9019 return var_result.value(); |
8914 } | 9020 } |
8915 | 9021 |
9022 void CodeStubAssembler::GotoIfNotNumber(compiler::Node* input, | |
9023 Label* is_not_number) { | |
9024 Label is_number(this); | |
9025 GotoIf(TaggedIsSmi(input), &is_number); | |
9026 Node* input_map = LoadMap(input); | |
9027 Branch(Word32NotEqual(input_map, HeapNumberMapConstant()), is_not_number, | |
Jakob Kummerow
2016/11/23 17:17:06
Maps are words, not word32s! Even better:
Branch(
danno
2016/11/29 14:39:59
Done.
| |
9028 &is_number); | |
9029 Bind(&is_number); | |
9030 } | |
9031 | |
9032 void CodeStubAssembler::GotoIfNumber(compiler::Node* input, Label* is_number) { | |
9033 GotoIf(TaggedIsSmi(input), is_number); | |
9034 Node* input_map = LoadMap(input); | |
9035 GotoIf(Word32Equal(input_map, HeapNumberMapConstant()), is_number); | |
Jakob Kummerow
2016/11/23 17:17:06
Same here
danno
2016/11/29 14:39:59
Done.
| |
9036 } | |
9037 | |
8916 compiler::Node* CodeStubAssembler::CreateArrayIterator( | 9038 compiler::Node* CodeStubAssembler::CreateArrayIterator( |
8917 compiler::Node* array, compiler::Node* array_map, | 9039 compiler::Node* array, compiler::Node* array_map, |
8918 compiler::Node* array_type, compiler::Node* context, IterationKind mode) { | 9040 compiler::Node* array_type, compiler::Node* context, IterationKind mode) { |
8919 int kBaseMapIndex = 0; | 9041 int kBaseMapIndex = 0; |
8920 switch (mode) { | 9042 switch (mode) { |
8921 case IterationKind::kKeys: | 9043 case IterationKind::kKeys: |
8922 kBaseMapIndex = Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX; | 9044 kBaseMapIndex = Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX; |
8923 break; | 9045 break; |
8924 case IterationKind::kValues: | 9046 case IterationKind::kValues: |
8925 kBaseMapIndex = Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX; | 9047 kBaseMapIndex = Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8962 // the receiver is a TypedArray or not. | 9084 // the receiver is a TypedArray or not. |
8963 | 9085 |
8964 Label if_istypedarray(this), if_isgeneric(this); | 9086 Label if_istypedarray(this), if_isgeneric(this); |
8965 | 9087 |
8966 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 9088 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
8967 &if_istypedarray, &if_isgeneric); | 9089 &if_istypedarray, &if_isgeneric); |
8968 | 9090 |
8969 Bind(&if_isgeneric); | 9091 Bind(&if_isgeneric); |
8970 { | 9092 { |
8971 Label if_isfast(this), if_isslow(this); | 9093 Label if_isfast(this), if_isslow(this); |
8972 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 9094 BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ, |
9095 &if_isfast, &if_isslow); | |
8973 | 9096 |
8974 Bind(&if_isfast); | 9097 Bind(&if_isfast); |
8975 { | 9098 { |
8976 var_map_index.Bind( | 9099 var_map_index.Bind( |
8977 IntPtrConstant(Context::FAST_ARRAY_KEY_ITERATOR_MAP_INDEX)); | 9100 IntPtrConstant(Context::FAST_ARRAY_KEY_ITERATOR_MAP_INDEX)); |
8978 var_array_map.Bind(array_map); | 9101 var_array_map.Bind(array_map); |
8979 Goto(&allocate_iterator); | 9102 Goto(&allocate_iterator); |
8980 } | 9103 } |
8981 | 9104 |
8982 Bind(&if_isslow); | 9105 Bind(&if_isslow); |
(...skipping 13 matching lines...) Expand all Loading... | |
8996 Goto(&allocate_iterator); | 9119 Goto(&allocate_iterator); |
8997 } | 9120 } |
8998 } else { | 9121 } else { |
8999 Label if_istypedarray(this), if_isgeneric(this); | 9122 Label if_istypedarray(this), if_isgeneric(this); |
9000 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 9123 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
9001 &if_istypedarray, &if_isgeneric); | 9124 &if_istypedarray, &if_isgeneric); |
9002 | 9125 |
9003 Bind(&if_isgeneric); | 9126 Bind(&if_isgeneric); |
9004 { | 9127 { |
9005 Label if_isfast(this), if_isslow(this); | 9128 Label if_isfast(this), if_isslow(this); |
9006 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 9129 BranchIfFastJSArray( |
9130 array, context, | |
9131 CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ, &if_isfast, | |
Jakob Kummerow
2016/11/23 17:17:06
nit: s/CodeStubAssembler:://
danno
2016/11/29 14:39:59
Done.
| |
9132 &if_isslow); | |
9007 | 9133 |
9008 Bind(&if_isfast); | 9134 Bind(&if_isfast); |
9009 { | 9135 { |
9010 Label if_ispacked(this), if_isholey(this); | 9136 Label if_ispacked(this), if_isholey(this); |
9011 Node* elements_kind = LoadMapElementsKind(array_map); | 9137 Node* elements_kind = LoadMapElementsKind(array_map); |
9012 Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey, | 9138 Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey, |
9013 &if_ispacked); | 9139 &if_ispacked); |
9014 | 9140 |
9015 Bind(&if_isholey); | 9141 Bind(&if_isholey); |
9016 { | 9142 { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9140 argc_, FAST_ELEMENTS, mode, | 9266 argc_, FAST_ELEMENTS, mode, |
9141 (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kPointerSize); | 9267 (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kPointerSize); |
9142 arguments_ = assembler_->IntPtrAddFoldConstants(fp_, offset); | 9268 arguments_ = assembler_->IntPtrAddFoldConstants(fp_, offset); |
9143 if (mode == CodeStubAssembler::INTEGER_PARAMETERS) { | 9269 if (mode == CodeStubAssembler::INTEGER_PARAMETERS) { |
9144 argc_ = assembler->ChangeInt32ToIntPtr(argc_); | 9270 argc_ = assembler->ChangeInt32ToIntPtr(argc_); |
9145 } else if (mode == CodeStubAssembler::SMI_PARAMETERS) { | 9271 } else if (mode == CodeStubAssembler::SMI_PARAMETERS) { |
9146 argc_ = assembler->SmiUntag(argc_); | 9272 argc_ = assembler->SmiUntag(argc_); |
9147 } | 9273 } |
9148 } | 9274 } |
9149 | 9275 |
9150 compiler::Node* CodeStubArguments::GetReceiver() { | 9276 compiler::Node* CodeStubArguments::GetReceiver() const { |
9151 return assembler_->Load(MachineType::AnyTagged(), arguments_, | 9277 return assembler_->Load(MachineType::AnyTagged(), arguments_, |
9152 assembler_->IntPtrConstant(kPointerSize)); | 9278 assembler_->IntPtrConstant(kPointerSize)); |
9153 } | 9279 } |
9154 | 9280 |
9155 compiler::Node* CodeStubArguments::AtIndex( | 9281 compiler::Node* CodeStubArguments::AtIndex( |
9156 compiler::Node* index, CodeStubAssembler::ParameterMode mode) { | 9282 compiler::Node* index, CodeStubAssembler::ParameterMode mode) const { |
9157 typedef compiler::Node Node; | 9283 typedef compiler::Node Node; |
9158 Node* negated_index = assembler_->IntPtrSubFoldConstants( | 9284 Node* negated_index = assembler_->IntPtrSubFoldConstants( |
9159 assembler_->IntPtrOrSmiConstant(0, mode), index); | 9285 assembler_->IntPtrOrSmiConstant(0, mode), index); |
9160 Node* offset = | 9286 Node* offset = |
9161 assembler_->ElementOffsetFromIndex(negated_index, FAST_ELEMENTS, mode, 0); | 9287 assembler_->ElementOffsetFromIndex(negated_index, FAST_ELEMENTS, mode, 0); |
9162 return assembler_->Load(MachineType::AnyTagged(), arguments_, offset); | 9288 return assembler_->Load(MachineType::AnyTagged(), arguments_, offset); |
9163 } | 9289 } |
9164 | 9290 |
9165 compiler::Node* CodeStubArguments::AtIndex(int index) { | 9291 compiler::Node* CodeStubArguments::AtIndex(int index) const { |
9166 return AtIndex(assembler_->IntPtrConstant(index)); | 9292 return AtIndex(assembler_->IntPtrConstant(index)); |
9167 } | 9293 } |
9168 | 9294 |
9169 void CodeStubArguments::ForEach(const CodeStubAssembler::VariableList& vars, | 9295 void CodeStubArguments::ForEach(const CodeStubAssembler::VariableList& vars, |
9170 CodeStubArguments::ForEachBodyFunction body, | 9296 CodeStubArguments::ForEachBodyFunction body, |
9171 compiler::Node* first, compiler::Node* last, | 9297 compiler::Node* first, compiler::Node* last, |
9172 CodeStubAssembler::ParameterMode mode) { | 9298 CodeStubAssembler::ParameterMode mode) { |
9173 assembler_->Comment("CodeStubArguments::ForEach"); | 9299 assembler_->Comment("CodeStubArguments::ForEach"); |
9174 DCHECK_IMPLIES(first == nullptr || last == nullptr, | 9300 DCHECK_IMPLIES(first == nullptr || last == nullptr, |
9175 mode == CodeStubAssembler::INTPTR_PARAMETERS); | 9301 mode == CodeStubAssembler::INTPTR_PARAMETERS); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9214 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); | 9340 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); |
9215 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); | 9341 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); |
9216 | 9342 |
9217 // Check prototype chain if receiver does not have packed elements. | 9343 // Check prototype chain if receiver does not have packed elements. |
9218 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); | 9344 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); |
9219 return Word32Equal(holey_elements, Int32Constant(1)); | 9345 return Word32Equal(holey_elements, Int32Constant(1)); |
9220 } | 9346 } |
9221 | 9347 |
9222 } // namespace internal | 9348 } // namespace internal |
9223 } // namespace v8 | 9349 } // namespace v8 |
OLD | NEW |