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
This commit is contained in:
parent
e405ff84b4
commit
85ac311a6e
@ -2622,138 +2622,8 @@ 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 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(), 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);
|
|
||||||
}
|
|
||||||
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::DoLoadKeyedFastDoubleElement(
|
|
||||||
LLoadKeyedFastDoubleElement* instr) {
|
|
||||||
Register elements = ToRegister(instr->elements());
|
|
||||||
bool key_is_constant = instr->key()->IsConstantOperand();
|
|
||||||
Register key = no_reg;
|
|
||||||
DoubleRegister result = ToDoubleRegister(instr->result());
|
|
||||||
Register scratch = scratch0();
|
|
||||||
|
|
||||||
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
|
|
||||||
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
|
|
||||||
? (element_size_shift - kSmiTagSize) : element_size_shift;
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key_is_constant) {
|
|
||||||
__ Addu(elements, elements,
|
|
||||||
Operand(((constant_key + instr->additional_index()) <<
|
|
||||||
element_size_shift) +
|
|
||||||
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
|
||||||
} else {
|
|
||||||
__ sll(scratch, key, shift_size);
|
|
||||||
__ Addu(elements, elements, Operand(scratch));
|
|
||||||
__ Addu(elements, elements,
|
|
||||||
Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
|
|
||||||
(instr->additional_index() << element_size_shift)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
|
||||||
__ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
|
|
||||||
DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
|
|
||||||
}
|
|
||||||
|
|
||||||
__ ldc1(result, MemOperand(elements));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MemOperand LCodeGen::PrepareKeyedOperand(Register key,
|
|
||||||
Register base,
|
|
||||||
bool key_is_constant,
|
|
||||||
int constant_key,
|
|
||||||
int element_size,
|
|
||||||
int shift_size,
|
|
||||||
int additional_index,
|
|
||||||
int additional_offset) {
|
|
||||||
if (additional_index != 0 && !key_is_constant) {
|
|
||||||
additional_index *= 1 << (element_size - shift_size);
|
|
||||||
__ Addu(scratch0(), key, Operand(additional_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key_is_constant) {
|
|
||||||
return MemOperand(base,
|
|
||||||
(constant_key << element_size) + additional_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (additional_index == 0) {
|
|
||||||
if (shift_size >= 0) {
|
|
||||||
__ sll(scratch0(), key, shift_size);
|
|
||||||
__ Addu(scratch0(), base, scratch0());
|
|
||||||
return MemOperand(scratch0());
|
|
||||||
} else {
|
|
||||||
ASSERT_EQ(-1, shift_size);
|
|
||||||
__ srl(scratch0(), key, 1);
|
|
||||||
__ Addu(scratch0(), base, scratch0());
|
|
||||||
return MemOperand(scratch0());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shift_size >= 0) {
|
|
||||||
__ sll(scratch0(), scratch0(), shift_size);
|
|
||||||
__ Addu(scratch0(), base, scratch0());
|
|
||||||
return MemOperand(scratch0());
|
|
||||||
} else {
|
|
||||||
ASSERT_EQ(-1, shift_size);
|
|
||||||
__ srl(scratch0(), scratch0(), 1);
|
|
||||||
__ Addu(scratch0(), base, scratch0());
|
|
||||||
return MemOperand(scratch0());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
|
||||||
LLoadKeyedSpecializedArrayElement* 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();
|
||||||
@ -2834,6 +2704,145 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
|
||||||
|
Register elements = ToRegister(instr->elements());
|
||||||
|
bool key_is_constant = instr->key()->IsConstantOperand();
|
||||||
|
Register key = no_reg;
|
||||||
|
DoubleRegister result = ToDoubleRegister(instr->result());
|
||||||
|
Register scratch = scratch0();
|
||||||
|
|
||||||
|
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
|
||||||
|
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
|
||||||
|
? (element_size_shift - kSmiTagSize) : element_size_shift;
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_is_constant) {
|
||||||
|
__ Addu(elements, elements,
|
||||||
|
Operand(((constant_key + instr->additional_index()) <<
|
||||||
|
element_size_shift) +
|
||||||
|
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
||||||
|
} else {
|
||||||
|
__ sll(scratch, key, shift_size);
|
||||||
|
__ Addu(elements, elements, Operand(scratch));
|
||||||
|
__ Addu(elements, elements,
|
||||||
|
Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
|
||||||
|
(instr->additional_index() << element_size_shift)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||||
|
__ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
|
||||||
|
DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
|
||||||
|
}
|
||||||
|
|
||||||
|
__ ldc1(result, MemOperand(elements));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
Register base,
|
||||||
|
bool key_is_constant,
|
||||||
|
int constant_key,
|
||||||
|
int element_size,
|
||||||
|
int shift_size,
|
||||||
|
int additional_index,
|
||||||
|
int additional_offset) {
|
||||||
|
if (additional_index != 0 && !key_is_constant) {
|
||||||
|
additional_index *= 1 << (element_size - shift_size);
|
||||||
|
__ Addu(scratch0(), key, Operand(additional_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_is_constant) {
|
||||||
|
return MemOperand(base,
|
||||||
|
(constant_key << element_size) + additional_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additional_index == 0) {
|
||||||
|
if (shift_size >= 0) {
|
||||||
|
__ sll(scratch0(), key, shift_size);
|
||||||
|
__ Addu(scratch0(), base, scratch0());
|
||||||
|
return MemOperand(scratch0());
|
||||||
|
} else {
|
||||||
|
ASSERT_EQ(-1, shift_size);
|
||||||
|
__ srl(scratch0(), key, 1);
|
||||||
|
__ Addu(scratch0(), base, scratch0());
|
||||||
|
return MemOperand(scratch0());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shift_size >= 0) {
|
||||||
|
__ sll(scratch0(), scratch0(), shift_size);
|
||||||
|
__ Addu(scratch0(), base, scratch0());
|
||||||
|
return MemOperand(scratch0());
|
||||||
|
} else {
|
||||||
|
ASSERT_EQ(-1, shift_size);
|
||||||
|
__ srl(scratch0(), scratch0(), 1);
|
||||||
|
__ Addu(scratch0(), base, scratch0());
|
||||||
|
return MemOperand(scratch0());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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(¬_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(¬_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(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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(¬_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(¬_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 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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,53 +1789,40 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
|
LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
|
||||||
HLoadKeyedFastElement* instr) {
|
|
||||||
ASSERT(instr->representation().IsTagged());
|
|
||||||
ASSERT(instr->key()->representation().IsInteger32() ||
|
ASSERT(instr->key()->representation().IsInteger32() ||
|
||||||
instr->key()->representation().IsTagged());
|
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() ||
|
|
||||||
instr->key()->representation().IsTagged());
|
|
||||||
LOperand* elements = UseTempRegister(instr->elements());
|
|
||||||
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
|
|
||||||
LLoadKeyedFastDoubleElement* result =
|
|
||||||
new(zone()) LLoadKeyedFastDoubleElement(elements, key);
|
|
||||||
return AssignEnvironment(DefineAsRegister(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
|
|
||||||
HLoadKeyedSpecializedArrayElement* instr) {
|
|
||||||
ElementsKind elements_kind = instr->elements_kind();
|
ElementsKind elements_kind = instr->elements_kind();
|
||||||
ASSERT(
|
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
|
||||||
(instr->representation().IsInteger32() &&
|
LLoadKeyed* result = NULL;
|
||||||
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
|
|
||||||
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
|
if (!instr->is_external()) {
|
||||||
(instr->representation().IsDouble() &&
|
LOperand* obj = NULL;
|
||||||
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
|
if (instr->representation().IsDouble()) {
|
||||||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
|
obj = UseTempRegister(instr->elements());
|
||||||
ASSERT(instr->key()->representation().IsInteger32() ||
|
} else {
|
||||||
instr->key()->representation().IsTagged());
|
ASSERT(instr->representation().IsTagged());
|
||||||
LOperand* external_pointer = UseRegister(instr->external_pointer());
|
obj = UseRegisterAtStart(instr->elements());
|
||||||
LOperand* key = UseRegisterOrConstant(instr->key());
|
}
|
||||||
LLoadKeyedSpecializedArrayElement* result =
|
result = new(zone()) LLoadKeyed(obj, key);
|
||||||
new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer, key);
|
} else {
|
||||||
LInstruction* load_instr = DefineAsRegister(result);
|
ASSERT(
|
||||||
|
(instr->representation().IsInteger32() &&
|
||||||
|
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
|
||||||
|
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
|
||||||
|
(instr->representation().IsDouble() &&
|
||||||
|
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
|
||||||
|
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
|
||||||
|
LOperand* external_pointer = UseRegister(instr->elements());
|
||||||
|
result = new(zone()) LLoadKeyed(external_pointer, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,66 +1836,47 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
|
|
||||||
HStoreKeyedFastDoubleElement* instr) {
|
|
||||||
ASSERT(instr->value()->representation().IsDouble());
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
|
|
||||||
HStoreKeyedSpecializedArrayElement* instr) {
|
|
||||||
ElementsKind elements_kind = instr->elements_kind();
|
|
||||||
ASSERT(
|
|
||||||
(instr->value()->representation().IsInteger32() &&
|
|
||||||
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
|
|
||||||
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
|
|
||||||
(instr->value()->representation().IsDouble() &&
|
|
||||||
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
|
|
||||||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
|
|
||||||
ASSERT(instr->external_pointer()->representation().IsExternal());
|
|
||||||
ASSERT(instr->key()->representation().IsInteger32() ||
|
|
||||||
instr->key()->representation().IsTagged());
|
|
||||||
|
|
||||||
LOperand* external_pointer = UseRegister(instr->external_pointer());
|
|
||||||
bool val_is_temp_register =
|
bool val_is_temp_register =
|
||||||
elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
|
elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
|
||||||
elements_kind == EXTERNAL_FLOAT_ELEMENTS;
|
elements_kind == EXTERNAL_FLOAT_ELEMENTS;
|
||||||
LOperand* val = val_is_temp_register
|
LOperand* val = val_is_temp_register || needs_write_barrier
|
||||||
? UseTempRegister(instr->value())
|
? UseTempRegister(instr->value())
|
||||||
: UseRegister(instr->value());
|
: UseRegister(instr->value());
|
||||||
LOperand* key = UseRegisterOrConstant(instr->key());
|
LStoreKeyed* result = NULL;
|
||||||
|
if (!instr->is_external()) {
|
||||||
|
ASSERT(instr->elements()->representation().IsTagged());
|
||||||
|
|
||||||
return new(zone()) LStoreKeyedSpecializedArrayElement(external_pointer,
|
LOperand* object = NULL;
|
||||||
key,
|
if (instr->value()->representation().IsDouble()) {
|
||||||
val);
|
object = UseRegisterAtStart(instr->elements());
|
||||||
|
} else {
|
||||||
|
ASSERT(instr->value()->representation().IsTagged());
|
||||||
|
object = UseTempRegister(instr->elements());
|
||||||
|
}
|
||||||
|
|
||||||
|
result = new(zone()) LStoreKeyed(object, key, val);
|
||||||
|
} else {
|
||||||
|
ASSERT(
|
||||||
|
(instr->value()->representation().IsInteger32() &&
|
||||||
|
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
|
||||||
|
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
|
||||||
|
(instr->value()->representation().IsDouble() &&
|
||||||
|
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
|
||||||
|
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
|
||||||
|
ASSERT(instr->elements()->representation().IsExternal());
|
||||||
|
|
||||||
|
LOperand* external_pointer = UseRegister(instr->elements());
|
||||||
|
result = new(zone()) LStoreKeyed(external_pointer, key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(result != NULL);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
|||||||
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> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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]; }
|
||||||
|
|
||||||
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOperand* elements() { return inputs_[0]; }
|
|
||||||
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]; }
|
|
||||||
LOperand* key() { return inputs_[1]; }
|
|
||||||
|
|
||||||
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
|
|
||||||
"load-keyed-specialized-array-element")
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
|
|
||||||
|
|
||||||
ElementsKind elements_kind() const {
|
ElementsKind elements_kind() const {
|
||||||
return hydrogen()->elements_kind();
|
return hydrogen()->elements_kind();
|
||||||
}
|
}
|
||||||
|
bool is_external() const {
|
||||||
|
return hydrogen()->is_external();
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
|
||||||
|
DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
|
||||||
|
|
||||||
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> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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> {
|
|||||||
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:
|
||||||
|
Loading…
Reference in New Issue
Block a user