| Index: runtime/vm/intermediate_language_x64.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_x64.cc (revision 36576)
|
| +++ runtime/vm/intermediate_language_x64.cc (working copy)
|
| @@ -751,8 +751,8 @@
|
| const Object& constant = index->definition()->AsConstant()->value();
|
| if (!constant.IsSmi()) return false;
|
| const Smi& smi_const = Smi::Cast(constant);
|
| - const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid);
|
| - const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid);
|
| + const intptr_t scale = Instance::ElementSizeFor(cid);
|
| + const intptr_t data_offset = Instance::DataOffsetFor(cid);
|
| const int64_t disp = smi_const.AsInt64Value() * scale + data_offset;
|
| return Utils::IsInt(32, disp);
|
| }
|
| @@ -973,30 +973,67 @@
|
| }
|
|
|
|
|
| +static Address ElementAddressForIntIndex(bool is_external,
|
| + intptr_t cid,
|
| + intptr_t index_scale,
|
| + Register array,
|
| + intptr_t index) {
|
| + if (is_external) {
|
| + return Address(array, index * index_scale);
|
| + } else {
|
| + const int64_t disp = static_cast<int64_t>(index) * index_scale +
|
| + Instance::DataOffsetFor(cid);
|
| + ASSERT(Utils::IsInt(32, disp));
|
| + return FieldAddress(array, static_cast<int32_t>(disp));
|
| + }
|
| +}
|
| +
|
| +
|
| +static ScaleFactor ToScaleFactor(intptr_t index_scale) {
|
| + // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with
|
| + // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is
|
| + // expected to be untagged before accessing.
|
| + ASSERT(kSmiTagShift == 1);
|
| + switch (index_scale) {
|
| + case 1: return TIMES_1;
|
| + case 2: return TIMES_1;
|
| + case 4: return TIMES_2;
|
| + case 8: return TIMES_4;
|
| + case 16: return TIMES_8;
|
| + default:
|
| + UNREACHABLE();
|
| + return TIMES_1;
|
| + }
|
| +}
|
| +
|
| +
|
| +static Address ElementAddressForRegIndex(bool is_external,
|
| + intptr_t cid,
|
| + intptr_t index_scale,
|
| + Register array,
|
| + Register index) {
|
| + if (is_external) {
|
| + return Address(array, index, ToScaleFactor(index_scale), 0);
|
| + } else {
|
| + return FieldAddress(array,
|
| + index,
|
| + ToScaleFactor(index_scale),
|
| + Instance::DataOffsetFor(cid));
|
| + }
|
| +}
|
| +
|
| +
|
| void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| Register array = locs()->in(0).reg();
|
| Location index = locs()->in(1);
|
|
|
| - const bool is_external =
|
| - (this->array()->definition()->representation() == kUntagged);
|
| Address element_address(kNoRegister, 0);
|
| + element_address = index.IsRegister()
|
| + ? ElementAddressForRegIndex(IsExternal(), class_id(), index_scale(),
|
| + array, index.reg())
|
| + : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(),
|
| + array, Smi::Cast(index.constant()).Value());
|
|
|
| - if (is_external) {
|
| - element_address = index.IsRegister()
|
| - ? compiler->ExternalElementAddressForRegIndex(
|
| - index_scale(), array, index.reg())
|
| - : compiler->ExternalElementAddressForIntIndex(
|
| - index_scale(), array, Smi::Cast(index.constant()).Value());
|
| - } else {
|
| - ASSERT(this->array()->definition()->representation() == kTagged);
|
| - element_address = index.IsRegister()
|
| - ? compiler->ElementAddressForRegIndex(
|
| - class_id(), index_scale(), array, index.reg())
|
| - : compiler->ElementAddressForIntIndex(
|
| - class_id(), index_scale(), array,
|
| - Smi::Cast(index.constant()).Value());
|
| - }
|
| -
|
| if ((representation() == kUnboxedDouble) ||
|
| (representation() == kUnboxedFloat32x4) ||
|
| (representation() == kUnboxedInt32x4) ||
|
| @@ -1161,24 +1198,12 @@
|
| Register array = locs()->in(0).reg();
|
| Location index = locs()->in(1);
|
|
|
| - const bool is_external =
|
| - (this->array()->definition()->representation() == kUntagged);
|
| Address element_address(kNoRegister, 0);
|
| - if (is_external) {
|
| - element_address = index.IsRegister()
|
| - ? compiler->ExternalElementAddressForRegIndex(
|
| - index_scale(), array, index.reg())
|
| - : compiler->ExternalElementAddressForIntIndex(
|
| - index_scale(), array, Smi::Cast(index.constant()).Value());
|
| - } else {
|
| - ASSERT(this->array()->definition()->representation() == kTagged);
|
| - element_address = index.IsRegister()
|
| - ? compiler->ElementAddressForRegIndex(
|
| - class_id(), index_scale(), array, index.reg())
|
| - : compiler->ElementAddressForIntIndex(
|
| - class_id(), index_scale(), array,
|
| - Smi::Cast(index.constant()).Value());
|
| - }
|
| + element_address = index.IsRegister()
|
| + ? ElementAddressForRegIndex(IsExternal(), class_id(), index_scale(),
|
| + array, index.reg())
|
| + : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(),
|
| + array, Smi::Cast(index.constant()).Value());
|
|
|
| if ((index_scale() == 1) && index.IsRegister()) {
|
| __ SmiUntag(index.reg());
|
|
|