Commit 87c7d630 authored by palfia@homejinni.com's avatar palfia@homejinni.com

MIPS: Implement in-heap backing store for typed arrays.

Port r18651 (49744859)

Original commit message:
This adds a fixed array sub-type that will represent a backing store for
typed arrays allocated with TypedArray(length) construtor.

BUG=
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/141143003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18652 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5da41be7
......@@ -3082,10 +3082,16 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
int element_size_shift = ElementsKindToShiftSize(elements_kind);
int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
? (element_size_shift - kSmiTagSize) : element_size_shift;
int additional_offset = instr->additional_index() << element_size_shift;
int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
: 0;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
elements_kind == FLOAT32_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS ||
elements_kind == FLOAT64_ELEMENTS) {
int base_offset =
(instr->additional_index() << element_size_shift) + additional_offset;
FPURegister result = ToDoubleRegister(instr->result());
if (key_is_constant) {
__ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
......@@ -3093,11 +3099,12 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
}
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ lwc1(result, MemOperand(scratch0(), additional_offset));
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == FLOAT32_ELEMENTS) {
__ lwc1(result, MemOperand(scratch0(), base_offset));
__ cvt_d_s(result, result);
} else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
__ ldc1(result, MemOperand(scratch0(), additional_offset));
} else { // loading doubles, not floats.
__ ldc1(result, MemOperand(scratch0(), base_offset));
}
} else {
Register result = ToRegister(instr->result());
......@@ -3107,28 +3114,37 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_BYTE_ELEMENTS:
case INT8_ELEMENTS:
__ lb(result, mem_operand);
break;
case EXTERNAL_PIXEL_ELEMENTS:
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case UINT8_ELEMENTS:
case UINT8_CLAMPED_ELEMENTS:
__ lbu(result, mem_operand);
break;
case EXTERNAL_SHORT_ELEMENTS:
case INT16_ELEMENTS:
__ lh(result, mem_operand);
break;
case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
case UINT16_ELEMENTS:
__ lhu(result, mem_operand);
break;
case EXTERNAL_INT_ELEMENTS:
case INT32_ELEMENTS:
__ lw(result, mem_operand);
break;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case UINT32_ELEMENTS:
__ lw(result, mem_operand);
if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
DeoptimizeIf(Ugreater_equal, instr->environment(),
result, Operand(0x80000000));
}
break;
case FLOAT32_ELEMENTS:
case FLOAT64_ELEMENTS:
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
case FAST_DOUBLE_ELEMENTS:
......@@ -3227,7 +3243,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
if (instr->is_external()) {
if (instr->is_typed_elements()) {
DoLoadKeyedExternalArray(instr);
} else if (instr->hydrogen()->representation().IsDouble()) {
DoLoadKeyedFixedDoubleArray(instr);
......@@ -3245,14 +3261,28 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key,
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));
}
int base_offset = (additional_index << element_size) + additional_offset;
if (key_is_constant) {
return MemOperand(base,
(constant_key << element_size) + additional_offset);
base_offset + (constant_key << element_size));
}
if (additional_offset != 0) {
if (shift_size >= 0) {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), Operand(base_offset));
} else {
ASSERT_EQ(-1, shift_size);
__ srl(scratch0(), key, 1);
__ Addu(scratch0(), scratch0(), Operand(base_offset));
}
__ Addu(scratch0(), base, scratch0());
return MemOperand(scratch0());
}
if (additional_index != 0) {
additional_index *= 1 << (element_size - shift_size);
__ Addu(scratch0(), key, Operand(additional_index));
}
if (additional_index == 0) {
......@@ -4178,10 +4208,16 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
int element_size_shift = ElementsKindToShiftSize(elements_kind);
int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
? (element_size_shift - kSmiTagSize) : element_size_shift;
int additional_offset = instr->additional_index() << element_size_shift;
int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
: 0;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
elements_kind == FLOAT32_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS ||
elements_kind == FLOAT64_ELEMENTS) {
int base_offset =
(instr->additional_index() << element_size_shift) + additional_offset;
Register address = scratch0();
FPURegister value(ToDoubleRegister(instr->value()));
if (key_is_constant) {
......@@ -4196,11 +4232,12 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
__ Addu(address, external_pointer, address);
}
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == FLOAT32_ELEMENTS) {
__ cvt_s_d(double_scratch0(), value);
__ swc1(double_scratch0(), MemOperand(address, additional_offset));
} else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
__ sdc1(value, MemOperand(address, additional_offset));
__ swc1(double_scratch0(), MemOperand(address, base_offset));
} else { // Storing doubles, not floats.
__ sdc1(value, MemOperand(address, base_offset));
}
} else {
Register value(ToRegister(instr->value()));
......@@ -4212,16 +4249,25 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
case EXTERNAL_PIXEL_ELEMENTS:
case EXTERNAL_BYTE_ELEMENTS:
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case UINT8_ELEMENTS:
case UINT8_CLAMPED_ELEMENTS:
case INT8_ELEMENTS:
__ sb(value, mem_operand);
break;
case EXTERNAL_SHORT_ELEMENTS:
case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
case INT16_ELEMENTS:
case UINT16_ELEMENTS:
__ sh(value, mem_operand);
break;
case EXTERNAL_INT_ELEMENTS:
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case INT32_ELEMENTS:
case UINT32_ELEMENTS:
__ sw(value, mem_operand);
break;
case FLOAT32_ELEMENTS:
case FLOAT64_ELEMENTS:
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
case FAST_DOUBLE_ELEMENTS:
......@@ -4340,7 +4386,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
// By cases: external, fast double
if (instr->is_external()) {
if (instr->is_typed_elements()) {
DoStoreKeyedExternalArray(instr);
} else if (instr->hydrogen()->value()->representation().IsDouble()) {
DoStoreKeyedFixedDoubleArray(instr);
......
......@@ -2035,7 +2035,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyed* result = NULL;
if (!instr->is_external()) {
if (!instr->is_typed_elements()) {
LOperand* obj = NULL;
if (instr->representation().IsDouble()) {
obj = UseRegister(instr->elements());
......@@ -2047,20 +2047,19 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
} else {
ASSERT(
(instr->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
!IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
(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);
IsDoubleOrFloatElementsKind(instr->elements_kind())));
LOperand* backing_store = UseRegister(instr->elements());
result = new(zone()) LLoadKeyed(backing_store, key);
}
DefineAsRegister(result);
// An unsigned int array load might overflow and cause a deopt, make sure it
// has an environment.
bool can_deoptimize = instr->RequiresHoleCheck() ||
(elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS);
elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS ||
elements_kind == UINT32_ELEMENTS;
return can_deoptimize ? AssignEnvironment(result) : result;
}
......@@ -2077,7 +2076,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
if (!instr->is_external()) {
if (!instr->is_typed_elements()) {
ASSERT(instr->elements()->representation().IsTagged());
bool needs_write_barrier = instr->NeedsWriteBarrier();
LOperand* object = NULL;
......@@ -2106,17 +2105,17 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
ASSERT(
(instr->value()->representation().IsInteger32() &&
(instr->elements_kind() != EXTERNAL_FLOAT_ELEMENTS) &&
(instr->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS)) ||
!IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
(instr->value()->representation().IsDouble() &&
((instr->elements_kind() == EXTERNAL_FLOAT_ELEMENTS) ||
(instr->elements_kind() == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->elements()->representation().IsExternal());
IsDoubleOrFloatElementsKind(instr->elements_kind())));
ASSERT((instr->is_fixed_typed_array() &&
instr->elements()->representation().IsTagged()) ||
(instr->is_external() &&
instr->elements()->representation().IsExternal()));
LOperand* val = UseRegister(instr->value());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LOperand* external_pointer = UseRegister(instr->elements());
return new(zone()) LStoreKeyed(external_pointer, key, val);
LOperand* backing_store = UseRegister(instr->elements());
return new(zone()) LStoreKeyed(backing_store, key, val);
}
......
......@@ -1575,6 +1575,12 @@ class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
bool is_external() const {
return hydrogen()->is_external();
}
bool is_fixed_typed_array() const {
return hydrogen()->is_fixed_typed_array();
}
bool is_typed_elements() const {
return is_external() || is_fixed_typed_array();
}
DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
......@@ -2207,6 +2213,12 @@ class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 0> {
}
bool is_external() const { return hydrogen()->is_external(); }
bool is_fixed_typed_array() const {
return hydrogen()->is_fixed_typed_array();
}
bool is_typed_elements() const {
return is_external() || is_fixed_typed_array();
}
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
......
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