Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Unified Diff: runtime/vm/assembler_arm64.cc

Issue 1264543002: Simplify constant pool usage in arm64 code generator (by removing extra argument (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/assembler_arm64_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_arm64.cc
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 4fb6be32b9f143c9905f128f12435026a1459d73..2422cb4572d61b39245097c4ae2ea05d8249bd76 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -30,7 +30,7 @@ Assembler::Assembler(bool use_far_branches)
prologue_offset_(-1),
use_far_branches_(use_far_branches),
comments_(),
- constant_pool_allowed_(true) {
+ constant_pool_allowed_(false) {
}
@@ -302,12 +302,12 @@ bool Operand::IsImmLogical(uint64_t value, uint8_t width, Operand* imm_op) {
}
-void Assembler::LoadPoolPointer(Register pp) {
+void Assembler::LoadPoolPointer() {
const intptr_t object_pool_pc_dist =
Instructions::HeaderSize() - Instructions::object_pool_offset() +
CodeSize();
// PP <- Read(PC - object_pool_pc_dist).
- ldr(pp, Address::PC(-object_pool_pc_dist));
+ ldr(PP, Address::PC(-object_pool_pc_dist));
// When in the PP register, the pool pointer is untagged. When we
// push it on the stack with TagAndPushPP it is tagged again. PopAndUntagPP
@@ -315,22 +315,23 @@ void Assembler::LoadPoolPointer(Register pp) {
// object pool only one instruction for the first 4096 entries. Otherwise,
// because the offset wouldn't be aligned, it would be only one instruction
// for the first 64 entries.
- sub(pp, pp, Operand(kHeapObjectTag));
+ sub(PP, PP, Operand(kHeapObjectTag));
+ set_constant_pool_allowed(true);
}
-void Assembler::LoadWordFromPoolOffset(Register dst, Register pp,
- uint32_t offset) {
- ASSERT(dst != pp);
+void Assembler::LoadWordFromPoolOffset(Register dst, uint32_t offset) {
+ ASSERT(constant_pool_allowed());
+ ASSERT(dst != PP);
Operand op;
const uint32_t upper20 = offset & 0xfffff000;
if (Address::CanHoldOffset(offset)) {
- ldr(dst, Address(pp, offset));
+ ldr(dst, Address(PP, offset));
} else if (Operand::CanHold(upper20, kXRegSizeInBits, &op) ==
Operand::Immediate) {
const uint32_t lower12 = offset & 0x00000fff;
ASSERT(Address::CanHoldOffset(lower12));
- add(dst, pp, op);
+ add(dst, PP, op);
ldr(dst, Address(dst, lower12));
} else {
const uint16_t offset_low = Utils::Low16Bits(offset);
@@ -339,14 +340,14 @@ void Assembler::LoadWordFromPoolOffset(Register dst, Register pp,
if (offset_high != 0) {
movk(dst, Immediate(offset_high), 1);
}
- ldr(dst, Address(pp, dst));
+ ldr(dst, Address(PP, dst));
}
}
-void Assembler::LoadWordFromPoolOffsetFixed(Register dst, Register pp,
- uint32_t offset) {
- ASSERT(dst != pp);
+void Assembler::LoadWordFromPoolOffsetFixed(Register dst, uint32_t offset) {
+ ASSERT(constant_pool_allowed());
+ ASSERT(dst != PP);
Operand op;
const uint32_t upper20 = offset & 0xfffff000;
const uint32_t lower12 = offset & 0x00000fff;
@@ -354,7 +355,7 @@ void Assembler::LoadWordFromPoolOffsetFixed(Register dst, Register pp,
Operand::CanHold(upper20, kXRegSizeInBits, &op);
ASSERT(ot == Operand::Immediate);
ASSERT(Address::CanHoldOffset(lower12));
- add(dst, pp, op);
+ add(dst, PP, op);
ldr(dst, Address(dst, lower12));
}
@@ -383,36 +384,24 @@ bool Assembler::CanLoadFromObjectPool(const Object& object) const {
}
-bool Assembler::CanLoadImmediateFromPool(int64_t imm, Register pp) {
- if (!constant_pool_allowed()) {
- return false;
- }
- return !Utils::IsInt(32, imm) && (pp != kNoPP);
-}
-
-
-void Assembler::LoadExternalLabel(Register dst,
- const ExternalLabel* label,
- Patchability patchable,
- Register pp) {
- const int64_t target = static_cast<int64_t>(label->address());
- if (CanLoadImmediateFromPool(target, pp)) {
+void Assembler::LoadExternalLabel(Register dst, const ExternalLabel* label) {
+ if (constant_pool_allowed()) {
const int32_t offset = ObjectPool::element_offset(
- object_pool_wrapper_.FindExternalLabel(label, patchable));
- LoadWordFromPoolOffset(dst, pp, offset);
+ object_pool_wrapper_.FindExternalLabel(label, kNotPatchable));
+ LoadWordFromPoolOffset(dst, offset);
} else {
- LoadImmediate(dst, target, kNoPP);
+ const int64_t target = static_cast<int64_t>(label->address());
+ LoadImmediate(dst, target);
}
}
void Assembler::LoadExternalLabelFixed(Register dst,
const ExternalLabel* label,
- Patchability patchable,
- Register pp) {
+ Patchability patchable) {
const int32_t offset = ObjectPool::element_offset(
object_pool_wrapper_.FindExternalLabel(label, patchable));
- LoadWordFromPoolOffsetFixed(dst, pp, offset);
+ LoadWordFromPoolOffsetFixed(dst, offset);
}
@@ -423,7 +412,6 @@ void Assembler::LoadIsolate(Register dst) {
void Assembler::LoadObjectHelper(Register dst,
const Object& object,
- Register pp,
bool is_unique) {
if (Thread::CanLoadFromThread(object)) {
ldr(dst, Address(THR, Thread::OffsetFromThread(object)));
@@ -431,43 +419,41 @@ void Assembler::LoadObjectHelper(Register dst,
const int32_t offset = ObjectPool::element_offset(
is_unique ? object_pool_wrapper_.AddObject(object)
: object_pool_wrapper_.FindObject(object));
- LoadWordFromPoolOffset(dst, pp, offset);
+ LoadWordFromPoolOffset(dst, offset);
} else {
ASSERT(object.IsSmi() || object.InVMHeap());
- LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()), pp);
+ LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()));
}
}
-void Assembler::LoadObject(Register dst, const Object& object, Register pp) {
- LoadObjectHelper(dst, object, pp, false);
+void Assembler::LoadObject(Register dst, const Object& object) {
+ LoadObjectHelper(dst, object, false);
}
-void Assembler::LoadUniqueObject(Register dst,
- const Object& object,
- Register pp) {
- LoadObjectHelper(dst, object, pp, true);
+void Assembler::LoadUniqueObject(Register dst, const Object& object) {
+ LoadObjectHelper(dst, object, true);
}
-void Assembler::CompareObject(Register reg, const Object& object, Register pp) {
+void Assembler::CompareObject(Register reg, const Object& object) {
if (Thread::CanLoadFromThread(object)) {
ldr(TMP, Address(THR, Thread::OffsetFromThread(object)));
CompareRegisters(reg, TMP);
} else if (CanLoadFromObjectPool(object)) {
- LoadObject(TMP, object, pp);
+ LoadObject(TMP, object);
CompareRegisters(reg, TMP);
} else {
- CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp);
+ CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()));
}
}
-void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) {
- if ((pp != kNoPP) && constant_pool_allowed()) {
+void Assembler::LoadDecodableImmediate(Register reg, int64_t imm) {
+ if (constant_pool_allowed()) {
const int32_t offset = ObjectPool::element_offset(FindImmediate(imm));
- LoadWordFromPoolOffset(reg, pp, offset);
+ LoadWordFromPoolOffset(reg, offset);
} else {
// TODO(zra): Since this sequence only needs to be decodable, it can be
// of variable length.
@@ -490,102 +476,103 @@ void Assembler::LoadImmediateFixed(Register reg, int64_t imm) {
}
-void Assembler::LoadImmediate(Register reg, int64_t imm, Register pp) {
+void Assembler::LoadImmediate(Register reg, int64_t imm) {
Comment("LoadImmediate");
- if (CanLoadImmediateFromPool(imm, pp)) {
- const int32_t offset = ObjectPool::element_offset(FindImmediate(imm));
- LoadWordFromPoolOffset(reg, pp, offset);
- } else {
- // 0. Is it 0?
- if (imm == 0) {
- movz(reg, Immediate(0), 0);
- return;
- }
+ // Is it 0?
+ if (imm == 0) {
+ movz(reg, Immediate(0), 0);
+ return;
+ }
- // 1. Can we use one orri operation?
- Operand op;
- Operand::OperandType ot;
- ot = Operand::CanHold(imm, kXRegSizeInBits, &op);
- if (ot == Operand::BitfieldImm) {
- orri(reg, ZR, Immediate(imm));
- return;
- }
+ // Can we use one orri operation?
+ Operand op;
+ Operand::OperandType ot;
+ ot = Operand::CanHold(imm, kXRegSizeInBits, &op);
+ if (ot == Operand::BitfieldImm) {
+ orri(reg, ZR, Immediate(imm));
+ return;
+ }
- // 2. Fall back on movz, movk, movn.
- const uint32_t w0 = Utils::Low32Bits(imm);
- const uint32_t w1 = Utils::High32Bits(imm);
- const uint16_t h0 = Utils::Low16Bits(w0);
- const uint16_t h1 = Utils::High16Bits(w0);
- const uint16_t h2 = Utils::Low16Bits(w1);
- const uint16_t h3 = Utils::High16Bits(w1);
-
- // Special case for w1 == 0xffffffff
- if (w1 == 0xffffffff) {
- if (h1 == 0xffff) {
- movn(reg, Immediate(~h0), 0);
- } else {
- movn(reg, Immediate(~h1), 1);
- movk(reg, Immediate(h0), 0);
- }
- return;
+ // We may fall back on movz, movk, movn.
+ const uint32_t w0 = Utils::Low32Bits(imm);
+ const uint32_t w1 = Utils::High32Bits(imm);
+ const uint16_t h0 = Utils::Low16Bits(w0);
+ const uint16_t h1 = Utils::High16Bits(w0);
+ const uint16_t h2 = Utils::Low16Bits(w1);
+ const uint16_t h3 = Utils::High16Bits(w1);
+
+ // Special case for w1 == 0xffffffff
+ if (w1 == 0xffffffff) {
+ if (h1 == 0xffff) {
+ movn(reg, Immediate(~h0), 0);
+ } else {
+ movn(reg, Immediate(~h1), 1);
+ movk(reg, Immediate(h0), 0);
}
+ return;
+ }
- // Special case for h3 == 0xffff
- if (h3 == 0xffff) {
- // We know h2 != 0xffff.
- movn(reg, Immediate(~h2), 2);
- if (h1 != 0xffff) {
- movk(reg, Immediate(h1), 1);
- }
- if (h0 != 0xffff) {
- movk(reg, Immediate(h0), 0);
- }
- return;
+ // Special case for h3 == 0xffff
+ if (h3 == 0xffff) {
+ // We know h2 != 0xffff.
+ movn(reg, Immediate(~h2), 2);
+ if (h1 != 0xffff) {
+ movk(reg, Immediate(h1), 1);
}
+ if (h0 != 0xffff) {
+ movk(reg, Immediate(h0), 0);
+ }
+ return;
+ }
+
+ // Use constant pool if allowed, unless we can load imm with 2 instructions.
+ if ((w1 != 0) && constant_pool_allowed()) {
+ const int32_t offset = ObjectPool::element_offset(FindImmediate(imm));
+ LoadWordFromPoolOffset(reg, offset);
+ return;
+ }
- bool initialized = false;
- if (h0 != 0) {
- movz(reg, Immediate(h0), 0);
+ bool initialized = false;
+ if (h0 != 0) {
+ movz(reg, Immediate(h0), 0);
+ initialized = true;
+ }
+ if (h1 != 0) {
+ if (initialized) {
+ movk(reg, Immediate(h1), 1);
+ } else {
+ movz(reg, Immediate(h1), 1);
initialized = true;
}
- if (h1 != 0) {
- if (initialized) {
- movk(reg, Immediate(h1), 1);
- } else {
- movz(reg, Immediate(h1), 1);
- initialized = true;
- }
- }
- if (h2 != 0) {
- if (initialized) {
- movk(reg, Immediate(h2), 2);
- } else {
- movz(reg, Immediate(h2), 2);
- initialized = true;
- }
+ }
+ if (h2 != 0) {
+ if (initialized) {
+ movk(reg, Immediate(h2), 2);
+ } else {
+ movz(reg, Immediate(h2), 2);
+ initialized = true;
}
- if (h3 != 0) {
- if (initialized) {
- movk(reg, Immediate(h3), 3);
- } else {
- movz(reg, Immediate(h3), 3);
- }
+ }
+ if (h3 != 0) {
+ if (initialized) {
+ movk(reg, Immediate(h3), 3);
+ } else {
+ movz(reg, Immediate(h3), 3);
}
}
}
-void Assembler::LoadDImmediate(VRegister vd, double immd, Register pp) {
+void Assembler::LoadDImmediate(VRegister vd, double immd) {
if (!fmovdi(vd, immd)) {
int64_t imm = bit_cast<int64_t, double>(immd);
- LoadImmediate(TMP, imm, pp);
+ LoadImmediate(TMP, imm);
fmovdr(vd, TMP);
}
}
-void Assembler::AddImmediate(
- Register dest, Register rn, int64_t imm, Register pp) {
+void Assembler::AddImmediate(Register dest, Register rn, int64_t imm) {
Operand op;
if (imm == 0) {
if (dest != rn) {
@@ -601,14 +588,13 @@ void Assembler::AddImmediate(
} else {
// TODO(zra): Try adding top 12 bits, then bottom 12 bits.
ASSERT(rn != TMP2);
- LoadImmediate(TMP2, imm, pp);
+ LoadImmediate(TMP2, imm);
add(dest, rn, Operand(TMP2));
}
}
-void Assembler::AddImmediateSetFlags(
- Register dest, Register rn, int64_t imm, Register pp) {
+void Assembler::AddImmediateSetFlags(Register dest, Register rn, int64_t imm) {
Operand op;
if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
// Handles imm == kMinInt64.
@@ -620,14 +606,13 @@ void Assembler::AddImmediateSetFlags(
} else {
// TODO(zra): Try adding top 12 bits, then bottom 12 bits.
ASSERT(rn != TMP2);
- LoadImmediate(TMP2, imm, pp);
+ LoadImmediate(TMP2, imm);
adds(dest, rn, Operand(TMP2));
}
}
-void Assembler::SubImmediateSetFlags(
- Register dest, Register rn, int64_t imm, Register pp) {
+void Assembler::SubImmediateSetFlags(Register dest, Register rn, int64_t imm) {
Operand op;
if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
// Handles imm == kMinInt64.
@@ -639,60 +624,57 @@ void Assembler::SubImmediateSetFlags(
} else {
// TODO(zra): Try subtracting top 12 bits, then bottom 12 bits.
ASSERT(rn != TMP2);
- LoadImmediate(TMP2, imm, pp);
+ LoadImmediate(TMP2, imm);
subs(dest, rn, Operand(TMP2));
}
}
-void Assembler::AndImmediate(
- Register rd, Register rn, int64_t imm, Register pp) {
+void Assembler::AndImmediate(Register rd, Register rn, int64_t imm) {
Operand imm_op;
if (Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op)) {
andi(rd, rn, Immediate(imm));
} else {
- LoadImmediate(TMP, imm, pp);
+ LoadImmediate(TMP, imm);
and_(rd, rn, Operand(TMP));
}
}
-void Assembler::OrImmediate(
- Register rd, Register rn, int64_t imm, Register pp) {
+void Assembler::OrImmediate(Register rd, Register rn, int64_t imm) {
Operand imm_op;
if (Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op)) {
orri(rd, rn, Immediate(imm));
} else {
- LoadImmediate(TMP, imm, pp);
+ LoadImmediate(TMP, imm);
orr(rd, rn, Operand(TMP));
}
}
-void Assembler::XorImmediate(
- Register rd, Register rn, int64_t imm, Register pp) {
+void Assembler::XorImmediate(Register rd, Register rn, int64_t imm) {
Operand imm_op;
if (Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op)) {
eori(rd, rn, Immediate(imm));
} else {
- LoadImmediate(TMP, imm, pp);
+ LoadImmediate(TMP, imm);
eor(rd, rn, Operand(TMP));
}
}
-void Assembler::TestImmediate(Register rn, int64_t imm, Register pp) {
+void Assembler::TestImmediate(Register rn, int64_t imm) {
Operand imm_op;
if (Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op)) {
tsti(rn, Immediate(imm));
} else {
- LoadImmediate(TMP, imm, pp);
+ LoadImmediate(TMP, imm);
tst(rn, Operand(TMP));
}
}
-void Assembler::CompareImmediate(Register rn, int64_t imm, Register pp) {
+void Assembler::CompareImmediate(Register rn, int64_t imm) {
Operand op;
if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
cmp(rn, op);
@@ -701,80 +683,76 @@ void Assembler::CompareImmediate(Register rn, int64_t imm, Register pp) {
cmn(rn, op);
} else {
ASSERT(rn != TMP2);
- LoadImmediate(TMP2, imm, pp);
+ LoadImmediate(TMP2, imm);
cmp(rn, Operand(TMP2));
}
}
void Assembler::LoadFromOffset(
- Register dest, Register base, int32_t offset, Register pp, OperandSize sz) {
+ Register dest, Register base, int32_t offset, OperandSize sz) {
if (Address::CanHoldOffset(offset, Address::Offset, sz)) {
ldr(dest, Address(base, offset, Address::Offset, sz), sz);
} else {
ASSERT(base != TMP2);
- AddImmediate(TMP2, base, offset, pp);
+ AddImmediate(TMP2, base, offset);
ldr(dest, Address(TMP2), sz);
}
}
-void Assembler::LoadDFromOffset(
- VRegister dest, Register base, int32_t offset, Register pp) {
+void Assembler::LoadDFromOffset(VRegister dest, Register base, int32_t offset) {
if (Address::CanHoldOffset(offset, Address::Offset, kDWord)) {
fldrd(dest, Address(base, offset, Address::Offset, kDWord));
} else {
ASSERT(base != TMP2);
- AddImmediate(TMP2, base, offset, pp);
+ AddImmediate(TMP2, base, offset);
fldrd(dest, Address(TMP2));
}
}
-void Assembler::LoadQFromOffset(
- VRegister dest, Register base, int32_t offset, Register pp) {
+void Assembler::LoadQFromOffset(VRegister dest, Register base, int32_t offset) {
if (Address::CanHoldOffset(offset, Address::Offset, kQWord)) {
fldrq(dest, Address(base, offset, Address::Offset, kQWord));
} else {
ASSERT(base != TMP2);
- AddImmediate(TMP2, base, offset, pp);
+ AddImmediate(TMP2, base, offset);
fldrq(dest, Address(TMP2));
}
}
void Assembler::StoreToOffset(
- Register src, Register base, int32_t offset, Register pp, OperandSize sz) {
+ Register src, Register base, int32_t offset, OperandSize sz) {
ASSERT(base != TMP2);
if (Address::CanHoldOffset(offset, Address::Offset, sz)) {
str(src, Address(base, offset, Address::Offset, sz), sz);
} else {
ASSERT(src != TMP2);
- AddImmediate(TMP2, base, offset, pp);
+ AddImmediate(TMP2, base, offset);
str(src, Address(TMP2), sz);
}
}
-void Assembler::StoreDToOffset(
- VRegister src, Register base, int32_t offset, Register pp) {
+void Assembler::StoreDToOffset(VRegister src, Register base, int32_t offset) {
if (Address::CanHoldOffset(offset, Address::Offset, kDWord)) {
fstrd(src, Address(base, offset, Address::Offset, kDWord));
} else {
ASSERT(base != TMP2);
- AddImmediate(TMP2, base, offset, pp);
+ AddImmediate(TMP2, base, offset);
fstrd(src, Address(TMP2));
}
}
-void Assembler::StoreQToOffset(
- VRegister src, Register base, int32_t offset, Register pp) {
+void Assembler::StoreQToOffset(VRegister src, Register base, int32_t offset) {
if (Address::CanHoldOffset(offset, Address::Offset, kQWord)) {
fstrq(src, Address(base, offset, Address::Offset, kQWord));
} else {
ASSERT(base != TMP2);
- AddImmediate(TMP2, base, offset, pp);
+ AddImmediate(TMP2, base, offset);
fstrq(src, Address(TMP2));
}
}
@@ -848,13 +826,12 @@ void Assembler::StoreIntoObjectFilter(Register object,
void Assembler::StoreIntoObjectOffset(Register object,
int32_t offset,
Register value,
- Register pp,
bool can_value_be_smi) {
if (Address::CanHoldOffset(offset - kHeapObjectTag)) {
StoreIntoObject(
object, FieldAddress(object, offset), value, can_value_be_smi);
} else {
- AddImmediate(TMP, object, offset - kHeapObjectTag, pp);
+ AddImmediate(TMP, object, offset - kHeapObjectTag);
StoreIntoObject(object, Address(TMP), value, can_value_be_smi);
}
}
@@ -908,12 +885,11 @@ void Assembler::StoreIntoObjectNoBarrier(Register object,
void Assembler::StoreIntoObjectOffsetNoBarrier(Register object,
int32_t offset,
- Register value,
- Register pp) {
+ Register value) {
if (Address::CanHoldOffset(offset - kHeapObjectTag)) {
StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
} else {
- AddImmediate(TMP, object, offset - kHeapObjectTag, pp);
+ AddImmediate(TMP, object, offset - kHeapObjectTag);
StoreIntoObjectNoBarrier(object, Address(TMP), value);
}
}
@@ -925,71 +901,69 @@ void Assembler::StoreIntoObjectNoBarrier(Register object,
ASSERT(value.IsSmi() || value.InVMHeap() ||
(value.IsOld() && value.IsNotTemporaryScopedHandle()));
// No store buffer update.
- LoadObject(TMP2, value, PP);
+ LoadObject(TMP2, value);
str(TMP2, dest);
}
void Assembler::StoreIntoObjectOffsetNoBarrier(Register object,
int32_t offset,
- const Object& value,
- Register pp) {
+ const Object& value) {
if (Address::CanHoldOffset(offset - kHeapObjectTag)) {
StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
} else {
- AddImmediate(TMP, object, offset - kHeapObjectTag, pp);
+ AddImmediate(TMP, object, offset - kHeapObjectTag);
StoreIntoObjectNoBarrier(object, Address(TMP), value);
}
}
-void Assembler::LoadClassId(Register result, Register object, Register pp) {
+void Assembler::LoadClassId(Register result, Register object) {
ASSERT(RawObject::kClassIdTagPos == kBitsPerInt32);
ASSERT(RawObject::kClassIdTagSize == kBitsPerInt32);
const intptr_t class_id_offset = Object::tags_offset() +
RawObject::kClassIdTagPos / kBitsPerByte;
- LoadFromOffset(result, object, class_id_offset - kHeapObjectTag, pp,
+ LoadFromOffset(result, object, class_id_offset - kHeapObjectTag,
kUnsignedWord);
}
-void Assembler::LoadClassById(Register result, Register class_id, Register pp) {
+void Assembler::LoadClassById(Register result, Register class_id) {
ASSERT(result != class_id);
LoadIsolate(result);
const intptr_t offset =
Isolate::class_table_offset() + ClassTable::table_offset();
- LoadFromOffset(result, result, offset, pp);
+ LoadFromOffset(result, result, offset);
ldr(result, Address(result, class_id, UXTX, Address::Scaled));
}
-void Assembler::LoadClass(Register result, Register object, Register pp) {
+void Assembler::LoadClass(Register result, Register object) {
ASSERT(object != TMP);
- LoadClassId(TMP, object, pp);
- LoadClassById(result, TMP, pp);
+ LoadClassId(TMP, object);
+ LoadClassById(result, TMP);
}
-void Assembler::CompareClassId(
- Register object, intptr_t class_id, Register pp) {
- LoadClassId(TMP, object, pp);
- CompareImmediate(TMP, class_id, pp);
+void Assembler::CompareClassId(Register object, intptr_t class_id) {
+ LoadClassId(TMP, object);
+ CompareImmediate(TMP, class_id);
}
void Assembler::LoadClassIdMayBeSmi(Register result, Register object) {
// Load up a null object. We only need it so we can use LoadClassId on it in
// the case that object is a Smi..
- LoadObject(TMP, Object::null_object(), PP);
+ LoadObject(TMP, Object::null_object());
// Check if the object is a Smi.
tsti(object, Immediate(kSmiTagMask));
// If the object *is* a Smi, use the null object instead. o/w leave alone.
csel(TMP, TMP, object, EQ);
// Loads either the cid of the object if it isn't a Smi, or the cid of null
// if it is a Smi, which will be ignored.
- LoadClassId(result, TMP, PP);
+ LoadClassId(result, TMP);
- LoadImmediate(TMP, kSmiCid, PP);
+ LoadImmediate(TMP, kSmiCid);
// If object is a Smi, move the Smi cid into result. o/w leave alone.
csel(result, TMP, result, EQ);
}
@@ -1011,22 +985,22 @@ void Assembler::ComputeRange(Register result,
b(&not_smi, NE);
AsrImmediate(scratch, value, 32);
- LoadImmediate(result, ICData::kUint32RangeBit, PP);
+ LoadImmediate(result, ICData::kUint32RangeBit);
cmp(scratch, Operand(1));
b(&done, EQ);
neg(scratch, scratch);
add(result, scratch, Operand(ICData::kInt32RangeBit));
cmp(scratch, Operand(1));
- LoadImmediate(TMP, ICData::kSignedRangeBit, PP);
+ LoadImmediate(TMP, ICData::kSignedRangeBit);
csel(result, result, TMP, LS);
b(&done);
Bind(&not_smi);
- CompareClassId(value, kMintCid, PP);
+ CompareClassId(value, kMintCid);
b(not_mint, NE);
- LoadImmediate(result, ICData::kInt64RangeBit, PP);
+ LoadImmediate(result, ICData::kInt64RangeBit);
Bind(&done);
}
@@ -1052,7 +1026,7 @@ void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
// Reserve space for arguments and align frame before entering
// the C++ world.
if (frame_space != 0) {
- AddImmediate(SP, SP, -frame_space, kNoPP);
+ AddImmediate(SP, SP, -frame_space);
}
if (OS::ActivationFrameAlignment() > 1) {
andi(SP, SP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
@@ -1077,37 +1051,40 @@ void Assembler::LeaveFrame() {
void Assembler::EnterDartFrame(intptr_t frame_size) {
+ ASSERT(!constant_pool_allowed());
// Setup the frame.
adr(TMP, Immediate(-CodeSize())); // TMP gets PC marker.
EnterFrame(0);
TagAndPushPPAndPcMarker(TMP); // Save PP and PC marker.
// Load the pool pointer.
- LoadPoolPointer(PP);
+ LoadPoolPointer();
// Reserve space.
if (frame_size > 0) {
- AddImmediate(SP, SP, -frame_size, PP);
+ AddImmediate(SP, SP, -frame_size);
}
}
void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp) {
+ ASSERT(!constant_pool_allowed());
// Setup the frame.
adr(TMP, Immediate(-CodeSize())); // TMP gets PC marker.
EnterFrame(0);
TagAndPushPPAndPcMarker(TMP); // Save PP and PC marker.
// Load the pool pointer.
- if (new_pp == kNoPP) {
- LoadPoolPointer(PP);
+ if (new_pp == kNoRegister) {
+ LoadPoolPointer();
} else {
mov(PP, new_pp);
+ set_constant_pool_allowed(true);
}
// Reserve space.
if (frame_size > 0) {
- AddImmediate(SP, SP, -frame_size, PP);
+ AddImmediate(SP, SP, -frame_size);
}
}
@@ -1118,27 +1095,33 @@ void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp) {
// optimized function and there may be extra space for spill slots to
// allocate. We must also set up the pool pointer for the function.
void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) {
+ ASSERT(!constant_pool_allowed());
Comment("EnterOsrFrame");
adr(TMP, Immediate(-CodeSize()));
- StoreToOffset(TMP, FP, kPcMarkerSlotFromFp * kWordSize, kNoPP);
+ StoreToOffset(TMP, FP, kPcMarkerSlotFromFp * kWordSize);
// Setup pool pointer for this dart function.
- if (new_pp == kNoPP) {
- LoadPoolPointer(PP);
+ if (new_pp == kNoRegister) {
+ LoadPoolPointer();
} else {
mov(PP, new_pp);
+ set_constant_pool_allowed(true);
}
if (extra_size > 0) {
- AddImmediate(SP, SP, -extra_size, PP);
+ AddImmediate(SP, SP, -extra_size);
}
}
void Assembler::LeaveDartFrame() {
+ // LeaveDartFrame is called from stubs (pp disallowed) and from Dart code (pp
+ // allowed), so there is no point in checking the current value of
+ // constant_pool_allowed().
+ set_constant_pool_allowed(false);
// Restore and untag PP.
- LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize, kNoPP);
+ LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize);
sub(PP, PP, Operand(kHeapObjectTag));
LeaveFrame();
}
@@ -1176,7 +1159,7 @@ void Assembler::LeaveCallRuntimeFrame() {
const intptr_t kPushedRegistersSize =
kDartVolatileCpuRegCount * kWordSize +
kDartVolatileFpuRegCount * kWordSize;
- AddImmediate(SP, FP, -kPushedRegistersSize, PP);
+ AddImmediate(SP, FP, -kPushedRegistersSize);
for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) {
const Register reg = static_cast<Register>(i);
Pop(reg);
@@ -1204,23 +1187,24 @@ void Assembler::CallRuntime(const RuntimeEntry& entry,
void Assembler::EnterStubFrame() {
+ set_constant_pool_allowed(false);
EnterFrame(0);
// Save caller's pool pointer. Push 0 in the saved PC area for stub frames.
TagAndPushPPAndPcMarker(ZR);
- LoadPoolPointer(PP);
+ LoadPoolPointer();
}
void Assembler::LeaveStubFrame() {
+ set_constant_pool_allowed(false);
// Restore and untag PP.
- LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize, kNoPP);
+ LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize);
sub(PP, PP, Operand(kHeapObjectTag));
LeaveFrame();
}
void Assembler::UpdateAllocationStats(intptr_t cid,
- Register pp,
Heap::Space space,
bool inline_isolate) {
ASSERT(cid > 0);
@@ -1231,28 +1215,27 @@ void Assembler::UpdateAllocationStats(intptr_t cid,
ClassHeapStats** table_ptr = class_table->TableAddressFor(cid);
if (cid < kNumPredefinedCids) {
LoadImmediate(
- TMP2, reinterpret_cast<uword>(*table_ptr) + counter_offset, pp);
+ TMP2, reinterpret_cast<uword>(*table_ptr) + counter_offset);
} else {
- LoadImmediate(TMP2, reinterpret_cast<uword>(table_ptr), pp);
+ LoadImmediate(TMP2, reinterpret_cast<uword>(table_ptr));
ldr(TMP, Address(TMP2));
- AddImmediate(TMP2, TMP, counter_offset, pp);
+ AddImmediate(TMP2, TMP, counter_offset);
}
} else {
LoadIsolate(TMP2);
intptr_t table_offset =
Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
ldr(TMP, Address(TMP2, table_offset));
- AddImmediate(TMP2, TMP, counter_offset, pp);
+ AddImmediate(TMP2, TMP, counter_offset);
}
ldr(TMP, Address(TMP2, 0));
- AddImmediate(TMP, TMP, 1, pp);
+ AddImmediate(TMP, TMP, 1);
str(TMP, Address(TMP2, 0));
}
void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
Register size_reg,
- Register pp,
Heap::Space space,
bool inline_isolate) {
ASSERT(cid > 0);
@@ -1268,21 +1251,21 @@ void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
ClassHeapStats** table_ptr = class_table->TableAddressFor(cid);
if (cid < kNumPredefinedCids) {
LoadImmediate(TMP2,
- reinterpret_cast<uword>(*table_ptr) + class_offset, pp);
+ reinterpret_cast<uword>(*table_ptr) + class_offset);
} else {
- LoadImmediate(TMP2, reinterpret_cast<uword>(table_ptr), pp);
+ LoadImmediate(TMP2, reinterpret_cast<uword>(table_ptr));
ldr(TMP, Address(TMP2));
- AddImmediate(TMP2, TMP, class_offset, pp);
+ AddImmediate(TMP2, TMP, class_offset);
}
} else {
LoadIsolate(TMP2);
intptr_t table_offset =
Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
ldr(TMP, Address(TMP2, table_offset));
- AddImmediate(TMP2, TMP, class_offset, pp);
+ AddImmediate(TMP2, TMP, class_offset);
}
ldr(TMP, Address(TMP2, count_field_offset));
- AddImmediate(TMP, TMP, 1, pp);
+ AddImmediate(TMP, TMP, 1);
str(TMP, Address(TMP2, count_field_offset));
ldr(TMP, Address(TMP2, size_field_offset));
add(TMP, TMP, Operand(size_reg));
@@ -1292,7 +1275,6 @@ void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
void Assembler::MaybeTraceAllocation(intptr_t cid,
Register temp_reg,
- Register pp,
Label* trace,
bool inline_isolate) {
ASSERT(cid > 0);
@@ -1302,18 +1284,18 @@ void Assembler::MaybeTraceAllocation(intptr_t cid,
ClassHeapStats** table_ptr = class_table->TableAddressFor(cid);
if (cid < kNumPredefinedCids) {
LoadImmediate(
- temp_reg, reinterpret_cast<uword>(*table_ptr) + state_offset, pp);
+ temp_reg, reinterpret_cast<uword>(*table_ptr) + state_offset);
} else {
- LoadImmediate(temp_reg, reinterpret_cast<uword>(table_ptr), pp);
+ LoadImmediate(temp_reg, reinterpret_cast<uword>(table_ptr));
ldr(temp_reg, Address(temp_reg, 0));
- AddImmediate(temp_reg, temp_reg, state_offset, pp);
+ AddImmediate(temp_reg, temp_reg, state_offset);
}
} else {
LoadIsolate(temp_reg);
intptr_t table_offset =
Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
ldr(temp_reg, Address(temp_reg, table_offset));
- AddImmediate(temp_reg, temp_reg, state_offset, pp);
+ AddImmediate(temp_reg, temp_reg, state_offset);
}
ldr(temp_reg, Address(temp_reg, 0));
tsti(temp_reg, Immediate(ClassHeapStats::TraceAllocationMask()));
@@ -1324,22 +1306,21 @@ void Assembler::MaybeTraceAllocation(intptr_t cid,
void Assembler::TryAllocate(const Class& cls,
Label* failure,
Register instance_reg,
- Register temp_reg,
- Register pp) {
+ Register temp_reg) {
ASSERT(failure != NULL);
if (FLAG_inline_alloc) {
// If this allocation is traced, program will jump to failure path
// (i.e. the allocation stub) which will allocate the object and trace the
// allocation call site.
- MaybeTraceAllocation(cls.id(), temp_reg, pp, failure);
+ MaybeTraceAllocation(cls.id(), temp_reg, failure);
const intptr_t instance_size = cls.instance_size();
Heap* heap = Isolate::Current()->heap();
Heap::Space space = heap->SpaceForAllocation(cls.id());
const uword top_address = heap->TopAddress(space);
- LoadImmediate(temp_reg, top_address, pp);
+ LoadImmediate(temp_reg, top_address);
ldr(instance_reg, Address(temp_reg));
// TODO(koda): Protect against unsigned overflow here.
- AddImmediateSetFlags(instance_reg, instance_reg, instance_size, pp);
+ AddImmediateSetFlags(instance_reg, instance_reg, instance_size);
// instance_reg: potential next object start.
const uword end_address = heap->EndAddress(space);
@@ -1356,15 +1337,15 @@ void Assembler::TryAllocate(const Class& cls,
ASSERT(instance_size >= kHeapObjectTag);
AddImmediate(
- instance_reg, instance_reg, -instance_size + kHeapObjectTag, pp);
- UpdateAllocationStats(cls.id(), pp, space);
+ instance_reg, instance_reg, -instance_size + kHeapObjectTag);
+ UpdateAllocationStats(cls.id(), space);
uword tags = 0;
tags = RawObject::SizeTag::update(instance_size, tags);
ASSERT(cls.id() != kIllegalCid);
tags = RawObject::ClassIdTag::update(cls.id(), tags);
- LoadImmediate(TMP, tags, pp);
- StoreFieldToOffset(TMP, instance_reg, Object::tags_offset(), pp);
+ LoadImmediate(TMP, tags);
+ StoreFieldToOffset(TMP, instance_reg, Object::tags_offset());
} else {
b(failure);
}
@@ -1382,19 +1363,19 @@ void Assembler::TryAllocateArray(intptr_t cid,
// If this allocation is traced, program will jump to failure path
// (i.e. the allocation stub) which will allocate the object and trace the
// allocation call site.
- MaybeTraceAllocation(cid, temp1, PP, failure);
+ MaybeTraceAllocation(cid, temp1, failure);
Isolate* isolate = Isolate::Current();
Heap* heap = isolate->heap();
Heap::Space space = heap->SpaceForAllocation(cid);
- LoadImmediate(temp1, heap->TopAddress(space), PP);
+ LoadImmediate(temp1, heap->TopAddress(space));
ldr(instance, Address(temp1, 0)); // Potential new object start.
- AddImmediateSetFlags(end_address, instance, instance_size, PP);
+ AddImmediateSetFlags(end_address, instance, instance_size);
b(failure, CS); // Fail on unsigned overflow.
// Check if the allocation fits into the remaining space.
// instance: potential new object start.
// end_address: potential next object start.
- LoadImmediate(temp2, heap->EndAddress(space), PP);
+ LoadImmediate(temp2, heap->EndAddress(space));
ldr(temp2, Address(temp2, 0));
cmp(end_address, Operand(temp2));
b(failure, CS);
@@ -1403,15 +1384,15 @@ void Assembler::TryAllocateArray(intptr_t cid,
// next object start and initialize the object.
str(end_address, Address(temp1, 0));
add(instance, instance, Operand(kHeapObjectTag));
- LoadImmediate(temp2, instance_size, PP);
- UpdateAllocationStatsWithSize(cid, temp2, PP, space);
+ LoadImmediate(temp2, instance_size);
+ UpdateAllocationStatsWithSize(cid, temp2, space);
// Initialize the tags.
// instance: new object start as a tagged pointer.
uword tags = 0;
tags = RawObject::ClassIdTag::update(cid, tags);
tags = RawObject::SizeTag::update(instance_size, tags);
- LoadImmediate(temp2, tags, PP);
+ LoadImmediate(temp2, tags);
str(temp2, FieldAddress(instance, Array::tags_offset())); // Store tags.
} else {
b(failure);
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/assembler_arm64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698