Chromium Code Reviews| 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 |