MIPS: Improve constant element index access code generation
Port r12232 (588ccf83) BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/10825263 Patch from Akos Palfi <palfia@homejinni.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12283 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
93fe6abc6c
commit
fe63070186
@ -2587,21 +2587,32 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
|
||||
|
||||
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
|
||||
Register elements = ToRegister(instr->elements());
|
||||
Register key = EmitLoadRegister(instr->key(), scratch0());
|
||||
Register result = ToRegister(instr->result());
|
||||
Register scratch = scratch0();
|
||||
|
||||
// Load the result.
|
||||
if (instr->hydrogen()->key()->representation().IsTagged()) {
|
||||
__ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
|
||||
__ addu(scratch, elements, scratch);
|
||||
if (instr->key()->IsConstantOperand()) {
|
||||
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
|
||||
int offset =
|
||||
(ToInteger32(const_operand) + instr->additional_index()) * kPointerSize
|
||||
+ FixedArray::kHeaderSize;
|
||||
__ lw(result, FieldMemOperand(elements, offset));
|
||||
} else {
|
||||
__ sll(scratch, key, kPointerSizeLog2);
|
||||
__ addu(scratch, elements, scratch);
|
||||
Register key = EmitLoadRegister(instr->key(), scratch);
|
||||
// Even though the HLoadKeyedFastElement instruction forces the input
|
||||
// representation for the key to be an integer, the input gets replaced
|
||||
// during bound check elimination with the index argument to the bounds
|
||||
// check, which can be tagged, so that case must be handled here, too.
|
||||
if (instr->hydrogen()->key()->representation().IsTagged()) {
|
||||
__ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
|
||||
__ addu(scratch, elements, scratch);
|
||||
} else {
|
||||
__ sll(scratch, key, kPointerSizeLog2);
|
||||
__ addu(scratch, elements, scratch);
|
||||
}
|
||||
uint32_t offset = FixedArray::kHeaderSize +
|
||||
(instr->additional_index() << kPointerSizeLog2);
|
||||
__ lw(result, FieldMemOperand(scratch, offset));
|
||||
}
|
||||
uint32_t offset = FixedArray::kHeaderSize +
|
||||
(instr->additional_index() << kPointerSizeLog2);
|
||||
__ lw(result, FieldMemOperand(scratch, offset));
|
||||
|
||||
// Check for the hole value.
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
@ -3647,10 +3658,24 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
|
||||
DeoptimizeIf(hs,
|
||||
instr->environment(),
|
||||
ToRegister(instr->index()),
|
||||
Operand(ToRegister(instr->length())));
|
||||
if (instr->index()->IsConstantOperand()) {
|
||||
int constant_index =
|
||||
ToInteger32(LConstantOperand::cast(instr->index()));
|
||||
if (instr->hydrogen()->length()->representation().IsTagged()) {
|
||||
__ li(at, Operand(Smi::FromInt(constant_index)));
|
||||
} else {
|
||||
__ li(at, Operand(constant_index));
|
||||
}
|
||||
DeoptimizeIf(hs,
|
||||
instr->environment(),
|
||||
at,
|
||||
Operand(ToRegister(instr->length())));
|
||||
} else {
|
||||
DeoptimizeIf(hs,
|
||||
instr->environment(),
|
||||
ToRegister(instr->index()),
|
||||
Operand(ToRegister(instr->length())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3669,6 +3694,10 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
|
||||
+ FixedArray::kHeaderSize;
|
||||
__ sw(value, FieldMemOperand(elements, offset));
|
||||
} else {
|
||||
// Even though the HLoadKeyedFastElement instruction forces the input
|
||||
// representation for the key to be an integer, the input gets replaced
|
||||
// during bound check elimination with the index argument to the bounds
|
||||
// check, which can be tagged, so that case must be handled here, too.
|
||||
if (instr->hydrogen()->key()->representation().IsTagged()) {
|
||||
__ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
|
||||
__ addu(scratch, elements, scratch);
|
||||
@ -3676,12 +3705,9 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
|
||||
__ sll(scratch, key, kPointerSizeLog2);
|
||||
__ addu(scratch, elements, scratch);
|
||||
}
|
||||
if (instr->additional_index() != 0) {
|
||||
__ Addu(scratch,
|
||||
scratch,
|
||||
instr->additional_index() << kPointerSizeLog2);
|
||||
}
|
||||
__ sw(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
|
||||
uint32_t offset = FixedArray::kHeaderSize +
|
||||
(instr->additional_index() << kPointerSizeLog2);
|
||||
__ sw(value, FieldMemOperand(scratch, offset));
|
||||
}
|
||||
|
||||
if (instr->hydrogen()->NeedsWriteBarrier()) {
|
||||
|
@ -1502,7 +1502,7 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
|
||||
LOperand* value = UseRegisterAtStart(instr->index());
|
||||
LOperand* value = UseRegisterOrConstantAtStart(instr->index());
|
||||
LOperand* length = UseRegister(instr->length());
|
||||
return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
|
||||
}
|
||||
@ -1795,7 +1795,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
|
||||
ASSERT(instr->key()->representation().IsInteger32() ||
|
||||
instr->key()->representation().IsTagged());
|
||||
LOperand* obj = UseRegisterAtStart(instr->object());
|
||||
LOperand* key = UseRegisterAtStart(instr->key());
|
||||
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
|
||||
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
|
||||
if (instr->RequiresHoleCheck()) AssignEnvironment(result);
|
||||
return DefineAsRegister(result);
|
||||
|
Loading…
Reference in New Issue
Block a user