OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/field-index.h" | 8 #include "src/field-index.h" |
9 #include "src/hydrogen.h" | 9 #include "src/hydrogen.h" |
10 #include "src/lithium.h" | 10 #include "src/lithium.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
64 FieldIndex index); | 64 FieldIndex index); |
65 void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, | 65 void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, |
66 Representation representation); | 66 Representation representation); |
67 | 67 |
68 enum ArgumentClass { | 68 enum ArgumentClass { |
69 NONE, | 69 NONE, |
70 SINGLE, | 70 SINGLE, |
71 MULTIPLE | 71 MULTIPLE |
72 }; | 72 }; |
73 | 73 |
74 HValue* UnmappedCase(HValue* elements, HValue* key); | |
75 | |
74 HValue* BuildArrayConstructor(ElementsKind kind, | 76 HValue* BuildArrayConstructor(ElementsKind kind, |
75 AllocationSiteOverrideMode override_mode, | 77 AllocationSiteOverrideMode override_mode, |
76 ArgumentClass argument_class); | 78 ArgumentClass argument_class); |
77 HValue* BuildInternalArrayConstructor(ElementsKind kind, | 79 HValue* BuildInternalArrayConstructor(ElementsKind kind, |
78 ArgumentClass argument_class); | 80 ArgumentClass argument_class); |
79 | 81 |
80 // BuildCheckAndInstallOptimizedCode emits code to install the optimized | 82 // BuildCheckAndInstallOptimizedCode emits code to install the optimized |
81 // function found in the optimized code map at map_index in js_function, if | 83 // function found in the optimized code map at map_index in js_function, if |
82 // the function at map_index matches the given native_context. Builder is | 84 // the function at map_index matches the given native_context. Builder is |
83 // left in the "Then()" state after the install. | 85 // left in the "Then()" state after the install. |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
593 HObjectAccess value_access = HObjectAccess::ForObservableJSObjectOffset( | 595 HObjectAccess value_access = HObjectAccess::ForObservableJSObjectOffset( |
594 DescriptorArray::GetValueOffset(casted_stub()->constant_index())); | 596 DescriptorArray::GetValueOffset(casted_stub()->constant_index())); |
595 return Add<HLoadNamedField>(descriptors, static_cast<HValue*>(NULL), | 597 return Add<HLoadNamedField>(descriptors, static_cast<HValue*>(NULL), |
596 value_access); | 598 value_access); |
597 } | 599 } |
598 | 600 |
599 | 601 |
600 Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } | 602 Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } |
601 | 603 |
602 | 604 |
605 HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) { | |
606 HValue* result; | |
607 HInstruction* backing_store = Add<HLoadKeyed>( | |
608 elements, graph()->GetConstant1(), static_cast<HValue*>(NULL), | |
609 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | |
610 Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map()); | |
611 HValue* backing_store_length = | |
612 Add<HLoadNamedField>(backing_store, static_cast<HValue*>(NULL), | |
613 HObjectAccess::ForFixedArrayLength()); | |
614 IfBuilder in_unmapped_range(this); | |
615 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length, | |
616 Token::LT); | |
617 in_unmapped_range.Then(); | |
618 { | |
619 result = Add<HLoadKeyed>(backing_store, key, static_cast<HValue*>(NULL), | |
620 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | |
621 } | |
622 in_unmapped_range.ElseDeopt("Outside of range"); | |
623 in_unmapped_range.End(); | |
624 return result; | |
625 } | |
626 | |
627 | |
628 template <> | |
629 HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { | |
630 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); | |
631 HValue* key = GetParameter(LoadDescriptor::kNameIndex); | |
632 | |
633 // | |
Toon Verwaest
2014/09/22 08:29:47
Remove // before and after the block ;)
mvstanton
2014/09/22 10:34:30
This was my attempt to indicate "importance" :D. D
| |
634 // Mapped arguments are actual arguments. Unmapped arguments are values added | |
635 // to the arguments object after it was created for the call. Mapped arguments | |
636 // are stored in the context at indexes given by elements[key + 2]. Unmapped | |
Toon Verwaest
2014/09/22 08:29:47
Space too many before Unmapped.
mvstanton
2014/09/22 10:34:30
Done.
| |
637 // arguments are stored as regular indexed properties in the arguments array, | |
638 // held at elements[1]. See NewSloppyArguments() in runtime.cc for a detailed | |
639 // look at argument object construction. | |
640 // | |
641 // The sloppy arguments elements array has a special format: | |
642 // | |
643 // 0: context | |
644 // 1: unmapped arguments array | |
645 // 2: mapped_index0, | |
646 // 3: mapped_index1, | |
647 // ... | |
648 // | |
649 // length is 2 + min(number_of_actual_arguments, number_of_formal_arguments). | |
650 // If key + 2 >= elements.length then attempt to look in the unmapped | |
651 // arguments array (given by elements[1]) and return the value at key, missing | |
652 // to the runtime if the unmapped arguments array is not a fixed array or if | |
653 // key >= unmapped_arguments_array.length. | |
654 // | |
655 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value | |
656 // in the unmapped arguments array, as described above. Otherwise, t is a Smi | |
657 // index into the context array given at elements[0]. Return the value at | |
658 // context[t]. | |
659 // | |
660 | |
661 key = AddUncasted<HForceRepresentation>(key, Representation::Smi()); | |
662 IfBuilder positive_smi(this); | |
663 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(), | |
Toon Verwaest
2014/09/22 08:29:47
Mmh you compare
key < 0 && key < length - 2
but th
mvstanton
2014/09/22 10:34:30
As we just talked over, there is an add right befo
| |
664 Token::LT); | |
665 positive_smi.ThenDeopt("key is negative"); | |
666 positive_smi.End(); | |
667 | |
668 HValue* constant_two = Add<HConstant>(2); | |
669 HValue* elements = AddLoadElements(receiver, static_cast<HValue*>(NULL)); | |
670 HValue* elements_length = | |
671 Add<HLoadNamedField>(elements, static_cast<HValue*>(NULL), | |
672 HObjectAccess::ForFixedArrayLength()); | |
673 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two); | |
674 IfBuilder in_range(this); | |
675 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT); | |
676 in_range.Then(); | |
677 { | |
678 HValue* index = AddUncasted<HAdd>(key, constant_two); | |
679 HInstruction* mapped_index = | |
680 Add<HLoadKeyed>(elements, index, static_cast<HValue*>(NULL), | |
681 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | |
682 | |
683 IfBuilder is_valid(this); | |
684 Handle<Object> hole(isolate()->heap()->the_hole_value(), isolate()); | |
Toon Verwaest
2014/09/22 08:29:47
isolate->factory()->the_hole_value() is already a
mvstanton
2014/09/22 10:34:30
Done. And I fixed another place in this file with
| |
685 HValue* hole_value = Add<HConstant>(hole); | |
686 is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index, hole_value); | |
687 is_valid.Then(); | |
688 { | |
689 // TODO(mvstanton): I'd like to assert from this point, that if the | |
690 // mapped_index is not the hole that it is indeed, a smi. An unnecessary | |
691 // smi check is being emitted. | |
692 HValue* the_context = | |
693 Add<HLoadKeyed>(elements, graph()->GetConstant0(), | |
694 static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
695 DCHECK(Context::kHeaderSize == FixedArray::kHeaderSize); | |
696 HValue* result = | |
697 Add<HLoadKeyed>(the_context, mapped_index, static_cast<HValue*>(NULL), | |
698 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | |
699 environment()->Push(result); | |
700 } | |
701 is_valid.Else(); | |
702 { | |
703 HValue* result = UnmappedCase(elements, key); | |
704 environment()->Push(result); | |
705 } | |
706 is_valid.End(); | |
707 } | |
708 in_range.Else(); | |
709 { | |
710 HValue* result = UnmappedCase(elements, key); | |
711 environment()->Push(result); | |
712 } | |
713 in_range.End(); | |
714 | |
715 return environment()->Pop(); | |
716 } | |
717 | |
718 | |
719 Handle<Code> KeyedLoadSloppyArgumentsStub::GenerateCode() { | |
720 return DoGenerateCode(this); | |
721 } | |
722 | |
723 | |
603 void CodeStubGraphBuilderBase::BuildStoreNamedField( | 724 void CodeStubGraphBuilderBase::BuildStoreNamedField( |
604 HValue* object, HValue* value, FieldIndex index, | 725 HValue* object, HValue* value, FieldIndex index, |
605 Representation representation) { | 726 Representation representation) { |
606 DCHECK(!index.is_double() || representation.IsDouble()); | 727 DCHECK(!index.is_double() || representation.IsDouble()); |
607 int offset = index.offset(); | 728 int offset = index.offset(); |
608 HObjectAccess access = | 729 HObjectAccess access = |
609 index.is_inobject() | 730 index.is_inobject() |
610 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) | 731 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) |
611 : HObjectAccess::ForBackingStoreOffset(offset, representation); | 732 : HObjectAccess::ForBackingStoreOffset(offset, representation); |
612 | 733 |
(...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1823 | 1944 |
1824 // Probe the stub cache. | 1945 // Probe the stub cache. |
1825 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 1946 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
1826 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 1947 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
1827 Add<HTailCallThroughMegamorphicCache>(receiver, name, flags); | 1948 Add<HTailCallThroughMegamorphicCache>(receiver, name, flags); |
1828 | 1949 |
1829 // We never continue. | 1950 // We never continue. |
1830 return graph()->GetConstant0(); | 1951 return graph()->GetConstant0(); |
1831 } | 1952 } |
1832 } } // namespace v8::internal | 1953 } } // namespace v8::internal |
OLD | NEW |