[turbofan] Fix assert caused by bogus merging of out-of-scope CodeAssembler variables
Previously, CodeAssembler Variables declared in an explicit C++ scope would continue to be merged into future labels beyond that scope, causing asserts. This CL ensures that Variables are properly ignored when they go out of scope. Review-Url: https://codereview.chromium.org/2035683002 Cr-Commit-Position: refs/heads/master@{#36690}
This commit is contained in:
parent
afb0e7a4bd
commit
70e302eedd
@ -600,10 +600,12 @@ class CodeAssembler::Variable::Impl : public ZoneObject {
|
|||||||
|
|
||||||
CodeAssembler::Variable::Variable(CodeAssembler* assembler,
|
CodeAssembler::Variable::Variable(CodeAssembler* assembler,
|
||||||
MachineRepresentation rep)
|
MachineRepresentation rep)
|
||||||
: impl_(new (assembler->zone()) Impl(rep)) {
|
: impl_(new (assembler->zone()) Impl(rep)), assembler_(assembler) {
|
||||||
assembler->variables_.push_back(impl_);
|
assembler->variables_.insert(impl_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodeAssembler::Variable::~Variable() { assembler_->variables_.erase(impl_); }
|
||||||
|
|
||||||
void CodeAssembler::Variable::Bind(Node* value) { impl_->value_ = value; }
|
void CodeAssembler::Variable::Bind(Node* value) { impl_->value_ = value; }
|
||||||
|
|
||||||
Node* CodeAssembler::Variable::value() const {
|
Node* CodeAssembler::Variable::value() const {
|
||||||
|
@ -166,6 +166,7 @@ class CodeAssembler {
|
|||||||
class Variable {
|
class Variable {
|
||||||
public:
|
public:
|
||||||
explicit Variable(CodeAssembler* assembler, MachineRepresentation rep);
|
explicit Variable(CodeAssembler* assembler, MachineRepresentation rep);
|
||||||
|
~Variable();
|
||||||
void Bind(Node* value);
|
void Bind(Node* value);
|
||||||
Node* value() const;
|
Node* value() const;
|
||||||
MachineRepresentation rep() const;
|
MachineRepresentation rep() const;
|
||||||
@ -175,6 +176,7 @@ class CodeAssembler {
|
|||||||
friend class CodeAssembler;
|
friend class CodeAssembler;
|
||||||
class Impl;
|
class Impl;
|
||||||
Impl* impl_;
|
Impl* impl_;
|
||||||
|
CodeAssembler* assembler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AllocationFlag : uint8_t {
|
enum AllocationFlag : uint8_t {
|
||||||
@ -362,7 +364,7 @@ class CodeAssembler {
|
|||||||
Code::Flags flags_;
|
Code::Flags flags_;
|
||||||
const char* name_;
|
const char* name_;
|
||||||
bool code_generated_;
|
bool code_generated_;
|
||||||
ZoneVector<Variable::Impl*> variables_;
|
ZoneSet<Variable::Impl*> variables_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
|
DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
|
||||||
};
|
};
|
||||||
|
@ -1090,5 +1090,34 @@ TEST(DeferredCodePhiHints) {
|
|||||||
CHECK(!m.GenerateCode().is_null());
|
CHECK(!m.GenerateCode().is_null());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TestOutOfScopeVariable) {
|
||||||
|
typedef CodeStubAssembler::Label Label;
|
||||||
|
typedef CodeStubAssembler::Variable Variable;
|
||||||
|
Isolate* isolate(CcTest::InitIsolateOnce());
|
||||||
|
VoidDescriptor descriptor(isolate);
|
||||||
|
CodeStubAssemblerTester m(isolate, descriptor);
|
||||||
|
Label block1(&m);
|
||||||
|
Label block2(&m);
|
||||||
|
Label block3(&m);
|
||||||
|
Label block4(&m);
|
||||||
|
m.Branch(m.WordEqual(m.Parameter(0), m.IntPtrConstant(0)), &block1, &block4);
|
||||||
|
m.Bind(&block4);
|
||||||
|
{
|
||||||
|
Variable var_object(&m, MachineRepresentation::kTagged);
|
||||||
|
m.Branch(m.WordEqual(m.Parameter(0), m.IntPtrConstant(0)), &block2,
|
||||||
|
&block3);
|
||||||
|
|
||||||
|
m.Bind(&block2);
|
||||||
|
var_object.Bind(m.IntPtrConstant(55));
|
||||||
|
m.Goto(&block1);
|
||||||
|
|
||||||
|
m.Bind(&block3);
|
||||||
|
var_object.Bind(m.IntPtrConstant(66));
|
||||||
|
m.Goto(&block1);
|
||||||
|
}
|
||||||
|
m.Bind(&block1);
|
||||||
|
CHECK(!m.GenerateCode().is_null());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
Loading…
Reference in New Issue
Block a user