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) { ...@@ -941,14 +941,14 @@ void Assembler::target_at_put(int pos, int target_pos) {
instr_at_put(pos, instr | (imm24 & kImm24Mask)); instr_at_put(pos, instr | (imm24 & kImm24Mask));
} }
void Assembler::print(const Label* L) {
void Assembler::print(Label* L) {
if (L->is_unused()) { if (L->is_unused()) {
PrintF("unused label\n"); PrintF("unused label\n");
} else if (L->is_bound()) { } else if (L->is_bound()) {
PrintF("bound label to %d\n", L->pos()); PrintF("bound label to %d\n", L->pos());
} else if (L->is_linked()) { } else if (L->is_linked()) {
Label l = *L; Label l;
l.link_to(L->pos());
PrintF("unbound label"); PrintF("unbound label");
while (l.is_linked()) { while (l.is_linked()) {
PrintF("@ %d ", l.pos()); PrintF("@ %d ", l.pos());
......
...@@ -1714,7 +1714,7 @@ class Assembler : public AssemblerBase { ...@@ -1714,7 +1714,7 @@ class Assembler : public AssemblerBase {
void AddrMode5(Instr instr, CRegister crd, const MemOperand& x); void AddrMode5(Instr instr, CRegister crd, const MemOperand& x);
// Labels // Labels
void print(Label* L); void print(const Label* L);
void bind_to(Label* L, int pos); void bind_to(Label* L, int pos);
void next(Label* L); void next(Label* L);
......
...@@ -1515,14 +1515,14 @@ void Assembler::ud2() { ...@@ -1515,14 +1515,14 @@ void Assembler::ud2() {
// to be generated; pos() is the position of the 32bit // to be generated; pos() is the position of the 32bit
// Displacement of the last instruction using the label. // Displacement of the last instruction using the label.
void Assembler::print(const Label* L) {
void Assembler::print(Label* L) {
if (L->is_unused()) { if (L->is_unused()) {
PrintF("unused label\n"); PrintF("unused label\n");
} else if (L->is_bound()) { } else if (L->is_bound()) {
PrintF("bound label to %d\n", L->pos()); PrintF("bound label to %d\n", L->pos());
} else if (L->is_linked()) { } else if (L->is_linked()) {
Label l = *L; Label l;
l.link_to(L->pos());
PrintF("unbound label"); PrintF("unbound label");
while (l.is_linked()) { while (l.is_linked()) {
Displacement disp = disp_at(&l); Displacement disp = disp_at(&l);
......
...@@ -1759,7 +1759,7 @@ class Assembler : public AssemblerBase { ...@@ -1759,7 +1759,7 @@ class Assembler : public AssemblerBase {
LeadingOpcode m, VexW w); LeadingOpcode m, VexW w);
// labels // labels
void print(Label* L); void print(const Label* L);
void bind_to(Label* L, int pos); void bind_to(Label* L, int pos);
// displacements // displacements
......
...@@ -20,10 +20,28 @@ class Label { ...@@ -20,10 +20,28 @@ class Label {
public: public:
enum Distance { kNear, kFar }; enum Distance { kNear, kFar };
INLINE(Label()) { Label() = default;
Unuse();
UnuseNear(); // 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()) { INLINE(~Label()) {
DCHECK(!is_linked()); DCHECK(!is_linked());
...@@ -55,10 +73,10 @@ class Label { ...@@ -55,10 +73,10 @@ class Label {
// pos_ < 0 bound label, pos() returns the jump target position // pos_ < 0 bound label, pos() returns the jump target position
// pos_ == 0 unused label // pos_ == 0 unused label
// pos_ > 0 linked label, pos() returns the last reference position // 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. // 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) { void bind_to(int pos) {
pos_ = -pos - 1; pos_ = -pos - 1;
...@@ -78,11 +96,9 @@ class Label { ...@@ -78,11 +96,9 @@ class Label {
friend class Displacement; friend class Displacement;
friend class RegExpMacroAssemblerIrregexp; friend class RegExpMacroAssemblerIrregexp;
#if V8_TARGET_ARCH_ARM64 // Disallow copy construction and assignment, but allow move construction and
// On ARM64, the Assembler keeps track of pointers to Labels to resolve // move assignment on selected platforms (see above).
// branches to distant targets. Copying labels would confuse the Assembler. DISALLOW_COPY_AND_ASSIGN(Label);
DISALLOW_COPY_AND_ASSIGN(Label); // NOLINT
#endif
}; };
} // namespace internal } // namespace internal
......
...@@ -924,14 +924,14 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos, ...@@ -924,14 +924,14 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos,
} }
} }
void Assembler::print(const Label* L) {
void Assembler::print(Label* L) {
if (L->is_unused()) { if (L->is_unused()) {
PrintF("unused label\n"); PrintF("unused label\n");
} else if (L->is_bound()) { } else if (L->is_bound()) {
PrintF("bound label to %d\n", L->pos()); PrintF("bound label to %d\n", L->pos());
} else if (L->is_linked()) { } else if (L->is_linked()) {
Label l = *L; Label l;
l.link_to(L->pos());
PrintF("unbound label"); PrintF("unbound label");
while (l.is_linked()) { while (l.is_linked()) {
PrintF("@ %d ", l.pos()); PrintF("@ %d ", l.pos());
......
...@@ -2113,7 +2113,7 @@ class Assembler : public AssemblerBase { ...@@ -2113,7 +2113,7 @@ class Assembler : public AssemblerBase {
} }
// Labels. // Labels.
void print(Label* L); void print(const Label* L);
void bind_to(Label* L, int pos); void bind_to(Label* L, int pos);
void next(Label* L, bool is_internal); void next(Label* L, bool is_internal);
......
...@@ -887,14 +887,14 @@ void Assembler::target_at_put(int pos, int target_pos, bool is_internal) { ...@@ -887,14 +887,14 @@ void Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
} }
} }
void Assembler::print(const Label* L) {
void Assembler::print(Label* L) {
if (L->is_unused()) { if (L->is_unused()) {
PrintF("unused label\n"); PrintF("unused label\n");
} else if (L->is_bound()) { } else if (L->is_bound()) {
PrintF("bound label to %d\n", L->pos()); PrintF("bound label to %d\n", L->pos());
} else if (L->is_linked()) { } else if (L->is_linked()) {
Label l = *L; Label l;
l.link_to(L->pos());
PrintF("unbound label"); PrintF("unbound label");
while (l.is_linked()) { while (l.is_linked()) {
PrintF("@ %d ", l.pos()); PrintF("@ %d ", l.pos());
......
...@@ -2176,7 +2176,7 @@ class Assembler : public AssemblerBase { ...@@ -2176,7 +2176,7 @@ class Assembler : public AssemblerBase {
} }
// Labels. // Labels.
void print(Label* L); void print(const Label* L);
void bind_to(Label* L, int pos); void bind_to(Label* L, int pos);
void next(Label* L, bool is_internal); 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