Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/interpreter-assembler.h" | 5 #include "src/interpreter/interpreter-assembler.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <ostream> | 8 #include <ostream> |
| 9 | 9 |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 623 Int32Mul(function_id, Int32Constant(sizeof(Runtime::Function))); | 623 Int32Mul(function_id, Int32Constant(sizeof(Runtime::Function))); |
| 624 Node* function = IntPtrAdd(function_table, function_offset); | 624 Node* function = IntPtrAdd(function_table, function_offset); |
| 625 Node* function_entry = | 625 Node* function_entry = |
| 626 Load(MachineType::Pointer(), function, | 626 Load(MachineType::Pointer(), function, |
| 627 IntPtrConstant(offsetof(Runtime::Function, entry))); | 627 IntPtrConstant(offsetof(Runtime::Function, entry))); |
| 628 | 628 |
| 629 return CallStub(callable.descriptor(), code_target, context, arg_count, | 629 return CallStub(callable.descriptor(), code_target, context, arg_count, |
| 630 first_arg, function_entry, result_size); | 630 first_arg, function_entry, result_size); |
| 631 } | 631 } |
| 632 | 632 |
| 633 Node* InterpreterAssembler::EnumLength(Node* map) { | |
| 634 Node* bitfield_3 = LoadMapBitField3(map); | |
| 635 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); | |
| 636 return SmiTag(enum_length); | |
| 637 } | |
| 638 | |
| 639 void InterpreterAssembler::CheckEnumCache(Node* receiver, Label* use_cache, | |
|
rmcilroy
2016/07/19 11:08:54
Could we move these both to CodeStubAssembler - th
oth
2016/07/19 12:59:25
Done.
| |
| 640 Label* use_runtime) { | |
| 641 Variable current_js_object(this, MachineRepresentation::kTagged); | |
| 642 current_js_object.Bind(receiver); | |
| 643 | |
| 644 Variable current_map(this, MachineRepresentation::kTagged); | |
| 645 current_map.Bind(LoadMap(current_js_object.value())); | |
| 646 | |
| 647 // These variables are updated in the loop below. | |
| 648 Variable* loop_vars[2] = {¤t_js_object, ¤t_map}; | |
| 649 Label start(this, 2, loop_vars); | |
|
rmcilroy
2016/07/19 11:08:54
nit - start->loop
oth
2016/07/19 12:59:25
Done.
| |
| 650 | |
| 651 // Check if the enum length field is properly initialized, indicating that | |
| 652 // there is an enum cache. | |
| 653 { | |
| 654 Node* invalid_enum_cache_sentinel = | |
| 655 SmiConstant(Smi::FromInt(kInvalidEnumCacheSentinel)); | |
| 656 Node* enum_length = EnumLength(current_map.value()); | |
| 657 | |
| 658 Node* condition = WordEqual(enum_length, invalid_enum_cache_sentinel); | |
| 659 BranchIf(condition, use_runtime, &start); | |
| 660 } | |
| 661 | |
| 662 Label next(this); | |
|
rmcilroy
2016/07/19 11:08:54
nit - move definition next to start
oth
2016/07/19 12:59:25
Done.
| |
| 663 | |
| 664 // Check that there are no elements. prototype contains the current JS | |
|
rmcilroy
2016/07/19 11:08:54
/s/prototype/|current_js_object| ?
oth
2016/07/19 12:59:25
Done.
| |
| 665 // object we've reached through the prototype chain. | |
| 666 Bind(&start); | |
| 667 { | |
| 668 Label if_elements(this), if_no_elements(this); | |
| 669 Node* elements = LoadElements(current_js_object.value()); | |
| 670 Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex); | |
| 671 // Check that there are no elements. | |
| 672 BranchIf(WordEqual(elements, empty_fixed_array), &if_no_elements, | |
|
rmcilroy
2016/07/19 11:08:54
You can do BranchIfWordEqual if you like.
oth
2016/07/19 12:59:25
Done.
| |
| 673 &if_elements); | |
| 674 Bind(&if_elements); | |
| 675 { | |
| 676 // Second chance, the object may be using the empty slow element | |
| 677 // dictionary. | |
| 678 Node* slow_empty_dictionary = | |
| 679 LoadRoot(Heap::kEmptySlowElementDictionaryRootIndex); | |
| 680 BranchIf(WordNotEqual(elements, slow_empty_dictionary), use_runtime, | |
| 681 &if_no_elements); | |
| 682 } | |
| 683 | |
| 684 Bind(&if_no_elements); | |
| 685 { | |
| 686 // Update map prototype. | |
| 687 current_js_object.Bind(LoadMapPrototype(current_map.value())); | |
| 688 BranchIf(WordEqual(current_js_object.value(), NullConstant()), use_cache, | |
| 689 &next); | |
| 690 } | |
| 691 } | |
| 692 | |
| 693 Bind(&next); | |
| 694 { | |
| 695 // For all objects but the receiver, check that the cache is empty. | |
| 696 current_map.Bind(LoadMap(current_js_object.value())); | |
| 697 Node* enum_length = EnumLength(current_map.value()); | |
| 698 Node* zero_constant = SmiConstant(Smi::FromInt(0)); | |
| 699 BranchIf(WordEqual(enum_length, zero_constant), &start, use_runtime); | |
| 700 } | |
| 701 } | |
| 702 | |
| 633 void InterpreterAssembler::UpdateInterruptBudget(Node* weight) { | 703 void InterpreterAssembler::UpdateInterruptBudget(Node* weight) { |
| 634 Label ok(this), interrupt_check(this, Label::kDeferred), end(this); | 704 Label ok(this), interrupt_check(this, Label::kDeferred), end(this); |
| 635 Node* budget_offset = | 705 Node* budget_offset = |
| 636 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); | 706 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); |
| 637 | 707 |
| 638 // Update budget by |weight| and check if it reaches zero. | 708 // Update budget by |weight| and check if it reaches zero. |
| 639 Variable new_budget(this, MachineRepresentation::kWord32); | 709 Variable new_budget(this, MachineRepresentation::kWord32); |
| 640 Node* old_budget = | 710 Node* old_budget = |
| 641 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); | 711 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); |
| 642 new_budget.Bind(Int32Add(old_budget, weight)); | 712 new_budget.Bind(Int32Add(old_budget, weight)); |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 932 Goto(&loop); | 1002 Goto(&loop); |
| 933 } | 1003 } |
| 934 Bind(&done_loop); | 1004 Bind(&done_loop); |
| 935 | 1005 |
| 936 return array; | 1006 return array; |
| 937 } | 1007 } |
| 938 | 1008 |
| 939 } // namespace interpreter | 1009 } // namespace interpreter |
| 940 } // namespace internal | 1010 } // namespace internal |
| 941 } // namespace v8 | 1011 } // namespace v8 |
| OLD | NEW |