| Index: runtime/vm/intermediate_language.h
|
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
|
| index 2c4f46eb9fca804504057c3146675d9bb431b4f3..76d2a050ab761296adf019a85465450370b0a6b9 100644
|
| --- a/runtime/vm/intermediate_language.h
|
| +++ b/runtime/vm/intermediate_language.h
|
| @@ -3217,24 +3217,29 @@ class CheckArrayBoundInstr : public TemplateDefinition<2> {
|
|
|
| #undef DECLARE_INSTRUCTION
|
|
|
| -
|
| class Environment : public ZoneAllocated {
|
| public:
|
| // Construct an environment by constructing uses from an array of definitions.
|
| - Environment(const GrowableArray<Definition*>& definitions,
|
| - intptr_t fixed_parameter_count);
|
| + static Environment* From(const GrowableArray<Definition*>& definitions,
|
| + intptr_t fixed_parameter_count,
|
| + const Environment* outer);
|
|
|
| void set_locations(Location* locations) {
|
| ASSERT(locations_ == NULL);
|
| locations_ = locations;
|
| }
|
|
|
| - const GrowableArray<Value*>& values() const {
|
| - return values_;
|
| + void set_deopt_id(intptr_t deopt_id) { deopt_id_ = deopt_id; }
|
| + intptr_t deopt_id() const { return deopt_id_; }
|
| +
|
| + Environment* outer() const { return outer_; }
|
| +
|
| + Value* ValueAt(intptr_t ix) const {
|
| + return values_[ix];
|
| }
|
|
|
| - GrowableArray<Value*>* values_ptr() {
|
| - return &values_;
|
| + intptr_t Length() const {
|
| + return values_.length();
|
| }
|
|
|
| Location LocationAt(intptr_t ix) const {
|
| @@ -3247,6 +3252,17 @@ class Environment : public ZoneAllocated {
|
| return &locations_[ix];
|
| }
|
|
|
| + // The use index is the index in the flattened environment.
|
| + Value* ValueAtUseIndex(intptr_t ix) const {
|
| + const Environment* env = this;
|
| + while (ix >= env->Length()) {
|
| + ASSERT(env->outer_ != NULL);
|
| + ix -= env->Length();
|
| + env = env->outer_;
|
| + }
|
| + return env->ValueAt(ix);
|
| + }
|
| +
|
| intptr_t fixed_parameter_count() const {
|
| return fixed_parameter_count_;
|
| }
|
| @@ -3256,19 +3272,78 @@ class Environment : public ZoneAllocated {
|
| void PrintTo(BufferFormatter* f) const;
|
|
|
| private:
|
| - Environment(intptr_t length, intptr_t fixed_parameter_count)
|
| + Environment(intptr_t length,
|
| + intptr_t fixed_parameter_count,
|
| + intptr_t deopt_id,
|
| + Environment* outer)
|
| : values_(length),
|
| locations_(NULL),
|
| - fixed_parameter_count_(fixed_parameter_count) { }
|
| + fixed_parameter_count_(fixed_parameter_count),
|
| + deopt_id_(deopt_id),
|
| + outer_(outer) { }
|
| +
|
| + Environment* Copy() const;
|
|
|
| GrowableArray<Value*> values_;
|
| Location* locations_;
|
| const intptr_t fixed_parameter_count_;
|
| + intptr_t deopt_id_;
|
| + Environment* outer_;
|
|
|
| + friend class EnvironmentIterator;
|
| DISALLOW_COPY_AND_ASSIGN(Environment);
|
| };
|
|
|
|
|
| +// Iterator over the full deoptimization environment.
|
| +// Iterates the environment from the inner most to the outer most.
|
| +class EnvironmentIterator : public ValueObject {
|
| + public:
|
| + explicit EnvironmentIterator(Environment* env) : env_(env), ix_(0) { }
|
| +
|
| + void Advance() {
|
| + ASSERT(!Done());
|
| + if (++ix_ == env_->values_.length()) {
|
| + ix_ = 0;
|
| + env_ = env_->outer();
|
| + }
|
| + }
|
| +
|
| + bool Done() const {
|
| + return env_ == NULL || ix_ == env_->values_.length();
|
| + }
|
| +
|
| + Value* CurrentValue() const {
|
| + return env_->values_[ix_];
|
| + }
|
| +
|
| + Location CurrentLocation() const {
|
| + return env_->locations_[ix_];
|
| + }
|
| +
|
| + Location* CurrentLocationSlot() const {
|
| + return &env_->locations_[ix_];
|
| + }
|
| +
|
| + Environment* CurrentEnvironment() const {
|
| + return env_;
|
| + }
|
| +
|
| + void ReplaceCurrentValue(Value* value) {
|
| + env_->values_[ix_] = value;
|
| + }
|
| +
|
| + void ReplaceCurrentLocation(Location loc) {
|
| + env_->locations_[ix_] = loc;
|
| + }
|
| +
|
| + private:
|
| + Environment* env_;
|
| + intptr_t ix_;
|
| +};
|
| +
|
| +
|
| +
|
| // Visitor base class to visit each instruction and computation in a flow
|
| // graph as defined by a reversed list of basic blocks.
|
| class FlowGraphVisitor : public ValueObject {
|
|
|