Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 99b4ddd1e884c4bef8ed45725289219bac43682c..24148adc0b2126374b366c67d01b78608426f172 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -7433,11 +7433,46 @@ HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( |
ElementsKind consolidated_elements_kind = has_seen_holey_elements |
? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) |
: most_general_consolidated_map->elements_kind(); |
+ LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; |
+ if (has_seen_holey_elements) { |
+ if (!isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
+ return NULL; |
+ } |
+ |
+ // Make sure that all of the maps we are handling have the initial array |
+ // prototype. |
+ for (int i = 0; i < maps->length(); ++i) { |
+ Handle<Map> map = maps->at(i); |
+ if (map->prototype() != *isolate()->initial_array_prototype()) { |
+ // We can't guarantee that loading the hole is safe. The prototype may |
+ // have an element at this position. |
+ return NULL; |
+ } |
+ } |
+ |
+ Handle<Map> holey_map = |
+ handle(isolate()->get_initial_js_array_map(consolidated_elements_kind)); |
+ load_mode = BuildKeyedHoleMode(holey_map); |
+ if (load_mode == NEVER_RETURN_HOLE) { |
+ return NULL; |
+ } |
+ |
+ for (int i = 0; i < maps->length(); ++i) { |
+ Handle<Map> map = maps->at(i); |
+ // The prototype check was already done for the holey map in |
+ // BuildKeyedHoleMode. |
+ if (!map.is_identical_to(holey_map)) { |
+ Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); |
+ Handle<JSObject> object_prototype = |
+ isolate()->initial_object_prototype(); |
+ BuildCheckPrototypeMaps(prototype, object_prototype); |
+ } |
+ } |
+ } |
HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
checked_object, key, val, |
most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
- consolidated_elements_kind, |
- LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); |
+ consolidated_elements_kind, LOAD, load_mode, STANDARD_STORE); |
return instr; |
} |