Commit eeb32224 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

Allow move semantics on Labels

The Label class currently allows to be copied on all platforms except
for arm64, where it can not be copied or moved.
This allows too much though:
Copying a label even on another platform than arm64 might fail if the
label was linked already, because only one of the copies will be bound
later, and the other will fire a DCHECK error in its destructor.

This CL changes the restriction to never allow to copy construct or
assign a Label, but allow move construction and move assignment on all
platforms except arm64.
This will allow to place Labels in containers, as will be done in
Liftoff (except for arm64, where it still needs to be allocated on the
heap).

R=mstarzinger@chromium.org

Bug: v8:6600
Change-Id: Ic1234c2d233317eed6a3d537c13faed2c701fe13
Reviewed-on: https://chromium-review.googlesource.com/783190
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49570}
parent 0d7a870b
......@@ -941,14 +941,14 @@ void Assembler::target_at_put(int pos, int target_pos) {
instr_at_put(pos, instr | (imm24 & kImm24Mask));
}
void Assembler::print(Label* L) {
void Assembler::print(const Label* L) {
if (L->is_unused()) {
PrintF("unused label\n");
} else if (L->is_bound()) {
PrintF("bound label to %d\n", L->pos());
} else if (L->is_linked()) {
Label l = *L;
Label l;
l.link_to(L->pos());
PrintF("unbound label");
while (l.is_linked()) {
PrintF("@ %d ", l.pos());
......
......@@ -1714,7 +1714,7 @@ class Assembler : public AssemblerBase {
void AddrMode5(Instr instr, CRegister crd, const MemOperand& x);
// Labels
void print(Label* L);
void print(const Label* L);
void bind_to(Label* L, int pos);
void next(Label* L);
......
......@@ -1515,14 +1515,14 @@ void Assembler::ud2() {
// to be generated; pos() is the position of the 32bit
// Displacement of the last instruction using the label.
void Assembler::print(Label* L) {
void Assembler::print(const Label* L) {
if (L->is_unused()) {
PrintF("unused label\n");
} else if (L->is_bound()) {
PrintF("bound label to %d\n", L->pos());
} else if (L->is_linked()) {
Label l = *L;
Label l;
l.link_to(L->pos());
PrintF("unbound label");
while (l.is_linked()) {
Displacement disp = disp_at(&l);
......
......@@ -1759,7 +1759,7 @@ class Assembler : public AssemblerBase {
LeadingOpcode m, VexW w);
// labels
void print(Label* L);
void print(const Label* L);
void bind_to(Label* L, int pos);
// displacements
......
......@@ -20,10 +20,28 @@ class Label {
public:
enum Distance { kNear, kFar };
INLINE(Label()) {
Unuse();
UnuseNear();
Label() = default;
// On ARM64, the Assembler keeps track of pointers to Labels to resolve
// branches to distant targets. Copying labels would confuse the Assembler.
// On other platforms, allow move construction.
#if !V8_TARGET_ARCH_ARM64
// In debug builds, the old Label has to be cleared in order to avoid a DCHECK
// failure in it's destructor.
#ifdef DEBUG
Label(Label&& other) { *this = std::move(other); }
Label& operator=(Label&& other) {
pos_ = other.pos_;
near_link_pos_ = other.near_link_pos_;
other.Unuse();
other.UnuseNear();
return *this;
}
#else
Label(Label&&) = default;
Label& operator=(Label&&) = default;
#endif
#endif
INLINE(~Label()) {
DCHECK(!is_linked());
......@@ -55,10 +73,10 @@ class Label {
// pos_ < 0 bound label, pos() returns the jump target position
// pos_ == 0 unused label
// pos_ > 0 linked label, pos() returns the last reference position
int pos_;
int pos_ = 0;
// Behaves like |pos_| in the "> 0" case, but for near jumps to this label.
int near_link_pos_;
int near_link_pos_ = 0;
void bind_to(int pos) {
pos_ = -pos - 1;
......@@ -78,11 +96,9 @@ class Label {
friend class Displacement;
friend class RegExpMacroAssemblerIrregexp;
#if V8_TARGET_ARCH_ARM64
// On ARM64, the Assembler keeps track of pointers to Labels to resolve
// branches to distant targets. Copying labels would confuse the Assembler.
DISALLOW_COPY_AND_ASSIGN(Label); // NOLINT
#endif
// Disallow copy construction and assignment, but allow move construction and
// move assignment on selected platforms (see above).
DISALLOW_COPY_AND_ASSIGN(Label);
};
} // namespace internal
......
......@@ -924,14 +924,14 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos,
}
}
void Assembler::print(Label* L) {
void Assembler::print(const Label* L) {
if (L->is_unused()) {
PrintF("unused label\n");
} else if (L->is_bound()) {
PrintF("bound label to %d\n", L->pos());
} else if (L->is_linked()) {
Label l = *L;
Label l;
l.link_to(L->pos());
PrintF("unbound label");
while (l.is_linked()) {
PrintF("@ %d ", l.pos());
......
......@@ -2113,7 +2113,7 @@ class Assembler : public AssemblerBase {
}
// Labels.
void print(Label* L);
void print(const Label* L);
void bind_to(Label* L, int pos);
void next(Label* L, bool is_internal);
......
......@@ -887,14 +887,14 @@ void Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
}
}
void Assembler::print(Label* L) {
void Assembler::print(const Label* L) {
if (L->is_unused()) {
PrintF("unused label\n");
} else if (L->is_bound()) {
PrintF("bound label to %d\n", L->pos());
} else if (L->is_linked()) {
Label l = *L;
Label l;
l.link_to(L->pos());
PrintF("unbound label");
while (l.is_linked()) {
PrintF("@ %d ", l.pos());
......
......@@ -2176,7 +2176,7 @@ class Assembler : public AssemblerBase {
}
// Labels.
void print(Label* L);
void print(const Label* L);
void bind_to(Label* L, int pos);
void next(Label* L, bool is_internal);
......
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