Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 57329ba726a3958f033b11467460e58d0cf6889e..d35ffbd8126a178c112e332d03975866e27b84df 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -3274,8 +3274,8 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
// Load the elements array before the first store. |
if (elements == NULL) { |
- elements = new(zone()) HLoadElements(literal); |
- AddInstruction(elements); |
+ elements = new(zone()) HLoadElements(literal); |
+ AddInstruction(elements); |
} |
HValue* key = AddInstruction( |
@@ -3906,12 +3906,15 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
: BuildLoadKeyedGeneric(object, key); |
} |
AddInstruction(new(zone()) HCheckNonSmi(object)); |
- AddInstruction(new(zone()) HCheckMap(object, map)); |
- HInstruction* elements = new(zone()) HLoadElements(object); |
+ HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); |
+ HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
+ if (is_store) { |
+ AddInstruction(new(zone()) HCheckMap( |
+ elements, isolate()->factory()->fixed_array_map())); |
+ } |
HInstruction* length = NULL; |
HInstruction* checked_key = NULL; |
if (map->has_external_array_elements()) { |
- AddInstruction(elements); |
length = AddInstruction(new(zone()) HExternalArrayLength(elements)); |
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
HLoadExternalArrayPointer* external_elements = |
@@ -3922,22 +3925,11 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
} |
ASSERT(map->has_fast_elements()); |
if (map->instance_type() == JS_ARRAY_TYPE) { |
- length = AddInstruction(new(zone()) HJSArrayLength(object)); |
- checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
- AddInstruction(elements); |
- if (is_store) { |
- AddInstruction(new(zone()) HCheckMap( |
- elements, isolate()->factory()->fixed_array_map())); |
- } |
+ length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck)); |
} else { |
- AddInstruction(elements); |
- if (is_store) { |
- AddInstruction(new(zone()) HCheckMap( |
- elements, isolate()->factory()->fixed_array_map())); |
- } |
length = AddInstruction(new(zone()) HFixedArrayLength(elements)); |
- checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
} |
+ checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
if (is_store) { |
return new(zone()) HStoreKeyedFastElement(elements, checked_key, val); |
} else { |
@@ -3981,7 +3973,8 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
HInstruction* elements_kind_instr = |
AddInstruction(new(zone()) HElementsKind(object)); |
- HInstruction* elements = NULL; |
+ HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
+ HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
HLoadExternalArrayPointer* external_elements = NULL; |
HInstruction* checked_key = NULL; |
@@ -3997,14 +3990,6 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
JSObject::LAST_ELEMENTS_KIND); |
if (elements_kind == JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND |
&& todo_external_array) { |
- elements = AddInstruction(new(zone()) HLoadElements(object)); |
- // We need to forcibly prevent some ElementsKind-dependent instructions |
- // from being hoisted out of any loops they might occur in, because |
- // the current loop-invariant-code-motion algorithm isn't clever enough |
- // to deal with them properly. |
- // There's some performance to be gained by developing a smarter |
- // solution for this. |
- elements->ClearFlag(HValue::kUseGVN); |
HInstruction* length = |
AddInstruction(new(zone()) HExternalArrayLength(elements)); |
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
@@ -4014,17 +3999,19 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
if (type_todo[elements_kind]) { |
HBasicBlock* if_true = graph()->CreateBasicBlock(); |
HBasicBlock* if_false = graph()->CreateBasicBlock(); |
- HCompareConstantEqAndBranch* compare = |
- new(zone()) HCompareConstantEqAndBranch(elements_kind_instr, |
- elements_kind, |
- Token::EQ_STRICT); |
- compare->SetSuccessorAt(0, if_true); |
- compare->SetSuccessorAt(1, if_false); |
- current_block()->Finish(compare); |
+ elements_kind_branch = new(zone()) HCompareConstantEqAndBranch( |
+ elements_kind_instr, elements_kind, Token::EQ_STRICT); |
+ elements_kind_branch->SetSuccessorAt(0, if_true); |
+ elements_kind_branch->SetSuccessorAt(1, if_false); |
+ current_block()->Finish(elements_kind_branch); |
set_current_block(if_true); |
HInstruction* access; |
if (elements_kind == JSObject::FAST_ELEMENTS) { |
+ if (is_store) { |
+ AddInstruction(new(zone()) HCheckMap( |
+ elements, isolate()->factory()->fixed_array_map())); |
+ } |
HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); |
HHasInstanceTypeAndBranch* typecheck = |
@@ -4034,15 +4021,10 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
current_block()->Finish(typecheck); |
set_current_block(if_jsarray); |
- HInstruction* length = new(zone()) HJSArrayLength(object); |
+ HInstruction* length = new(zone()) HJSArrayLength(object, typecheck); |
AddInstruction(length); |
- length->ClearFlag(HValue::kUseGVN); |
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
- elements = AddInstruction(new(zone()) HLoadElements(object)); |
- elements->ClearFlag(HValue::kUseGVN); |
if (is_store) { |
- AddInstruction(new(zone()) HCheckMap( |
- elements, isolate()->factory()->fixed_array_map())); |
access = AddInstruction( |
new(zone()) HStoreKeyedFastElement(elements, checked_key, val)); |
} else { |
@@ -4057,12 +4039,6 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
if_jsarray->Goto(join); |
set_current_block(if_fastobject); |
- elements = AddInstruction(new(zone()) HLoadElements(object)); |
- elements->ClearFlag(HValue::kUseGVN); |
- if (is_store) { |
- AddInstruction(new(zone()) HCheckMap( |
- elements, isolate()->factory()->fixed_array_map())); |
- } |
length = AddInstruction(new(zone()) HFixedArrayLength(elements)); |
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
if (is_store) { |
@@ -4195,8 +4171,9 @@ void HGraphBuilder::VisitProperty(Property* expr) { |
if (expr->IsArrayLength()) { |
HValue* array = Pop(); |
AddInstruction(new(zone()) HCheckNonSmi(array)); |
- AddInstruction(HCheckInstanceType::NewIsJSArray(array)); |
- instr = new(zone()) HJSArrayLength(array); |
+ HInstruction* mapcheck = |
+ AddInstruction(HCheckInstanceType::NewIsJSArray(array)); |
+ instr = new(zone()) HJSArrayLength(array, mapcheck); |
} else if (expr->IsStringLength()) { |
HValue* string = Pop(); |