Last cross-platform cleanup in preparation of improved ARM code for indexed

loads and stores.

R=srdjan@google.com

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

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@36577 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
regis@google.com 2014-05-23 18:31:10 +00:00
parent c6101ca4b5
commit 9868b7ed94
21 changed files with 218 additions and 407 deletions

View file

@ -2197,7 +2197,7 @@ void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
for_value.value()->BindsToConstant()
? kNoStoreBarrier
: kEmitStoreBarrier;
intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id);
const intptr_t index_scale = Instance::ElementSizeFor(class_id);
StoreIndexedInstr* store = new StoreIndexedInstr(
array, index, for_value.value(), emit_store_barrier,
index_scale, class_id, deopt_id, node->token_pos());

View file

@ -1289,50 +1289,6 @@ ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() {
}
intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) {
if (RawObject::IsExternalTypedDataClassId(cid)) {
return ExternalTypedData::ElementSizeInBytes(cid);
} else if (RawObject::IsTypedDataClassId(cid)) {
return TypedData::ElementSizeInBytes(cid);
}
switch (cid) {
case kArrayCid:
case kImmutableArrayCid:
return Array::kBytesPerElement;
case kOneByteStringCid:
return OneByteString::kBytesPerElement;
case kTwoByteStringCid:
return TwoByteString::kBytesPerElement;
default:
UNIMPLEMENTED();
return 0;
}
}
intptr_t FlowGraphCompiler::DataOffsetFor(intptr_t cid) {
if (RawObject::IsExternalTypedDataClassId(cid)) {
// Elements start at offset 0 of the external data.
return 0;
}
if (RawObject::IsTypedDataClassId(cid)) {
return TypedData::data_offset();
}
switch (cid) {
case kArrayCid:
case kImmutableArrayCid:
return Array::data_offset();
case kOneByteStringCid:
return OneByteString::data_offset();
case kTwoByteStringCid:
return TwoByteString::data_offset();
default:
UNIMPLEMENTED();
return Array::data_offset();
}
}
static int HighestCountFirst(const CidTarget* a, const CidTarget* b) {
// Negative if 'a' should sort before 'b'.
return b->count - a->count;

View file

@ -447,24 +447,6 @@ class FlowGraphCompiler : public ValueObject {
bool may_reoptimize() const { return may_reoptimize_; }
// Array/list element address computations.
static intptr_t DataOffsetFor(intptr_t cid);
static intptr_t ElementSizeFor(intptr_t cid);
Address ElementAddressForIntIndex(intptr_t cid,
intptr_t index_scale,
Register array,
intptr_t offset);
Address ElementAddressForRegIndex(intptr_t cid,
intptr_t index_scale,
Register array,
Register index);
Address ExternalElementAddressForIntIndex(intptr_t index_scale,
Register array,
intptr_t offset);
Address ExternalElementAddressForRegIndex(intptr_t index_scale,
Register array,
Register index);
// Returns 'sorted' array in decreasing count order.
static void SortICDataByCount(const ICData& ic_data,
GrowableArray<CidTarget>* sorted);

View file

@ -1511,11 +1511,11 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
for (intptr_t i = 0; i < len; i++) {
const bool is_last_check = (i == (len - 1));
Label next_test;
assembler()->CompareImmediate(class_id_reg, sorted[i].cid);
__ CompareImmediate(class_id_reg, sorted[i].cid);
if (is_last_check) {
assembler()->b(deopt, NE);
__ b(deopt, NE);
} else {
assembler()->b(&next_test, NE);
__ b(&next_test, NE);
}
// Do not use the code from the function, but let the code be patched so
// that we can record the outgoing edges to other code.
@ -1528,47 +1528,11 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
AddStaticCallTarget(function);
__ Drop(argument_count);
if (!is_last_check) {
assembler()->b(&match_found);
__ b(&match_found);
}
assembler()->Bind(&next_test);
__ Bind(&next_test);
}
assembler()->Bind(&match_found);
}
Address FlowGraphCompiler::ElementAddressForIntIndex(intptr_t cid,
intptr_t index_scale,
Register array,
intptr_t index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
intptr_t index_scale,
Register array,
Register index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
intptr_t index_scale,
Register array,
intptr_t index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
intptr_t index_scale,
Register array,
Register index) {
UNREACHABLE();
return FieldAddress(array, index);
__ Bind(&match_found);
}

View file

@ -1529,42 +1529,6 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
}
Address FlowGraphCompiler::ElementAddressForIntIndex(intptr_t cid,
intptr_t index_scale,
Register array,
intptr_t index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
intptr_t index_scale,
Register array,
Register index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
intptr_t index_scale,
Register array,
intptr_t index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
intptr_t index_scale,
Register array,
Register index) {
UNREACHABLE();
return FieldAddress(array, index);
}
#undef __
#define __ compiler_->assembler()->

View file

@ -1539,62 +1539,6 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
}
Address FlowGraphCompiler::ElementAddressForIntIndex(intptr_t cid,
intptr_t index_scale,
Register array,
intptr_t index) {
const int64_t disp =
static_cast<int64_t>(index) * index_scale + 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;
}
}
Address FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
intptr_t index_scale,
Register array,
Register index) {
return FieldAddress(array,
index,
ToScaleFactor(index_scale),
DataOffsetFor(cid));
}
Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
intptr_t index_scale,
Register array,
intptr_t index) {
return Address(array, index * index_scale);
}
Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
intptr_t index_scale,
Register array,
Register index) {
return Address(array, index, ToScaleFactor(index_scale), 0);
}
#undef __
#define __ compiler_->assembler()->

View file

@ -1597,42 +1597,6 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
}
Address FlowGraphCompiler::ElementAddressForIntIndex(intptr_t cid,
intptr_t index_scale,
Register array,
intptr_t index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
intptr_t index_scale,
Register array,
Register index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
intptr_t index_scale,
Register array,
intptr_t index) {
UNREACHABLE();
return FieldAddress(array, index);
}
Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
intptr_t index_scale,
Register array,
Register index) {
UNREACHABLE();
return FieldAddress(array, index);
}
#undef __
#define __ compiler_->assembler()->

View file

@ -1550,11 +1550,11 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
for (intptr_t i = 0; i < len; i++) {
const bool is_last_check = (i == (len - 1));
Label next_test;
assembler()->cmpl(class_id_reg, Immediate(sorted[i].cid));
__ cmpl(class_id_reg, Immediate(sorted[i].cid));
if (is_last_check) {
assembler()->j(NOT_EQUAL, deopt);
__ j(NOT_EQUAL, deopt);
} else {
assembler()->j(NOT_EQUAL, &next_test);
__ j(NOT_EQUAL, &next_test);
}
// Do not use the code from the function, but let the code be patched so
// that we can record the outgoing edges to other code.
@ -1567,67 +1567,11 @@ void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
AddStaticCallTarget(function);
__ Drop(argument_count);
if (!is_last_check) {
assembler()->jmp(&match_found);
__ jmp(&match_found);
}
assembler()->Bind(&next_test);
__ Bind(&next_test);
}
assembler()->Bind(&match_found);
}
Address FlowGraphCompiler::ElementAddressForIntIndex(intptr_t cid,
intptr_t index_scale,
Register array,
intptr_t index) {
const int64_t disp =
static_cast<int64_t>(index) * index_scale + 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;
}
}
Address FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
intptr_t index_scale,
Register array,
Register index) {
return FieldAddress(array,
index,
ToScaleFactor(index_scale),
DataOffsetFor(cid));
}
Address FlowGraphCompiler::ExternalElementAddressForIntIndex(
intptr_t index_scale,
Register array,
intptr_t index) {
return Address(array, index * index_scale);
}
Address FlowGraphCompiler::ExternalElementAddressForRegIndex(
intptr_t index_scale,
Register array,
Register index) {
return Address(array, index, ToScaleFactor(index_scale), 0);
__ Bind(&match_found);
}

View file

@ -311,7 +311,7 @@ void FlowGraphOptimizer::OptimizeLeftShiftBitAndSmiOp(
void FlowGraphOptimizer::AppendLoadIndexedForMerged(Definition* instr,
intptr_t ix,
intptr_t cid) {
const intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(cid);
const intptr_t index_scale = Instance::ElementSizeFor(cid);
ConstantInstr* index_instr =
flow_graph()->GetConstant(Smi::Handle(Smi::New(ix)));
LoadIndexedInstr* load = new LoadIndexedInstr(new Value(instr),
@ -1301,7 +1301,7 @@ bool FlowGraphOptimizer::InlineSetIndexed(
FlowGraph::kValue);
}
intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
const intptr_t index_scale = Instance::ElementSizeFor(array_cid);
*last = new StoreIndexedInstr(new Value(array),
new Value(index),
new Value(stored_value),
@ -1653,7 +1653,7 @@ bool FlowGraphOptimizer::InlineGetIndexed(MethodRecognizer::Kind kind,
}
// Array load and return.
intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
intptr_t index_scale = Instance::ElementSizeFor(array_cid);
*last = new LoadIndexedInstr(new Value(array),
new Value(index),
index_scale,
@ -2724,7 +2724,7 @@ Definition* FlowGraphOptimizer::PrepareInlineStringIndexOp(
LoadIndexedInstr* load_indexed = new LoadIndexedInstr(
new Value(str),
new Value(index),
FlowGraphCompiler::ElementSizeFor(cid),
Instance::ElementSizeFor(cid),
cid,
Isolate::kNoDeoptId,
call->token_pos());
@ -3708,7 +3708,7 @@ intptr_t FlowGraphOptimizer::PrepareInlineByteArrayViewOp(
NULL,
FlowGraph::kValue);
intptr_t element_size = FlowGraphCompiler::ElementSizeFor(array_cid);
intptr_t element_size = Instance::ElementSizeFor(array_cid);
ConstantInstr* bytes_per_element =
flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size)));
BinarySmiOpInstr* len_in_bytes =
@ -3721,7 +3721,7 @@ intptr_t FlowGraphOptimizer::PrepareInlineByteArrayViewOp(
ConstantInstr* length_adjustment =
flow_graph()->GetConstant(Smi::Handle(Smi::New(
FlowGraphCompiler::ElementSizeFor(view_cid) - 1)));
Instance::ElementSizeFor(view_cid) - 1)));
// adjusted_length = len_in_bytes - (element_size - 1).
BinarySmiOpInstr* adjusted_length =
new BinarySmiOpInstr(Token::kSUB,

View file

@ -1203,7 +1203,7 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
if (!IsExternal()) {
ASSERT(this->array()->definition()->representation() == kTagged);
__ AddImmediate(idx,
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
}
Address element_address(idx);
const QRegister result = locs()->out(0).fpu_reg();
@ -1239,7 +1239,7 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(kSmiTagShift == 1);
const intptr_t offset = IsExternal()
? 0
: FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag;
: Instance::DataOffsetFor(class_id()) - kHeapObjectTag;
switch (index_scale()) {
case 1: {
__ add(index.reg(), array, ShifterOperand(index.reg(), ASR, kSmiTagSize));
@ -1250,7 +1250,7 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
// No scaling needed, since index is a smi.
if (!IsExternal()) {
__ AddImmediate(index.reg(), index.reg(),
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
element_address = Address(array, index.reg(), LSL, 0);
} else {
element_address = Address(array, index.reg(), LSL, 0);
@ -1470,7 +1470,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
if (!IsExternal()) {
ASSERT(this->array()->definition()->representation() == kTagged);
__ AddImmediate(idx,
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
}
switch (class_id()) {
case kTypedDataFloat32ArrayCid: {
@ -1508,7 +1508,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(kSmiTagShift == 1);
const intptr_t offset = IsExternal()
? 0
: FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag;
: Instance::DataOffsetFor(class_id()) - kHeapObjectTag;
switch (index_scale()) {
case 1: {
__ add(index.reg(), array, ShifterOperand(index.reg(), ASR, kSmiTagSize));

View file

@ -1010,7 +1010,7 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
intptr_t offset = 0;
if (!IsExternal()) {
ASSERT(this->array()->definition()->representation() == kTagged);
offset = FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag;
offset = Instance::DataOffsetFor(class_id()) - kHeapObjectTag;
}
// Note that index is expected smi-tagged, (i.e, times 2) for all arrays
@ -1204,7 +1204,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
intptr_t offset = 0;
if (!IsExternal()) {
ASSERT(this->array()->definition()->representation() == kTagged);
offset = FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag;
offset = Instance::DataOffsetFor(class_id()) - kHeapObjectTag;
}
// Note that index is expected smi-tagged, (i.e, times 2) for all arrays

View file

@ -822,8 +822,8 @@ static bool CanBeImmediateIndex(Value* value, intptr_t cid) {
return false;
}
const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid);
const intptr_t offset = FlowGraphCompiler::DataOffsetFor(cid);
const intptr_t scale = Instance::ElementSizeFor(cid);
const intptr_t offset = Instance::DataOffsetFor(cid);
const int64_t displacement = index * scale + offset;
return Utils::IsInt(32, displacement);
}
@ -1060,26 +1060,66 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(Isolate* isolate,
}
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);
Address element_address(kNoRegister, 0);
if (IsExternal()) {
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 ((representation() == kUnboxedDouble) ||
(representation() == kUnboxedFloat32x4) ||
@ -1300,21 +1340,11 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Location index = locs()->in(1);
Address element_address(kNoRegister, 0);
if (IsExternal()) {
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());

View file

@ -1165,7 +1165,7 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
// mode, then we must load the offset into a register and add it to the
// index.
element_address = Address(index.reg(),
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
}
if ((representation() == kUnboxedDouble) ||
@ -1186,7 +1186,7 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
break;
case kTypedDataFloat64ArrayCid:
__ LoadDFromOffset(result, index.reg(),
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
break;
case kTypedDataInt32x4ArrayCid:
case kTypedDataFloat32x4ArrayCid:
@ -1371,7 +1371,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
} else {
ASSERT(this->array()->definition()->representation() == kTagged);
element_address = Address(index.reg(),
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
}
switch (class_id()) {
@ -1455,7 +1455,7 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
case kTypedDataFloat64ArrayCid:
__ StoreDToOffset(locs()->in(2).fpu_reg(), index.reg(),
FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
break;
case kTypedDataInt32x4ArrayCid:
case kTypedDataFloat32x4ArrayCid:

View file

@ -751,8 +751,8 @@ static bool CanBeImmediateIndex(Value* index, intptr_t cid) {
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,29 +973,66 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(Isolate* isolate,
}
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);
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 ((representation() == kUnboxedDouble) ||
(representation() == kUnboxedFloat32x4) ||
@ -1161,24 +1198,12 @@ void StoreIndexedInstr::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);
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());

View file

@ -1249,12 +1249,9 @@ void Intrinsifier::Random_nextState(Assembler* assembler) {
__ ldr(R1, FieldAddress(R0, state_field.Offset())); // Field '_state'.
// Addresses of _state[0] and _state[1].
const int64_t disp_0 =
FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid);
const int64_t disp_1 =
FlowGraphCompiler::ElementSizeFor(kTypedDataUint32ArrayCid) +
FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid);
const int64_t disp_0 = Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
const int64_t disp_1 = disp_0 +
Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
__ LoadImmediate(R0, a_int32_value);
__ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);

View file

@ -1134,8 +1134,7 @@ void Intrinsifier::Random_nextState(Assembler* assembler) {
// Addresses of _state[0].
const int64_t disp =
FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid) -
kHeapObjectTag;
Instance::DataOffsetFor(kTypedDataUint32ArrayCid) - kHeapObjectTag;
__ LoadImmediate(R0, a_int_value, kNoPP);
__ LoadFromOffset(R2, R1, disp, kNoPP);

View file

@ -1248,12 +1248,10 @@ void Intrinsifier::Random_nextState(Assembler* assembler) {
__ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver.
__ movl(EBX, FieldAddress(EAX, state_field.Offset())); // Field '_state'.
// Addresses of _state[0] and _state[1].
const intptr_t index_scale =
FlowGraphCompiler::ElementSizeFor(kTypedDataUint32ArrayCid);
const intptr_t offset =
FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid);
Address addr_0 = FieldAddress(EBX, 0 * index_scale + offset);
Address addr_1 = FieldAddress(EBX, 1 * index_scale + offset);
const intptr_t scale = Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
const intptr_t offset = Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
Address addr_0 = FieldAddress(EBX, 0 * scale + offset);
Address addr_1 = FieldAddress(EBX, 1 * scale + offset);
__ movl(EAX, Immediate(a_int32_value));
// 64-bit multiply EAX * value -> EDX:EAX.
__ mull(addr_0);

View file

@ -1275,12 +1275,10 @@ void Intrinsifier::Random_nextState(Assembler* assembler) {
__ lw(T1, FieldAddress(T0, state_field.Offset())); // Field '_state'.
// Addresses of _state[0] and _state[1].
const Address& addr_0 = FieldAddress(T1,
FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid));
const Address& addr_1 = FieldAddress(T1,
FlowGraphCompiler::ElementSizeFor(kTypedDataUint32ArrayCid) +
FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid));
const intptr_t scale = Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
const intptr_t offset = Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
const Address& addr_0 = FieldAddress(T1, 0 * scale + offset);
const Address& addr_1 = FieldAddress(T1, 1 * scale + offset);
__ LoadImmediate(T0, a_int32_value);
__ lw(T2, addr_0);

View file

@ -1150,12 +1150,10 @@ void Intrinsifier::Random_nextState(Assembler* assembler) {
__ movq(RAX, Address(RSP, + 1 * kWordSize)); // Receiver.
__ movq(RBX, FieldAddress(RAX, state_field.Offset())); // Field '_state'.
// Addresses of _state[0] and _state[1].
const intptr_t index_scale =
FlowGraphCompiler::ElementSizeFor(kTypedDataUint32ArrayCid);
const intptr_t offset =
FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid);
Address addr_0 = FieldAddress(RBX, 0 * index_scale + offset);
Address addr_1 = FieldAddress(RBX, 1 * index_scale + offset);
const intptr_t scale = Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
const intptr_t offset = Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
Address addr_0 = FieldAddress(RBX, 0 * scale + offset);
Address addr_1 = FieldAddress(RBX, 1 * scale + offset);
__ movq(RAX, Immediate(a_int_value));
__ movl(RCX, addr_0);
__ imulq(RCX, RAX);

View file

@ -13054,6 +13054,50 @@ bool Instance::IsValidFieldOffset(intptr_t offset) const {
}
intptr_t Instance::ElementSizeFor(intptr_t cid) {
if (RawObject::IsExternalTypedDataClassId(cid)) {
return ExternalTypedData::ElementSizeInBytes(cid);
} else if (RawObject::IsTypedDataClassId(cid)) {
return TypedData::ElementSizeInBytes(cid);
}
switch (cid) {
case kArrayCid:
case kImmutableArrayCid:
return Array::kBytesPerElement;
case kOneByteStringCid:
return OneByteString::kBytesPerElement;
case kTwoByteStringCid:
return TwoByteString::kBytesPerElement;
default:
UNIMPLEMENTED();
return 0;
}
}
intptr_t Instance::DataOffsetFor(intptr_t cid) {
if (RawObject::IsExternalTypedDataClassId(cid)) {
// Elements start at offset 0 of the external data.
return 0;
}
if (RawObject::IsTypedDataClassId(cid)) {
return TypedData::data_offset();
}
switch (cid) {
case kArrayCid:
case kImmutableArrayCid:
return Array::data_offset();
case kOneByteStringCid:
return OneByteString::data_offset();
case kTwoByteStringCid:
return TwoByteString::data_offset();
default:
UNIMPLEMENTED();
return Array::data_offset();
}
}
const char* Instance::ToCString() const {
if (IsNull()) {
return "null";

View file

@ -4212,6 +4212,10 @@ class Instance : public Object {
static RawInstance* New(const Class& cls, Heap::Space space = Heap::kNew);
// Array/list element address computations.
static intptr_t DataOffsetFor(intptr_t cid);
static intptr_t ElementSizeFor(intptr_t cid);
protected:
virtual void PrintSharedInstanceJSON(JSONObject* jsobj, bool ref) const;