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