Revision: 6638
Author: [email protected]
Date: Fri Feb  4 05:28:23 2011
Log: Remove instruction summaries.

Instead of constructing a temporary container for all LOperands of each
instruction, the register works directly on the LIR instructions that
 provide an abstract interface for input/output/temp operands.

This saves allocation of zone memory and speeds up LIR construction,
but makes iterating over all uses in the register allocator slightly
more expensive because environment uses are stored in a linked list of
environments. We can fix this by using a flat representation of LOperands.


Review URL: http://codereview.chromium.org/6352006
http://code.google.com/p/v8/source/detail?r=6638

Added:
 /branches/bleeding_edge/src/lithium-allocator-inl.h
Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/lithium-allocator.cc
 /branches/bleeding_edge/src/lithium-allocator.h
 /branches/bleeding_edge/src/lithium.h
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h
 /branches/bleeding_edge/tools/gyp/v8.gyp
 /branches/bleeding_edge/tools/visual_studio/v8_base.vcproj
 /branches/bleeding_edge/tools/visual_studio/v8_base_arm.vcproj
 /branches/bleeding_edge/tools/visual_studio/v8_base_x64.vcproj

=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/lithium-allocator-inl.h Fri Feb 4 05:28:23 2011
@@ -0,0 +1,140 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_LITHIUM_ALLOCATOR_INL_H_
+#define V8_LITHIUM_ALLOCATOR_INL_H_
+
+#include "lithium-allocator.h"
+
+#if V8_TARGET_ARCH_IA32
+#include "ia32/lithium-ia32.h"
+#elif V8_TARGET_ARCH_X64
+#include "x64/lithium-x64.h"
+#elif V8_TARGET_ARCH_ARM
+#include "arm/lithium-arm.h"
+#else
+#error "Unknown architecture."
+#endif
+
+namespace v8 {
+namespace internal {
+
+bool LAllocator::IsGapAt(int index) { return chunk_->IsGapAt(index); }
+
+
+LInstruction* LAllocator::InstructionAt(int index) {
+  return chunk_->instructions()->at(index);
+}
+
+
+LGap* LAllocator::GapAt(int index) {
+  return chunk_->GetGapAt(index);
+}
+
+
+TempIterator::TempIterator(LInstruction* instr)
+    : instr_(instr),
+      limit_(instr->TempCount()),
+      current_(0) {
+  current_ = AdvanceToNext(0);
+}
+
+
+bool TempIterator::HasNext() { return current_ < limit_; }
+
+
+LOperand* TempIterator::Next() {
+  ASSERT(HasNext());
+  return instr_->TempAt(current_);
+}
+
+
+int TempIterator::AdvanceToNext(int start) {
+  while (start < limit_ && instr_->TempAt(start) == NULL) start++;
+  return start;
+}
+
+
+void TempIterator::Advance() {
+  current_ = AdvanceToNext(current_ + 1);
+}
+
+
+InputIterator::InputIterator(LInstruction* instr)
+    : instr_(instr),
+      limit_(instr->InputCount()),
+      current_(0) {
+  current_ = AdvanceToNext(0);
+}
+
+
+bool InputIterator::HasNext() { return current_ < limit_; }
+
+
+LOperand* InputIterator::Next() {
+  ASSERT(HasNext());
+  return instr_->InputAt(current_);
+}
+
+
+void InputIterator::Advance() {
+  current_ = AdvanceToNext(current_ + 1);
+}
+
+
+int InputIterator::AdvanceToNext(int start) {
+ while (start < limit_ && instr_->InputAt(start)->IsConstantOperand()) start++;
+  return start;
+}
+
+
+UseIterator::UseIterator(LInstruction* instr)
+    : input_iterator_(instr), env_iterator_(instr->environment()) { }
+
+
+bool UseIterator::HasNext() {
+  return input_iterator_.HasNext() || env_iterator_.HasNext();
+}
+
+
+LOperand* UseIterator::Next() {
+  ASSERT(HasNext());
+  return input_iterator_.HasNext()
+      ? input_iterator_.Next()
+      : env_iterator_.Next();
+}
+
+
+void UseIterator::Advance() {
+  input_iterator_.HasNext()
+      ? input_iterator_.Advance()
+      : env_iterator_.Advance();
+}
+
+} }  // namespace v8::internal
+
+#endif  // V8_LITHIUM_ALLOCATOR_INL_H_
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Fri Feb  4 02:52:19 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Fri Feb  4 05:28:23 2011
@@ -25,6 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+#include "lithium-allocator-inl.h"
 #include "arm/lithium-arm.h"
 #include "arm/lithium-codegen-arm.h"

@@ -54,6 +55,31 @@
   ASSERT(register_spills_[allocation_index] == NULL);
   register_spills_[allocation_index] = spill_operand;
 }
+
+
+#ifdef DEBUG
+void LInstruction::VerifyCall() {
+  // Call instructions can use only fixed registers as
+  // temporaries and outputs because all registers
+  // are blocked by the calling convention.
+  // Inputs can use either fixed register or have a short lifetime (be
+  // used at start of the instruction).
+  ASSERT(Output() == NULL ||
+         LUnallocated::cast(Output())->HasFixedPolicy() ||
+         !LUnallocated::cast(Output())->HasRegisterPolicy());
+  for (UseIterator it(this); it.HasNext(); it.Advance()) {
+    LOperand* operand = it.Next();
+    ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
+           LUnallocated::cast(operand)->IsUsedAtStart() ||
+           !LUnallocated::cast(operand)->HasRegisterPolicy());
+  }
+  for (TempIterator it(this); it.HasNext(); it.Advance()) {
+    LOperand* operand = it.Next();
+    ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
+           !LUnallocated::cast(operand)->HasRegisterPolicy());
+  }
+}
+#endif


 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
@@ -66,9 +92,8 @@

 void LInstruction::PrintTo(StringStream* stream) {
   stream->Add("%s ", this->Mnemonic());
-  if (HasResult()) {
-    PrintOutputOperandTo(stream);
-  }
+
+  PrintOutputOperandTo(stream);

   PrintDataTo(stream);

@@ -401,7 +426,7 @@
 }


-int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
+void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
   LGap* gap = new LGap(block);
   int index = -1;
   if (instr->IsControl()) {
@@ -417,7 +442,6 @@
     pointer_maps_.Add(instr->pointer_map());
     instr->pointer_map()->set_lithium_position(index);
   }
-  return index;
 }


@@ -683,7 +707,10 @@
 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
                                         HInstruction* hinstr,
                                         CanDeoptimize can_deoptimize) {
-  allocator_->MarkAsCall();
+#ifdef DEBUG
+  instr->VerifyCall();
+#endif
+  instr->MarkAsCall();
   instr = AssignPointerMap(instr);

   if (hinstr->HasSideEffects()) {
@@ -708,7 +735,7 @@


 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
-  allocator_->MarkAsSaveDoubles();
+  instr->MarkAsSaveDoubles();
   return instr;
 }

@@ -908,7 +935,6 @@
 void LChunkBuilder::VisitInstruction(HInstruction* current) {
   HInstruction* old_current = current_instruction_;
   current_instruction_ = current;
-  allocator_->BeginInstruction();
   if (current->has_position()) position_ = current->position();
   LInstruction* instr = current->CompileToLithium(this);

@@ -931,11 +957,7 @@
       instr->set_hydrogen_value(current);
     }

-    int index = chunk_->AddInstruction(instr, current_block_);
-    allocator_->SummarizeInstruction(index);
-  } else {
-    // This instruction should be omitted.
-    allocator_->OmitInstruction();
+    chunk_->AddInstruction(instr, current_block_);
   }
   current_instruction_ = old_current;
 }
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Thu Feb  3 23:08:50 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Fri Feb  4 05:28:23 2011
@@ -181,7 +181,10 @@
 class LInstruction: public ZoneObject {
  public:
   LInstruction()
-      : hydrogen_value_(NULL) { }
+      :  environment_(NULL),
+         hydrogen_value_(NULL),
+         is_call_(false),
+         is_save_doubles_(false) { }
   virtual ~LInstruction() { }

   virtual void CompileToNative(LCodeGen* generator) = 0;
@@ -198,15 +201,13 @@
   virtual bool IsControl() const { return false; }
   virtual void SetBranchTargets(int true_block_id, int false_block_id) { }

-  void set_environment(LEnvironment* env) { environment_.set(env); }
-  LEnvironment* environment() const { return environment_.get(); }
-  bool HasEnvironment() const { return environment_.is_set(); }
+  void set_environment(LEnvironment* env) { environment_ = env; }
+  LEnvironment* environment() const { return environment_; }
+  bool HasEnvironment() const { return environment_ != NULL; }

   void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
   LPointerMap* pointer_map() const { return pointer_map_.get(); }
   bool HasPointerMap() const { return pointer_map_.is_set(); }
-
-  virtual bool HasResult() const = 0;

   void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
   HValue* hydrogen_value() const { return hydrogen_value_; }
@@ -220,12 +221,32 @@
   bool HasDeoptimizationEnvironment() const {
     return deoptimization_environment_.is_set();
   }
+
+  void MarkAsCall() { is_call_ = true; }
+  void MarkAsSaveDoubles() { is_save_doubles_ = true; }
+
+  // Interface to the register allocator and iterators.
+  bool IsMarkedAsCall() const { return is_call_; }
+  bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; }
+
+  virtual bool HasResult() const = 0;
+  virtual LOperand* result() = 0;
+
+  virtual int InputCount() = 0;
+  virtual LOperand* InputAt(int i) = 0;
+  virtual int TempCount() = 0;
+  virtual LOperand* TempAt(int i) = 0;
+
+  LOperand* FirstInput() { return InputAt(0); }
+  LOperand* Output() { return HasResult() ? result() : NULL; }

  private:
-  SetOncePointer<LEnvironment> environment_;
+  LEnvironment* environment_;
   SetOncePointer<LPointerMap> pointer_map_;
   HValue* hydrogen_value_;
   SetOncePointer<LEnvironment> deoptimization_environment_;
+  bool is_call_;
+  bool is_save_doubles_;
 };


@@ -252,6 +273,11 @@
  public:
   int length() { return 0; }
   void PrintOperandsTo(StringStream* stream) { }
+  ElementType& operator[](int i) {
+    UNREACHABLE();
+    static ElementType t = 0;
+    return t;
+  }
 };


@@ -1734,7 +1760,7 @@
  public:
   explicit LChunk(HGraph* graph);

-  int AddInstruction(LInstruction* instruction, HBasicBlock* block);
+  void AddInstruction(LInstruction* instruction, HBasicBlock* block);
   LConstantOperand* DefineConstantOperand(HConstant* constant);
   Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri Feb 4 04:06:41 2011 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri Feb 4 05:28:23 2011
@@ -29,6 +29,7 @@

 #if defined(V8_TARGET_ARCH_IA32)

+#include "lithium-allocator-inl.h"
 #include "ia32/lithium-ia32.h"
 #include "ia32/lithium-codegen-ia32.h"

@@ -66,13 +67,37 @@
   ASSERT(double_register_spills_[allocation_index] == NULL);
   double_register_spills_[allocation_index] = spill_operand;
 }
+
+
+#ifdef DEBUG
+void LInstruction::VerifyCall() {
+  // Call instructions can use only fixed registers as
+  // temporaries and outputs because all registers
+  // are blocked by the calling convention.
+  // Inputs can use either fixed register or have a short lifetime (be
+  // used at start of the instruction).
+  ASSERT(Output() == NULL ||
+         LUnallocated::cast(Output())->HasFixedPolicy() ||
+         !LUnallocated::cast(Output())->HasRegisterPolicy());
+  for (UseIterator it(this); it.HasNext(); it.Advance()) {
+    LOperand* operand = it.Next();
+    ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
+           LUnallocated::cast(operand)->IsUsedAtStart() ||
+           !LUnallocated::cast(operand)->HasRegisterPolicy());
+  }
+  for (TempIterator it(this); it.HasNext(); it.Advance()) {
+    LOperand* operand = it.Next();
+    ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
+           !LUnallocated::cast(operand)->HasRegisterPolicy());
+  }
+}
+#endif


 void LInstruction::PrintTo(StringStream* stream) {
   stream->Add("%s ", this->Mnemonic());
-  if (HasResult()) {
-    PrintOutputOperandTo(stream);
-  }
+
+  PrintOutputOperandTo(stream);

   PrintDataTo(stream);

@@ -399,7 +424,7 @@
 }


-int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
+void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
   LGap* gap = new LGap(block);
   int index = -1;
   if (instr->IsControl()) {
@@ -415,7 +440,6 @@
     pointer_maps_.Add(instr->pointer_map());
     instr->pointer_map()->set_lithium_position(index);
   }
-  return index;
 }


@@ -683,7 +707,10 @@
 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
                                         HInstruction* hinstr,
                                         CanDeoptimize can_deoptimize) {
-  allocator_->MarkAsCall();
+#ifdef DEBUG
+  instr->VerifyCall();
+#endif
+  instr->MarkAsCall();
   instr = AssignPointerMap(instr);

   if (hinstr->HasSideEffects()) {
@@ -708,7 +735,7 @@


 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
-  allocator_->MarkAsSaveDoubles();
+  instr->MarkAsSaveDoubles();
   return instr;
 }

@@ -917,7 +944,6 @@
 void LChunkBuilder::VisitInstruction(HInstruction* current) {
   HInstruction* old_current = current_instruction_;
   current_instruction_ = current;
-  allocator_->BeginInstruction();
   if (current->has_position()) position_ = current->position();
   LInstruction* instr = current->CompileToLithium(this);

@@ -940,11 +966,7 @@
       instr->set_hydrogen_value(current);
     }

-    int index = chunk_->AddInstruction(instr, current_block_);
-    allocator_->SummarizeInstruction(index);
-  } else {
-    // This instruction should be omitted.
-    allocator_->OmitInstruction();
+    chunk_->AddInstruction(instr, current_block_);
   }
   current_instruction_ = old_current;
 }
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h     Thu Feb  3 05:10:28 2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h     Fri Feb  4 05:28:23 2011
@@ -182,7 +182,10 @@
 class LInstruction: public ZoneObject {
  public:
   LInstruction()
-      : hydrogen_value_(NULL) { }
+      : environment_(NULL),
+        hydrogen_value_(NULL),
+        is_call_(false),
+        is_save_doubles_(false) { }
   virtual ~LInstruction() { }

   virtual void CompileToNative(LCodeGen* generator) = 0;
@@ -199,15 +202,14 @@
   virtual bool IsControl() const { return false; }
   virtual void SetBranchTargets(int true_block_id, int false_block_id) { }

-  void set_environment(LEnvironment* env) { environment_.set(env); }
-  LEnvironment* environment() const { return environment_.get(); }
-  bool HasEnvironment() const { return environment_.is_set(); }
+  void set_environment(LEnvironment* env) { environment_ = env; }
+  LEnvironment* environment() const { return environment_; }
+  bool HasEnvironment() const { return environment_ != NULL; }

   void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
   LPointerMap* pointer_map() const { return pointer_map_.get(); }
   bool HasPointerMap() const { return pointer_map_.is_set(); }

-  virtual bool HasResult() const = 0;

   void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
   HValue* hydrogen_value() const { return hydrogen_value_; }
@@ -221,12 +223,36 @@
   bool HasDeoptimizationEnvironment() const {
     return deoptimization_environment_.is_set();
   }
+
+  void MarkAsCall() { is_call_ = true; }
+  void MarkAsSaveDoubles() { is_save_doubles_ = true; }
+
+  // Interface to the register allocator and iterators.
+  bool IsMarkedAsCall() const { return is_call_; }
+  bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; }
+
+  virtual bool HasResult() const = 0;
+  virtual LOperand* result() = 0;
+
+  virtual int InputCount() = 0;
+  virtual LOperand* InputAt(int i) = 0;
+  virtual int TempCount() = 0;
+  virtual LOperand* TempAt(int i) = 0;
+
+  LOperand* FirstInput() { return InputAt(0); }
+  LOperand* Output() { return HasResult() ? result() : NULL; }
+
+#ifdef DEBUG
+  void VerifyCall();
+#endif

  private:
-  SetOncePointer<LEnvironment> environment_;
+  LEnvironment* environment_;
   SetOncePointer<LPointerMap> pointer_map_;
   HValue* hydrogen_value_;
   SetOncePointer<LEnvironment> deoptimization_environment_;
+  bool is_call_;
+  bool is_save_doubles_;
 };


@@ -253,6 +279,11 @@
  public:
   int length() { return 0; }
   void PrintOperandsTo(StringStream* stream) { }
+  ElementType& operator[](int i) {
+    UNREACHABLE();
+    static ElementType t = 0;
+    return t;
+  }
 };


@@ -1760,7 +1791,7 @@
       pointer_maps_(8),
       inlined_closures_(1) { }

-  int AddInstruction(LInstruction* instruction, HBasicBlock* block);
+  void AddInstruction(LInstruction* instruction, HBasicBlock* block);
   LConstantOperand* DefineConstantOperand(HConstant* constant);
   Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
=======================================
--- /branches/bleeding_edge/src/lithium-allocator.cc Tue Feb 1 06:33:23 2011 +++ /branches/bleeding_edge/src/lithium-allocator.cc Fri Feb 4 05:28:23 2011
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-#include "lithium-allocator.h"
+#include "lithium-allocator-inl.h"

 #include "hydrogen.h"
 #include "string-stream.h"
@@ -532,7 +532,7 @@

 void LAllocator::InitializeLivenessAnalysis() {
   // Initialize the live_in sets for each block to NULL.
-  int block_count = graph()->blocks()->length();
+  int block_count = graph_->blocks()->length();
   live_in_sets_.Initialize(block_count);
   live_in_sets_.AddBlock(NULL, block_count);
 }
@@ -613,7 +613,7 @@
   }
   if (is_tagged) {
     TraceAlloc("Fixed reg is tagged at %d\n", pos);
-    LInstruction* instr = chunk_->instructions()->at(pos);
+    LInstruction* instr = InstructionAt(pos);
     if (instr->HasPointerMap()) {
       instr->pointer_map()->RecordPointer(operand);
     }
@@ -668,17 +668,17 @@
 }


-LGap* LAllocator::GetLastGap(HBasicBlock* block) const {
+LGap* LAllocator::GetLastGap(HBasicBlock* block) {
   int last_instruction = block->last_instruction_index();
   int index = chunk_->NearestGapPos(last_instruction);
-  return chunk_->GetGapAt(index);
+  return GapAt(index);
 }


 HPhi* LAllocator::LookupPhi(LOperand* operand) const {
   if (!operand->IsUnallocated()) return NULL;
   int index = operand->VirtualRegister();
-  HValue* instr = graph()->LookupValue(index);
+  HValue* instr = graph_->LookupValue(index);
   if (instr != NULL && instr->IsPhi()) {
     return HPhi::cast(instr);
   }
@@ -737,7 +737,7 @@
 void LAllocator::AddConstraintsGapMove(int index,
                                        LOperand* from,
                                        LOperand* to) {
-  LGap* gap = chunk_->GetGapAt(index);
+  LGap* gap = GapAt(index);
   LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START);
   if (from->IsUnallocated()) {
     const ZoneList<LMoveOperands>* move_operands = move->move_operands();
@@ -760,24 +760,24 @@
   int start = block->first_instruction_index();
   int end = block->last_instruction_index();
   for (int i = start; i <= end; ++i) {
-    if (chunk_->IsGapAt(i)) {
-      InstructionSummary* summary = NULL;
-      InstructionSummary* prev_summary = NULL;
-      if (i < end) summary = GetSummary(i + 1);
-      if (i > start) prev_summary = GetSummary(i - 1);
-      MeetConstraintsBetween(prev_summary, summary, i);
+    if (IsGapAt(i)) {
+      LInstruction* instr = NULL;
+      LInstruction* prev_instr = NULL;
+      if (i < end) instr = InstructionAt(i + 1);
+      if (i > start) prev_instr = InstructionAt(i - 1);
+      MeetConstraintsBetween(prev_instr, instr, i);
     }
   }
 }


-void LAllocator::MeetConstraintsBetween(InstructionSummary* first,
-                                        InstructionSummary* second,
+void LAllocator::MeetConstraintsBetween(LInstruction* first,
+                                        LInstruction* second,
                                         int gap_index) {
   // Handle fixed temporaries.
   if (first != NULL) {
-    for (int i = 0; i < first->TempCount(); ++i) {
-      LUnallocated* temp = LUnallocated::cast(first->TempAt(i));
+    for (TempIterator it(first); it.HasNext(); it.Advance()) {
+      LUnallocated* temp = LUnallocated::cast(it.Next());
       if (temp->HasFixedPolicy()) {
         AllocateFixed(temp, gap_index - 1, false);
       }
@@ -810,7 +810,7 @@
       // and splitting of live ranges do not account for it.
       // Thus it should be inserted to a lifetime position corresponding to
       // the instruction end.
-      LGap* gap = chunk_->GetGapAt(gap_index);
+      LGap* gap = GapAt(gap_index);
       LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE);
       move->AddMove(first_output, range->GetSpillOperand());
     }
@@ -818,8 +818,8 @@

   // Handle fixed input operands of second instruction.
   if (second != NULL) {
-    for (int i = 0; i < second->InputCount(); ++i) {
-      LUnallocated* cur_input = LUnallocated::cast(second->InputAt(i));
+    for (UseIterator it(second); it.HasNext(); it.Advance()) {
+      LUnallocated* cur_input = LUnallocated::cast(it.Next());
       if (cur_input->HasFixedPolicy()) {
         LUnallocated* input_copy = cur_input->CopyUnconstrained();
         bool is_tagged = HasTaggedValue(cur_input->VirtualRegister());
@@ -848,7 +848,7 @@
   if (second != NULL && second->Output() != NULL) {
     LUnallocated* second_output = LUnallocated::cast(second->Output());
     if (second_output->HasSameAsInputPolicy()) {
-      LUnallocated* cur_input = LUnallocated::cast(second->InputAt(0));
+      LUnallocated* cur_input = LUnallocated::cast(second->FirstInput());
       int output_vreg = second_output->VirtualRegister();
       int input_vreg = cur_input->VirtualRegister();

@@ -858,7 +858,7 @@

       if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) {
         int index = gap_index + 1;
-        LInstruction* instr = chunk_->instructions()->at(index);
+        LInstruction* instr = InstructionAt(index);
         if (instr->HasPointerMap()) {
           instr->pointer_map()->RecordPointer(input_copy);
         }
@@ -886,9 +886,9 @@
     LifetimePosition curr_position =
         LifetimePosition::FromInstructionIndex(index);

-    if (chunk_->IsGapAt(index)) {
+    if (IsGapAt(index)) {
       // We have a gap at this position.
-      LGap* gap = chunk_->GetGapAt(index);
+      LGap* gap = GapAt(index);
       LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START);
       const ZoneList<LMoveOperands>* move_operands = move->move_operands();
       for (int i = 0; i < move_operands->length(); ++i) {
@@ -922,17 +922,17 @@
         }
       }
     } else {
-      ASSERT(!chunk_->IsGapAt(index));
-      InstructionSummary* summary = GetSummary(index);
-
-      if (summary != NULL) {
-        LOperand* output = summary->Output();
+      ASSERT(!IsGapAt(index));
+      LInstruction* instr = InstructionAt(index);
+
+      if (instr != NULL) {
+        LOperand* output = instr->Output();
         if (output != NULL) {
if (output->IsUnallocated()) live->Remove(output->VirtualRegister());
           Define(curr_position, output, NULL);
         }

-        if (summary->IsCall()) {
+        if (instr->IsMarkedAsCall()) {
           for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) {
             if (output == NULL || !output->IsRegister() ||
                 output->index() != i) {
@@ -943,7 +943,7 @@
           }
         }

-        if (summary->IsCall() || summary->IsSaveDoubles()) {
+        if (instr->IsMarkedAsCall() || instr->IsMarkedAsSaveDoubles()) {
for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) {
             if (output == NULL || !output->IsDoubleRegister() ||
                 output->index() != i) {
@@ -954,8 +954,8 @@
           }
         }

-        for (int i = 0; i < summary->InputCount(); ++i) {
-          LOperand* input = summary->InputAt(i);
+        for (UseIterator it(instr); it.HasNext(); it.Advance()) {
+          LOperand* input = it.Next();

           LifetimePosition use_pos;
           if (input->IsUnallocated() &&
@@ -969,9 +969,9 @@
           if (input->IsUnallocated()) live->Add(input->VirtualRegister());
         }

-        for (int i = 0; i < summary->TempCount(); ++i) {
-          LOperand* temp = summary->TempAt(i);
-          if (summary->IsCall()) {
+        for (TempIterator it(instr); it.HasNext(); it.Advance()) {
+          LOperand* temp = it.Next();
+          if (instr->IsMarkedAsCall()) {
             if (temp->IsRegister()) continue;
             if (temp->IsUnallocated()) {
               LUnallocated* temp_unalloc = LUnallocated::cast(temp);
@@ -1042,9 +1042,9 @@


 void LAllocator::MeetRegisterConstraints() {
-  HPhase phase("Register constraints", chunk());
+  HPhase phase("Register constraints", chunk_);
   first_artificial_register_ = next_virtual_register_;
-  const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
+  const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
   for (int i = 0; i < blocks->length(); ++i) {
     HBasicBlock* block = blocks->at(i);
     MeetRegisterConstraints(block);
@@ -1053,10 +1053,10 @@


 void LAllocator::ResolvePhis() {
-  HPhase phase("Resolve phis", chunk());
+  HPhase phase("Resolve phis", chunk_);

   // Process the blocks in reverse order.
-  const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
+  const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
   for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) {
     HBasicBlock* block = blocks->at(block_id);
     ResolvePhis(block);
@@ -1094,7 +1094,7 @@
     if (!pred_op->Equals(cur_op)) {
       LGap* gap = NULL;
       if (block->predecessors()->length() == 1) {
-        gap = chunk_->GetGapAt(block->first_instruction_index());
+        gap = GapAt(block->first_instruction_index());
       } else {
         ASSERT(pred->end()->SecondSuccessor() == NULL);
         gap = GetLastGap(pred);
@@ -1107,19 +1107,19 @@

LParallelMove* LAllocator::GetConnectingParallelMove(LifetimePosition pos) {
   int index = pos.InstructionIndex();
-  if (chunk_->IsGapAt(index)) {
-    LGap* gap = chunk_->GetGapAt(index);
+  if (IsGapAt(index)) {
+    LGap* gap = GapAt(index);
     return gap->GetOrCreateParallelMove(
         pos.IsInstructionStart() ? LGap::START : LGap::END);
   }
   int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1);
-  return chunk_->GetGapAt(gap_pos)->GetOrCreateParallelMove(
+  return GapAt(gap_pos)->GetOrCreateParallelMove(
       (gap_pos < index) ? LGap::AFTER : LGap::BEFORE);
 }


 HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) {
- LGap* gap = chunk_->GetGapAt(chunk_->NearestGapPos(pos.InstructionIndex()));
+  LGap* gap = GapAt(chunk_->NearestGapPos(pos.InstructionIndex()));
   return gap->block();
 }

@@ -1166,7 +1166,7 @@

 void LAllocator::ResolveControlFlow() {
   HPhase phase("Resolve control flow", this);
-  const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
+  const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
   for (int block_id = 1; block_id < blocks->length(); ++block_id) {
     HBasicBlock* block = blocks->at(block_id);
     if (CanEagerlyResolveControlFlow(block)) continue;
@@ -1189,7 +1189,7 @@
   HPhase phase("Build live ranges", this);
   InitializeLivenessAnalysis();
   // Process the blocks in reverse order.
-  const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
+  const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
   for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) {
     HBasicBlock* block = blocks->at(block_id);
     BitVector* live = ComputeLiveOut(block);
@@ -1264,7 +1264,7 @@
         found = true;
         int operand_index = iterator.Current();
         PrintF("Function: %s\n",
-               *graph()->info()->function()->debug_name()->ToCString());
+               *graph_->info()->function()->debug_name()->ToCString());
         PrintF("Value %d used before first definition!\n", operand_index);
         LiveRange* range = LiveRangeFor(operand_index);
         PrintF("First use is at %d\n", range->first_pos()->pos().Value());
@@ -1469,7 +1469,7 @@
     if (current->HasAllocatedSpillOperand()) {
TraceAlloc("Live range %d already has a spill operand\n", current->id());
       LifetimePosition next_pos = position;
-      if (chunk_->IsGapAt(next_pos.InstructionIndex())) {
+      if (IsGapAt(next_pos.InstructionIndex())) {
         next_pos = next_pos.NextInstruction();
       }
UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
@@ -1554,16 +1554,10 @@
     va_end(arguments);
   }
 }
-
-
-void LAllocator::RecordUse(HValue* value, LUnallocated* operand) {
-  operand->set_virtual_register(value->id());
-  current_summary()->AddInput(operand);
-}


 bool LAllocator::HasTaggedValue(int virtual_register) const {
-  HValue* value = graph()->LookupValue(virtual_register);
+  HValue* value = graph_->LookupValue(virtual_register);
   if (value == NULL) return false;
   return value->representation().IsTagged();
 }
@@ -1571,7 +1565,7 @@

 RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const {
   if (virtual_register < first_artificial_register_) {
-    HValue* value = graph()->LookupValue(virtual_register);
+    HValue* value = graph_->LookupValue(virtual_register);
     if (value != NULL && value->representation().IsDouble()) {
       return DOUBLE_REGISTERS;
     }
@@ -1582,41 +1576,10 @@

   return GENERAL_REGISTERS;
 }
-
-
-void LAllocator::MarkAsCall() {
-  // Call instructions can use only fixed registers as
-  // temporaries and outputs because all registers
-  // are blocked by the calling convention.
-  // Inputs can use either fixed register or have a short lifetime (be
-  // used at start of the instruction).
-  InstructionSummary* summary = current_summary();
-#ifdef DEBUG
-  ASSERT(summary->Output() == NULL ||
-         LUnallocated::cast(summary->Output())->HasFixedPolicy() ||
-         !LUnallocated::cast(summary->Output())->HasRegisterPolicy());
-  for (int i = 0; i < summary->InputCount(); i++) {
-    ASSERT(LUnallocated::cast(summary->InputAt(i))->HasFixedPolicy() ||
-           LUnallocated::cast(summary->InputAt(i))->IsUsedAtStart() ||
-           !LUnallocated::cast(summary->InputAt(i))->HasRegisterPolicy());
-  }
-  for (int i = 0; i < summary->TempCount(); i++) {
-    ASSERT(LUnallocated::cast(summary->TempAt(i))->HasFixedPolicy() ||
-           !LUnallocated::cast(summary->TempAt(i))->HasRegisterPolicy());
-  }
-#endif
-  summary->MarkAsCall();
-}
-
-
-void LAllocator::MarkAsSaveDoubles() {
-  current_summary()->MarkAsSaveDoubles();
-}


void LAllocator::RecordDefinition(HInstruction* instr, LUnallocated* operand) {
   operand->set_virtual_register(instr->id());
-  current_summary()->SetOutput(operand);
 }


@@ -1625,40 +1588,16 @@
   if (!operand->HasFixedPolicy()) {
     operand->set_virtual_register(next_virtual_register_++);
   }
-  current_summary()->AddTemp(operand);
 }


-int LAllocator::max_initial_value_ids() {
-  return LUnallocated::kMaxVirtualRegisters / 32;
+void LAllocator::RecordUse(HValue* value, LUnallocated* operand) {
+  operand->set_virtual_register(value->id());
 }


-void LAllocator::BeginInstruction() {
-  if (next_summary_ == NULL) {
-    next_summary_ = new InstructionSummary();
-  }
-  summary_stack_.Add(next_summary_);
-  next_summary_ = NULL;
-}
-
-
-void LAllocator::SummarizeInstruction(int index) {
-  InstructionSummary* sum = summary_stack_.RemoveLast();
-  if (summaries_.length() <= index) {
-    summaries_.AddBlock(NULL, index + 1 - summaries_.length());
-  }
-  ASSERT(summaries_[index] == NULL);
- if (sum->Output() != NULL || sum->InputCount() > 0 || sum->TempCount() > 0) {
-    summaries_[index] = sum;
-  } else {
-    next_summary_ = sum;
-  }
-}
-
-
-void LAllocator::OmitInstruction() {
-  summary_stack_.RemoveLast();
+int LAllocator::max_initial_value_ids() {
+  return LUnallocated::kMaxVirtualRegisters / 32;
 }


@@ -2007,7 +1946,7 @@

 bool LAllocator::IsBlockBoundary(LifetimePosition pos) {
   return pos.IsInstructionStart() &&
-      chunk_->instructions()->at(pos.InstructionIndex())->IsLabel();
+      InstructionAt(pos.InstructionIndex())->IsLabel();
 }


=======================================
--- /branches/bleeding_edge/src/lithium-allocator.h     Thu Jan 20 06:37:28 2011
+++ /branches/bleeding_edge/src/lithium-allocator.h     Fri Feb  4 05:28:23 2011
@@ -31,6 +31,7 @@
 #include "v8.h"

 #include "data-flow.h"
+#include "lithium.h"
 #include "zone.h"

 namespace v8 {
@@ -153,52 +154,55 @@

// 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 {
+
+class LInstruction;
+class LEnvironment;
+
+// Iterator for non-null temp operands.
+class TempIterator BASE_EMBEDDED {
  public:
-  InstructionSummary()
-      : output_operand_(NULL),
-        input_count_(0),
-        operands_(4),
-        is_call_(false),
-        is_save_doubles_(false) {}
-
-  // Output operands.
-  LOperand* Output() const { return output_operand_; }
-  void SetOutput(LOperand* output) {
-    ASSERT(output_operand_ == NULL);
-    output_operand_ = output;
-  }
-
-  // Input operands.
-  int InputCount() const { return input_count_; }
-  LOperand* InputAt(int i) const {
-    ASSERT(i < input_count_);
-    return operands_[i];
-  }
-  void AddInput(LOperand* input) {
-    operands_.InsertAt(input_count_, input);
-    input_count_++;
-  }
-
-  // Temporary operands.
-  int TempCount() const { return operands_.length() - input_count_; }
-  LOperand* TempAt(int i) const { return operands_[i + input_count_]; }
-  void AddTemp(LOperand* temp) { operands_.Add(temp); }
-
-  void MarkAsCall() { is_call_ = true; }
-  bool IsCall() const { return is_call_; }
-
-  void MarkAsSaveDoubles() { is_save_doubles_ = true; }
-  bool IsSaveDoubles() const { return is_save_doubles_; }
+  inline explicit TempIterator(LInstruction* instr);
+  inline bool HasNext();
+  inline LOperand* Next();
+  inline void Advance();
+
+ private:
+  inline int AdvanceToNext(int start);
+  LInstruction* instr_;
+  int limit_;
+  int current_;
+};
+
+
+// Iterator for non-constant input operands.
+class InputIterator BASE_EMBEDDED {
+ public:
+  inline explicit InputIterator(LInstruction* instr);
+  inline bool HasNext();
+  inline LOperand* Next();
+  inline void Advance();
+
+ private:
+  inline int AdvanceToNext(int start);
+  LInstruction* instr_;
+  int limit_;
+  int current_;
+};
+
+
+class UseIterator BASE_EMBEDDED {
+ public:
+  inline explicit UseIterator(LInstruction* instr);
+  inline bool HasNext();
+  inline LOperand* Next();
+  inline void Advance();

  private:
-  LOperand* output_operand_;
-  int input_count_;
-  ZoneList<LOperand*> operands_;
-  bool is_call_;
-  bool is_save_doubles_;
+  InputIterator input_iterator_;
+  DeepIterator env_iterator_;
 };

+
 // Representation of the non-empty interval [start,end[.
 class UseInterval: public ZoneObject {
  public:
@@ -428,9 +432,6 @@
  public:
   explicit LAllocator(int first_virtual_register, HGraph* graph)
       : chunk_(NULL),
-        summaries_(0),
-        next_summary_(NULL),
-        summary_stack_(2),
         live_in_sets_(0),
         live_ranges_(16),
         fixed_live_ranges_(8),
@@ -457,27 +458,12 @@
   // Record a temporary operand.
   void RecordTemporary(LUnallocated* operand);

-  // Marks the current instruction as a call.
-  void MarkAsCall();
-
-  // Marks the current instruction as requiring saving double registers.
-  void MarkAsSaveDoubles();
-
   // Checks whether the value of a given virtual register is tagged.
   bool HasTaggedValue(int virtual_register) const;

   // Returns the register kind required by the given virtual register.
   RegisterKind RequiredRegisterKind(int virtual_register) const;

-  // Begin a new instruction.
-  void BeginInstruction();
-
-  // Summarize the current instruction.
-  void SummarizeInstruction(int index);
-
-  // Summarize the current instruction.
-  void OmitInstruction();
-
   // Control max function size.
   static int max_initial_value_ids();

@@ -525,8 +511,8 @@
   void AddInitialIntervals(HBasicBlock* block, BitVector* live_out);
   void ProcessInstructions(HBasicBlock* block, BitVector* live);
   void MeetRegisterConstraints(HBasicBlock* block);
-  void MeetConstraintsBetween(InstructionSummary* first,
-                              InstructionSummary* second,
+  void MeetConstraintsBetween(LInstruction* first,
+                              LInstruction* second,
                               int gap_index);
   void ResolvePhis(HBasicBlock* block);

@@ -603,12 +589,6 @@

   // Return the block which contains give lifetime position.
   HBasicBlock* GetBlock(LifetimePosition pos);
-
-  // Current active summary.
- InstructionSummary* current_summary() const { return summary_stack_.last(); }
-
-  // Get summary for given instruction index.
- InstructionSummary* GetSummary(int index) const { return summaries_[index]; }

   // Helper methods for the fixed registers.
   int RegisterCount() const;
@@ -618,15 +598,17 @@
   LiveRange* FixedDoubleLiveRangeFor(int index);
   LiveRange* LiveRangeFor(int index);
   HPhi* LookupPhi(LOperand* operand) const;
-  LGap* GetLastGap(HBasicBlock* block) const;
+  LGap* GetLastGap(HBasicBlock* block);

   const char* RegisterName(int allocation_index);

-  LChunk* chunk_;
-  ZoneList<InstructionSummary*> summaries_;
-  InstructionSummary* next_summary_;
-
-  ZoneList<InstructionSummary*> summary_stack_;
+  inline bool IsGapAt(int index);
+
+  inline LInstruction* InstructionAt(int index);
+
+  inline LGap* GapAt(int index);
+
+  LChunk* chunk_;

   // During liveness analysis keep a mapping from block id to live_in sets
   // for blocks already analyzed.
=======================================
--- /branches/bleeding_edge/src/lithium.h       Wed Jan 19 05:55:56 2011
+++ /branches/bleeding_edge/src/lithium.h       Fri Feb  4 05:28:23 2011
@@ -509,6 +509,82 @@
   friend class LCodegen;
 };

+
+// Iterates over the non-null, non-constant operands in an environment.
+class ShallowIterator BASE_EMBEDDED {
+ public:
+  explicit ShallowIterator(LEnvironment* env)
+      : env_(env),
+        limit_(env != NULL ? env->values()->length() : 0),
+        current_(0) {
+    current_ = AdvanceToNext(0);
+  }
+
+  inline bool HasNext() {
+    return env_ != NULL && current_ < limit_;
+  }
+
+  inline LOperand* Next() {
+    ASSERT(HasNext());
+    return env_->values()->at(current_);
+  }
+
+  inline void Advance() {
+    current_ = AdvanceToNext(current_ + 1);
+  }
+
+  inline LEnvironment* env() { return env_; }
+
+ private:
+  inline int AdvanceToNext(int start) {
+    while (start < limit_ &&
+           (env_->values()->at(start) == NULL ||
+            env_->values()->at(start)->IsConstantOperand())) {
+      start++;
+    }
+    return start;
+  }
+
+  LEnvironment* env_;
+  int limit_;
+  int current_;
+};
+
+
+// Iterator for non-null, non-constant operands incl. outer environments.
+class DeepIterator BASE_EMBEDDED {
+ public:
+  explicit DeepIterator(LEnvironment* env)
+      : current_iterator_(env) { }
+
+  inline bool HasNext() {
+    if (current_iterator_.HasNext()) return true;
+    if (current_iterator_.env() == NULL) return false;
+    AdvanceToOuter();
+    return current_iterator_.HasNext();
+  }
+
+  inline LOperand* Next() {
+    ASSERT(current_iterator_.HasNext());
+    return current_iterator_.Next();
+  }
+
+  inline void Advance() {
+    if (current_iterator_.HasNext()) {
+      current_iterator_.Advance();
+    } else {
+      AdvanceToOuter();
+    }
+  }
+
+ private:
+  inline void AdvanceToOuter() {
+    current_iterator_ = ShallowIterator(current_iterator_.env()->outer());
+  }
+
+  ShallowIterator current_iterator_;
+};
+
 } }  // namespace v8::internal

 #endif  // V8_LITHIUM_H_
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Fri Feb  4 03:10:39 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Fri Feb  4 05:28:23 2011
@@ -29,6 +29,7 @@

 #if defined(V8_TARGET_ARCH_X64)

+#include "lithium-allocator-inl.h"
 #include "x64/lithium-x64.h"
 #include "x64/lithium-codegen-x64.h"

@@ -66,13 +67,37 @@
   ASSERT(double_register_spills_[allocation_index] == NULL);
   double_register_spills_[allocation_index] = spill_operand;
 }
+
+
+#ifdef DEBUG
+void LInstruction::VerifyCall() {
+  // Call instructions can use only fixed registers as
+  // temporaries and outputs because all registers
+  // are blocked by the calling convention.
+  // Inputs can use either fixed register or have a short lifetime (be
+  // used at start of the instruction).
+  ASSERT(Output() == NULL ||
+         LUnallocated::cast(Output())->HasFixedPolicy() ||
+         !LUnallocated::cast(Output())->HasRegisterPolicy());
+  for (UseIterator it(this); it.HasNext(); it.Advance()) {
+    LOperand* operand = it.Next();
+    ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
+           LUnallocated::cast(operand)->IsUsedAtStart() ||
+           !LUnallocated::cast(operand)->HasRegisterPolicy());
+  }
+  for (TempIterator it(this); it.HasNext(); it.Advance()) {
+    LOperand* operand = it.Next();
+    ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
+           !LUnallocated::cast(operand)->HasRegisterPolicy());
+  }
+}
+#endif


 void LInstruction::PrintTo(StringStream* stream) {
   stream->Add("%s ", this->Mnemonic());
-  if (HasResult()) {
-    PrintOutputOperandTo(stream);
-  }
+
+  PrintOutputOperandTo(stream);

   PrintDataTo(stream);

@@ -393,7 +418,7 @@
 }


-int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
+void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
   LGap* gap = new LGap(block);
   int index = -1;
   if (instr->IsControl()) {
@@ -409,7 +434,6 @@
     pointer_maps_.Add(instr->pointer_map());
     instr->pointer_map()->set_lithium_position(index);
   }
-  return index;
 }


@@ -677,7 +701,10 @@
 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
                                         HInstruction* hinstr,
                                         CanDeoptimize can_deoptimize) {
-  allocator_->MarkAsCall();
+#ifdef DEBUG
+  instr->VerifyCall();
+#endif
+  instr->MarkAsCall();
   instr = AssignPointerMap(instr);

   if (hinstr->HasSideEffects()) {
@@ -702,7 +729,7 @@


 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
-  allocator_->MarkAsSaveDoubles();
+  instr->MarkAsSaveDoubles();
   return instr;
 }

@@ -907,7 +934,6 @@
 void LChunkBuilder::VisitInstruction(HInstruction* current) {
   HInstruction* old_current = current_instruction_;
   current_instruction_ = current;
-  allocator_->BeginInstruction();
   if (current->has_position()) position_ = current->position();
   LInstruction* instr = current->CompileToLithium(this);

@@ -930,11 +956,7 @@
       instr->set_hydrogen_value(current);
     }

-    int index = chunk_->AddInstruction(instr, current_block_);
-    allocator_->SummarizeInstruction(index);
-  } else {
-    // This instruction should be omitted.
-    allocator_->OmitInstruction();
+    chunk_->AddInstruction(instr, current_block_);
   }
   current_instruction_ = old_current;
 }
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Thu Feb  3 05:10:28 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Fri Feb  4 05:28:23 2011
@@ -287,7 +287,11 @@
 class LInstruction: public ZoneObject {
  public:
   LInstruction()
-      : hydrogen_value_(NULL) { }
+      :  environment_(NULL),
+         hydrogen_value_(NULL),
+         is_call_(false),
+         is_save_doubles_(false) { }
+
   virtual ~LInstruction() { }

   virtual void CompileToNative(LCodeGen* generator) = 0;
@@ -304,15 +308,13 @@
   virtual bool IsControl() const { return false; }
   virtual void SetBranchTargets(int true_block_id, int false_block_id) { }

-  void set_environment(LEnvironment* env) { environment_.set(env); }
-  LEnvironment* environment() const { return environment_.get(); }
-  bool HasEnvironment() const { return environment_.is_set(); }
+  void set_environment(LEnvironment* env) { environment_ = env; }
+  LEnvironment* environment() const { return environment_; }
+  bool HasEnvironment() const { return environment_ != NULL; }

   void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
   LPointerMap* pointer_map() const { return pointer_map_.get(); }
   bool HasPointerMap() const { return pointer_map_.is_set(); }
-
-  virtual bool HasResult() const = 0;

   void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
   HValue* hydrogen_value() const { return hydrogen_value_; }
@@ -326,12 +328,36 @@
   bool HasDeoptimizationEnvironment() const {
     return deoptimization_environment_.is_set();
   }
+
+  void MarkAsCall() { is_call_ = true; }
+  void MarkAsSaveDoubles() { is_save_doubles_ = true; }
+
+  // Interface to the register allocator and iterators.
+  bool IsMarkedAsCall() const { return is_call_; }
+  bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; }
+
+  virtual bool HasResult() const = 0;
+  virtual LOperand* result() = 0;
+
+  virtual int InputCount() = 0;
+  virtual LOperand* InputAt(int i) = 0;
+  virtual int TempCount() = 0;
+  virtual LOperand* TempAt(int i) = 0;
+
+  LOperand* FirstInput() { return InputAt(0); }
+  LOperand* Output() { return HasResult() ? result() : NULL; }
+
+#ifdef DEBUG
+  void VerifyCall();
+#endif

  private:
-  SetOncePointer<LEnvironment> environment_;
+  LEnvironment* environment_;
   SetOncePointer<LPointerMap> pointer_map_;
   HValue* hydrogen_value_;
   SetOncePointer<LEnvironment> deoptimization_environment_;
+  bool is_call_;
+  bool is_save_doubles_;
 };


@@ -358,6 +384,11 @@
  public:
   int length() { return 0; }
   void PrintOperandsTo(StringStream* stream) { }
+  ElementType& operator[](int i) {
+    UNREACHABLE();
+    static ElementType t = 0;
+    return t;
+  }
 };


@@ -1785,7 +1816,7 @@
       pointer_maps_(8),
       inlined_closures_(1) { }

-  int AddInstruction(LInstruction* instruction, HBasicBlock* block);
+  void AddInstruction(LInstruction* instruction, HBasicBlock* block);
   LConstantOperand* DefineConstantOperand(HConstant* constant);
   Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp    Tue Jan 25 03:25:30 2011
+++ /branches/bleeding_edge/tools/gyp/v8.gyp    Fri Feb  4 05:28:23 2011
@@ -441,6 +441,7 @@
             '../../src/lithium.h',
             '../../src/lithium-allocator.cc',
             '../../src/lithium-allocator.h',
+            '../../src/lithium-allocator-inl.h',
             '../../src/liveedit.cc',
             '../../src/liveedit.h',
             '../../src/liveobjectlist-inl.h',
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_base.vcproj Thu Feb 3 05:29:10 2011 +++ /branches/bleeding_edge/tools/visual_studio/v8_base.vcproj Fri Feb 4 05:28:23 2011
@@ -703,6 +703,10 @@
       <File
         RelativePath="..\..\src\lithium-allocator.h"
         >
+      </File>
+      <File
+        RelativePath="..\..\src\lithium-allocator-inl.h"
+        >
       </File>
       <File
         RelativePath="..\..\src\ia32\lithium-ia32.cc"
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_base_arm.vcproj Wed Dec 22 05:04:47 2010 +++ /branches/bleeding_edge/tools/visual_studio/v8_base_arm.vcproj Fri Feb 4 05:28:23 2011
@@ -695,6 +695,10 @@
       <File
         RelativePath="..\..\src\lithium-allocator.h"
         >
+      </File>
+      <File
+        RelativePath="..\..\src\lithium-allocator-inl.h"
+        >
       </File>
       <File
         RelativePath="..\..\src\arm\lithium-arm.cc"
=======================================
--- /branches/bleeding_edge/tools/visual_studio/v8_base_x64.vcproj Thu Feb 3 05:29:10 2011 +++ /branches/bleeding_edge/tools/visual_studio/v8_base_x64.vcproj Fri Feb 4 05:28:23 2011
@@ -704,6 +704,10 @@
       <File
         RelativePath="..\..\src\lithium-allocator.h"
         >
+      </File>
+      <File
+        RelativePath="..\..\src\lithium-allocator-inl.h"
+        >
       </File>
       <File
         RelativePath="..\..\src\x64\lithium-x64.cc"

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to