Consistently make the bounds check for AccessArgumentsAt explicit.
This has the advantage that AccessArgumentsAt itself can't deopt anymore and the bounds check is visible for the elimination phase. Furthermore, things are simply more consistent now, a good thing in itself. :-) Review URL: https://codereview.chromium.org/11106012 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12721 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
2389a514a0
commit
5a0176222b
@ -2164,12 +2164,10 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
|
|||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
||||||
LOperand* arguments = UseRegister(instr->arguments());
|
LOperand* args = UseRegister(instr->arguments());
|
||||||
LOperand* length = UseTempRegister(instr->length());
|
LOperand* length = UseTempRegister(instr->length());
|
||||||
LOperand* index = UseRegister(instr->index());
|
LOperand* index = UseRegister(instr->index());
|
||||||
LAccessArgumentsAt* result =
|
return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
|
||||||
new(zone()) LAccessArgumentsAt(arguments, length, index);
|
|
||||||
return AssignEnvironment(DefineAsRegister(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2904,14 +2904,9 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
|
|||||||
Register length = ToRegister(instr->length());
|
Register length = ToRegister(instr->length());
|
||||||
Register index = ToRegister(instr->index());
|
Register index = ToRegister(instr->index());
|
||||||
Register result = ToRegister(instr->result());
|
Register result = ToRegister(instr->result());
|
||||||
|
|
||||||
// Bailout index is not a valid argument index. Use unsigned check to get
|
|
||||||
// negative check for free.
|
|
||||||
__ sub(length, length, index, SetCC);
|
|
||||||
DeoptimizeIf(ls, instr->environment());
|
|
||||||
|
|
||||||
// There are two words between the frame pointer and the last argument.
|
// There are two words between the frame pointer and the last argument.
|
||||||
// Subtracting from length accounts for one of them add one more.
|
// Subtracting from length accounts for one of them add one more.
|
||||||
|
__ sub(length, length, index);
|
||||||
__ add(length, length, Operand(1));
|
__ add(length, length, Operand(1));
|
||||||
__ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
|
__ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
|
||||||
}
|
}
|
||||||
|
@ -9016,8 +9016,10 @@ void HGraphBuilder::GenerateArguments(CallRuntime* call) {
|
|||||||
HInstruction* elements = AddInstruction(
|
HInstruction* elements = AddInstruction(
|
||||||
new(zone()) HArgumentsElements(false));
|
new(zone()) HArgumentsElements(false));
|
||||||
HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
|
HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
|
||||||
|
HInstruction* checked_index =
|
||||||
|
AddInstruction(new(zone()) HBoundsCheck(index, length));
|
||||||
HAccessArgumentsAt* result =
|
HAccessArgumentsAt* result =
|
||||||
new(zone()) HAccessArgumentsAt(elements, length, index);
|
new(zone()) HAccessArgumentsAt(elements, length, checked_index);
|
||||||
return ast_context()->ReturnInstruction(result, call->id());
|
return ast_context()->ReturnInstruction(result, call->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2742,12 +2742,9 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
|
|||||||
Register length = ToRegister(instr->length());
|
Register length = ToRegister(instr->length());
|
||||||
Operand index = ToOperand(instr->index());
|
Operand index = ToOperand(instr->index());
|
||||||
Register result = ToRegister(instr->result());
|
Register result = ToRegister(instr->result());
|
||||||
|
|
||||||
__ sub(length, index);
|
|
||||||
DeoptimizeIf(below_equal, instr->environment());
|
|
||||||
|
|
||||||
// There are two words between the frame pointer and the last argument.
|
// There are two words between the frame pointer and the last argument.
|
||||||
// Subtracting from length accounts for one of them add one more.
|
// Subtracting from length accounts for one of them add one more.
|
||||||
|
__ sub(length, index);
|
||||||
__ mov(result, Operand(arguments, length, times_4, kPointerSize));
|
__ mov(result, Operand(arguments, length, times_4, kPointerSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2279,12 +2279,10 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
|
|||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
||||||
LOperand* arguments = UseRegister(instr->arguments());
|
LOperand* args = UseRegister(instr->arguments());
|
||||||
LOperand* length = UseTempRegister(instr->length());
|
LOperand* length = UseTempRegister(instr->length());
|
||||||
LOperand* index = Use(instr->index());
|
LOperand* index = Use(instr->index());
|
||||||
LAccessArgumentsAt* result =
|
return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
|
||||||
new(zone()) LAccessArgumentsAt(arguments, length, index);
|
|
||||||
return AssignEnvironment(DefineAsRegister(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2612,14 +2612,6 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
|
|||||||
Register length = ToRegister(instr->length());
|
Register length = ToRegister(instr->length());
|
||||||
Register index = ToRegister(instr->index());
|
Register index = ToRegister(instr->index());
|
||||||
Register result = ToRegister(instr->result());
|
Register result = ToRegister(instr->result());
|
||||||
|
|
||||||
// Bailout index is not a valid argument index. Use unsigned check to get
|
|
||||||
// negative check for free.
|
|
||||||
|
|
||||||
// TODO(plind): Shoud be optimized to do the sub before the DeoptimizeIf(),
|
|
||||||
// as they do in Arm. It will save us an instruction.
|
|
||||||
DeoptimizeIf(ls, instr->environment(), length, Operand(index));
|
|
||||||
|
|
||||||
// There are two words between the frame pointer and the last argument.
|
// There are two words between the frame pointer and the last argument.
|
||||||
// Subtracting from length accounts for one of them, add one more.
|
// Subtracting from length accounts for one of them, add one more.
|
||||||
__ subu(length, length, index);
|
__ subu(length, length, index);
|
||||||
|
@ -2106,12 +2106,10 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
|
|||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
||||||
LOperand* arguments = UseRegister(instr->arguments());
|
LOperand* args = UseRegister(instr->arguments());
|
||||||
LOperand* length = UseTempRegister(instr->length());
|
LOperand* length = UseTempRegister(instr->length());
|
||||||
LOperand* index = UseRegister(instr->index());
|
LOperand* index = UseRegister(instr->index());
|
||||||
LAccessArgumentsAt* result =
|
return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
|
||||||
new(zone()) LAccessArgumentsAt(arguments, length, index);
|
|
||||||
return AssignEnvironment(DefineAsRegister(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2601,16 +2601,13 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
|
|||||||
Register arguments = ToRegister(instr->arguments());
|
Register arguments = ToRegister(instr->arguments());
|
||||||
Register length = ToRegister(instr->length());
|
Register length = ToRegister(instr->length());
|
||||||
Register result = ToRegister(instr->result());
|
Register result = ToRegister(instr->result());
|
||||||
|
// There are two words between the frame pointer and the last argument.
|
||||||
|
// Subtracting from length accounts for one of them add one more.
|
||||||
if (instr->index()->IsRegister()) {
|
if (instr->index()->IsRegister()) {
|
||||||
__ subl(length, ToRegister(instr->index()));
|
__ subl(length, ToRegister(instr->index()));
|
||||||
} else {
|
} else {
|
||||||
__ subl(length, ToOperand(instr->index()));
|
__ subl(length, ToOperand(instr->index()));
|
||||||
}
|
}
|
||||||
DeoptimizeIf(below_equal, instr->environment());
|
|
||||||
|
|
||||||
// There are two words between the frame pointer and the last argument.
|
|
||||||
// Subtracting from length accounts for one of them add one more.
|
|
||||||
__ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
|
__ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2167,12 +2167,10 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
|
|||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
||||||
LOperand* arguments = UseRegister(instr->arguments());
|
LOperand* args = UseRegister(instr->arguments());
|
||||||
LOperand* length = UseTempRegister(instr->length());
|
LOperand* length = UseTempRegister(instr->length());
|
||||||
LOperand* index = Use(instr->index());
|
LOperand* index = Use(instr->index());
|
||||||
LAccessArgumentsAt* result =
|
return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
|
||||||
new(zone()) LAccessArgumentsAt(arguments, length, index);
|
|
||||||
return AssignEnvironment(DefineAsRegister(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user