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 5491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5502 Variable* vars[] = {&var_holder, &var_smi_handler}; | 5502 Variable* vars[] = {&var_holder, &var_smi_handler}; |
5503 Label if_smi_handler(this, 2, vars); | 5503 Label if_smi_handler(this, 2, vars); |
5504 Label try_proto_handler(this), call_handler(this); | 5504 Label try_proto_handler(this), call_handler(this); |
5505 | 5505 |
5506 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); | 5506 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_handler); |
5507 | 5507 |
5508 // |handler| is a Smi, encoding what to do. See SmiHandler methods | 5508 // |handler| is a Smi, encoding what to do. See SmiHandler methods |
5509 // for the encoding format. | 5509 // for the encoding format. |
5510 Bind(&if_smi_handler); | 5510 Bind(&if_smi_handler); |
5511 { | 5511 { |
5512 Variable var_double_value(this, MachineRepresentation::kFloat64); | 5512 HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(), |
Igor Sheludko
2016/11/14 18:08:54
This whole piece of code was moved to HandleLoadIC
| |
5513 Label rebox_double(this, &var_double_value); | 5513 miss, support_elements); |
5514 | |
5515 Node* holder = var_holder.value(); | |
5516 Node* handler_word = SmiUntag(var_smi_handler.value()); | |
5517 Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word); | |
5518 if (support_elements == kSupportElements) { | |
5519 Label property(this); | |
5520 GotoUnless( | |
5521 WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForElements)), | |
5522 &property); | |
5523 | |
5524 Comment("element_load"); | |
5525 Node* intptr_index = TryToIntptr(p->name, miss); | |
5526 Node* elements = LoadElements(holder); | |
5527 Node* is_jsarray_condition = | |
5528 IsSetWord<LoadHandler::IsJsArrayBits>(handler_word); | |
5529 Node* elements_kind = | |
5530 DecodeWord<LoadHandler::ElementsKindBits>(handler_word); | |
5531 Label if_hole(this), unimplemented_elements_kind(this); | |
5532 Label* out_of_bounds = miss; | |
5533 EmitElementLoad(holder, elements, elements_kind, intptr_index, | |
5534 is_jsarray_condition, &if_hole, &rebox_double, | |
5535 &var_double_value, &unimplemented_elements_kind, | |
5536 out_of_bounds, miss); | |
5537 | |
5538 Bind(&unimplemented_elements_kind); | |
5539 { | |
5540 // Smi handlers should only be installed for supported elements kinds. | |
5541 // Crash if we get here. | |
5542 DebugBreak(); | |
5543 Goto(miss); | |
5544 } | |
5545 | |
5546 Bind(&if_hole); | |
5547 { | |
5548 Comment("convert hole"); | |
5549 GotoUnless(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss); | |
5550 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); | |
5551 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); | |
5552 GotoUnless( | |
5553 WordEqual( | |
5554 LoadObjectField(protector_cell, PropertyCell::kValueOffset), | |
5555 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), | |
5556 miss); | |
5557 Return(UndefinedConstant()); | |
5558 } | |
5559 | |
5560 Bind(&property); | |
5561 Comment("property_load"); | |
5562 } | |
5563 | |
5564 Label constant(this), field(this); | |
5565 Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)), | |
5566 &field, &constant); | |
5567 | |
5568 Bind(&field); | |
5569 { | |
5570 Comment("field_load"); | |
5571 Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word); | |
5572 | |
5573 Label inobject(this), out_of_object(this); | |
5574 Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject, | |
5575 &out_of_object); | |
5576 | |
5577 Bind(&inobject); | |
5578 { | |
5579 Label is_double(this); | |
5580 GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); | |
5581 Return(LoadObjectField(holder, offset)); | |
5582 | |
5583 Bind(&is_double); | |
5584 if (FLAG_unbox_double_fields) { | |
5585 var_double_value.Bind( | |
5586 LoadObjectField(holder, offset, MachineType::Float64())); | |
5587 } else { | |
5588 Node* mutable_heap_number = LoadObjectField(holder, offset); | |
5589 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); | |
5590 } | |
5591 Goto(&rebox_double); | |
5592 } | |
5593 | |
5594 Bind(&out_of_object); | |
5595 { | |
5596 Label is_double(this); | |
5597 Node* properties = LoadProperties(holder); | |
5598 Node* value = LoadObjectField(properties, offset); | |
5599 GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); | |
5600 Return(value); | |
5601 | |
5602 Bind(&is_double); | |
5603 var_double_value.Bind(LoadHeapNumberValue(value)); | |
5604 Goto(&rebox_double); | |
5605 } | |
5606 | |
5607 Bind(&rebox_double); | |
5608 Return(AllocateHeapNumberWithValue(var_double_value.value())); | |
5609 } | |
5610 | |
5611 Bind(&constant); | |
5612 { | |
5613 Comment("constant_load"); | |
5614 Node* descriptors = LoadMapDescriptors(LoadMap(holder)); | |
5615 Node* descriptor = | |
5616 DecodeWord<LoadHandler::DescriptorValueIndexBits>(handler_word); | |
5617 #if defined(DEBUG) | |
Igor Sheludko
2016/11/14 18:08:54
I only removed this #ifdef.
| |
5618 CSA_ASSERT( | |
5619 this, UintPtrLessThan(descriptor, | |
5620 LoadAndUntagFixedArrayBaseLength(descriptors))); | |
5621 #endif | |
5622 Node* value = | |
5623 LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS); | |
5624 | |
5625 Label if_accessor_info(this); | |
5626 GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word), | |
5627 &if_accessor_info); | |
5628 Return(value); | |
5629 | |
5630 Bind(&if_accessor_info); | |
5631 Callable callable = CodeFactory::ApiGetter(isolate()); | |
5632 TailCallStub(callable, p->context, p->receiver, holder, value); | |
5633 } | |
5634 } | 5514 } |
5635 | 5515 |
5636 Bind(&try_proto_handler); | 5516 Bind(&try_proto_handler); |
5637 { | 5517 { |
5638 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); | 5518 GotoIf(IsCodeMap(LoadMap(handler)), &call_handler); |
5639 HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler, | 5519 HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler, |
5640 &if_smi_handler, miss); | 5520 &if_smi_handler, miss); |
5641 } | 5521 } |
5642 | 5522 |
5643 Bind(&call_handler); | 5523 Bind(&call_handler); |
5644 { | 5524 { |
5645 typedef LoadWithVectorDescriptor Descriptor; | 5525 typedef LoadWithVectorDescriptor Descriptor; |
5646 TailCallStub(Descriptor(isolate()), handler, p->context, | 5526 TailCallStub(Descriptor(isolate()), handler, p->context, |
5647 Arg(Descriptor::kReceiver, p->receiver), | 5527 Arg(Descriptor::kReceiver, p->receiver), |
5648 Arg(Descriptor::kName, p->name), | 5528 Arg(Descriptor::kName, p->name), |
5649 Arg(Descriptor::kSlot, p->slot), | 5529 Arg(Descriptor::kSlot, p->slot), |
5650 Arg(Descriptor::kVector, p->vector)); | 5530 Arg(Descriptor::kVector, p->vector)); |
5651 } | 5531 } |
5652 } | 5532 } |
5653 | 5533 |
5534 void CodeStubAssembler::HandleLoadICSmiHandlerCase( | |
5535 const LoadICParameters* p, Node* holder, Node* smi_handler, Label* miss, | |
5536 ElementSupport support_elements) { | |
5537 Variable var_double_value(this, MachineRepresentation::kFloat64); | |
5538 Label rebox_double(this, &var_double_value); | |
5539 | |
5540 Node* handler_word = SmiUntag(smi_handler); | |
5541 Node* handler_kind = DecodeWord<LoadHandler::KindBits>(handler_word); | |
5542 if (support_elements == kSupportElements) { | |
5543 Label property(this); | |
5544 GotoUnless( | |
5545 WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForElements)), | |
5546 &property); | |
5547 | |
5548 Comment("element_load"); | |
5549 Node* intptr_index = TryToIntptr(p->name, miss); | |
5550 Node* elements = LoadElements(holder); | |
5551 Node* is_jsarray_condition = | |
5552 IsSetWord<LoadHandler::IsJsArrayBits>(handler_word); | |
5553 Node* elements_kind = | |
5554 DecodeWord<LoadHandler::ElementsKindBits>(handler_word); | |
5555 Label if_hole(this), unimplemented_elements_kind(this); | |
5556 Label* out_of_bounds = miss; | |
5557 EmitElementLoad(holder, elements, elements_kind, intptr_index, | |
5558 is_jsarray_condition, &if_hole, &rebox_double, | |
5559 &var_double_value, &unimplemented_elements_kind, | |
5560 out_of_bounds, miss); | |
5561 | |
5562 Bind(&unimplemented_elements_kind); | |
5563 { | |
5564 // Smi handlers should only be installed for supported elements kinds. | |
5565 // Crash if we get here. | |
5566 DebugBreak(); | |
5567 Goto(miss); | |
5568 } | |
5569 | |
5570 Bind(&if_hole); | |
5571 { | |
5572 Comment("convert hole"); | |
5573 GotoUnless(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss); | |
5574 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); | |
5575 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); | |
5576 GotoUnless( | |
5577 WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), | |
5578 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), | |
5579 miss); | |
5580 Return(UndefinedConstant()); | |
5581 } | |
5582 | |
5583 Bind(&property); | |
5584 Comment("property_load"); | |
5585 } | |
5586 | |
5587 Label constant(this), field(this); | |
5588 Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kForFields)), | |
5589 &field, &constant); | |
5590 | |
5591 Bind(&field); | |
5592 { | |
5593 Comment("field_load"); | |
5594 Node* offset = DecodeWord<LoadHandler::FieldOffsetBits>(handler_word); | |
5595 | |
5596 Label inobject(this), out_of_object(this); | |
5597 Branch(IsSetWord<LoadHandler::IsInobjectBits>(handler_word), &inobject, | |
5598 &out_of_object); | |
5599 | |
5600 Bind(&inobject); | |
5601 { | |
5602 Label is_double(this); | |
5603 GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); | |
5604 Return(LoadObjectField(holder, offset)); | |
5605 | |
5606 Bind(&is_double); | |
5607 if (FLAG_unbox_double_fields) { | |
5608 var_double_value.Bind( | |
5609 LoadObjectField(holder, offset, MachineType::Float64())); | |
5610 } else { | |
5611 Node* mutable_heap_number = LoadObjectField(holder, offset); | |
5612 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); | |
5613 } | |
5614 Goto(&rebox_double); | |
5615 } | |
5616 | |
5617 Bind(&out_of_object); | |
5618 { | |
5619 Label is_double(this); | |
5620 Node* properties = LoadProperties(holder); | |
5621 Node* value = LoadObjectField(properties, offset); | |
5622 GotoIf(IsSetWord<LoadHandler::IsDoubleBits>(handler_word), &is_double); | |
5623 Return(value); | |
5624 | |
5625 Bind(&is_double); | |
5626 var_double_value.Bind(LoadHeapNumberValue(value)); | |
5627 Goto(&rebox_double); | |
5628 } | |
5629 | |
5630 Bind(&rebox_double); | |
5631 Return(AllocateHeapNumberWithValue(var_double_value.value())); | |
5632 } | |
5633 | |
5634 Bind(&constant); | |
5635 { | |
5636 Comment("constant_load"); | |
5637 Node* descriptors = LoadMapDescriptors(LoadMap(holder)); | |
5638 Node* descriptor = | |
5639 DecodeWord<LoadHandler::DescriptorValueIndexBits>(handler_word); | |
5640 CSA_ASSERT(this, | |
5641 UintPtrLessThan(descriptor, | |
5642 LoadAndUntagFixedArrayBaseLength(descriptors))); | |
5643 Node* value = | |
5644 LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS); | |
5645 | |
5646 Label if_accessor_info(this); | |
5647 GotoIf(IsSetWord<LoadHandler::IsAccessorInfoBits>(handler_word), | |
5648 &if_accessor_info); | |
5649 Return(value); | |
5650 | |
5651 Bind(&if_accessor_info); | |
5652 Callable callable = CodeFactory::ApiGetter(isolate()); | |
5653 TailCallStub(callable, p->context, p->receiver, holder, value); | |
5654 } | |
5655 } | |
5656 | |
5654 void CodeStubAssembler::HandleLoadICProtoHandler( | 5657 void CodeStubAssembler::HandleLoadICProtoHandler( |
5655 const LoadICParameters* p, Node* handler, Variable* var_holder, | 5658 const LoadICParameters* p, Node* handler, Variable* var_holder, |
5656 Variable* var_smi_handler, Label* if_smi_handler, Label* miss) { | 5659 Variable* var_smi_handler, Label* if_smi_handler, Label* miss) { |
5657 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); | 5660 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); |
5658 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); | 5661 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); |
5659 | 5662 |
5660 // IC dispatchers rely on these assumptions to be held. | 5663 // IC dispatchers rely on these assumptions to be held. |
5661 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); | 5664 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); |
5662 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), | 5665 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), |
5663 LoadHandler::kSmiHandlerOffset); | 5666 LoadHandler::kSmiHandlerOffset); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5710 // both the receiver map check and the validity cell check. | 5713 // both the receiver map check and the validity cell check. |
5711 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); | 5714 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); |
5712 | 5715 |
5713 var_holder->Bind(holder); | 5716 var_holder->Bind(holder); |
5714 var_smi_handler->Bind(smi_handler); | 5717 var_smi_handler->Bind(smi_handler); |
5715 Goto(if_smi_handler); | 5718 Goto(if_smi_handler); |
5716 } | 5719 } |
5717 | 5720 |
5718 Bind(&array_handler); | 5721 Bind(&array_handler); |
5719 { | 5722 { |
5720 Node* length = SmiUntag(maybe_holder_cell); | 5723 Node* handler_length = SmiUntag(maybe_holder_cell); |
5721 | 5724 Node* holder = EmitLoadICProtoArrayCheck(p, handler, handler_length, |
5722 Variable start_index(this, MachineType::PointerRepresentation()); | 5725 handler_flags, miss); |
Igor Sheludko
2016/11/14 18:08:54
This code block now returns a holder.
| |
5723 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); | |
5724 | |
5725 Label can_access(this); | |
5726 GotoUnless( | |
5727 IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags), | |
5728 &can_access); | |
5729 { | |
5730 // Skip this entry of a handler. | |
5731 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex + 1)); | |
5732 | |
5733 int offset = | |
5734 FixedArray::OffsetOfElementAt(LoadHandler::kFirstPrototypeIndex); | |
5735 Node* expected_native_context = | |
5736 LoadWeakCellValue(LoadObjectField(handler, offset), miss); | |
5737 CSA_ASSERT(this, IsNativeContext(expected_native_context)); | |
5738 | |
5739 Node* native_context = LoadNativeContext(p->context); | |
5740 GotoIf(WordEqual(expected_native_context, native_context), &can_access); | |
5741 // If the receiver is not a JSGlobalProxy then we miss. | |
5742 GotoUnless(IsJSGlobalProxy(p->receiver), miss); | |
5743 // For JSGlobalProxy receiver try to compare security tokens of current | |
5744 // and expected native contexts. | |
5745 Node* expected_token = LoadContextElement(expected_native_context, | |
5746 Context::SECURITY_TOKEN_INDEX); | |
5747 Node* current_token = | |
5748 LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX); | |
5749 Branch(WordEqual(expected_token, current_token), &can_access, miss); | |
5750 } | |
5751 Bind(&can_access); | |
5752 | |
5753 BuildFastLoop(MachineType::PointerRepresentation(), start_index.value(), | |
5754 length, | |
5755 [this, p, handler, miss](CodeStubAssembler*, Node* current) { | |
5756 Node* prototype_cell = LoadFixedArrayElement( | |
5757 handler, current, 0, INTPTR_PARAMETERS); | |
5758 CheckPrototype(prototype_cell, p->name, miss); | |
5759 }, | |
5760 1, IndexAdvanceMode::kPost); | |
5761 | |
5762 Node* maybe_holder_cell = LoadFixedArrayElement( | |
5763 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0, | |
5764 INTPTR_PARAMETERS); | |
5765 Label load_existent(this); | |
5766 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); | |
5767 // This is a handler for a load of a non-existent value. | |
5768 Return(UndefinedConstant()); | |
5769 | |
5770 Bind(&load_existent); | |
5771 Node* holder = LoadWeakCellValue(maybe_holder_cell); | |
5772 // The |holder| is guaranteed to be alive at this point since we passed | |
5773 // the receiver map check, the validity cell check and the prototype chain | |
5774 // check. | |
5775 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); | |
5776 | |
5777 var_holder->Bind(holder); | 5726 var_holder->Bind(holder); |
5778 var_smi_handler->Bind(smi_handler); | 5727 var_smi_handler->Bind(smi_handler); |
5779 Goto(if_smi_handler); | 5728 Goto(if_smi_handler); |
5780 } | 5729 } |
5781 } | 5730 } |
5782 | 5731 |
5732 Node* CodeStubAssembler::EmitLoadICProtoArrayCheck(const LoadICParameters* p, | |
5733 Node* handler, | |
5734 Node* handler_length, | |
5735 Node* handler_flags, | |
5736 Label* miss) { | |
5737 Variable start_index(this, MachineType::PointerRepresentation()); | |
5738 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex)); | |
5739 | |
5740 Label can_access(this); | |
5741 GotoUnless(IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_flags), | |
5742 &can_access); | |
5743 { | |
5744 // Skip this entry of a handler. | |
5745 start_index.Bind(IntPtrConstant(LoadHandler::kFirstPrototypeIndex + 1)); | |
5746 | |
5747 int offset = | |
5748 FixedArray::OffsetOfElementAt(LoadHandler::kFirstPrototypeIndex); | |
5749 Node* expected_native_context = | |
5750 LoadWeakCellValue(LoadObjectField(handler, offset), miss); | |
5751 CSA_ASSERT(this, IsNativeContext(expected_native_context)); | |
5752 | |
5753 Node* native_context = LoadNativeContext(p->context); | |
5754 GotoIf(WordEqual(expected_native_context, native_context), &can_access); | |
5755 // If the receiver is not a JSGlobalProxy then we miss. | |
5756 GotoUnless(IsJSGlobalProxy(p->receiver), miss); | |
5757 // For JSGlobalProxy receiver try to compare security tokens of current | |
5758 // and expected native contexts. | |
5759 Node* expected_token = LoadContextElement(expected_native_context, | |
5760 Context::SECURITY_TOKEN_INDEX); | |
5761 Node* current_token = | |
5762 LoadContextElement(native_context, Context::SECURITY_TOKEN_INDEX); | |
5763 Branch(WordEqual(expected_token, current_token), &can_access, miss); | |
5764 } | |
5765 Bind(&can_access); | |
5766 | |
5767 BuildFastLoop( | |
5768 MachineType::PointerRepresentation(), start_index.value(), handler_length, | |
5769 [this, p, handler, miss](CodeStubAssembler*, Node* current) { | |
5770 Node* prototype_cell = | |
5771 LoadFixedArrayElement(handler, current, 0, INTPTR_PARAMETERS); | |
5772 CheckPrototype(prototype_cell, p->name, miss); | |
5773 }, | |
5774 1, IndexAdvanceMode::kPost); | |
5775 | |
5776 Node* maybe_holder_cell = LoadFixedArrayElement( | |
5777 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0, | |
5778 INTPTR_PARAMETERS); | |
5779 Label load_existent(this); | |
5780 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); | |
5781 // This is a handler for a load of a non-existent value. | |
5782 Return(UndefinedConstant()); | |
5783 | |
5784 Bind(&load_existent); | |
5785 Node* holder = LoadWeakCellValue(maybe_holder_cell); | |
5786 // The |holder| is guaranteed to be alive at this point since we passed | |
5787 // the receiver map check, the validity cell check and the prototype chain | |
5788 // check. | |
5789 CSA_ASSERT(this, WordNotEqual(holder, IntPtrConstant(0))); | |
5790 return holder; | |
5791 } | |
5792 | |
5783 void CodeStubAssembler::CheckPrototype(Node* prototype_cell, Node* name, | 5793 void CodeStubAssembler::CheckPrototype(Node* prototype_cell, Node* name, |
5784 Label* miss) { | 5794 Label* miss) { |
5785 Node* maybe_prototype = LoadWeakCellValue(prototype_cell, miss); | 5795 Node* maybe_prototype = LoadWeakCellValue(prototype_cell, miss); |
5786 | 5796 |
5787 Label done(this); | 5797 Label done(this); |
5788 Label if_property_cell(this), if_dictionary_object(this); | 5798 Label if_property_cell(this), if_dictionary_object(this); |
5789 | 5799 |
5790 // |maybe_prototype| is either a PropertyCell or a slow-mode prototype. | 5800 // |maybe_prototype| is either a PropertyCell or a slow-mode prototype. |
5791 Branch(WordEqual(LoadMap(maybe_prototype), | 5801 Branch(WordEqual(LoadMap(maybe_prototype), |
5792 LoadRoot(Heap::kGlobalPropertyCellMapRootIndex)), | 5802 LoadRoot(Heap::kGlobalPropertyCellMapRootIndex)), |
(...skipping 3253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9046 } | 9056 } |
9047 | 9057 |
9048 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 9058 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
9049 assembler_->PopAndReturn( | 9059 assembler_->PopAndReturn( |
9050 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 9060 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
9051 value); | 9061 value); |
9052 } | 9062 } |
9053 | 9063 |
9054 } // namespace internal | 9064 } // namespace internal |
9055 } // namespace v8 | 9065 } // namespace v8 |
OLD | NEW |