diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2011-01-24 20:55:18 -0800 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2011-01-24 20:55:18 -0800 |
commit | 4c5e570706c6e2a0fa2a6dbeef54553b8da07b6c (patch) | |
tree | add83cbc40d3189ca135590e623030582fc649ef /deps/v8/src/lithium-allocator.h | |
parent | 07f3274ac425a55454b32caeb17f4b0d10683971 (diff) | |
download | node-4c5e570706c6e2a0fa2a6dbeef54553b8da07b6c.tar.gz |
Upgrade V8 to 3.0.10
Diffstat (limited to 'deps/v8/src/lithium-allocator.h')
-rw-r--r-- | deps/v8/src/lithium-allocator.h | 412 |
1 files changed, 9 insertions, 403 deletions
diff --git a/deps/v8/src/lithium-allocator.h b/deps/v8/src/lithium-allocator.h index 48c65631d..83f5583e3 100644 --- a/deps/v8/src/lithium-allocator.h +++ b/deps/v8/src/lithium-allocator.h @@ -48,6 +48,8 @@ class StringStream; class LArgument; class LChunk; +class LOperand; +class LUnallocated; class LConstantOperand; class LGap; class LParallelMove; @@ -149,355 +151,6 @@ enum RegisterKind { }; -class LOperand: public ZoneObject { - public: - enum Kind { - INVALID, - UNALLOCATED, - CONSTANT_OPERAND, - STACK_SLOT, - DOUBLE_STACK_SLOT, - REGISTER, - DOUBLE_REGISTER, - ARGUMENT - }; - - LOperand() : value_(KindField::encode(INVALID)) { } - - Kind kind() const { return KindField::decode(value_); } - int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } - bool IsConstantOperand() const { return kind() == CONSTANT_OPERAND; } - bool IsStackSlot() const { return kind() == STACK_SLOT; } - bool IsDoubleStackSlot() const { return kind() == DOUBLE_STACK_SLOT; } - bool IsRegister() const { return kind() == REGISTER; } - bool IsDoubleRegister() const { return kind() == DOUBLE_REGISTER; } - bool IsArgument() const { return kind() == ARGUMENT; } - bool IsUnallocated() const { return kind() == UNALLOCATED; } - bool Equals(LOperand* other) const { return value_ == other->value_; } - int VirtualRegister(); - - void PrintTo(StringStream* stream); - void ConvertTo(Kind kind, int index) { - value_ = KindField::encode(kind); - value_ |= index << kKindFieldWidth; - ASSERT(this->index() == index); - } - - protected: - static const int kKindFieldWidth = 3; - class KindField : public BitField<Kind, 0, kKindFieldWidth> { }; - - LOperand(Kind kind, int index) { ConvertTo(kind, index); } - - unsigned value_; -}; - - -class LUnallocated: public LOperand { - public: - enum Policy { - NONE, - ANY, - FIXED_REGISTER, - FIXED_DOUBLE_REGISTER, - FIXED_SLOT, - MUST_HAVE_REGISTER, - WRITABLE_REGISTER, - SAME_AS_FIRST_INPUT, - IGNORE - }; - - // Lifetime of operand inside the instruction. - enum Lifetime { - // USED_AT_START operand is guaranteed to be live only at - // instruction start. Register allocator is free to assign the same register - // to some other operand used inside instruction (i.e. temporary or - // output). - USED_AT_START, - - // USED_AT_END operand is treated as live until the end of - // instruction. This means that register allocator will not reuse it's - // register for any other operand inside instruction. - USED_AT_END - }; - - explicit LUnallocated(Policy policy) : LOperand(UNALLOCATED, 0) { - Initialize(policy, 0, USED_AT_END); - } - - LUnallocated(Policy policy, int fixed_index) : LOperand(UNALLOCATED, 0) { - Initialize(policy, fixed_index, USED_AT_END); - } - - LUnallocated(Policy policy, Lifetime lifetime) : LOperand(UNALLOCATED, 0) { - Initialize(policy, 0, lifetime); - } - - // The superclass has a KindField. Some policies have a signed fixed - // index in the upper bits. - static const int kPolicyWidth = 4; - static const int kLifetimeWidth = 1; - static const int kVirtualRegisterWidth = 17; - - static const int kPolicyShift = kKindFieldWidth; - static const int kLifetimeShift = kPolicyShift + kPolicyWidth; - static const int kVirtualRegisterShift = kLifetimeShift + kLifetimeWidth; - static const int kFixedIndexShift = - kVirtualRegisterShift + kVirtualRegisterWidth; - - class PolicyField : public BitField<Policy, kPolicyShift, kPolicyWidth> { }; - - class LifetimeField - : public BitField<Lifetime, kLifetimeShift, kLifetimeWidth> { - }; - - class VirtualRegisterField - : public BitField<unsigned, - kVirtualRegisterShift, - kVirtualRegisterWidth> { - }; - - static const int kMaxVirtualRegisters = 1 << (kVirtualRegisterWidth + 1); - static const int kMaxFixedIndices = 128; - - bool HasIgnorePolicy() const { return policy() == IGNORE; } - bool HasNoPolicy() const { return policy() == NONE; } - bool HasAnyPolicy() const { - return policy() == ANY; - } - bool HasFixedPolicy() const { - return policy() == FIXED_REGISTER || - policy() == FIXED_DOUBLE_REGISTER || - policy() == FIXED_SLOT; - } - bool HasRegisterPolicy() const { - return policy() == WRITABLE_REGISTER || policy() == MUST_HAVE_REGISTER; - } - bool HasSameAsInputPolicy() const { - return policy() == SAME_AS_FIRST_INPUT; - } - Policy policy() const { return PolicyField::decode(value_); } - void set_policy(Policy policy) { - value_ &= ~PolicyField::mask(); - value_ |= PolicyField::encode(policy); - } - int fixed_index() const { - return static_cast<int>(value_) >> kFixedIndexShift; - } - - unsigned virtual_register() const { - return VirtualRegisterField::decode(value_); - } - - void set_virtual_register(unsigned id) { - value_ &= ~VirtualRegisterField::mask(); - value_ |= VirtualRegisterField::encode(id); - } - - LUnallocated* CopyUnconstrained() { - LUnallocated* result = new LUnallocated(ANY); - result->set_virtual_register(virtual_register()); - return result; - } - - static LUnallocated* cast(LOperand* op) { - ASSERT(op->IsUnallocated()); - return reinterpret_cast<LUnallocated*>(op); - } - - bool IsUsedAtStart() { - return LifetimeField::decode(value_) == USED_AT_START; - } - - private: - void Initialize(Policy policy, int fixed_index, Lifetime lifetime) { - value_ |= PolicyField::encode(policy); - value_ |= LifetimeField::encode(lifetime); - value_ |= fixed_index << kFixedIndexShift; - ASSERT(this->fixed_index() == fixed_index); - } -}; - - -class LMoveOperands BASE_EMBEDDED { - public: - LMoveOperands(LOperand* source, LOperand* destination) - : source_(source), destination_(destination) { - } - - LOperand* source() const { return source_; } - void set_source(LOperand* operand) { source_ = operand; } - - LOperand* destination() const { return destination_; } - void set_destination(LOperand* operand) { destination_ = operand; } - - // The gap resolver marks moves as "in-progress" by clearing the - // destination (but not the source). - bool IsPending() const { - return destination_ == NULL && source_ != NULL; - } - - // True if this move a move into the given destination operand. - bool Blocks(LOperand* operand) const { - return !IsEliminated() && source()->Equals(operand); - } - - // A move is redundant if it's been eliminated, if its source and - // destination are the same, or if its destination is unneeded. - bool IsRedundant() const { - return IsEliminated() || source_->Equals(destination_) || IsIgnored(); - } - - bool IsIgnored() const { - return destination_ != NULL && - destination_->IsUnallocated() && - LUnallocated::cast(destination_)->HasIgnorePolicy(); - } - - // We clear both operands to indicate move that's been eliminated. - void Eliminate() { source_ = destination_ = NULL; } - bool IsEliminated() const { - ASSERT(source_ != NULL || destination_ == NULL); - return source_ == NULL; - } - - private: - LOperand* source_; - LOperand* destination_; -}; - - -class LConstantOperand: public LOperand { - public: - static LConstantOperand* Create(int index) { - ASSERT(index >= 0); - if (index < kNumCachedOperands) return &cache[index]; - return new LConstantOperand(index); - } - - static LConstantOperand* cast(LOperand* op) { - ASSERT(op->IsConstantOperand()); - return reinterpret_cast<LConstantOperand*>(op); - } - - static void SetupCache(); - - private: - static const int kNumCachedOperands = 128; - static LConstantOperand cache[]; - - LConstantOperand() : LOperand() { } - explicit LConstantOperand(int index) : LOperand(CONSTANT_OPERAND, index) { } -}; - - -class LArgument: public LOperand { - public: - explicit LArgument(int index) : LOperand(ARGUMENT, index) { } - - static LArgument* cast(LOperand* op) { - ASSERT(op->IsArgument()); - return reinterpret_cast<LArgument*>(op); - } -}; - - -class LStackSlot: public LOperand { - public: - static LStackSlot* Create(int index) { - ASSERT(index >= 0); - if (index < kNumCachedOperands) return &cache[index]; - return new LStackSlot(index); - } - - static LStackSlot* cast(LOperand* op) { - ASSERT(op->IsStackSlot()); - return reinterpret_cast<LStackSlot*>(op); - } - - static void SetupCache(); - - private: - static const int kNumCachedOperands = 128; - static LStackSlot cache[]; - - LStackSlot() : LOperand() { } - explicit LStackSlot(int index) : LOperand(STACK_SLOT, index) { } -}; - - -class LDoubleStackSlot: public LOperand { - public: - static LDoubleStackSlot* Create(int index) { - ASSERT(index >= 0); - if (index < kNumCachedOperands) return &cache[index]; - return new LDoubleStackSlot(index); - } - - static LDoubleStackSlot* cast(LOperand* op) { - ASSERT(op->IsStackSlot()); - return reinterpret_cast<LDoubleStackSlot*>(op); - } - - static void SetupCache(); - - private: - static const int kNumCachedOperands = 128; - static LDoubleStackSlot cache[]; - - LDoubleStackSlot() : LOperand() { } - explicit LDoubleStackSlot(int index) : LOperand(DOUBLE_STACK_SLOT, index) { } -}; - - -class LRegister: public LOperand { - public: - static LRegister* Create(int index) { - ASSERT(index >= 0); - if (index < kNumCachedOperands) return &cache[index]; - return new LRegister(index); - } - - static LRegister* cast(LOperand* op) { - ASSERT(op->IsRegister()); - return reinterpret_cast<LRegister*>(op); - } - - static void SetupCache(); - - private: - static const int kNumCachedOperands = 16; - static LRegister cache[]; - - LRegister() : LOperand() { } - explicit LRegister(int index) : LOperand(REGISTER, index) { } -}; - - -class LDoubleRegister: public LOperand { - public: - static LDoubleRegister* Create(int index) { - ASSERT(index >= 0); - if (index < kNumCachedOperands) return &cache[index]; - return new LDoubleRegister(index); - } - - static LDoubleRegister* cast(LOperand* op) { - ASSERT(op->IsDoubleRegister()); - return reinterpret_cast<LDoubleRegister*>(op); - } - - static void SetupCache(); - - private: - static const int kNumCachedOperands = 16; - static LDoubleRegister cache[]; - - LDoubleRegister() : LOperand() { } - explicit LDoubleRegister(int index) : LOperand(DOUBLE_REGISTER, index) { } -}; - - // A register-allocator view of a Lithium instruction. It contains the id of // the output operand and a list of input operand uses. class InstructionSummary: public ZoneObject { @@ -588,27 +241,14 @@ class UseInterval: public ZoneObject { // Representation of a use position. class UsePosition: public ZoneObject { public: - UsePosition(LifetimePosition pos, LOperand* operand) - : operand_(operand), - hint_(NULL), - pos_(pos), - next_(NULL), - requires_reg_(false), - register_beneficial_(true) { - if (operand_ != NULL && operand_->IsUnallocated()) { - LUnallocated* unalloc = LUnallocated::cast(operand_); - requires_reg_ = unalloc->HasRegisterPolicy(); - register_beneficial_ = !unalloc->HasAnyPolicy(); - } - ASSERT(pos_.IsValid()); - } + UsePosition(LifetimePosition pos, LOperand* operand); LOperand* operand() const { return operand_; } bool HasOperand() const { return operand_ != NULL; } LOperand* hint() const { return hint_; } void set_hint(LOperand* hint) { hint_ = hint; } - bool HasHint() const { return hint_ != NULL && !hint_->IsUnallocated(); } + bool HasHint() const; bool RequiresRegister() const; bool RegisterIsBeneficial() const; @@ -634,21 +274,7 @@ class LiveRange: public ZoneObject { public: static const int kInvalidAssignment = 0x7fffffff; - explicit LiveRange(int id) - : id_(id), - spilled_(false), - assigned_register_(kInvalidAssignment), - assigned_register_kind_(NONE), - last_interval_(NULL), - first_interval_(NULL), - first_pos_(NULL), - parent_(NULL), - next_(NULL), - current_interval_(NULL), - last_processed_use_(NULL), - spill_start_index_(kMaxInt) { - spill_operand_ = new LUnallocated(LUnallocated::IGNORE); - } + explicit LiveRange(int id); UseInterval* first_interval() const { return first_interval_; } UsePosition* first_pos() const { return first_pos_; } @@ -663,19 +289,8 @@ class LiveRange: public ZoneObject { LOperand* CreateAssignedOperand(); int assigned_register() const { return assigned_register_; } int spill_start_index() const { return spill_start_index_; } - void set_assigned_register(int reg, RegisterKind register_kind) { - ASSERT(!HasRegisterAssigned() && !IsSpilled()); - assigned_register_ = reg; - assigned_register_kind_ = register_kind; - ConvertOperands(); - } - void MakeSpilled() { - ASSERT(!IsSpilled()); - ASSERT(TopLevel()->HasAllocatedSpillOperand()); - spilled_ = true; - assigned_register_ = kInvalidAssignment; - ConvertOperands(); - } + void set_assigned_register(int reg, RegisterKind register_kind); + void MakeSpilled(); // Returns use position in this live range that follows both start // and last processed use position. @@ -724,17 +339,9 @@ class LiveRange: public ZoneObject { return last_interval_->end(); } - bool HasAllocatedSpillOperand() const { - return spill_operand_ != NULL && !spill_operand_->IsUnallocated(); - } - + bool HasAllocatedSpillOperand() const; LOperand* GetSpillOperand() const { return spill_operand_; } - void SetSpillOperand(LOperand* operand) { - ASSERT(!operand->IsUnallocated()); - ASSERT(spill_operand_ != NULL); - ASSERT(spill_operand_->IsUnallocated()); - spill_operand_->ConvertTo(operand->kind(), operand->index()); - } + void SetSpillOperand(LOperand* operand); void SetSpillStartIndex(int start) { spill_start_index_ = Min(start, spill_start_index_); @@ -984,7 +591,6 @@ class LAllocator BASE_EMBEDDED { void Spill(LiveRange* range); bool IsBlockBoundary(LifetimePosition pos); - void AddGapMove(int pos, LiveRange* prev, LiveRange* next); // Helper methods for resolving control flow. void ResolveControlFlow(LiveRange* range, |