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

Side by Side Diff: src/hydrogen.cc

Issue 15014020: Elide hole checks on KeyedLoads of holey double arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Implement missing platforms and add tests Created 7 years, 7 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 } 1116 }
1117 1117
1118 1118
1119 HInstruction* HGraphBuilder::BuildFastElementAccess( 1119 HInstruction* HGraphBuilder::BuildFastElementAccess(
1120 HValue* elements, 1120 HValue* elements,
1121 HValue* checked_key, 1121 HValue* checked_key,
1122 HValue* val, 1122 HValue* val,
1123 HValue* load_dependency, 1123 HValue* load_dependency,
1124 ElementsKind elements_kind, 1124 ElementsKind elements_kind,
1125 bool is_store, 1125 bool is_store,
1126 LoadKeyedHoleMode load_mode,
1126 KeyedAccessStoreMode store_mode) { 1127 KeyedAccessStoreMode store_mode) {
1127 Zone* zone = this->zone(); 1128 Zone* zone = this->zone();
1128 if (is_store) { 1129 if (is_store) {
1129 ASSERT(val != NULL); 1130 ASSERT(val != NULL);
1130 switch (elements_kind) { 1131 switch (elements_kind) {
1131 case FAST_SMI_ELEMENTS: 1132 case FAST_SMI_ELEMENTS:
1132 case FAST_HOLEY_SMI_ELEMENTS: 1133 case FAST_HOLEY_SMI_ELEMENTS:
1133 if (!val->type().IsSmi()) { 1134 if (!val->type().IsSmi()) {
1134 // Smi-only arrays need a smi check. 1135 // Smi-only arrays need a smi check.
1135 AddInstruction(new(zone) HCheckSmi(val)); 1136 AddInstruction(new(zone) HCheckSmi(val));
1136 } 1137 }
1137 // Fall through. 1138 // Fall through.
1138 case FAST_ELEMENTS: 1139 case FAST_ELEMENTS:
1139 case FAST_HOLEY_ELEMENTS: 1140 case FAST_HOLEY_ELEMENTS:
1140 case FAST_DOUBLE_ELEMENTS: 1141 case FAST_DOUBLE_ELEMENTS:
1141 case FAST_HOLEY_DOUBLE_ELEMENTS: 1142 case FAST_HOLEY_DOUBLE_ELEMENTS:
1142 return new(zone) HStoreKeyed(elements, checked_key, val, elements_kind); 1143 return new(zone) HStoreKeyed(elements, checked_key, val, elements_kind);
1143 default: 1144 default:
1144 UNREACHABLE(); 1145 UNREACHABLE();
1145 return NULL; 1146 return NULL;
1146 } 1147 }
1147 } 1148 }
1148 // It's an element load (!is_store). 1149 // It's an element load (!is_store).
1149 return new(zone) HLoadKeyed(elements, 1150 return new(zone) HLoadKeyed(elements,
1150 checked_key, 1151 checked_key,
1151 load_dependency, 1152 load_dependency,
1152 elements_kind); 1153 elements_kind,
1154 load_mode);
1153 } 1155 }
1154 1156
1155 1157
1156 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, 1158 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
1157 HValue* elements, 1159 HValue* elements,
1158 ElementsKind kind, 1160 ElementsKind kind,
1159 HValue* length, 1161 HValue* length,
1160 HValue* key, 1162 HValue* key,
1161 bool is_js_array) { 1163 bool is_js_array) {
1162 Zone* zone = this->zone(); 1164 Zone* zone = this->zone();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 1251
1250 1252
1251 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 1253 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1252 HValue* object, 1254 HValue* object,
1253 HValue* key, 1255 HValue* key,
1254 HValue* val, 1256 HValue* val,
1255 HCheckMaps* mapcheck, 1257 HCheckMaps* mapcheck,
1256 bool is_js_array, 1258 bool is_js_array,
1257 ElementsKind elements_kind, 1259 ElementsKind elements_kind,
1258 bool is_store, 1260 bool is_store,
1261 LoadKeyedHoleMode load_mode,
1259 KeyedAccessStoreMode store_mode, 1262 KeyedAccessStoreMode store_mode,
1260 Representation checked_index_representation) { 1263 Representation checked_index_representation) {
1261 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); 1264 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array);
1262 Zone* zone = this->zone(); 1265 Zone* zone = this->zone();
1263 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 1266 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
1264 // on a HElementsTransition instruction. The flag can also be removed if the 1267 // on a HElementsTransition instruction. The flag can also be removed if the
1265 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 1268 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
1266 // ElementsKind transitions. Finally, the dependency can be removed for stores 1269 // ElementsKind transitions. Finally, the dependency can be removed for stores
1267 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 1270 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
1268 // generated store code. 1271 // generated store code.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 } else { 1357 } else {
1355 HCheckMaps* check_cow_map = HCheckMaps::New( 1358 HCheckMaps* check_cow_map = HCheckMaps::New(
1356 elements, isolate()->factory()->fixed_array_map(), zone); 1359 elements, isolate()->factory()->fixed_array_map(), zone);
1357 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1360 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1358 AddInstruction(check_cow_map); 1361 AddInstruction(check_cow_map);
1359 } 1362 }
1360 } 1363 }
1361 } 1364 }
1362 return AddInstruction( 1365 return AddInstruction(
1363 BuildFastElementAccess(elements, checked_key, val, mapcheck, 1366 BuildFastElementAccess(elements, checked_key, val, mapcheck,
1364 elements_kind, is_store, store_mode)); 1367 elements_kind, is_store, load_mode, store_mode));
1365 } 1368 }
1366 1369
1367 1370
1368 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, 1371 HValue* HGraphBuilder::BuildAllocateElements(HValue* context,
1369 ElementsKind kind, 1372 ElementsKind kind,
1370 HValue* capacity) { 1373 HValue* capacity) {
1371 Zone* zone = this->zone(); 1374 Zone* zone = this->zone();
1372 1375
1373 int elements_size = IsFastDoubleElementsKind(kind) 1376 int elements_size = IsFastDoubleElementsKind(kind)
1374 ? kDoubleSize : kPointerSize; 1377 ? kDoubleSize : kPointerSize;
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 entry_block_(NULL), 2096 entry_block_(NULL),
2094 blocks_(8, info->zone()), 2097 blocks_(8, info->zone()),
2095 values_(16, info->zone()), 2098 values_(16, info->zone()),
2096 phi_list_(NULL), 2099 phi_list_(NULL),
2097 uint32_instructions_(NULL), 2100 uint32_instructions_(NULL),
2098 info_(info), 2101 info_(info),
2099 zone_(info->zone()), 2102 zone_(info->zone()),
2100 is_recursive_(false), 2103 is_recursive_(false),
2101 use_optimistic_licm_(false), 2104 use_optimistic_licm_(false),
2102 has_soft_deoptimize_(false), 2105 has_soft_deoptimize_(false),
2106 depends_on_empty_array_proto_elements_(false),
2103 type_change_checksum_(0) { 2107 type_change_checksum_(0) {
2104 if (info->IsStub()) { 2108 if (info->IsStub()) {
2105 HydrogenCodeStub* stub = info->code_stub(); 2109 HydrogenCodeStub* stub = info->code_stub();
2106 CodeStubInterfaceDescriptor* descriptor = 2110 CodeStubInterfaceDescriptor* descriptor =
2107 stub->GetInterfaceDescriptor(isolate_); 2111 stub->GetInterfaceDescriptor(isolate_);
2108 start_environment_ = 2112 start_environment_ =
2109 new(zone_) HEnvironment(zone_, descriptor->environment_length()); 2113 new(zone_) HEnvironment(zone_, descriptor->environment_length());
2110 } else { 2114 } else {
2111 start_environment_ = 2115 start_environment_ =
2112 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); 2116 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
(...skipping 5818 matching lines...) Expand 10 before | Expand all | Expand 10 after
7931 HValue* val, 7935 HValue* val,
7932 HValue* dependency, 7936 HValue* dependency,
7933 Handle<Map> map, 7937 Handle<Map> map,
7934 bool is_store, 7938 bool is_store,
7935 KeyedAccessStoreMode store_mode) { 7939 KeyedAccessStoreMode store_mode) {
7936 HCheckMaps* mapcheck = HCheckMaps::New(object, map, zone(), dependency); 7940 HCheckMaps* mapcheck = HCheckMaps::New(object, map, zone(), dependency);
7937 AddInstruction(mapcheck); 7941 AddInstruction(mapcheck);
7938 if (dependency) { 7942 if (dependency) {
7939 mapcheck->ClearGVNFlag(kDependsOnElementsKind); 7943 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
7940 } 7944 }
7945
7946 // Loads from a "stock" fast holey double arrays can elide the hole check.
7947 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE;
7948 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) &&
7949 isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
7950 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate());
7951 Handle<JSObject> object_prototype = isolate()->initial_object_prototype();
7952 AddInstruction(
7953 new(zone()) HCheckPrototypeMaps(prototype, object_prototype, zone()));
7954 load_mode = ALLOW_RETURN_HOLE;
7955 graph()->MarkDependsOnEmptyArrayProtoElements();
7956 }
7957
7941 return BuildUncheckedMonomorphicElementAccess( 7958 return BuildUncheckedMonomorphicElementAccess(
7942 object, key, val, 7959 object, key, val,
7943 mapcheck, map->instance_type() == JS_ARRAY_TYPE, 7960 mapcheck, map->instance_type() == JS_ARRAY_TYPE,
7944 map->elements_kind(), is_store, store_mode); 7961 map->elements_kind(), is_store, load_mode, store_mode);
7945 } 7962 }
7946 7963
7947 7964
7948 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( 7965 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad(
7949 HValue* object, 7966 HValue* object,
7950 HValue* key, 7967 HValue* key,
7951 HValue* val, 7968 HValue* val,
7952 SmallMapList* maps) { 7969 SmallMapList* maps) {
7953 // For polymorphic loads of similar elements kinds (i.e. all tagged or all 7970 // For polymorphic loads of similar elements kinds (i.e. all tagged or all
7954 // double), always use the "worst case" code without a transition. This is 7971 // double), always use the "worst case" code without a transition. This is
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
7989 } 8006 }
7990 } 8007 }
7991 if (!has_double_maps && !has_smi_or_object_maps) return NULL; 8008 if (!has_double_maps && !has_smi_or_object_maps) return NULL;
7992 8009
7993 HCheckMaps* check_maps = HCheckMaps::New(object, maps, zone()); 8010 HCheckMaps* check_maps = HCheckMaps::New(object, maps, zone());
7994 AddInstruction(check_maps); 8011 AddInstruction(check_maps);
7995 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 8012 HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
7996 object, key, val, check_maps, 8013 object, key, val, check_maps,
7997 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, 8014 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
7998 most_general_consolidated_map->elements_kind(), 8015 most_general_consolidated_map->elements_kind(),
7999 false, STANDARD_STORE); 8016 false, NEVER_RETURN_HOLE, STANDARD_STORE);
8000 return instr; 8017 return instr;
8001 } 8018 }
8002 8019
8003 8020
8004 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 8021 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
8005 HValue* object, 8022 HValue* object,
8006 HValue* key, 8023 HValue* key,
8007 HValue* val, 8024 HValue* val,
8008 Expression* prop, 8025 Expression* prop,
8009 BailoutId ast_id, 8026 BailoutId ast_id,
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
8162 current_block()->Finish(typecheck); 8179 current_block()->Finish(typecheck);
8163 8180
8164 set_current_block(if_jsarray); 8181 set_current_block(if_jsarray);
8165 HInstruction* length; 8182 HInstruction* length;
8166 length = AddInstruction( 8183 length = AddInstruction(
8167 HLoadNamedField::NewArrayLength(zone(), object, typecheck, 8184 HLoadNamedField::NewArrayLength(zone(), object, typecheck,
8168 HType::Smi())); 8185 HType::Smi()));
8169 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); 8186 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
8170 access = AddInstruction(BuildFastElementAccess( 8187 access = AddInstruction(BuildFastElementAccess(
8171 elements, checked_key, val, elements_kind_branch, 8188 elements, checked_key, val, elements_kind_branch,
8172 elements_kind, is_store, STANDARD_STORE)); 8189 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE));
8173 if (!is_store) { 8190 if (!is_store) {
8174 Push(access); 8191 Push(access);
8175 } 8192 }
8176 8193
8177 *has_side_effects |= access->HasObservableSideEffects(); 8194 *has_side_effects |= access->HasObservableSideEffects();
8178 // The caller will use has_side_effects and add correct Simulate. 8195 // The caller will use has_side_effects and add correct Simulate.
8179 access->SetFlag(HValue::kHasNoObservableSideEffects); 8196 access->SetFlag(HValue::kHasNoObservableSideEffects);
8180 if (position != -1) { 8197 if (position != -1) {
8181 access->set_position(position); 8198 access->set_position(position);
8182 } 8199 }
8183 if_jsarray->GotoNoSimulate(join); 8200 if_jsarray->GotoNoSimulate(join);
8184 8201
8185 set_current_block(if_fastobject); 8202 set_current_block(if_fastobject);
8186 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 8203 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
8187 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); 8204 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
8188 access = AddInstruction(BuildFastElementAccess( 8205 access = AddInstruction(BuildFastElementAccess(
8189 elements, checked_key, val, elements_kind_branch, 8206 elements, checked_key, val, elements_kind_branch,
8190 elements_kind, is_store, STANDARD_STORE)); 8207 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE));
8191 } else if (elements_kind == DICTIONARY_ELEMENTS) { 8208 } else if (elements_kind == DICTIONARY_ELEMENTS) {
8192 if (is_store) { 8209 if (is_store) {
8193 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); 8210 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
8194 } else { 8211 } else {
8195 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); 8212 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
8196 } 8213 }
8197 } else { // External array elements. 8214 } else { // External array elements.
8198 access = AddInstruction(BuildExternalArrayElementAccess( 8215 access = AddInstruction(BuildExternalArrayElementAccess(
8199 external_elements, checked_key, val, 8216 external_elements, checked_key, val,
8200 elements_kind_branch, elements_kind, is_store)); 8217 elements_kind_branch, elements_kind, is_store));
(...skipping 4170 matching lines...) Expand 10 before | Expand all | Expand 10 after
12371 } 12388 }
12372 } 12389 }
12373 12390
12374 #ifdef DEBUG 12391 #ifdef DEBUG
12375 if (graph_ != NULL) graph_->Verify(false); // No full verify. 12392 if (graph_ != NULL) graph_->Verify(false); // No full verify.
12376 if (allocator_ != NULL) allocator_->Verify(); 12393 if (allocator_ != NULL) allocator_->Verify();
12377 #endif 12394 #endif
12378 } 12395 }
12379 12396
12380 } } // namespace v8::internal 12397 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/isolate.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698