Commit 9641c255 authored by danno@chromium.org's avatar danno@chromium.org

Improve constant element index access code generation

R=jkummerow@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10831049

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12232 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1094c8f1
......@@ -1546,7 +1546,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));
}
......@@ -1838,7 +1838,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);
......
......@@ -2779,20 +2779,31 @@ 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()) {
__ add(scratch, elements,
Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
if (instr->key()->IsConstantOperand()) {
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
int offset =
(ToInteger32(const_operand) + instr->additional_index()) * kPointerSize
+ FixedArray::kHeaderSize;
__ ldr(result, FieldMemOperand(elements, offset));
} else {
__ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
Register key = EmitLoadRegister(instr->key(), scratch0());
// 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()) {
__ add(scratch, elements,
Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
} else {
__ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
}
uint32_t offset = FixedArray::kHeaderSize +
(instr->additional_index() << kPointerSizeLog2);
__ ldr(result, FieldMemOperand(scratch, offset));
}
uint32_t offset = FixedArray::kHeaderSize +
(instr->additional_index() << kPointerSizeLog2);
__ ldr(result, FieldMemOperand(scratch, offset));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
......@@ -3817,7 +3828,18 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
__ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
if (instr->index()->IsConstantOperand()) {
int constant_index =
ToInteger32(LConstantOperand::cast(instr->index()));
if (instr->hydrogen()->length()->representation().IsTagged()) {
__ mov(ip, Operand(Smi::FromInt(constant_index)));
} else {
__ mov(ip, Operand(constant_index));
}
__ cmp(ip, ToRegister(instr->length()));
} else {
__ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
}
DeoptimizeIf(hs, instr->environment());
}
......@@ -3837,18 +3859,19 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
+ FixedArray::kHeaderSize;
__ str(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()) {
__ add(scratch, elements,
Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
} else {
__ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
}
if (instr->additional_index() != 0) {
__ add(scratch,
scratch,
Operand(instr->additional_index() << kPointerSizeLog2));
}
__ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
uint32_t offset = FixedArray::kHeaderSize +
(instr->additional_index() << kPointerSizeLog2);
__ str(value, FieldMemOperand(scratch, offset));
}
if (instr->hydrogen()->NeedsWriteBarrier()) {
......
......@@ -2776,13 +2776,25 @@ class HBoundsCheck: public HTemplateInstruction<2> {
}
virtual Representation RequiredInputRepresentation(int arg_index) {
if (index()->representation().IsTagged() &&
!index()->IsConstant() &&
key_mode_ == ALLOW_SMI_KEY) {
return Representation::Tagged();
} else {
if (key_mode_ == DONT_ALLOW_SMI_KEY ||
!length()->representation().IsTagged()) {
return Representation::Integer32();
}
// If the index is tagged and isn't constant, then allow the length
// to be tagged, since it is usually already tagged from loading it out of
// the length field of a JSArray. This allows for direct comparison without
// untagging.
if (index()->representation().IsTagged() && !index()->IsConstant()) {
return Representation::Tagged();
}
// Also allow the length to be tagged if the index is constant, because
// it can be tagged to allow direct comparison.
if (index()->IsConstant() &&
index()->representation().IsInteger32() &&
arg_index == 1) {
return Representation::Tagged();
}
return Representation::Integer32();
}
virtual void PrintDataTo(StringStream* stream);
......
......@@ -5900,7 +5900,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
} else {
length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
}
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
ALLOW_SMI_KEY));
return BuildFastElementAccess(elements, checked_key, val, mapcheck,
map->elements_kind(), is_store);
}
......
......@@ -2705,6 +2705,10 @@ Operand LCodeGen::BuildFastArrayOperand(
uint32_t additional_index) {
Register elements_pointer_reg = ToRegister(elements_pointer);
int shift_size = ElementsKindToShiftSize(elements_kind);
// Even though the HLoad/StoreKeyedFastElement instructions force 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 (key_representation.IsTagged() && (shift_size >= 1)) {
shift_size -= kSmiTagSize;
}
......@@ -3672,8 +3676,14 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->index()->IsConstantOperand()) {
__ cmp(ToOperand(instr->length()),
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
int constant_index =
ToInteger32(LConstantOperand::cast(instr->index()));
if (instr->hydrogen()->length()->representation().IsTagged()) {
__ cmp(ToOperand(instr->length()),
Immediate(Smi::FromInt(constant_index)));
} else {
__ cmp(ToOperand(instr->length()), Immediate(constant_index));
}
DeoptimizeIf(below_equal, instr->environment());
} else {
__ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
......
......@@ -2506,6 +2506,10 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
LOperand* key = instr->key();
if (!key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
// Even though the HLoad/StoreKeyedFastElement instructions force 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()) {
__ SmiToInteger64(key_reg, key_reg);
} else if (instr->hydrogen()->IsDehoisted()) {
......@@ -2542,6 +2546,10 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
LOperand* key = instr->key();
if (!key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
// Even though the HLoad/StoreKeyedFastElement instructions force 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()) {
__ SmiToInteger64(key_reg, key_reg);
} else if (instr->hydrogen()->IsDehoisted()) {
......@@ -2606,6 +2614,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LOperand* key = instr->key();
if (!key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
// Even though the HLoad/StoreKeyedFastElement instructions force 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()) {
__ SmiToInteger64(key_reg, key_reg);
} else if (instr->hydrogen()->IsDehoisted()) {
......@@ -3549,6 +3561,10 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
LOperand* key = instr->key();
if (!key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
// Even though the HLoad/StoreKeyedFastElement instructions force 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()) {
__ SmiToInteger64(key_reg, key_reg);
} else if (instr->hydrogen()->IsDehoisted()) {
......@@ -3611,8 +3627,13 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
__ AbortIfNotZeroExtended(reg);
}
if (instr->index()->IsConstantOperand()) {
__ cmpq(reg,
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
int constant_index =
ToInteger32(LConstantOperand::cast(instr->index()));
if (instr->hydrogen()->length()->representation().IsTagged()) {
__ Cmp(reg, Smi::FromInt(constant_index));
} else {
__ cmpq(reg, Immediate(constant_index));
}
} else {
Register reg2 = ToRegister(instr->index());
if (FLAG_debug_code &&
......@@ -3639,6 +3660,10 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
LOperand* key = instr->key();
if (!key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
// Even though the HLoad/StoreKeyedFastElement instructions force 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()) {
__ SmiToInteger64(key_reg, key_reg);
} else if (instr->hydrogen()->IsDehoisted()) {
......@@ -3682,6 +3707,10 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
LOperand* key = instr->key();
if (!key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
// Even though the HLoad/StoreKeyedFastElement instructions force 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()) {
__ SmiToInteger64(key_reg, key_reg);
} else if (instr->hydrogen()->IsDehoisted()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment