Author: [email protected]
Date: Fri May 15 04:09:51 2009
New Revision: 1965

Modified:
    branches/bleeding_edge/src/codegen.cc
    branches/bleeding_edge/src/codegen.h
    branches/bleeding_edge/src/compiler.h
    branches/bleeding_edge/src/ia32/codegen-ia32.cc
    branches/bleeding_edge/src/ia32/register-allocator-ia32.cc
    branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc
    branches/bleeding_edge/src/ia32/virtual-frame-ia32.h
    branches/bleeding_edge/src/register-allocator-inl.h
    branches/bleeding_edge/src/register-allocator.cc
    branches/bleeding_edge/src/register-allocator.h
    branches/bleeding_edge/src/virtual-frame.cc
    branches/bleeding_edge/test/cctest/test-log-ia32.cc

Log:
Clean up the Result class.  Reduce the size of Result from four words
to one by keeping a stack of active code generators and by using
indirection to handles.

Mainly a cleanup.  No visible performance impact.
Review URL: http://codereview.chromium.org/113455

Modified: branches/bleeding_edge/src/codegen.cc
==============================================================================
--- branches/bleeding_edge/src/codegen.cc       (original)
+++ branches/bleeding_edge/src/codegen.cc       Fri May 15 04:09:51 2009
@@ -40,6 +40,10 @@

  namespace v8 { namespace internal {

+
+CodeGenerator* CodeGeneratorScope::top_ = NULL;
+
+
  DeferredCode::DeferredCode(CodeGenerator* generator)
    : generator_(generator),
      masm_(generator->masm()),
@@ -154,6 +158,7 @@
    // Generate code.
    const int initial_buffer_size = 4 * KB;
    CodeGenerator cgen(initial_buffer_size, script, is_eval);
+  CodeGeneratorScope scope(&cgen);
    cgen.GenCode(flit);
    if (cgen.HasStackOverflow()) {
      ASSERT(!Top::has_pending_exception());

Modified: branches/bleeding_edge/src/codegen.h
==============================================================================
--- branches/bleeding_edge/src/codegen.h        (original)
+++ branches/bleeding_edge/src/codegen.h        Fri May 15 04:09:51 2009
@@ -86,7 +86,33 @@
  #include "arm/codegen-arm.h"
  #endif

+#include "register-allocator.h"
+
  namespace v8 { namespace internal {
+
+
+// Code generation can be nested.  Code generation scopes form a stack
+// of active code generators.
+class CodeGeneratorScope BASE_EMBEDDED {
+ public:
+  explicit CodeGeneratorScope(CodeGenerator* cgen) {
+    previous_ = top_;
+    top_ = cgen;
+  }
+
+  ~CodeGeneratorScope() {
+    top_ = previous_;
+  }
+
+  static CodeGenerator* Current() {
+    ASSERT(top_ != NULL);
+    return top_;
+  }
+
+ private:
+  static CodeGenerator* top_;
+  CodeGenerator* previous_;
+};


  // Use lazy compilation; defaults to true.

Modified: branches/bleeding_edge/src/compiler.h
==============================================================================
--- branches/bleeding_edge/src/compiler.h       (original)
+++ branches/bleeding_edge/src/compiler.h       Fri May 15 04:09:51 2009
@@ -79,7 +79,10 @@
   public:
    explicit CompilationZoneScope(ZoneScopeMode mode) : ZoneScope(mode) { }
    virtual ~CompilationZoneScope() {
-    if (ShouldDeleteOnExit()) FrameElement::ClearConstantList();
+    if (ShouldDeleteOnExit()) {
+      FrameElement::ClearConstantList();
+      Result::ClearConstantList();
+    }
    }
  };


Modified: branches/bleeding_edge/src/ia32/codegen-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/codegen-ia32.cc     (original)
+++ branches/bleeding_edge/src/ia32/codegen-ia32.cc     Fri May 15 04:09:51 2009
@@ -281,7 +281,7 @@
          ASSERT(!function_return_is_shadowed_);
          CodeForReturnPosition(fun);
          frame_->PrepareForReturn();
-        Result undefined(Factory::undefined_value(), this);
+        Result undefined(Factory::undefined_value());
          if (function_return_.is_bound()) {
            function_return_.Jump(&undefined);
          } else {
@@ -296,7 +296,7 @@
          // control does not flow off the end of the body so we did not
          // compile an artificial return statement just above, and (b) there
          // are return statements in the body but (c) they are all shadowed.
-        Result return_value(this);
+        Result return_value;
          // Though this is a (possibly) backward block, the frames can
          // only differ on their top element.
          function_return_.Bind(&return_value, 1);
@@ -388,7 +388,7 @@
                                                           JumpTarget* slow)  
{
    ASSERT(slot->type() == Slot::CONTEXT);
    ASSERT(tmp.is_register());
-  Result context(esi, this);
+  Result context(esi);

    for (Scope* s = scope(); s != slot->var()->scope(); s =  
s->outer_scope()) {
      if (s->num_heap_slots() > 0) {
@@ -803,8 +803,8 @@


  void DeferredInlineBinaryOperation::Generate() {
-  Result left(generator());
-  Result right(generator());
+  Result left;
+  Result right;
    enter()->Bind(&left, &right);
    generator()->frame()->Push(&left);
    generator()->frame()->Push(&right);
@@ -859,7 +859,7 @@
      if (left_is_string || right_is_string) {
        frame_->Push(&left);
        frame_->Push(&right);
-      Result answer(this);
+      Result answer;
        if (left_is_string) {
          if (right_is_string) {
            // TODO(lrn): if (left.is_constant() && right.is_constant())
@@ -1045,7 +1045,7 @@


  void DeferredInlineSmiOperation::Generate() {
-  Result left(generator());
+  Result left;
    enter()->Bind(&left);
    generator()->frame()->Push(&left);
    generator()->frame()->Push(value_);
@@ -1078,7 +1078,7 @@


  void DeferredInlineSmiOperationReversed::Generate() {
-  Result right(generator());
+  Result right;
    enter()->Bind(&right);
    generator()->frame()->Push(value_);
    generator()->frame()->Push(&right);
@@ -1109,7 +1109,7 @@

  void DeferredInlineSmiAdd::Generate() {
    // Undo the optimistic add operation and call the shared stub.
-  Result left(generator());  // Initially left + value_.
+  Result left;  // Initially left + value_.
    enter()->Bind(&left);
    left.ToRegister();
    generator()->frame()->Spill(left.reg());
@@ -1143,7 +1143,7 @@

  void DeferredInlineSmiAddReversed::Generate() {
    // Undo the optimistic add operation and call the shared stub.
-  Result right(generator());  // Initially value_ + right.
+  Result right;  // Initially value_ + right.
    enter()->Bind(&right);
    right.ToRegister();
    generator()->frame()->Spill(right.reg());
@@ -1177,7 +1177,7 @@

  void DeferredInlineSmiSub::Generate() {
    // Undo the optimistic sub operation and call the shared stub.
-  Result left(generator());  // Initially left - value_.
+  Result left;  // Initially left - value_.
    enter()->Bind(&left);
    left.ToRegister();
    generator()->frame()->Spill(left.reg());
@@ -1211,7 +1211,7 @@

  void DeferredInlineSmiSubReversed::Generate() {
    // Call the shared stub.
-  Result right(generator());
+  Result right;
    enter()->Bind(&right);
    generator()->frame()->Push(value_);
    generator()->frame()->Push(&right);
@@ -1235,7 +1235,7 @@
    // TODO(199): Optimize some special cases of operations involving a
    // smi literal (multiply by 2, shift by 0, etc.).
    if (IsUnsafeSmi(value)) {
-    Result unsafe_operand(value, this);
+    Result unsafe_operand(value);
      if (reversed) {
        LikelySmiBinaryOperation(op, &unsafe_operand, operand,
                                 overwrite_mode);
@@ -1275,7 +1275,7 @@

      case Token::SUB: {
        DeferredCode* deferred = NULL;
-      Result answer(this);  // Only allocate a new register if reversed.
+      Result answer;  // Only allocate a new register if reversed.
        if (reversed) {
          answer = allocator()->Allocate();
          ASSERT(answer.is_valid());
@@ -1304,7 +1304,7 @@

      case Token::SAR: {
        if (reversed) {
-        Result constant_operand(value, this);
+        Result constant_operand(value);
          LikelySmiBinaryOperation(op, &constant_operand, operand,
                                   overwrite_mode);
        } else {
@@ -1330,7 +1330,7 @@

      case Token::SHR: {
        if (reversed) {
-        Result constant_operand(value, this);
+        Result constant_operand(value);
          LikelySmiBinaryOperation(op, &constant_operand, operand,
                                   overwrite_mode);
        } else {
@@ -1365,7 +1365,7 @@

      case Token::SHL: {
        if (reversed) {
-        Result constant_operand(value, this);
+        Result constant_operand(value);
          LikelySmiBinaryOperation(op, &constant_operand, operand,
                                   overwrite_mode);
        } else {
@@ -1435,7 +1435,7 @@
      }

      default: {
-      Result constant_operand(value, this);
+      Result constant_operand(value);
        if (reversed) {
          LikelySmiBinaryOperation(op, &constant_operand, operand,
                                   overwrite_mode);
@@ -1484,8 +1484,8 @@
    // Strict only makes sense for equality comparisons.
    ASSERT(!strict || cc == equal);

-  Result left_side(this);
-  Result right_side(this);
+  Result left_side;
+  Result right_side;
    // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion  
order.
    if (cc == greater || cc == less_equal) {
      cc = ReverseCondition(cc);
@@ -1769,7 +1769,7 @@
    frame_->Push(pairs);

    // Duplicate the context register.
-  Result context(esi, this);
+  Result context(esi);
    frame_->Push(&context);

    frame_->Push(Smi::FromInt(is_eval() ? 1 : 0));
@@ -1793,7 +1793,7 @@
      // during variable resolution and must have mode DYNAMIC.
      ASSERT(var->is_dynamic());
      // For now, just do a runtime call.  Duplicate the context register.
-    Result context(esi, this);
+    Result context(esi);
      frame_->Push(&context);
      frame_->Push(var->name());
      // Declaration nodes are always introduced in one of two modes.
@@ -2032,7 +2032,7 @@
    Comment cmnt(masm_, "[ WithEnterStatement");
    CodeForStatementPosition(node);
    Load(node->expression());
-  Result context(this);
+  Result context;
    if (node->is_catch_block()) {
      context = frame_->CallRuntime(Runtime::kPushCatchContext, 1);
    } else {
@@ -2941,7 +2941,7 @@

    // Generate unlink code for the (formerly) shadowing targets that
    // have been jumped to.  Deallocate each shadow target.
-  Result return_value(this);
+  Result return_value;
    for (int i = 0; i < shadows.length(); i++) {
      if (shadows[i]->is_linked()) {
        // Unlink from try chain; be careful not to destroy the TOS if
@@ -3073,7 +3073,7 @@
        // on the virtual frame.  We must preserve it until it is
        // pushed.
        if (i == kReturnShadowIndex) {
-        Result return_value(this);
+        Result return_value;
          shadows[i]->Bind(&return_value);
          return_value.ToRegister(eax);
        } else {
@@ -3256,7 +3256,7 @@

      JumpTarget slow(this);
      JumpTarget done(this);
-    Result value(this);
+    Result value;

      // Generate fast-case code for variables that might be shadowed by
      // eval-introduced variables.  Eval is used a lot without
@@ -3356,7 +3356,7 @@
      JumpTarget* slow) {
    // Check that no extension objects have been created by calls to
    // eval from the current scope to the global scope.
-  Result context(esi, this);
+  Result context(esi);
    Result tmp = allocator_->Allocate();
    ASSERT(tmp.is_valid());  // All non-reserved registers were available.

@@ -3431,7 +3431,7 @@
      frame_->Push(esi);
      frame_->Push(slot->var()->name());

-    Result value(this);
+    Result value;
      if (init_state == CONST_INIT) {
        // Same as the case for a normal store, but ignores attribute
        // (e.g. READ_ONLY) of context slot so that we can initialize const
@@ -3574,7 +3574,7 @@


  void DeferredRegExpLiteral::Generate() {
-  Result literals(generator());
+  Result literals;
    enter()->Bind(&literals);
    // Since the entry is undefined we call the runtime system to
    // compute the literal.
@@ -3651,7 +3651,7 @@


  void DeferredObjectLiteral::Generate() {
-  Result literals(generator());
+  Result literals;
    enter()->Bind(&literals);
    // Since the entry is undefined we call the runtime system to
    // compute the literal.
@@ -3789,7 +3789,7 @@


  void DeferredArrayLiteral::Generate() {
-  Result literals(generator());
+  Result literals;
    enter()->Bind(&literals);
    // Since the entry is undefined we call the runtime system to
    // compute the literal.
@@ -4438,7 +4438,7 @@
    ASSERT(args->length() == 0);
    // ArgumentsAccessStub takes the parameter count as an input argument
    // in register eax.  Create a constant result for it.
-  Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters())), this);
+  Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters())));
    // Call the shared stub to get to the arguments.length.
    ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
    Result result = frame_->CallStub(&stub, &count);
@@ -4521,7 +4521,7 @@
    Load(args->at(0));
    Result key = frame_->Pop();
    // Explicitly create a constant result.
-  Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters())), this);
+  Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters())));
    // Call the shared stub to get to arguments[key].
    ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
    Result result = frame_->CallStub(&stub, &key, &count);
@@ -4771,7 +4771,7 @@

  void DeferredCountOperation::Generate() {
    CodeGenerator* cgen = generator();
-  Result value(cgen);
+  Result value;
    enter()->Bind(&value);
    VirtualFrame* frame = cgen->frame();
    // Undo the optimistic smi operation.
@@ -5269,7 +5269,7 @@

  void DeferredReferenceGetNamedValue::Generate() {
    CodeGenerator* cgen = generator();
-  Result receiver(cgen);
+  Result receiver;
    enter()->Bind(&receiver);

    cgen->frame()->Push(&receiver);
@@ -5311,8 +5311,8 @@

  void DeferredReferenceGetKeyedValue::Generate() {
    CodeGenerator* cgen = generator();
-  Result receiver(cgen);
-  Result key(cgen);
+  Result receiver;
+  Result key;
    enter()->Bind(&receiver, &key);
    cgen->frame()->Push(&receiver);  // First IC argument.
    cgen->frame()->Push(&key);       // Second IC argument.

Modified: branches/bleeding_edge/src/ia32/register-allocator-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/register-allocator-ia32.cc  (original)
+++ branches/bleeding_edge/src/ia32/register-allocator-ia32.cc  Fri May 15  
04:09:51 2009
@@ -38,12 +38,13 @@
  void Result::ToRegister() {
    ASSERT(is_valid());
    if (is_constant()) {
-    Result fresh = cgen_->allocator()->Allocate();
+    Result fresh = CodeGeneratorScope::Current()->allocator()->Allocate();
      ASSERT(fresh.is_valid());
-    if (cgen_->IsUnsafeSmi(handle())) {
-      cgen_->LoadUnsafeSmi(fresh.reg(), handle());
+    if (CodeGeneratorScope::Current()->IsUnsafeSmi(handle())) {
+      CodeGeneratorScope::Current()->LoadUnsafeSmi(fresh.reg(), handle());
      } else {
-      cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+      CodeGeneratorScope::Current()->masm()->Set(fresh.reg(),
+                                                 Immediate(handle()));
      }
      // This result becomes a copy of the fresh one.
      *this = fresh;
@@ -55,23 +56,24 @@
  void Result::ToRegister(Register target) {
    ASSERT(is_valid());
    if (!is_register() || !reg().is(target)) {
-    Result fresh = cgen_->allocator()->Allocate(target);
+    Result fresh =  
CodeGeneratorScope::Current()->allocator()->Allocate(target);
      ASSERT(fresh.is_valid());
      if (is_register()) {
-      cgen_->masm()->mov(fresh.reg(), reg());
+      CodeGeneratorScope::Current()->masm()->mov(fresh.reg(), reg());
      } else {
        ASSERT(is_constant());
-      if (cgen_->IsUnsafeSmi(handle())) {
-        cgen_->LoadUnsafeSmi(fresh.reg(), handle());
+      if (CodeGeneratorScope::Current()->IsUnsafeSmi(handle())) {
+        CodeGeneratorScope::Current()->LoadUnsafeSmi(fresh.reg(),  
handle());
        } else {
-        cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+        CodeGeneratorScope::Current()->masm()->Set(fresh.reg(),
+                                                   Immediate(handle()));
        }
      }
      *this = fresh;
    } else if (is_register() && reg().is(target)) {
-    ASSERT(cgen_->has_valid_frame());
-    cgen_->frame()->Spill(target);
-    ASSERT(cgen_->allocator()->count(target) == 1);
+    ASSERT(CodeGeneratorScope::Current()->has_valid_frame());
+    CodeGeneratorScope::Current()->frame()->Spill(target);
+    ASSERT(CodeGeneratorScope::Current()->allocator()->count(target) == 1);
    }
    ASSERT(is_register());
    ASSERT(reg().is(target));
@@ -127,7 +129,7 @@
    // register if valid and return an invalid result.
    if (result.is_valid() && !result.reg().is_byte_register()) {
      result.Unuse();
-    return Result(cgen_);
+    return Result();
    }
    return result;
  }

Modified: branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc       (original)
+++ branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc       Fri May 15  
04:09:51 2009
@@ -1075,12 +1075,12 @@
      new_element.set_static_type(element.static_type());
      elements_[index] = new_element;
      __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
-    return Result(temp.reg(), cgen_, element.static_type());
+    return Result(temp.reg(), element.static_type());
    } else if (element.is_register()) {
-    return Result(element.reg(), cgen_, element.static_type());
+    return Result(element.reg(), element.static_type());
    } else {
      ASSERT(element.is_constant());
-    return Result(element.handle(), cgen_);
+    return Result(element.handle());
    }
  }


Modified: branches/bleeding_edge/src/ia32/virtual-frame-ia32.h
==============================================================================
--- branches/bleeding_edge/src/ia32/virtual-frame-ia32.h        (original)
+++ branches/bleeding_edge/src/ia32/virtual-frame-ia32.h        Fri May 15  
04:09:51 2009
@@ -187,7 +187,7 @@

    // Set a frame element to a constant.  The index is frame-top relative.
    void SetElementAt(int index, Handle<Object> value) {
-    Result temp(value, cgen_);
+    Result temp(value);
      SetElementAt(index, &temp);
    }


Modified: branches/bleeding_edge/src/register-allocator-inl.h
==============================================================================
--- branches/bleeding_edge/src/register-allocator-inl.h (original)
+++ branches/bleeding_edge/src/register-allocator-inl.h Fri May 15 04:09:51  
2009
@@ -35,13 +35,25 @@
  namespace v8 { namespace internal {

  Result::~Result() {
-  if (is_register()) cgen_->allocator()->Unuse(reg());
+  if (is_register()) {
+    CodeGeneratorScope::Current()->allocator()->Unuse(reg());
+  }
  }


  void Result::Unuse() {
-  if (is_register()) cgen_->allocator()->Unuse(reg());
-  type_ = INVALID;
+  if (is_register()) {
+    CodeGeneratorScope::Current()->allocator()->Unuse(reg());
+  }
+  invalidate();
+}
+
+
+void Result::CopyTo(Result* destination) const {
+  destination->value_ = value_;
+  if (is_register()) {
+    CodeGeneratorScope::Current()->allocator()->Use(reg());
+  }
  }



Modified: branches/bleeding_edge/src/register-allocator.cc
==============================================================================
--- branches/bleeding_edge/src/register-allocator.cc    (original)
+++ branches/bleeding_edge/src/register-allocator.cc    Fri May 15 04:09:51  
2009
@@ -35,39 +35,22 @@
  //  
-------------------------------------------------------------------------
  // Result implementation.

-Result::Result(Register reg, CodeGenerator* cgen)
-    : static_type_(),
-      type_(REGISTER),
-      cgen_(cgen) {
-  data_.reg_ = reg;
-  ASSERT(reg.is_valid());
-  cgen_->allocator()->Use(reg);
-}
-

-Result::Result(Register reg, CodeGenerator* cgen, StaticType static_type)
-    : static_type_(static_type),
-      type_(REGISTER),
-      cgen_(cgen) {
-  data_.reg_ = reg;
+Result::Result(Register reg) {
    ASSERT(reg.is_valid());
-  cgen_->allocator()->Use(reg);
+  CodeGeneratorScope::Current()->allocator()->Use(reg);
+  value_ = StaticTypeField::encode(StaticType::UNKNOWN_TYPE)
+      | TypeField::encode(REGISTER)
+      | DataField::encode(reg.code_);
  }


-void Result::CopyTo(Result* destination) const {
-  destination->static_type_ = static_type_;
-  destination->type_ = type();
-  destination->cgen_ = cgen_;
-
-  if (is_register()) {
-    destination->data_.reg_ = reg();
-    cgen_->allocator()->Use(reg());
-  } else if (is_constant()) {
-    destination->data_.handle_ = data_.handle_;
-  } else {
-    ASSERT(!is_valid());
-  }
+Result::Result(Register reg, StaticType type) {
+  ASSERT(reg.is_valid());
+  CodeGeneratorScope::Current()->allocator()->Use(reg);
+  value_ = StaticTypeField::encode(type.static_type_)
+      | TypeField::encode(REGISTER)
+      | DataField::encode(reg.code_);
  }


@@ -80,9 +63,9 @@
    int free_reg = registers_.ScanForFreeRegister();
    if (free_reg < kNumRegisters) {
      Register free_result = { free_reg };
-    return Result(free_result, cgen_);
+    return Result(free_result);
    }
-  return Result(cgen_);
+  return Result();
  }


@@ -94,7 +77,7 @@
      Register free_reg = cgen_->frame()->SpillAnyRegister();
      if (free_reg.is_valid()) {
        ASSERT(!is_used(free_reg));
-      return Result(free_reg, cgen_);
+      return Result(free_reg);
      }
    }
    return result;
@@ -104,7 +87,7 @@
  Result RegisterAllocator::Allocate(Register target) {
    // If the target is not referenced, it can simply be allocated.
    if (!is_used(target)) {
-    return Result(target, cgen_);
+    return Result(target);
    }
    // If the target is only referenced in the frame, it can be spilled and
    // then allocated.
@@ -112,10 +95,10 @@
    if (cgen_->frame()->is_used(target) && count(target) == 1)  {
      cgen_->frame()->Spill(target);
      ASSERT(!is_used(target));
-    return Result(target, cgen_);
+    return Result(target);
    }
    // Otherwise (if it's referenced outside the frame) we cannot allocate  
it.
-  return Result(cgen_);
+  return Result();
  }



Modified: branches/bleeding_edge/src/register-allocator.h
==============================================================================
--- branches/bleeding_edge/src/register-allocator.h     (original)
+++ branches/bleeding_edge/src/register-allocator.h     Fri May 15 04:09:51 2009
@@ -103,6 +103,7 @@
    StaticTypeEnum static_type_;

    friend class FrameElement;
+  friend class Result;
  };


@@ -121,26 +122,20 @@
    };

    // Construct an invalid result.
-  explicit Result(CodeGenerator* cgen)
-      : static_type_(),
-        type_(INVALID),
-        cgen_(cgen) {}
+  Result() { invalidate(); }

    // Construct a register Result.
-  Result(Register reg,
-         CodeGenerator* cgen);
+  explicit Result(Register reg);

    // Construct a register Result with a known static type.
-  Result(Register reg,
-         CodeGenerator* cgen,
-         StaticType static_type);
+  Result(Register reg, StaticType static_type);

    // Construct a Result whose value is a compile-time constant.
-  Result(Handle<Object> value, CodeGenerator * cgen)
-      : static_type_(StaticType::TypeOf(*value)),
-        type_(CONSTANT),
-        cgen_(cgen) {
-    data_.handle_ = value.location();
+  explicit Result(Handle<Object> value) {
+    value_ =  
StaticTypeField::encode(StaticType::TypeOf(*value).static_type_)
+        | TypeField::encode(CONSTANT)
+        | DataField::encode(ConstantList()->length());
+    ConstantList()->Add(value);
    }

    // The copy constructor and assignment operators could each create a new
@@ -159,25 +154,51 @@

    inline ~Result();

+  // Static indirection table for handles to constants.  If a Result
+  // represents a constant, the data contains an index into this table
+  // of handles to the actual constants.
+  typedef ZoneList<Handle<Object> > ZoneObjectList;
+
+  static ZoneObjectList* ConstantList() {
+    static ZoneObjectList list(10);
+    return &list;
+  }
+
+  // Clear the constants indirection table.
+  static void ClearConstantList() {
+    ConstantList()->Clear();
+  }
+
    inline void Unuse();

-  StaticType static_type() const { return static_type_; }
-  void set_static_type(StaticType static_type) { static_type_ =  
static_type; }
+  StaticType static_type() const {
+    return StaticType(StaticTypeField::decode(value_));
+  }
+
+  void set_static_type(StaticType type) {
+    value_ = value_ & ~StaticTypeField::mask();
+    value_ = value_ | StaticTypeField::encode(type.static_type_);
+  }
+
+  Type type() const { return TypeField::decode(value_); }

-  Type type() const { return static_cast<Type>(type_); }
+  void invalidate() { value_ = TypeField::encode(INVALID); }

    bool is_valid() const { return type() != INVALID; }
    bool is_register() const { return type() == REGISTER; }
    bool is_constant() const { return type() == CONSTANT; }

    Register reg() const {
-    ASSERT(type() == REGISTER);
-    return data_.reg_;
+    ASSERT(is_register());
+    uint32_t reg = DataField::decode(value_);
+    Register result;
+    result.code_ = reg;
+    return result;
    }

    Handle<Object> handle() const {
      ASSERT(type() == CONSTANT);
-    return Handle<Object>(data_.handle_);
+    return ConstantList()->at(DataField::decode(value_));
    }

    // Move this result to an arbitrary register.  The register is not
@@ -191,17 +212,15 @@
    void ToRegister(Register reg);

   private:
-  StaticType static_type_;
-  byte type_;
+  uint32_t value_;

-  union {
-    Register reg_;
-    Object** handle_;
-  } data_;
+  class StaticTypeField: public BitField<StaticType::StaticTypeEnum, 0, 3>  
{};
+  class TypeField: public BitField<Type, 3, 2> {};
+  class DataField: public BitField<uint32_t, 5, 32 - 6> {};

-  CodeGenerator* cgen_;
+  inline void CopyTo(Result* destination) const;

-  void CopyTo(Result* destination) const;
+  friend class CodeGeneratorScope;
  };



Modified: branches/bleeding_edge/src/virtual-frame.cc
==============================================================================
--- branches/bleeding_edge/src/virtual-frame.cc (original)
+++ branches/bleeding_edge/src/virtual-frame.cc Fri May 15 04:09:51 2009
@@ -324,11 +324,11 @@

    // Early exit if the element is the same as the one being set.
    bool same_register = original.is_register()
-                    && value->is_register()
-                    && original.reg().is(value->reg());
+      && value->is_register()
+      && original.reg().is(value->reg());
    bool same_constant = original.is_constant()
-                    && value->is_constant()
-                    && original.handle().is_identical_to(value->handle());
+      && value->is_constant()
+      && original.handle().is_identical_to(value->handle());
    if (same_register || same_constant) {
      value->Unuse();
      return;

Modified: branches/bleeding_edge/test/cctest/test-log-ia32.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-log-ia32.cc (original)
+++ branches/bleeding_edge/test/cctest/test-log-ia32.cc Fri May 15 04:09:51  
2009
@@ -13,6 +13,7 @@
  #include "top.h"
  #include "cctest.h"
  #include "disassembler.h"
+#include "register-allocator-inl.h"

  using v8::Function;
  using v8::Local;

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

Reply via email to