From: fschneider@chromium.org Date: Wed, 18 Jan 2012 14:05:11 +0000 (+0000) Subject: Eliminate a superfluous map check when building generic array element access. X-Git-Tag: upstream/4.7.83~17589 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=98013d9824dc5b9e904a542987a73fd6958b7b46;p=platform%2Fupstream%2Fv8.git Eliminate a superfluous map check when building generic array element access. In the case where we generate a generic load or store, we don't need to emit a non-smi-check and a map-check before it. Review URL: http://codereview.chromium.org/9252008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10430 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 47dcc8053..9fa4556b2 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -4266,14 +4266,6 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); bool fast_smi_only_elements = map->has_fast_smi_only_elements(); bool fast_elements = map->has_fast_elements(); - bool fast_double_elements = map->has_fast_double_elements(); - if (!fast_smi_only_elements && - !fast_elements && - !fast_double_elements && - !map->has_external_array_elements()) { - return is_store ? BuildStoreKeyedGeneric(object, key, val) - : BuildLoadKeyedGeneric(object, key); - } HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); if (is_store && (fast_elements || fast_smi_only_elements)) { AddInstruction(new(zone()) HCheckMap( @@ -4290,7 +4282,9 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, return BuildExternalArrayElementAccess(external_elements, checked_key, val, map->elements_kind(), is_store); } - ASSERT(fast_smi_only_elements || fast_elements || fast_double_elements); + ASSERT(fast_smi_only_elements || + fast_elements || + map->has_fast_double_elements()); if (map->instance_type() == JS_ARRAY_TYPE) { length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck)); } else { @@ -4362,8 +4356,14 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, // If only one map is left after transitioning, handle this case // monomorphically. if (num_untransitionable_maps == 1) { - HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess( - object, key, val, untransitionable_map, is_store)); + HInstruction* instr = NULL; + if (untransitionable_map->has_slow_elements_kind()) { + instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val) + : BuildLoadKeyedGeneric(object, key)); + } else { + instr = AddInstruction(BuildMonomorphicElementAccess( + object, key, val, untransitionable_map, is_store)); + } *has_side_effects |= instr->HasObservableSideEffects(); instr->set_position(position); return is_store ? NULL : instr; @@ -4499,8 +4499,13 @@ HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj, HInstruction* instr = NULL; if (expr->IsMonomorphic()) { Handle map = expr->GetMonomorphicReceiverType(); - AddInstruction(new(zone()) HCheckNonSmi(obj)); - instr = BuildMonomorphicElementAccess(obj, key, val, map, is_store); + if (map->has_slow_elements_kind()) { + instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) + : BuildLoadKeyedGeneric(obj, key); + } else { + AddInstruction(new(zone()) HCheckNonSmi(obj)); + instr = BuildMonomorphicElementAccess(obj, key, val, map, is_store); + } } else if (expr->GetReceiverTypes() != NULL && !expr->GetReceiverTypes()->is_empty()) { return HandlePolymorphicElementAccess( diff --git a/src/objects.h b/src/objects.h index c223de854..0d5bec546 100644 --- a/src/objects.h +++ b/src/objects.h @@ -4492,6 +4492,11 @@ class Map: public HeapObject { return elements_kind() == DICTIONARY_ELEMENTS; } + inline bool has_slow_elements_kind() { + return elements_kind() == DICTIONARY_ELEMENTS + || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; + } + static bool IsValidElementsTransition(ElementsKind from_kind, ElementsKind to_kind);