| Index: src/hydrogen.cc
|
| ===================================================================
|
| --- src/hydrogen.cc (revision 8230)
|
| +++ src/hydrogen.cc (working copy)
|
| @@ -2248,10 +2248,32 @@
|
| 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.
|
| + ASSERT(instr->uses()->length() > 0);
|
| + instr->ReplaceValue(HBoundsCheck::cast(instr)->index());
|
| + }
|
| + instr = instr->next();
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
|
| ASSERT(current_block() != NULL);
|
| current_block()->AddInstruction(instr);
|
| @@ -3580,16 +3602,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);
|
| }
|
|
|
|
|
| @@ -3607,13 +3630,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;
|
| }
|
|
|
| @@ -3669,8 +3693,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);
|
| }
|
|
|
|
|
| @@ -3689,13 +3714,14 @@
|
| 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);
|
| return new(zone()) HStoreKeyedSpecializedArrayElement(
|
| external_elements,
|
| - key,
|
| + checked_key,
|
| val,
|
| expr->external_array_type());
|
| }
|
| @@ -3746,8 +3772,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;
|
| @@ -4778,8 +4805,9 @@
|
| string, FIRST_STRING_TYPE, LAST_STRING_TYPE));
|
| 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);
|
| }
|
|
|
|
|
|
|