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

Side by Side Diff: src/hydrogen.cc

Issue 18503006: Move representation into HObjectAccess and remove from HLoadNamedField and HStoreNamedField. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Cleanups after first round of comments; FixedArrayLength is always Smi Created 7 years, 5 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 capacity_checker.Else(); 1166 capacity_checker.Else();
1167 1167
1168 environment()->Push(elements); 1168 environment()->Push(elements);
1169 capacity_checker.End(); 1169 capacity_checker.End();
1170 1170
1171 if (is_js_array) { 1171 if (is_js_array) {
1172 HValue* new_length = AddInstruction( 1172 HValue* new_length = AddInstruction(
1173 HAdd::New(zone, context, length, graph_->GetConstant1())); 1173 HAdd::New(zone, context, length, graph_->GetConstant1()));
1174 new_length->ClearFlag(HValue::kCanOverflow); 1174 new_length->ClearFlag(HValue::kCanOverflow);
1175 1175
1176 Representation representation = IsFastElementsKind(kind) 1176 AddStore(object, HObjectAccess::ForArrayLength(IsFastElementsKind(kind)),
1177 ? Representation::Smi() : Representation::Tagged(); 1177 new_length);
1178 AddStore(object, HObjectAccess::ForArrayLength(), new_length,
1179 representation);
1180 } 1178 }
1181 1179
1182 length_checker.Else(); 1180 length_checker.Else();
1183 1181
1184 Add<HBoundsCheck>(key, length); 1182 Add<HBoundsCheck>(key, length);
1185 environment()->Push(elements); 1183 environment()->Push(elements);
1186 1184
1187 length_checker.End(); 1185 length_checker.End();
1188 1186
1189 return environment()->Pop(); 1187 return environment()->Pop();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 HValue* elements = AddLoadElements(object, mapcheck); 1245 HValue* elements = AddLoadElements(object, mapcheck);
1248 if (is_store && (fast_elements || fast_smi_only_elements) && 1246 if (is_store && (fast_elements || fast_smi_only_elements) &&
1249 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1247 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1250 HCheckMaps* check_cow_map = HCheckMaps::New( 1248 HCheckMaps* check_cow_map = HCheckMaps::New(
1251 elements, isolate()->factory()->fixed_array_map(), zone); 1249 elements, isolate()->factory()->fixed_array_map(), zone);
1252 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1250 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1253 AddInstruction(check_cow_map); 1251 AddInstruction(check_cow_map);
1254 } 1252 }
1255 HInstruction* length = NULL; 1253 HInstruction* length = NULL;
1256 if (is_js_array) { 1254 if (is_js_array) {
1257 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, 1255 length = AddLoad(object, HObjectAccess::ForArrayLength(true), mapcheck);
1258 Representation::Smi());
1259 } else { 1256 } else {
1260 length = AddLoadFixedArrayLength(elements); 1257 length = AddLoadFixedArrayLength(elements);
1261 } 1258 }
1262 length->set_type(HType::Smi()); 1259 length->set_type(HType::Smi());
1263 HValue* checked_key = NULL; 1260 HValue* checked_key = NULL;
1264 if (IsExternalArrayElementsKind(elements_kind)) { 1261 if (IsExternalArrayElementsKind(elements_kind)) {
1265 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1262 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1266 NoObservableSideEffectsScope no_effects(this); 1263 NoObservableSideEffectsScope no_effects(this);
1267 HLoadExternalArrayPointer* external_elements = 1264 HLoadExternalArrayPointer* external_elements =
1268 Add<HLoadExternalArrayPointer>(elements); 1265 Add<HLoadExternalArrayPointer>(elements);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 1363
1367 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 1364 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
1368 ElementsKind kind, 1365 ElementsKind kind,
1369 HValue* capacity) { 1366 HValue* capacity) {
1370 Factory* factory = isolate()->factory(); 1367 Factory* factory = isolate()->factory();
1371 Handle<Map> map = IsFastDoubleElementsKind(kind) 1368 Handle<Map> map = IsFastDoubleElementsKind(kind)
1372 ? factory->fixed_double_array_map() 1369 ? factory->fixed_double_array_map()
1373 : factory->fixed_array_map(); 1370 : factory->fixed_array_map();
1374 1371
1375 AddStoreMapConstant(elements, map); 1372 AddStoreMapConstant(elements, map);
1376 Representation representation = IsFastElementsKind(kind) 1373 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity);
1377 ? Representation::Smi() : Representation::Tagged();
1378 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity,
1379 representation);
1380 } 1374 }
1381 1375
1382 1376
1383 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 1377 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
1384 HValue* context, 1378 HValue* context,
1385 ElementsKind kind, 1379 ElementsKind kind,
1386 HValue* capacity) { 1380 HValue* capacity) {
1387 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1381 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1388 BuildInitializeElementsHeader(new_elements, kind, capacity); 1382 BuildInitializeElementsHeader(new_elements, kind, capacity);
1389 return new_elements; 1383 return new_elements;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 } 1417 }
1424 1418
1425 1419
1426 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 1420 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
1427 HValue* typecheck) { 1421 HValue* typecheck) {
1428 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); 1422 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck);
1429 } 1423 }
1430 1424
1431 1425
1432 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { 1426 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
1433 HLoadNamedField* instr = AddLoad(object, HObjectAccess::ForFixedArrayLength(), 1427 return AddLoad(object, HObjectAccess::ForFixedArrayLength());
1434 NULL, Representation::Smi());
1435 instr->set_type(HType::Smi());
1436 return instr;
1437 } 1428 }
1438 1429
1439 1430
1440 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1431 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
1441 HValue* old_capacity) { 1432 HValue* old_capacity) {
1442 Zone* zone = this->zone(); 1433 Zone* zone = this->zone();
1443 HValue* half_old_capacity = 1434 HValue* half_old_capacity =
1444 AddInstruction(HShr::New(zone, context, old_capacity, 1435 AddInstruction(HShr::New(zone, context, old_capacity,
1445 graph_->GetConstant1())); 1436 graph_->GetConstant1()));
1446 half_old_capacity->ClearFlag(HValue::kCanOverflow); 1437 half_old_capacity->ClearFlag(HValue::kCanOverflow);
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 allocation_site_payload_(NULL), 1787 allocation_site_payload_(NULL),
1797 constructor_function_(constructor_function) { 1788 constructor_function_(constructor_function) {
1798 } 1789 }
1799 1790
1800 1791
1801 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1792 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1802 if (kind_ == GetInitialFastElementsKind()) { 1793 if (kind_ == GetInitialFastElementsKind()) {
1803 // No need for a context lookup if the kind_ matches the initial 1794 // No need for a context lookup if the kind_ matches the initial
1804 // map, because we can just load the map in that case. 1795 // map, because we can just load the map in that case.
1805 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1796 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1806 HInstruction* load = 1797 return builder()->AddInstruction(
1807 builder()->BuildLoadNamedField(constructor_function_, 1798 builder()->BuildLoadNamedField(constructor_function_, access));
1808 access,
1809 Representation::Tagged());
1810 return builder()->AddInstruction(load);
1811 } 1799 }
1812 1800
1813 HInstruction* native_context = builder()->BuildGetNativeContext(context); 1801 HInstruction* native_context = builder()->BuildGetNativeContext(context);
1814 HInstruction* index = builder()->Add<HConstant>( 1802 HInstruction* index = builder()->Add<HConstant>(
1815 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 1803 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
1816 1804
1817 HInstruction* map_array = builder()->Add<HLoadKeyed>( 1805 HInstruction* map_array = builder()->Add<HLoadKeyed>(
1818 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1806 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1819 1807
1820 HInstruction* kind_index = builder()->Add<HConstant>(kind_); 1808 HInstruction* kind_index = builder()->Add<HConstant>(kind_);
1821 1809
1822 return builder()->Add<HLoadKeyed>( 1810 return builder()->Add<HLoadKeyed>(
1823 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1811 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1824 } 1812 }
1825 1813
1826 1814
1827 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 1815 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
1828 // Find the map near the constructor function 1816 // Find the map near the constructor function
1829 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1817 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1830 return builder()->AddInstruction( 1818 return builder()->AddInstruction(
1831 builder()->BuildLoadNamedField(constructor_function_, 1819 builder()->BuildLoadNamedField(constructor_function_, access));
1832 access,
1833 Representation::Tagged()));
1834 } 1820 }
1835 1821
1836 1822
1837 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1823 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1838 HValue* length_node) { 1824 HValue* length_node) {
1839 HValue* context = builder()->environment()->LookupContext(); 1825 HValue* context = builder()->environment()->LookupContext();
1840 ASSERT(length_node != NULL); 1826 ASSERT(length_node != NULL);
1841 1827
1842 int base_size = JSArray::kSize; 1828 int base_size = JSArray::kSize;
1843 if (mode_ == TRACK_ALLOCATION_SITE) { 1829 if (mode_ == TRACK_ALLOCATION_SITE) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, 1914 builder()->BuildFillElementsWithHole(context, elements_location_, kind_,
1929 graph()->GetConstant0(), capacity); 1915 graph()->GetConstant0(), capacity);
1930 } 1916 }
1931 1917
1932 return new_object; 1918 return new_object;
1933 } 1919 }
1934 1920
1935 1921
1936 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, 1922 HStoreNamedField* HGraphBuilder::AddStore(HValue *object,
1937 HObjectAccess access, 1923 HObjectAccess access,
1938 HValue *val, 1924 HValue *val) {
1939 Representation representation) { 1925 return Add<HStoreNamedField>(object, access, val);
1940 return Add<HStoreNamedField>(object, access, val, representation);
1941 } 1926 }
1942 1927
1943 1928
1944 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, 1929 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object,
1945 HObjectAccess access, 1930 HObjectAccess access,
1946 HValue *typecheck, 1931 HValue *typecheck) {
1947 Representation representation) { 1932 return Add<HLoadNamedField>(object, access, typecheck);
1948 return Add<HLoadNamedField>(object, access, typecheck, representation);
1949 } 1933 }
1950 1934
1951 1935
1952 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, 1936 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
1953 Handle<Map> map) { 1937 Handle<Map> map) {
1954 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), 1938 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
1955 Add<HConstant>(map)); 1939 Add<HConstant>(map));
1956 } 1940 }
1957 1941
1958 1942
(...skipping 2827 matching lines...) Expand 10 before | Expand all | Expand 10 after
4786 if (!is_store) return false; 4770 if (!is_store) return false;
4787 4771
4788 // 2nd chance: A store into a non-existent field can still be inlined if we 4772 // 2nd chance: A store into a non-existent field can still be inlined if we
4789 // have a matching transition and some room left in the object. 4773 // have a matching transition and some room left in the object.
4790 type->LookupTransition(NULL, *name, lookup); 4774 type->LookupTransition(NULL, *name, lookup);
4791 return lookup->IsTransitionToField(*type) && 4775 return lookup->IsTransitionToField(*type) &&
4792 (type->unused_property_fields() > 0); 4776 (type->unused_property_fields() > 0);
4793 } 4777 }
4794 4778
4795 4779
4796 static Representation ComputeLoadStoreRepresentation(Handle<Map> type,
4797 LookupResult* lookup) {
4798 if (lookup->IsField()) {
4799 return lookup->representation();
4800 } else {
4801 Map* transition = lookup->GetTransitionMapFromMap(*type);
4802 int descriptor = transition->LastAdded();
4803 PropertyDetails details =
4804 transition->instance_descriptors()->GetDetails(descriptor);
4805 return details.representation();
4806 }
4807 }
4808
4809
4810 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { 4780 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
4811 BuildCheckHeapObject(object); 4781 BuildCheckHeapObject(object);
4812 AddInstruction(HCheckMaps::New(object, map, zone())); 4782 AddInstruction(HCheckMaps::New(object, map, zone()));
4813 } 4783 }
4814 4784
4815 4785
4816 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, 4786 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
4817 Handle<Map> map) { 4787 Handle<Map> map) {
4818 BuildCheckHeapObject(object); 4788 BuildCheckHeapObject(object);
4819 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); 4789 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
(...skipping 30 matching lines...) Expand all
4850 } 4820 }
4851 ASSERT(proto->GetPrototype(isolate())->IsNull()); 4821 ASSERT(proto->GetPrototype(isolate())->IsNull());
4852 } 4822 }
4853 ASSERT(proto->IsJSObject()); 4823 ASSERT(proto->IsJSObject());
4854 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), 4824 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())),
4855 Handle<JSObject>(JSObject::cast(proto)), 4825 Handle<JSObject>(JSObject::cast(proto)),
4856 zone(), top_info()); 4826 zone(), top_info());
4857 } 4827 }
4858 4828
4859 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); 4829 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
4860 Representation representation = ComputeLoadStoreRepresentation(map, lookup);
4861 bool transition_to_field = lookup->IsTransitionToField(*map); 4830 bool transition_to_field = lookup->IsTransitionToField(*map);
4862 4831
4863 HStoreNamedField *instr; 4832 HStoreNamedField *instr;
4864 if (FLAG_track_double_fields && representation.IsDouble()) { 4833 if (FLAG_track_double_fields && field_access.representation().IsDouble()) {
4834 HObjectAccess heap_number_access =
4835 field_access.WithRepresentation(Representation::Tagged());
4865 if (transition_to_field) { 4836 if (transition_to_field) {
4866 // The store requires a mutable HeapNumber to be allocated. 4837 // The store requires a mutable HeapNumber to be allocated.
4867 NoObservableSideEffectsScope no_side_effects(this); 4838 NoObservableSideEffectsScope no_side_effects(this);
4868 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 4839 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
4869 HInstruction* double_box = Add<HAllocate>( 4840 HInstruction* heap_number = Add<HAllocate>(
4870 environment()->LookupContext(), heap_number_size, 4841 environment()->LookupContext(), heap_number_size,
4871 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); 4842 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE);
4872 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); 4843 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
4873 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 4844 AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value);
4874 value, Representation::Double()); 4845 instr = new(zone()) HStoreNamedField(
4875 instr = new(zone()) HStoreNamedField(object, field_access, double_box); 4846 object, heap_number_access, heap_number);
4876 } else { 4847 } else {
4877 // Already holds a HeapNumber; load the box and write its value field. 4848 // Already holds a HeapNumber; load the box and write its value field.
4878 HInstruction* double_box = AddLoad(object, field_access); 4849 HInstruction* heap_number = AddLoad(object, heap_number_access);
4879 double_box->set_type(HType::HeapNumber()); 4850 heap_number->set_type(HType::HeapNumber());
4880 instr = new(zone()) HStoreNamedField(double_box, 4851 instr = new(zone()) HStoreNamedField(heap_number,
4881 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); 4852 HObjectAccess::ForHeapNumberValue(), value);
4882 } 4853 }
4883 } else { 4854 } else {
4884 // This is a non-double store. 4855 // This is a normal store.
4885 instr = new(zone()) HStoreNamedField( 4856 instr = new(zone()) HStoreNamedField(object, field_access, value);
4886 object, field_access, value, representation);
4887 } 4857 }
4888 4858
4889 if (transition_to_field) { 4859 if (transition_to_field) {
4890 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 4860 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
4891 instr->SetTransition(transition, top_info()); 4861 instr->SetTransition(transition, top_info());
4892 // TODO(fschneider): Record the new map type of the object in the IR to 4862 // TODO(fschneider): Record the new map type of the object in the IR to
4893 // enable elimination of redundant checks after the transition store. 4863 // enable elimination of redundant checks after the transition store.
4894 instr->SetGVNFlag(kChangesMaps); 4864 instr->SetGVNFlag(kChangesMaps);
4895 } 4865 }
4896 return instr; 4866 return instr;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4945 Property* expr, 4915 Property* expr,
4946 HValue* object, 4916 HValue* object,
4947 SmallMapList* types, 4917 SmallMapList* types,
4948 Handle<String> name) { 4918 Handle<String> name) {
4949 // Use monomorphic load if property lookup results in the same field index 4919 // Use monomorphic load if property lookup results in the same field index
4950 // for all maps. Requires special map check on the set of all handled maps. 4920 // for all maps. Requires special map check on the set of all handled maps.
4951 if (types->length() > kMaxLoadPolymorphism) return NULL; 4921 if (types->length() > kMaxLoadPolymorphism) return NULL;
4952 4922
4953 LookupResult lookup(isolate()); 4923 LookupResult lookup(isolate());
4954 int count; 4924 int count;
4955 Representation representation = Representation::None();
4956 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 4925 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
4957 for (count = 0; count < types->length(); ++count) { 4926 for (count = 0; count < types->length(); ++count) {
4958 Handle<Map> map = types->at(count); 4927 Handle<Map> map = types->at(count);
4959 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 4928 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
4960 4929
4961 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 4930 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
4962 Representation new_representation =
4963 ComputeLoadStoreRepresentation(map, &lookup);
4964 4931
4965 if (count == 0) { 4932 if (count == 0) {
4966 // First time through the loop; set access and representation. 4933 // First time through the loop; set access and representation.
4967 access = new_access; 4934 access = new_access;
4968 } else if (!representation.IsCompatibleForLoad(new_representation)) { 4935 } else if (!access.representation().IsCompatibleForLoad(
4936 new_access.representation())) {
4969 // Representations did not match. 4937 // Representations did not match.
4970 break; 4938 break;
4971 } else if (access.offset() != new_access.offset()) { 4939 } else if (access.offset() != new_access.offset()) {
4972 // Offsets did not match. 4940 // Offsets did not match.
4973 break; 4941 break;
4974 } else if (access.IsInobject() != new_access.IsInobject()) { 4942 } else if (access.IsInobject() != new_access.IsInobject()) {
4975 // In-objectness did not match. 4943 // In-objectness did not match.
4976 break; 4944 break;
4977 } 4945 }
4978 representation = representation.generalize(new_representation); 4946 access = access.WithRepresentation(
4947 access.representation().generalize(new_access.representation()));
4979 } 4948 }
4980 4949
4981 if (count == types->length()) { 4950 if (count == types->length()) {
4982 // Everything matched; can use monomorphic load. 4951 // Everything matched; can use monomorphic load.
4983 BuildCheckHeapObject(object); 4952 BuildCheckHeapObject(object);
4984 AddInstruction(HCheckMaps::New(object, types, zone())); 4953 AddInstruction(HCheckMaps::New(object, types, zone()));
4985 return BuildLoadNamedField(object, access, representation); 4954 return BuildLoadNamedField(object, access);
4986 } 4955 }
4987 4956
4988 if (count != 0) return NULL; 4957 if (count != 0) return NULL;
4989 4958
4990 // Second chance: the property is on the prototype and all maps have the 4959 // Second chance: the property is on the prototype and all maps have the
4991 // same prototype. 4960 // same prototype.
4992 Handle<Map> map(types->at(0)); 4961 Handle<Map> map(types->at(0));
4993 if (map->has_named_interceptor()) return NULL; 4962 if (map->has_named_interceptor()) return NULL;
4994 if (map->is_dictionary_map()) return NULL; 4963 if (map->is_dictionary_map()) return NULL;
4995 4964
4996 Handle<Object> prototype(map->prototype(), isolate()); 4965 Handle<Object> prototype(map->prototype(), isolate());
4997 for (count = 1; count < types->length(); ++count) { 4966 for (count = 1; count < types->length(); ++count) {
4998 Handle<Map> test_map(types->at(count)); 4967 Handle<Map> test_map(types->at(count));
4999 // Ensure the property is on the prototype, not the object itself. 4968 // Ensure the property is on the prototype, not the object itself.
5000 if (map->has_named_interceptor()) return NULL; 4969 if (map->has_named_interceptor()) return NULL;
5001 if (test_map->is_dictionary_map()) return NULL; 4970 if (test_map->is_dictionary_map()) return NULL;
5002 test_map->LookupDescriptor(NULL, *name, &lookup); 4971 test_map->LookupDescriptor(NULL, *name, &lookup);
5003 if (lookup.IsFound()) return NULL; 4972 if (lookup.IsFound()) return NULL;
5004 if (test_map->prototype() != *prototype) return NULL; 4973 if (test_map->prototype() != *prototype) return NULL;
5005 } 4974 }
5006 4975
5007 LookupInPrototypes(map, name, &lookup); 4976 LookupInPrototypes(map, name, &lookup);
5008 if (!lookup.IsField()) return NULL; 4977 if (!lookup.IsField()) return NULL;
5009 4978
5010 BuildCheckHeapObject(object); 4979 BuildCheckHeapObject(object);
5011 AddInstruction(HCheckMaps::New(object, types, zone())); 4980 AddInstruction(HCheckMaps::New(object, types, zone()));
4981
5012 Handle<JSObject> holder(lookup.holder()); 4982 Handle<JSObject> holder(lookup.holder());
5013 Handle<Map> holder_map(holder->map()); 4983 Handle<Map> holder_map(holder->map());
5014 AddInstruction(new(zone()) HCheckPrototypeMaps( 4984 AddInstruction(new(zone()) HCheckPrototypeMaps(
5015 Handle<JSObject>::cast(prototype), holder, zone(), top_info())); 4985 Handle<JSObject>::cast(prototype), holder, zone(), top_info()));
5016 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); 4986 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder));
5017 return BuildLoadNamedField(holder_value, 4987 return BuildLoadNamedField(holder_value,
5018 HObjectAccess::ForField(holder_map, &lookup, name), 4988 HObjectAccess::ForField(holder_map, &lookup, name));
5019 ComputeLoadStoreRepresentation(map, &lookup));
5020 } 4989 }
5021 4990
5022 4991
5023 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 4992 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
5024 Property* expr, 4993 Property* expr,
5025 HValue* object, 4994 HValue* object,
5026 SmallMapList* types, 4995 SmallMapList* types,
5027 Handle<String> name) { 4996 Handle<String> name) {
5028 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( 4997 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
5029 expr, object, types, name); 4998 expr, object, types, name);
(...skipping 26 matching lines...) Expand all
5056 LookupResult lookup(isolate()); 5025 LookupResult lookup(isolate());
5057 int count; 5026 int count;
5058 Representation representation = Representation::None(); 5027 Representation representation = Representation::None();
5059 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 5028 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
5060 for (count = 0; count < types->length(); ++count) { 5029 for (count = 0; count < types->length(); ++count) {
5061 Handle<Map> map = types->at(count); 5030 Handle<Map> map = types->at(count);
5062 // Pass false to ignore transitions. 5031 // Pass false to ignore transitions.
5063 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 5032 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
5064 5033
5065 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 5034 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
5066 Representation new_representation = 5035 Representation new_representation = new_access.representation();
5067 ComputeLoadStoreRepresentation(map, &lookup);
5068 5036
5069 if (count == 0) { 5037 if (count == 0) {
5070 // First time through the loop; set access and representation. 5038 // First time through the loop; set access and representation.
5071 access = new_access; 5039 access = new_access;
5072 representation = new_representation; 5040 representation = new_representation;
5073 } else if (!representation.IsCompatibleForStore(new_representation)) { 5041 } else if (!representation.IsCompatibleForStore(new_representation)) {
5074 // Representations did not match. 5042 // Representations did not match.
5075 break; 5043 break;
5076 } else if (access.offset() != new_access.offset()) { 5044 } else if (access.offset() != new_access.offset()) {
5077 // Offsets did not match. 5045 // Offsets did not match.
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
5639 HValue* context = environment()->LookupContext(); 5607 HValue* context = environment()->LookupContext();
5640 HValue* value = environment()->Pop(); 5608 HValue* value = environment()->Pop();
5641 HThrow* instr = Add<HThrow>(context, value); 5609 HThrow* instr = Add<HThrow>(context, value);
5642 instr->set_position(expr->position()); 5610 instr->set_position(expr->position());
5643 AddSimulate(expr->id()); 5611 AddSimulate(expr->id());
5644 current_block()->FinishExit(new(zone()) HAbnormalExit); 5612 current_block()->FinishExit(new(zone()) HAbnormalExit);
5645 set_current_block(NULL); 5613 set_current_block(NULL);
5646 } 5614 }
5647 5615
5648 5616
5649 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( 5617 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
5650 HValue* object, 5618 HObjectAccess access) {
5651 HObjectAccess access, 5619 if (FLAG_track_double_fields && access.representation().IsDouble()) {
5652 Representation representation) { 5620 // load the heap number
5653 bool load_double = false; 5621 HLoadNamedField* heap_number =
5654 if (representation.IsDouble()) { 5622 AddLoad(object, access.WithRepresentation(Representation::Tagged()));
5655 representation = Representation::Tagged(); 5623 heap_number->set_type(HType::HeapNumber());
5656 load_double = FLAG_track_double_fields; 5624 // load the double value from it
5625 return new(zone()) HLoadNamedField(heap_number,
5626 HObjectAccess::ForHeapNumberValue(), NULL);
5657 } 5627 }
5658 HLoadNamedField* field = 5628 return new(zone()) HLoadNamedField(object, access, NULL);
5659 new(zone()) HLoadNamedField(object, access, NULL, representation);
5660 if (load_double) {
5661 AddInstruction(field);
5662 field->set_type(HType::HeapNumber());
5663 return new(zone()) HLoadNamedField(field,
5664 HObjectAccess::ForHeapNumberValue(), NULL, Representation::Double());
5665 }
5666 return field;
5667 } 5629 }
5668 5630
5669 5631
5670 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 5632 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
5671 HValue* object, 5633 HValue* object,
5672 Handle<String> name, 5634 Handle<String> name,
5673 Property* expr) { 5635 Property* expr) {
5674 if (expr->IsUninitialized()) { 5636 if (expr->IsUninitialized()) {
5675 AddSoftDeoptimize(); 5637 AddSoftDeoptimize();
5676 } 5638 }
(...skipping 28 matching lines...) Expand all
5705 return new(zone()) HLoadNamedField(object, 5667 return new(zone()) HLoadNamedField(object,
5706 HObjectAccess::ForArrayLength()); 5668 HObjectAccess::ForArrayLength());
5707 } 5669 }
5708 } 5670 }
5709 5671
5710 LookupResult lookup(isolate()); 5672 LookupResult lookup(isolate());
5711 map->LookupDescriptor(NULL, *name, &lookup); 5673 map->LookupDescriptor(NULL, *name, &lookup);
5712 if (lookup.IsField()) { 5674 if (lookup.IsField()) {
5713 AddCheckMap(object, map); 5675 AddCheckMap(object, map);
5714 return BuildLoadNamedField(object, 5676 return BuildLoadNamedField(object,
5715 HObjectAccess::ForField(map, &lookup, name), 5677 HObjectAccess::ForField(map, &lookup, name));
5716 ComputeLoadStoreRepresentation(map, &lookup));
5717 } 5678 }
5718 5679
5719 // Handle a load of a constant known function. 5680 // Handle a load of a constant known function.
5720 if (lookup.IsConstantFunction()) { 5681 if (lookup.IsConstantFunction()) {
5721 AddCheckMap(object, map); 5682 AddCheckMap(object, map);
5722 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 5683 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
5723 return new(zone()) HConstant(function); 5684 return new(zone()) HConstant(function);
5724 } 5685 }
5725 5686
5726 // Handle a load from a known field somewhere in the prototype chain. 5687 // Handle a load from a known field somewhere in the prototype chain.
5727 LookupInPrototypes(map, name, &lookup); 5688 LookupInPrototypes(map, name, &lookup);
5728 if (lookup.IsField()) { 5689 if (lookup.IsField()) {
5729 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5690 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5730 Handle<JSObject> holder(lookup.holder()); 5691 Handle<JSObject> holder(lookup.holder());
5731 Handle<Map> holder_map(holder->map()); 5692 Handle<Map> holder_map(holder->map());
5732 AddCheckMap(object, map); 5693 AddCheckMap(object, map);
5733 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5694 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
5734 HValue* holder_value = Add<HConstant>(holder); 5695 HValue* holder_value = Add<HConstant>(holder);
5735 return BuildLoadNamedField(holder_value, 5696 return BuildLoadNamedField(holder_value,
5736 HObjectAccess::ForField(holder_map, &lookup, name), 5697 HObjectAccess::ForField(holder_map, &lookup, name));
5737 ComputeLoadStoreRepresentation(map, &lookup));
5738 } 5698 }
5739 5699
5740 // Handle a load of a constant function somewhere in the prototype chain. 5700 // Handle a load of a constant function somewhere in the prototype chain.
5741 if (lookup.IsConstantFunction()) { 5701 if (lookup.IsConstantFunction()) {
5742 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5702 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5743 Handle<JSObject> holder(lookup.holder()); 5703 Handle<JSObject> holder(lookup.holder());
5744 Handle<Map> holder_map(holder->map()); 5704 Handle<Map> holder_map(holder->map());
5745 AddCheckMap(object, map); 5705 AddCheckMap(object, map);
5746 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5706 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
5747 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 5707 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
5999 // it's a keyed property) and registered in the full codegen. 5959 // it's a keyed property) and registered in the full codegen.
6000 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); 5960 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
6001 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); 5961 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
6002 HHasInstanceTypeAndBranch* typecheck = 5962 HHasInstanceTypeAndBranch* typecheck =
6003 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 5963 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
6004 typecheck->SetSuccessorAt(0, if_jsarray); 5964 typecheck->SetSuccessorAt(0, if_jsarray);
6005 typecheck->SetSuccessorAt(1, if_fastobject); 5965 typecheck->SetSuccessorAt(1, if_fastobject);
6006 current_block()->Finish(typecheck); 5966 current_block()->Finish(typecheck);
6007 5967
6008 set_current_block(if_jsarray); 5968 set_current_block(if_jsarray);
6009 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), 5969 HInstruction* length = AddLoad(object,
6010 typecheck, Representation::Smi()); 5970 HObjectAccess::ForArrayLength(true), typecheck);
6011 length->set_type(HType::Smi()); 5971 length->set_type(HType::Smi());
6012 5972
6013 checked_key = Add<HBoundsCheck>(key, length); 5973 checked_key = Add<HBoundsCheck>(key, length);
6014 access = AddInstruction(BuildFastElementAccess( 5974 access = AddInstruction(BuildFastElementAccess(
6015 elements, checked_key, val, elements_kind_branch, 5975 elements, checked_key, val, elements_kind_branch,
6016 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); 5976 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE));
6017 if (!is_store) { 5977 if (!is_store) {
6018 Push(access); 5978 Push(access);
6019 } 5979 }
6020 5980
(...skipping 2692 matching lines...) Expand 10 before | Expand all | Expand 10 after
8713 AddStore(object_header, access, properties); 8673 AddStore(object_header, access, properties);
8714 8674
8715 if (boilerplate_object->IsJSArray()) { 8675 if (boilerplate_object->IsJSArray()) {
8716 Handle<JSArray> boilerplate_array = 8676 Handle<JSArray> boilerplate_array =
8717 Handle<JSArray>::cast(boilerplate_object); 8677 Handle<JSArray>::cast(boilerplate_object);
8718 Handle<Object> length_field = 8678 Handle<Object> length_field =
8719 Handle<Object>(boilerplate_array->length(), isolate()); 8679 Handle<Object>(boilerplate_array->length(), isolate());
8720 HInstruction* length = Add<HConstant>(length_field); 8680 HInstruction* length = Add<HConstant>(length_field);
8721 8681
8722 ASSERT(boilerplate_array->length()->IsSmi()); 8682 ASSERT(boilerplate_array->length()->IsSmi());
8723 Representation representation = 8683 AddStore(object_header, HObjectAccess::ForArrayLength(
8724 IsFastElementsKind(boilerplate_array->GetElementsKind()) 8684 IsFastElementsKind(boilerplate_array->GetElementsKind())),
8725 ? Representation::Smi() : Representation::Tagged(); 8685 length);
8726 AddStore(object_header, HObjectAccess::ForArrayLength(),
8727 length, representation);
8728 } 8686 }
8729 8687
8730 return result; 8688 return result;
8731 } 8689 }
8732 8690
8733 8691
8734 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( 8692 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
8735 Handle<JSObject> boilerplate_object, 8693 Handle<JSObject> boilerplate_object,
8736 Handle<JSObject> original_boilerplate_object, 8694 Handle<JSObject> original_boilerplate_object,
8737 HValue* object_properties, 8695 HValue* object_properties,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
8783 if (data_target != NULL) { 8741 if (data_target != NULL) {
8784 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); 8742 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset);
8785 *data_offset += HeapNumber::kSize; 8743 *data_offset += HeapNumber::kSize;
8786 } else { 8744 } else {
8787 double_box = Add<HInnerAllocatedObject>(target, *offset); 8745 double_box = Add<HInnerAllocatedObject>(target, *offset);
8788 *offset += HeapNumber::kSize; 8746 *offset += HeapNumber::kSize;
8789 } 8747 }
8790 AddStoreMapConstant(double_box, 8748 AddStoreMapConstant(double_box,
8791 isolate()->factory()->heap_number_map()); 8749 isolate()->factory()->heap_number_map());
8792 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 8750 AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
8793 value_instruction, Representation::Double()); 8751 value_instruction);
8794 value_instruction = double_box; 8752 value_instruction = double_box;
8795 } 8753 }
8796 8754
8797 AddStore(object_properties, access, value_instruction); 8755 AddStore(object_properties, access, value_instruction);
8798 } 8756 }
8799 } 8757 }
8800 8758
8801 int inobject_properties = boilerplate_object->map()->inobject_properties(); 8759 int inobject_properties = boilerplate_object->map()->inobject_properties();
8802 HInstruction* value_instruction = 8760 HInstruction* value_instruction =
8803 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 8761 Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after
10176 if (ShouldProduceTraceOutput()) { 10134 if (ShouldProduceTraceOutput()) {
10177 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10135 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10178 } 10136 }
10179 10137
10180 #ifdef DEBUG 10138 #ifdef DEBUG
10181 graph_->Verify(false); // No full verify. 10139 graph_->Verify(false); // No full verify.
10182 #endif 10140 #endif
10183 } 10141 }
10184 10142
10185 } } // namespace v8::internal 10143 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698