Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 546683003: Make KeyedLoads from a sloppy arguments array use a handler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Webkit test found bug, updating. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/code-stubs.cc ('k') | src/elements-kind.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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_HOLEY_ELEMENTS, NEVER_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 // Mapped arguments are actual arguments. Unmapped arguments are values added
634 // to the arguments object after it was created for the call. Mapped arguments
635 // are stored in the context at indexes given by elements[key + 2]. Unmapped
636 // arguments are stored as regular indexed properties in the arguments array,
637 // held at elements[1]. See NewSloppyArguments() in runtime.cc for a detailed
638 // look at argument object construction.
639 //
640 // The sloppy arguments elements array has a special format:
641 //
642 // 0: context
643 // 1: unmapped arguments array
644 // 2: mapped_index0,
645 // 3: mapped_index1,
646 // ...
647 //
648 // length is 2 + min(number_of_actual_arguments, number_of_formal_arguments).
649 // If key + 2 >= elements.length then attempt to look in the unmapped
650 // arguments array (given by elements[1]) and return the value at key, missing
651 // to the runtime if the unmapped arguments array is not a fixed array or if
652 // key >= unmapped_arguments_array.length.
653 //
654 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value
655 // in the unmapped arguments array, as described above. Otherwise, t is a Smi
656 // index into the context array given at elements[0]. Return the value at
657 // context[t].
658
659 key = AddUncasted<HForceRepresentation>(key, Representation::Smi());
660 IfBuilder positive_smi(this);
661 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(),
662 Token::LT);
663 positive_smi.ThenDeopt("key is negative");
664 positive_smi.End();
665
666 HValue* constant_two = Add<HConstant>(2);
667 HValue* elements = AddLoadElements(receiver, static_cast<HValue*>(NULL));
668 HValue* elements_length =
669 Add<HLoadNamedField>(elements, static_cast<HValue*>(NULL),
670 HObjectAccess::ForFixedArrayLength());
671 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two);
672 IfBuilder in_range(this);
673 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT);
674 in_range.Then();
675 {
676 HValue* index = AddUncasted<HAdd>(key, constant_two);
677 HInstruction* mapped_index =
678 Add<HLoadKeyed>(elements, index, static_cast<HValue*>(NULL),
679 FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE);
680
681 IfBuilder is_valid(this);
682 is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index,
683 graph()->GetConstantHole());
684 is_valid.Then();
685 {
686 // TODO(mvstanton): I'd like to assert from this point, that if the
687 // mapped_index is not the hole that it is indeed, a smi. An unnecessary
688 // smi check is being emitted.
689 HValue* the_context =
690 Add<HLoadKeyed>(elements, graph()->GetConstant0(),
691 static_cast<HValue*>(NULL), FAST_ELEMENTS);
692 DCHECK(Context::kHeaderSize == FixedArray::kHeaderSize);
693 HValue* result =
694 Add<HLoadKeyed>(the_context, mapped_index, static_cast<HValue*>(NULL),
695 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
696 environment()->Push(result);
697 }
698 is_valid.Else();
699 {
700 HValue* result = UnmappedCase(elements, key);
701 environment()->Push(result);
702 }
703 is_valid.End();
704 }
705 in_range.Else();
706 {
707 HValue* result = UnmappedCase(elements, key);
708 environment()->Push(result);
709 }
710 in_range.End();
711
712 return environment()->Pop();
713 }
714
715
716 Handle<Code> KeyedLoadSloppyArgumentsStub::GenerateCode() {
717 return DoGenerateCode(this);
718 }
719
720
603 void CodeStubGraphBuilderBase::BuildStoreNamedField( 721 void CodeStubGraphBuilderBase::BuildStoreNamedField(
604 HValue* object, HValue* value, FieldIndex index, 722 HValue* object, HValue* value, FieldIndex index,
605 Representation representation) { 723 Representation representation) {
606 DCHECK(!index.is_double() || representation.IsDouble()); 724 DCHECK(!index.is_double() || representation.IsDouble());
607 int offset = index.offset(); 725 int offset = index.offset();
608 HObjectAccess access = 726 HObjectAccess access =
609 index.is_inobject() 727 index.is_inobject()
610 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) 728 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation)
611 : HObjectAccess::ForBackingStoreOffset(offset, representation); 729 : HObjectAccess::ForBackingStoreOffset(offset, representation);
612 730
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 1203
1086 1204
1087 Handle<Code> ToBooleanStub::GenerateCode() { 1205 Handle<Code> ToBooleanStub::GenerateCode() {
1088 return DoGenerateCode(this); 1206 return DoGenerateCode(this);
1089 } 1207 }
1090 1208
1091 1209
1092 template <> 1210 template <>
1093 HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() { 1211 HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
1094 StoreGlobalStub* stub = casted_stub(); 1212 StoreGlobalStub* stub = casted_stub();
1095 Handle<Object> hole(isolate()->heap()->the_hole_value(), isolate());
1096 Handle<Object> placeholer_value(Smi::FromInt(0), isolate()); 1213 Handle<Object> placeholer_value(Smi::FromInt(0), isolate());
1097 Handle<PropertyCell> placeholder_cell = 1214 Handle<PropertyCell> placeholder_cell =
1098 isolate()->factory()->NewPropertyCell(placeholer_value); 1215 isolate()->factory()->NewPropertyCell(placeholer_value);
1099 1216
1100 HParameter* value = GetParameter(StoreDescriptor::kValueIndex); 1217 HParameter* value = GetParameter(StoreDescriptor::kValueIndex);
1101 1218
1102 if (stub->check_global()) { 1219 if (stub->check_global()) {
1103 // Check that the map of the global has not changed: use a placeholder map 1220 // Check that the map of the global has not changed: use a placeholder map
1104 // that will be replaced later with the global object's map. 1221 // that will be replaced later with the global object's map.
1105 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); 1222 Handle<Map> placeholder_map = isolate()->factory()->meta_map();
(...skipping 11 matching lines...) Expand all
1117 IfBuilder builder(this); 1234 IfBuilder builder(this);
1118 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); 1235 builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
1119 builder.Then(); 1236 builder.Then();
1120 builder.ElseDeopt("Unexpected cell contents in constant global store"); 1237 builder.ElseDeopt("Unexpected cell contents in constant global store");
1121 builder.End(); 1238 builder.End();
1122 } else { 1239 } else {
1123 // Load the payload of the global parameter cell. A hole indicates that the 1240 // Load the payload of the global parameter cell. A hole indicates that the
1124 // property has been deleted and that the store must be handled by the 1241 // property has been deleted and that the store must be handled by the
1125 // runtime. 1242 // runtime.
1126 IfBuilder builder(this); 1243 IfBuilder builder(this);
1127 HValue* hole_value = Add<HConstant>(hole); 1244 HValue* hole_value = graph()->GetConstantHole();
1128 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value); 1245 builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
1129 builder.Then(); 1246 builder.Then();
1130 builder.Deopt("Unexpected cell contents in global store"); 1247 builder.Deopt("Unexpected cell contents in global store");
1131 builder.Else(); 1248 builder.Else();
1132 Add<HStoreNamedField>(cell, access, value); 1249 Add<HStoreNamedField>(cell, access, value);
1133 builder.End(); 1250 builder.End();
1134 } 1251 }
1135 1252
1136 return value; 1253 return value;
1137 } 1254 }
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
1823 1940
1824 // Probe the stub cache. 1941 // Probe the stub cache.
1825 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( 1942 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
1826 Code::ComputeHandlerFlags(Code::LOAD_IC)); 1943 Code::ComputeHandlerFlags(Code::LOAD_IC));
1827 Add<HTailCallThroughMegamorphicCache>(receiver, name, flags); 1944 Add<HTailCallThroughMegamorphicCache>(receiver, name, flags);
1828 1945
1829 // We never continue. 1946 // We never continue.
1830 return graph()->GetConstant0(); 1947 return graph()->GetConstant0();
1831 } 1948 }
1832 } } // namespace v8::internal 1949 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/elements-kind.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698