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 |