MIPS: Consolidated all the key store/load classes in the Hydrogen and Lithium...

MIPS: Consolidated all the key store/load classes in the Hydrogen and Lithium space into just two: HLoadKeyed/HLoadKeyedGeneric and HStoreKeyed/HStoreKeyedGeneric LLoadKeyed/LLoadKeyedGeneric and LStoreKeyed/LStoreKeyedGeneric

Port r12839 (b8b7faa3)

BUG=
TEST=

Review URL: https://codereview.chromium.org/11369110
Patch from palfia <palfia@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12876 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e405ff84
...@@ -2622,50 +2622,89 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { ...@@ -2622,50 +2622,89 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
} }
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
Register elements = ToRegister(instr->elements()); Register external_pointer = ToRegister(instr->elements());
Register result = ToRegister(instr->result()); Register key = no_reg;
Register scratch = scratch0(); ElementsKind elements_kind = instr->elements_kind();
Register store_base = scratch; bool key_is_constant = instr->key()->IsConstantOperand();
int offset = 0; int constant_key = 0;
if (key_is_constant) {
if (instr->key()->IsConstantOperand()) { constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); if (constant_key & 0xF0000000) {
offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + Abort("array index constant value too big.");
instr->additional_index()); }
store_base = elements;
} else {
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 { } else {
__ sll(scratch, key, kPointerSizeLog2); key = ToRegister(instr->key());
__ addu(scratch, elements, scratch);
} }
offset = FixedArray::OffsetOfElementAt(instr->additional_index()); int element_size_shift = ElementsKindToShiftSize(elements_kind);
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
? (element_size_shift - kSmiTagSize) : element_size_shift;
int additional_offset = instr->additional_index() << element_size_shift;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
FPURegister result = ToDoubleRegister(instr->result());
if (key_is_constant) {
__ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
} }
__ lw(result, FieldMemOperand(store_base, offset));
// Check for the hole value. if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
if (instr->hydrogen()->RequiresHoleCheck()) { __ lwc1(result, MemOperand(scratch0(), additional_offset));
if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { __ cvt_d_s(result, result);
__ And(scratch, result, Operand(kSmiTagMask)); } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); __ ldc1(result, MemOperand(scratch0(), additional_offset));
}
} else { } else {
__ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); Register result = ToRegister(instr->result());
DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); MemOperand mem_operand = PrepareKeyedOperand(
key, external_pointer, key_is_constant, constant_key,
element_size_shift, shift_size,
instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_BYTE_ELEMENTS:
__ lb(result, mem_operand);
break;
case EXTERNAL_PIXEL_ELEMENTS:
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ lbu(result, mem_operand);
break;
case EXTERNAL_SHORT_ELEMENTS:
__ lh(result, mem_operand);
break;
case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ lhu(result, mem_operand);
break;
case EXTERNAL_INT_ELEMENTS:
__ lw(result, mem_operand);
break;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ lw(result, mem_operand);
if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
DeoptimizeIf(Ugreater_equal, instr->environment(),
result, Operand(0x80000000));
}
break;
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
case FAST_DOUBLE_ELEMENTS:
case FAST_ELEMENTS:
case FAST_SMI_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
} }
} }
} }
void LCodeGen::DoLoadKeyedFastDoubleElement( void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
LLoadKeyedFastDoubleElement* instr) {
Register elements = ToRegister(instr->elements()); Register elements = ToRegister(instr->elements());
bool key_is_constant = instr->key()->IsConstantOperand(); bool key_is_constant = instr->key()->IsConstantOperand();
Register key = no_reg; Register key = no_reg;
...@@ -2707,6 +2746,59 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( ...@@ -2707,6 +2746,59 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
} }
void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
Register elements = ToRegister(instr->elements());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
Register store_base = scratch;
int offset = 0;
if (instr->key()->IsConstantOperand()) {
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
instr->additional_index());
store_base = elements;
} else {
Register key = EmitLoadRegister(instr->key(), scratch0());
// Even though the HLoadKeyed 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);
}
offset = FixedArray::OffsetOfElementAt(instr->additional_index());
}
__ lw(result, FieldMemOperand(store_base, offset));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
__ And(scratch, result, Operand(kSmiTagMask));
DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
} else {
__ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
DeoptimizeIf(eq, instr->environment(), result, Operand(scratch));
}
}
}
void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
if (instr->is_external()) {
DoLoadKeyedExternalArray(instr);
} else if (instr->hydrogen()->representation().IsDouble()) {
DoLoadKeyedFixedDoubleArray(instr);
} else {
DoLoadKeyedFixedArray(instr);
}
}
MemOperand LCodeGen::PrepareKeyedOperand(Register key, MemOperand LCodeGen::PrepareKeyedOperand(Register key,
Register base, Register base,
bool key_is_constant, bool key_is_constant,
...@@ -2751,89 +2843,6 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key, ...@@ -2751,89 +2843,6 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key,
} }
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
Register key = no_reg;
ElementsKind elements_kind = instr->elements_kind();
bool key_is_constant = instr->key()->IsConstantOperand();
int constant_key = 0;
if (key_is_constant) {
constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
if (constant_key & 0xF0000000) {
Abort("array index constant value too big.");
}
} else {
key = ToRegister(instr->key());
}
int element_size_shift = ElementsKindToShiftSize(elements_kind);
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
? (element_size_shift - kSmiTagSize) : element_size_shift;
int additional_offset = instr->additional_index() << element_size_shift;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
FPURegister result = ToDoubleRegister(instr->result());
if (key_is_constant) {
__ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
}
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ lwc1(result, MemOperand(scratch0(), additional_offset));
__ cvt_d_s(result, result);
} else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
__ ldc1(result, MemOperand(scratch0(), additional_offset));
}
} else {
Register result = ToRegister(instr->result());
MemOperand mem_operand = PrepareKeyedOperand(
key, external_pointer, key_is_constant, constant_key,
element_size_shift, shift_size,
instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_BYTE_ELEMENTS:
__ lb(result, mem_operand);
break;
case EXTERNAL_PIXEL_ELEMENTS:
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ lbu(result, mem_operand);
break;
case EXTERNAL_SHORT_ELEMENTS:
__ lh(result, mem_operand);
break;
case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ lhu(result, mem_operand);
break;
case EXTERNAL_INT_ELEMENTS:
__ lw(result, mem_operand);
break;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ lw(result, mem_operand);
if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
DeoptimizeIf(Ugreater_equal, instr->environment(),
result, Operand(0x80000000));
}
break;
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
case FAST_DOUBLE_ELEMENTS:
case FAST_ELEMENTS:
case FAST_SMI_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
}
}
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->object()).is(a1)); ASSERT(ToRegister(instr->object()).is(a1));
ASSERT(ToRegister(instr->key()).is(a0)); ASSERT(ToRegister(instr->key()).is(a0));
...@@ -3737,108 +3746,8 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { ...@@ -3737,108 +3746,8 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
} }
void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
Register value = ToRegister(instr->value()); Register external_pointer = ToRegister(instr->elements());
Register elements = ToRegister(instr->object());
Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
Register scratch = scratch0();
Register store_base = scratch;
int offset = 0;
// Do the store.
if (instr->key()->IsConstantOperand()) {
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
instr->additional_index());
store_base = elements;
} 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);
} else {
__ sll(scratch, key, kPointerSizeLog2);
__ addu(scratch, elements, scratch);
}
offset = FixedArray::OffsetOfElementAt(instr->additional_index());
}
__ sw(value, FieldMemOperand(store_base, offset));
if (instr->hydrogen()->NeedsWriteBarrier()) {
HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
// Compute address of modified element and store it into key register.
__ Addu(key, store_base, Operand(offset - kHeapObjectTag));
__ RecordWrite(elements,
key,
value,
kRAHasBeenSaved,
kSaveFPRegs,
EMIT_REMEMBERED_SET,
check_needed);
}
}
void LCodeGen::DoStoreKeyedFastDoubleElement(
LStoreKeyedFastDoubleElement* instr) {
DoubleRegister value = ToDoubleRegister(instr->value());
Register elements = ToRegister(instr->elements());
Register key = no_reg;
Register scratch = scratch0();
bool key_is_constant = instr->key()->IsConstantOperand();
int constant_key = 0;
Label not_nan;
// Calculate the effective address of the slot in the array to store the
// double value.
if (key_is_constant) {
constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
if (constant_key & 0xF0000000) {
Abort("array index constant value too big.");
}
} else {
key = ToRegister(instr->key());
}
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
? (element_size_shift - kSmiTagSize) : element_size_shift;
if (key_is_constant) {
__ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
__ Addu(scratch, elements, Operand(scratch));
__ Addu(scratch, scratch,
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
}
if (instr->NeedsCanonicalization()) {
Label is_nan;
// Check for NaN. All NaNs must be canonicalized.
__ BranchF(NULL, &is_nan, eq, value, value);
__ Branch(&not_nan);
// Only load canonical NaN if the comparison above set the overflow.
__ bind(&is_nan);
__ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
}
__ bind(&not_nan);
__ sdc1(value, MemOperand(scratch, instr->additional_index() <<
element_size_shift));
}
void LCodeGen::DoStoreKeyedSpecializedArrayElement(
LStoreKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
Register key = no_reg; Register key = no_reg;
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
bool key_is_constant = instr->key()->IsConstantOperand(); bool key_is_constant = instr->key()->IsConstantOperand();
...@@ -3909,6 +3818,117 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( ...@@ -3909,6 +3818,117 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
} }
} }
void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
DoubleRegister value = ToDoubleRegister(instr->value());
Register elements = ToRegister(instr->elements());
Register key = no_reg;
Register scratch = scratch0();
bool key_is_constant = instr->key()->IsConstantOperand();
int constant_key = 0;
Label not_nan;
// Calculate the effective address of the slot in the array to store the
// double value.
if (key_is_constant) {
constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
if (constant_key & 0xF0000000) {
Abort("array index constant value too big.");
}
} else {
key = ToRegister(instr->key());
}
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
? (element_size_shift - kSmiTagSize) : element_size_shift;
if (key_is_constant) {
__ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
__ Addu(scratch, elements, Operand(scratch));
__ Addu(scratch, scratch,
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
}
if (instr->NeedsCanonicalization()) {
Label is_nan;
// Check for NaN. All NaNs must be canonicalized.
__ BranchF(NULL, &is_nan, eq, value, value);
__ Branch(&not_nan);
// Only load canonical NaN if the comparison above set the overflow.
__ bind(&is_nan);
__ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
}
__ bind(&not_nan);
__ sdc1(value, MemOperand(scratch, instr->additional_index() <<
element_size_shift));
}
void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
Register value = ToRegister(instr->value());
Register elements = ToRegister(instr->elements());
Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
: no_reg;
Register scratch = scratch0();
Register store_base = scratch;
int offset = 0;
// Do the store.
if (instr->key()->IsConstantOperand()) {
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
instr->additional_index());
store_base = elements;
} else {
// Even though the HLoadKeyed 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);
}
offset = FixedArray::OffsetOfElementAt(instr->additional_index());
}
__ sw(value, FieldMemOperand(store_base, offset));
if (instr->hydrogen()->NeedsWriteBarrier()) {
HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
// Compute address of modified element and store it into key register.
__ Addu(key, store_base, Operand(offset - kHeapObjectTag));
__ RecordWrite(elements,
key,
value,
kRAHasBeenSaved,
kSaveFPRegs,
EMIT_REMEMBERED_SET,
check_needed);
}
}
void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
// By cases: external, fast double
if (instr->is_external()) {
DoStoreKeyedExternalArray(instr);
} else if (instr->hydrogen()->value()->representation().IsDouble()) {
DoStoreKeyedFixedDoubleArray(instr);
} else {
DoStoreKeyedFixedArray(instr);
}
}
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
ASSERT(ToRegister(instr->object()).is(a2)); ASSERT(ToRegister(instr->object()).is(a2));
ASSERT(ToRegister(instr->key()).is(a1)); ASSERT(ToRegister(instr->key()).is(a1));
......
...@@ -376,6 +376,12 @@ class LCodeGen BASE_EMBEDDED { ...@@ -376,6 +376,12 @@ class LCodeGen BASE_EMBEDDED {
}; };
void EnsureSpaceForLazyDeopt(); void EnsureSpaceForLazyDeopt();
void DoLoadKeyedExternalArray(LLoadKeyed* instr);
void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
void DoLoadKeyedFixedArray(LLoadKeyed* instr);
void DoStoreKeyedExternalArray(LStoreKeyed* instr);
void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
void DoStoreKeyedFixedArray(LStoreKeyed* instr);
Zone* zone_; Zone* zone_;
LPlatformChunk* const chunk_; LPlatformChunk* const chunk_;
......
...@@ -372,16 +372,7 @@ void LStoreNamedGeneric::PrintDataTo(StringStream* stream) { ...@@ -372,16 +372,7 @@ void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
} }
void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) { void LStoreKeyed::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream);
stream->Add("[");
key()->PrintTo(stream);
stream->Add("] <- ");
value()->PrintTo(stream);
}
void LStoreKeyedFastDoubleElement::PrintDataTo(StringStream* stream) {
elements()->PrintTo(stream); elements()->PrintTo(stream);
stream->Add("["); stream->Add("[");
key()->PrintTo(stream); key()->PrintTo(stream);
...@@ -1798,35 +1789,23 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( ...@@ -1798,35 +1789,23 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
} }
LInstruction* LChunkBuilder::DoLoadKeyedFastElement( LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
HLoadKeyedFastElement* instr) {
ASSERT(instr->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
if (instr->RequiresHoleCheck()) AssignEnvironment(result);
return DefineAsRegister(result);
}
LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
HLoadKeyedFastDoubleElement* instr) {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->key()->representation().IsInteger32() || ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged()); instr->key()->representation().IsTagged());
LOperand* elements = UseTempRegister(instr->elements()); ElementsKind elements_kind = instr->elements_kind();
LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastDoubleElement* result = LLoadKeyed* result = NULL;
new(zone()) LLoadKeyedFastDoubleElement(elements, key);
return AssignEnvironment(DefineAsRegister(result));
}
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( if (!instr->is_external()) {
HLoadKeyedSpecializedArrayElement* instr) { LOperand* obj = NULL;
ElementsKind elements_kind = instr->elements_kind(); if (instr->representation().IsDouble()) {
obj = UseTempRegister(instr->elements());
} else {
ASSERT(instr->representation().IsTagged());
obj = UseRegisterAtStart(instr->elements());
}
result = new(zone()) LLoadKeyed(obj, key);
} else {
ASSERT( ASSERT(
(instr->representation().IsInteger32() && (instr->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
...@@ -1834,17 +1813,16 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( ...@@ -1834,17 +1813,16 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
(instr->representation().IsDouble() && (instr->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->key()->representation().IsInteger32() || LOperand* external_pointer = UseRegister(instr->elements());
instr->key()->representation().IsTagged()); result = new(zone()) LLoadKeyed(external_pointer, key);
LOperand* external_pointer = UseRegister(instr->external_pointer()); }
LOperand* key = UseRegisterOrConstant(instr->key());
LLoadKeyedSpecializedArrayElement* result = DefineAsRegister(result);
new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer, key);
LInstruction* load_instr = DefineAsRegister(result);
// An unsigned int array load might overflow and cause a deopt, make sure it // An unsigned int array load might overflow and cause a deopt, make sure it
// has an environment. // has an environment.
return (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) ? bool can_deoptimize = instr->RequiresHoleCheck() ||
AssignEnvironment(load_instr) : load_instr; (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS);
return can_deoptimize ? AssignEnvironment(result) : result;
} }
...@@ -1858,43 +1836,32 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { ...@@ -1858,43 +1836,32 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
} }
LInstruction* LChunkBuilder::DoStoreKeyedFastElement( LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
HStoreKeyedFastElement* instr) { ElementsKind elements_kind = instr->elements_kind();
bool needs_write_barrier = instr->NeedsWriteBarrier(); bool needs_write_barrier = instr->NeedsWriteBarrier();
ASSERT(instr->value()->representation().IsTagged());
ASSERT(instr->object()->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* obj = UseTempRegister(instr->object());
LOperand* val = needs_write_barrier
? UseTempRegister(instr->value())
: UseRegisterAtStart(instr->value());
LOperand* key = needs_write_barrier LOperand* key = needs_write_barrier
? UseTempRegister(instr->key()) ? UseTempRegister(instr->key())
: UseRegisterOrConstantAtStart(instr->key()); : UseRegisterOrConstantAtStart(instr->key());
return new(zone()) LStoreKeyedFastElement(obj, key, val); bool val_is_temp_register =
} elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
elements_kind == EXTERNAL_FLOAT_ELEMENTS;
LOperand* val = val_is_temp_register || needs_write_barrier
LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement( ? UseTempRegister(instr->value())
HStoreKeyedFastDoubleElement* instr) { : UseRegister(instr->value());
ASSERT(instr->value()->representation().IsDouble()); LStoreKeyed* result = NULL;
if (!instr->is_external()) {
ASSERT(instr->elements()->representation().IsTagged()); ASSERT(instr->elements()->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* elements = UseRegisterAtStart(instr->elements());
LOperand* val = UseTempRegister(instr->value());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
return new(zone()) LStoreKeyedFastDoubleElement(elements, key, val);
}
LOperand* object = NULL;
if (instr->value()->representation().IsDouble()) {
object = UseRegisterAtStart(instr->elements());
} else {
ASSERT(instr->value()->representation().IsTagged());
object = UseTempRegister(instr->elements());
}
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( result = new(zone()) LStoreKeyed(object, key, val);
HStoreKeyedSpecializedArrayElement* instr) { } else {
ElementsKind elements_kind = instr->elements_kind();
ASSERT( ASSERT(
(instr->value()->representation().IsInteger32() && (instr->value()->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
...@@ -1902,22 +1869,14 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( ...@@ -1902,22 +1869,14 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
(instr->value()->representation().IsDouble() && (instr->value()->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->elements()->representation().IsExternal());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* external_pointer = UseRegister(instr->elements());
bool val_is_temp_register = result = new(zone()) LStoreKeyed(external_pointer, key, val);
elements_kind == EXTERNAL_PIXEL_ELEMENTS || }
elements_kind == EXTERNAL_FLOAT_ELEMENTS;
LOperand* val = val_is_temp_register
? UseTempRegister(instr->value())
: UseRegister(instr->value());
LOperand* key = UseRegisterOrConstant(instr->key());
return new(zone()) LStoreKeyedSpecializedArrayElement(external_pointer, ASSERT(result != NULL);
key, return result;
val);
} }
......
...@@ -125,10 +125,8 @@ class LCodeGen; ...@@ -125,10 +125,8 @@ class LCodeGen;
V(LoadFunctionPrototype) \ V(LoadFunctionPrototype) \
V(LoadGlobalCell) \ V(LoadGlobalCell) \
V(LoadGlobalGeneric) \ V(LoadGlobalGeneric) \
V(LoadKeyedFastDoubleElement) \ V(LoadKeyed) \
V(LoadKeyedFastElement) \
V(LoadKeyedGeneric) \ V(LoadKeyedGeneric) \
V(LoadKeyedSpecializedArrayElement) \
V(LoadNamedField) \ V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \ V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \ V(LoadNamedGeneric) \
...@@ -156,10 +154,8 @@ class LCodeGen; ...@@ -156,10 +154,8 @@ class LCodeGen;
V(StoreContextSlot) \ V(StoreContextSlot) \
V(StoreGlobalCell) \ V(StoreGlobalCell) \
V(StoreGlobalGeneric) \ V(StoreGlobalGeneric) \
V(StoreKeyedFastDoubleElement) \ V(StoreKeyed) \
V(StoreKeyedFastElement) \
V(StoreKeyedGeneric) \ V(StoreKeyedGeneric) \
V(StoreKeyedSpecializedArrayElement) \
V(StoreNamedField) \ V(StoreNamedField) \
V(StoreNamedGeneric) \ V(StoreNamedGeneric) \
V(StringAdd) \ V(StringAdd) \
...@@ -1337,59 +1333,25 @@ class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> { ...@@ -1337,59 +1333,25 @@ class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> {
}; };
class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> { class LLoadKeyed: public LTemplateInstruction<1, 2, 0> {
public: public:
LLoadKeyedFastElement(LOperand* elements, LOperand* key) { LLoadKeyed(LOperand* elements, LOperand* key) {
inputs_[0] = elements; inputs_[0] = elements;
inputs_[1] = key; inputs_[1] = key;
} }
LOperand* elements() { return inputs_[0]; } LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
ElementsKind elements_kind() const {
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element") return hydrogen()->elements_kind();
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
public:
LLoadKeyedFastDoubleElement(LOperand* elements, LOperand* key) {
inputs_[0] = elements;
inputs_[1] = key;
} }
bool is_external() const {
LOperand* elements() { return inputs_[0]; } return hydrogen()->is_external();
LOperand* key() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,
"load-keyed-fast-double-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement)
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
public:
LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
LOperand* key) {
inputs_[0] = external_pointer;
inputs_[1] = key;
} }
LOperand* external_pointer() { return inputs_[0]; } DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
LOperand* key() { return inputs_[1]; } DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
"load-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
uint32_t additional_index() const { return hydrogen()->index_offset(); } uint32_t additional_index() const { return hydrogen()->index_offset(); }
}; };
...@@ -1903,51 +1865,28 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> { ...@@ -1903,51 +1865,28 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
}; };
class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> { class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
public: public:
LStoreKeyedFastElement(LOperand* object, LOperand* key, LOperand* value) { LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) {
inputs_[0] = object; inputs_[0] = object;
inputs_[1] = key; inputs_[1] = key;
inputs_[2] = value; inputs_[2] = value;
} }
LOperand* object() { return inputs_[0]; } bool is_external() const { return hydrogen()->is_external(); }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
"store-keyed-fast-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
virtual void PrintDataTo(StringStream* stream);
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyedFastDoubleElement(LOperand* elements,
LOperand* key,
LOperand* value) {
inputs_[0] = elements;
inputs_[1] = key;
inputs_[2] = value;
}
LOperand* elements() { return inputs_[0]; } LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; } LOperand* value() { return inputs_[2]; }
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement, DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
"store-keyed-fast-double-element") DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
virtual void PrintDataTo(StringStream* stream); virtual void PrintDataTo(StringStream* stream);
uint32_t additional_index() const { return hydrogen()->index_offset(); }
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
}; };
...@@ -1971,28 +1910,6 @@ class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> { ...@@ -1971,28 +1910,6 @@ class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
}; };
class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
public:
LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
LOperand* key,
LOperand* value) {
inputs_[0] = external_pointer;
inputs_[1] = key;
inputs_[2] = value;
}
LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
"store-keyed-specialized-array-element")
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> { class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
public: public:
......
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