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
parent 99718b95
...@@ -4266,14 +4266,6 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, ...@@ -4266,14 +4266,6 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map));
bool fast_smi_only_elements = map->has_fast_smi_only_elements(); bool fast_smi_only_elements = map->has_fast_smi_only_elements();
bool fast_elements = map->has_fast_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)); HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
if (is_store && (fast_elements || fast_smi_only_elements)) { if (is_store && (fast_elements || fast_smi_only_elements)) {
AddInstruction(new(zone()) HCheckMap( AddInstruction(new(zone()) HCheckMap(
...@@ -4290,7 +4282,9 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, ...@@ -4290,7 +4282,9 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
return BuildExternalArrayElementAccess(external_elements, checked_key, return BuildExternalArrayElementAccess(external_elements, checked_key,
val, map->elements_kind(), is_store); 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) { if (map->instance_type() == JS_ARRAY_TYPE) {
length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck)); length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck));
} else { } else {
...@@ -4362,8 +4356,14 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, ...@@ -4362,8 +4356,14 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
// If only one map is left after transitioning, handle this case // If only one map is left after transitioning, handle this case
// monomorphically. // monomorphically.
if (num_untransitionable_maps == 1) { if (num_untransitionable_maps == 1) {
HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess( HInstruction* instr = NULL;
object, key, val, untransitionable_map, is_store)); 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(); *has_side_effects |= instr->HasObservableSideEffects();
instr->set_position(position); instr->set_position(position);
return is_store ? NULL : instr; return is_store ? NULL : instr;
...@@ -4499,8 +4499,13 @@ HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj, ...@@ -4499,8 +4499,13 @@ HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj,
HInstruction* instr = NULL; HInstruction* instr = NULL;
if (expr->IsMonomorphic()) { if (expr->IsMonomorphic()) {
Handle<Map> map = expr->GetMonomorphicReceiverType(); Handle<Map> map = expr->GetMonomorphicReceiverType();
AddInstruction(new(zone()) HCheckNonSmi(obj)); if (map->has_slow_elements_kind()) {
instr = BuildMonomorphicElementAccess(obj, key, val, map, is_store); 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 && } else if (expr->GetReceiverTypes() != NULL &&
!expr->GetReceiverTypes()->is_empty()) { !expr->GetReceiverTypes()->is_empty()) {
return HandlePolymorphicElementAccess( return HandlePolymorphicElementAccess(
......
...@@ -4492,6 +4492,11 @@ class Map: public HeapObject { ...@@ -4492,6 +4492,11 @@ class Map: public HeapObject {
return elements_kind() == DICTIONARY_ELEMENTS; 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, static bool IsValidElementsTransition(ElementsKind from_kind,
ElementsKind to_kind); ElementsKind to_kind);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment