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 2676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2687 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); | 2687 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
2688 return IsJSReceiverInstanceType(LoadInstanceType(object)); | 2688 return IsJSReceiverInstanceType(LoadInstanceType(object)); |
2689 } | 2689 } |
2690 | 2690 |
2691 Node* CodeStubAssembler::IsJSObject(Node* object) { | 2691 Node* CodeStubAssembler::IsJSObject(Node* object) { |
2692 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); | 2692 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
2693 return Int32GreaterThanOrEqual(LoadInstanceType(object), | 2693 return Int32GreaterThanOrEqual(LoadInstanceType(object), |
2694 Int32Constant(FIRST_JS_RECEIVER_TYPE)); | 2694 Int32Constant(FIRST_JS_RECEIVER_TYPE)); |
2695 } | 2695 } |
2696 | 2696 |
| 2697 Node* CodeStubAssembler::IsJSGlobalProxy(Node* object) { |
| 2698 return Word32Equal(LoadInstanceType(object), |
| 2699 Int32Constant(JS_GLOBAL_PROXY_TYPE)); |
| 2700 } |
| 2701 |
2697 Node* CodeStubAssembler::IsMap(Node* map) { | 2702 Node* CodeStubAssembler::IsMap(Node* map) { |
2698 return HasInstanceType(map, MAP_TYPE); | 2703 return HasInstanceType(map, MAP_TYPE); |
2699 } | 2704 } |
2700 | 2705 |
2701 Node* CodeStubAssembler::IsJSValue(Node* map) { | 2706 Node* CodeStubAssembler::IsJSValue(Node* map) { |
2702 return HasInstanceType(map, JS_VALUE_TYPE); | 2707 return HasInstanceType(map, JS_VALUE_TYPE); |
2703 } | 2708 } |
2704 | 2709 |
2705 Node* CodeStubAssembler::IsJSArray(Node* object) { | 2710 Node* CodeStubAssembler::IsJSArray(Node* object) { |
2706 return HasInstanceType(object, JS_ARRAY_TYPE); | 2711 return HasInstanceType(object, JS_ARRAY_TYPE); |
(...skipping 2933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5640 &validity_cell_check_done); | 5645 &validity_cell_check_done); |
5641 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); | 5646 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); |
5642 GotoIf(WordNotEqual(cell_value, | 5647 GotoIf(WordNotEqual(cell_value, |
5643 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), | 5648 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), |
5644 miss); | 5649 miss); |
5645 Goto(&validity_cell_check_done); | 5650 Goto(&validity_cell_check_done); |
5646 | 5651 |
5647 Bind(&validity_cell_check_done); | 5652 Bind(&validity_cell_check_done); |
5648 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); | 5653 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); |
5649 CSA_ASSERT(TaggedIsSmi(smi_handler)); | 5654 CSA_ASSERT(TaggedIsSmi(smi_handler)); |
| 5655 Node* handler_flags = SmiUntag(smi_handler); |
5650 | 5656 |
5651 Label check_prototypes(this); | 5657 Label check_prototypes(this); |
5652 GotoUnless(IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>( | 5658 GotoUnless( |
5653 SmiUntag(smi_handler)), | 5659 IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>(handler_flags), |
5654 &check_prototypes); | 5660 &check_prototypes); |
5655 { | 5661 { |
5656 // We have a dictionary receiver, do a negative lookup check. | 5662 // We have a dictionary receiver, do a negative lookup check. |
5657 NameDictionaryNegativeLookup(p->receiver, p->name, miss); | 5663 NameDictionaryNegativeLookup(p->receiver, p->name, miss); |
5658 Goto(&check_prototypes); | 5664 Goto(&check_prototypes); |
5659 } | 5665 } |
5660 | 5666 |
5661 Bind(&check_prototypes); | 5667 Bind(&check_prototypes); |
5662 Node* maybe_holder_cell = | 5668 Node* maybe_holder_cell = |
5663 LoadObjectField(handler, LoadHandler::kHolderCellOffset); | 5669 LoadObjectField(handler, LoadHandler::kHolderCellOffset); |
5664 Label array_handler(this), tuple_handler(this); | 5670 Label array_handler(this), tuple_handler(this); |
(...skipping 13 matching lines...) Expand all Loading... |
5678 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0))); | 5684 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0))); |
5679 | 5685 |
5680 var_holder->Bind(holder); | 5686 var_holder->Bind(holder); |
5681 var_smi_handler->Bind(smi_handler); | 5687 var_smi_handler->Bind(smi_handler); |
5682 Goto(if_smi_handler); | 5688 Goto(if_smi_handler); |
5683 } | 5689 } |
5684 | 5690 |
5685 Bind(&array_handler); | 5691 Bind(&array_handler); |
5686 { | 5692 { |
5687 Node* length = SmiUntag(maybe_holder_cell); | 5693 Node* length = SmiUntag(maybe_holder_cell); |
5688 BuildFastLoop(MachineType::PointerRepresentation(), | 5694 |
5689 IntPtrConstant(LoadHandler::kFirstPrototypeIndex), length, | 5695 Variable start_index(this, MachineType::PointerRepresentation()); |
| 5696 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); |
| 5697 |
| 5698 Label can_access(this); |
| 5699 GotoUnless( |
| 5700 IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags), |
| 5701 &can_access); |
| 5702 { |
| 5703 // Skip this entry of a handler. |
| 5704 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex + 1)); |
| 5705 |
| 5706 int offset = |
| 5707 FixedArray::OffsetOfElementAt(LoadHandler::kFirstPrototypeIndex); |
| 5708 Node* expected_native_context = |
| 5709 LoadWeakCellValue(LoadObjectField(handler, offset), miss); |
| 5710 CSA_ASSERT(IsNativeContext(expected_native_context)); |
| 5711 |
| 5712 Node* native_context = LoadNativeContext(p->context); |
| 5713 GotoIf(WordEqual(expected_native_context, native_context), &can_access); |
| 5714 // If the receiver is not a JSGlobalProxy then we miss. |
| 5715 GotoUnless(IsJSGlobalProxy(p->receiver), miss); |
| 5716 // For JSGlobalProxy receiver try to compare security tokens of current |
| 5717 // and expected native contexts. |
| 5718 Node* expected_token = LoadContextElement(expected_native_context, |
| 5719 Context::SECURITY_TOKEN_INDEX); |
| 5720 Node* current_token = |
| 5721 LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX); |
| 5722 Branch(WordEqual(expected_token, current_token), &can_access, miss); |
| 5723 } |
| 5724 Bind(&can_access); |
| 5725 |
| 5726 BuildFastLoop(MachineType::PointerRepresentation(), start_index.value(), |
| 5727 length, |
5690 [this, p, handler, miss](CodeStubAssembler*, Node* current) { | 5728 [this, p, handler, miss](CodeStubAssembler*, Node* current) { |
5691 Node* prototype_cell = LoadFixedArrayElement( | 5729 Node* prototype_cell = LoadFixedArrayElement( |
5692 handler, current, 0, INTPTR_PARAMETERS); | 5730 handler, current, 0, INTPTR_PARAMETERS); |
5693 CheckPrototype(prototype_cell, p->name, miss); | 5731 CheckPrototype(prototype_cell, p->name, miss); |
5694 }, | 5732 }, |
5695 1, IndexAdvanceMode::kPost); | 5733 1, IndexAdvanceMode::kPost); |
5696 | 5734 |
5697 Node* maybe_holder_cell = LoadFixedArrayElement( | 5735 Node* maybe_holder_cell = LoadFixedArrayElement( |
5698 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0, | 5736 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0, |
5699 INTPTR_PARAMETERS); | 5737 INTPTR_PARAMETERS); |
(...skipping 22 matching lines...) Expand all Loading... |
5722 Label done(this); | 5760 Label done(this); |
5723 Label if_property_cell(this), if_dictionary_object(this); | 5761 Label if_property_cell(this), if_dictionary_object(this); |
5724 | 5762 |
5725 // |maybe_prototype| is either a PropertyCell or a slow-mode prototype. | 5763 // |maybe_prototype| is either a PropertyCell or a slow-mode prototype. |
5726 Branch(WordEqual(LoadMap(maybe_prototype), | 5764 Branch(WordEqual(LoadMap(maybe_prototype), |
5727 LoadRoot(Heap::kGlobalPropertyCellMapRootIndex)), | 5765 LoadRoot(Heap::kGlobalPropertyCellMapRootIndex)), |
5728 &if_property_cell, &if_dictionary_object); | 5766 &if_property_cell, &if_dictionary_object); |
5729 | 5767 |
5730 Bind(&if_dictionary_object); | 5768 Bind(&if_dictionary_object); |
5731 { | 5769 { |
| 5770 CSA_ASSERT(IsDictionaryMap(LoadMap(maybe_prototype))); |
5732 NameDictionaryNegativeLookup(maybe_prototype, name, miss); | 5771 NameDictionaryNegativeLookup(maybe_prototype, name, miss); |
5733 Goto(&done); | 5772 Goto(&done); |
5734 } | 5773 } |
5735 | 5774 |
5736 Bind(&if_property_cell); | 5775 Bind(&if_property_cell); |
5737 { | 5776 { |
5738 // Ensure the property cell still contains the hole. | 5777 // Ensure the property cell still contains the hole. |
5739 Node* value = LoadObjectField(maybe_prototype, PropertyCell::kValueOffset); | 5778 Node* value = LoadObjectField(maybe_prototype, PropertyCell::kValueOffset); |
5740 GotoIf(WordNotEqual(value, LoadRoot(Heap::kTheHoleValueRootIndex)), miss); | 5779 GotoIf(WordNotEqual(value, LoadRoot(Heap::kTheHoleValueRootIndex)), miss); |
5741 Goto(&done); | 5780 Goto(&done); |
(...skipping 3098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8840 } | 8879 } |
8841 | 8880 |
8842 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 8881 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
8843 assembler_->PopAndReturn( | 8882 assembler_->PopAndReturn( |
8844 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 8883 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
8845 value); | 8884 value); |
8846 } | 8885 } |
8847 | 8886 |
8848 } // namespace internal | 8887 } // namespace internal |
8849 } // namespace v8 | 8888 } // namespace v8 |
OLD | NEW |