| Index: src/hydrogen.cc
|
| ===================================================================
|
| --- src/hydrogen.cc (revision 8225)
|
| +++ src/hydrogen.cc (working copy)
|
| @@ -2262,10 +2262,31 @@
|
| gvn.Analyze();
|
| }
|
|
|
| + // Replace the results of check instructions with the original value, if the
|
| + // result is used. This is safe now, since we don't do code motion after this
|
| + // point. It enables better register allocation since the value produced by
|
| + // check instructions is really a copy of the original value.
|
| + graph()->ReplaceCheckedValues();
|
| +
|
| return graph();
|
| }
|
|
|
|
|
| +void HGraph::ReplaceCheckedValues() {
|
| + HPhase phase("Replace checked values", this);
|
| + for (int i = 0; i < blocks()->length(); ++i) {
|
| + HInstruction* instr = blocks()->at(i)->first();
|
| + while (instr != NULL) {
|
| + if (instr->IsBoundsCheck()) {
|
| + // Replace all uses of the checked value with the original input.
|
| + instr->ReplaceAllUsesWith(HBoundsCheck::cast(instr)->index());
|
| + }
|
| + instr = instr->next();
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
|
| ASSERT(current_block() != NULL);
|
| current_block()->AddInstruction(instr);
|
| @@ -3714,16 +3735,17 @@
|
| bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
|
| HLoadElements* elements = new(zone()) HLoadElements(object);
|
| HInstruction* length = NULL;
|
| + HInstruction* checked_key = NULL;
|
| if (is_array) {
|
| length = AddInstruction(new(zone()) HJSArrayLength(object));
|
| - AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| + checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| AddInstruction(elements);
|
| } else {
|
| AddInstruction(elements);
|
| length = AddInstruction(new(zone()) HFixedArrayLength(elements));
|
| - AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| + checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| }
|
| - return new(zone()) HLoadKeyedFastElement(elements, key);
|
| + return new(zone()) HLoadKeyedFastElement(elements, checked_key);
|
| }
|
|
|
|
|
| @@ -3741,13 +3763,14 @@
|
| AddInstruction(elements);
|
| HInstruction* length = new(zone()) HExternalArrayLength(elements);
|
| AddInstruction(length);
|
| - AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| + HInstruction* checked_key =
|
| + AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| HLoadExternalArrayPointer* external_elements =
|
| new(zone()) HLoadExternalArrayPointer(elements);
|
| AddInstruction(external_elements);
|
| HLoadKeyedSpecializedArrayElement* pixel_array_value =
|
| new(zone()) HLoadKeyedSpecializedArrayElement(
|
| - external_elements, key, expr->external_array_type());
|
| + external_elements, checked_key, expr->external_array_type());
|
| return pixel_array_value;
|
| }
|
|
|
| @@ -3802,8 +3825,9 @@
|
| } else {
|
| length = AddInstruction(new(zone()) HFixedArrayLength(elements));
|
| }
|
| - AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| - return new(zone()) HStoreKeyedFastElement(elements, key, val);
|
| + HInstruction* checked_key =
|
| + AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| + return new(zone()) HStoreKeyedFastElement(elements, checked_key, val);
|
| }
|
|
|
|
|
| @@ -3822,7 +3846,8 @@
|
| AddInstruction(elements);
|
| HInstruction* length = AddInstruction(
|
| new(zone()) HExternalArrayLength(elements));
|
| - AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| + HInstruction* checked_key =
|
| + AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| HLoadExternalArrayPointer* external_elements =
|
| new(zone()) HLoadExternalArrayPointer(elements);
|
| AddInstruction(external_elements);
|
| @@ -3851,7 +3876,7 @@
|
| }
|
| return new(zone()) HStoreKeyedSpecializedArrayElement(
|
| external_elements,
|
| - key,
|
| + checked_key,
|
| val,
|
| expr->external_array_type());
|
| }
|
| @@ -3909,8 +3934,9 @@
|
| HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
|
| HInstruction* length = AddInstruction(
|
| new(zone()) HArgumentsLength(elements));
|
| - AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| - result = new(zone()) HAccessArgumentsAt(elements, length, key);
|
| + HInstruction* checked_key =
|
| + AddInstruction(new(zone()) HBoundsCheck(key, length));
|
| + result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
|
| }
|
| ast_context()->ReturnInstruction(result, expr->id());
|
| return true;
|
| @@ -5023,8 +5049,9 @@
|
| AddInstruction(HCheckInstanceType::NewIsString(string));
|
| HStringLength* length = new(zone()) HStringLength(string);
|
| AddInstruction(length);
|
| - AddInstruction(new(zone()) HBoundsCheck(index, length));
|
| - return new(zone()) HStringCharCodeAt(string, index);
|
| + HInstruction* checked_index =
|
| + AddInstruction(new(zone()) HBoundsCheck(index, length));
|
| + return new(zone()) HStringCharCodeAt(string, checked_index);
|
| }
|
|
|
|
|
|
|