Revision: 15936
Author:   [email protected]
Date:     Mon Jul 29 06:56:51 2013
Log: This adds generic support for ExternalReferences in Hydrogen (and Lithium), as required for AddIncrementCounter.

[email protected], [email protected]

Review URL: https://codereview.chromium.org/19562003
http://code.google.com/p/v8/source/detail?r=15936

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/assembler.h
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/hydrogen.h
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
 /branches/bleeding_edge/src/mips/lithium-mips.cc
 /branches/bleeding_edge/src/mips/lithium-mips.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.h
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Mon Jul 29 02:12:16 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Mon Jul 29 06:56:51 2013
@@ -2095,6 +2095,8 @@
     return DefineAsRegister(new(zone()) LConstantI);
   } else if (r.IsDouble()) {
     return DefineAsRegister(new(zone()) LConstantD);
+  } else if (r.IsExternal()) {
+    return DefineAsRegister(new(zone()) LConstantE);
   } else if (r.IsTagged()) {
     return DefineAsRegister(new(zone()) LConstantT);
   } else {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Mon Jul 29 04:57:42 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Mon Jul 29 06:56:51 2013
@@ -79,6 +79,7 @@
   V(CmpMapAndBranch)                            \
   V(CmpT)                                       \
   V(ConstantD)                                  \
+  V(ConstantE)                                  \
   V(ConstantI)                                  \
   V(ConstantS)                                  \
   V(ConstantT)                                  \
@@ -1232,6 +1233,17 @@
 };


+class LConstantE: public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  ExternalReference value() const {
+    return hydrogen()->ExternalReferenceValue();
+  }
+};
+
+
 class LConstantT: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Jul 29 02:12:16 2013 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Jul 29 06:56:51 2013
@@ -1820,6 +1820,11 @@
   double v = instr->value();
   __ Vmov(result, v, scratch0());
 }
+
+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+  __ mov(ToRegister(instr->result()), Operand(instr->value()));
+}


 void LCodeGen::DoConstantT(LConstantT* instr) {
@@ -3002,6 +3007,13 @@
   HObjectAccess access = instr->hydrogen()->access();
   int offset = access.offset();
   Register object = ToRegister(instr->object());
+
+  if (access.IsExternalMemory()) {
+    Register result = ToRegister(instr->result());
+    __ ldr(result, MemOperand(object, offset));
+    return;
+  }
+
   if (instr->hydrogen()->representation().IsDouble()) {
     DwVfpRegister result = ToDoubleRegister(instr->result());
     __ vldr(result, FieldMemOperand(object, offset));
@@ -4181,10 +4193,15 @@

   Register object = ToRegister(instr->object());
   Register scratch = scratch0();
-
   HObjectAccess access = instr->hydrogen()->access();
   int offset = access.offset();

+  if (access.IsExternalMemory()) {
+    Register value = ToRegister(instr->value());
+    __ str(value, MemOperand(object, offset));
+    return;
+  }
+
   Handle<Map> transition = instr->transition();

   if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
=======================================
--- /branches/bleeding_edge/src/assembler.h     Thu Jul 18 01:12:01 2013
+++ /branches/bleeding_edge/src/assembler.h     Mon Jul 29 06:56:51 2013
@@ -683,6 +683,8 @@
   static void TearDownMathExpData();

   typedef void* ExternalReferenceRedirector(void* original, Type type);
+
+  ExternalReference() : address_(NULL) {}

   ExternalReference(Builtins::CFunctionId id, Isolate* isolate);

@@ -829,7 +831,7 @@

   static ExternalReference cpu_features();

-  Address address() const {return reinterpret_cast<Address>(address_);}
+  Address address() const { return reinterpret_cast<Address>(address_); }

 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Function Debug::Break()
@@ -868,6 +870,14 @@

   static ExternalReference stress_deopt_count(Isolate* isolate);

+  bool operator==(const ExternalReference& other) const {
+    return address_ == other.address_;
+  }
+
+  bool operator!=(const ExternalReference& other) const {
+    return !(*this == other);
+  }
+
  private:
   explicit ExternalReference(void* address)
       : address_(address) {}
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Jul 29 05:35:43 2013 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Jul 29 06:56:51 2013
@@ -448,6 +448,7 @@
   // Note: The c1visualizer syntax for locals allows only a sequence of the
   // following characters: A-Za-z0-9_-|:
   switch (type_) {
+    case kNone: return "none";
     case kTagged: return "tagged";
     case kTaggedPrimitive: return "primitive";
     case kTaggedNumber: return "number";
@@ -2644,6 +2645,7 @@
     has_smi_value_(false),
     has_int32_value_(false),
     has_double_value_(false),
+    has_external_reference_value_(false),
     is_internalized_string_(false),
     is_not_in_new_space_(true),
     is_cell_(false),
@@ -2679,15 +2681,16 @@
                      bool is_not_in_new_space,
                      bool is_cell,
                      bool boolean_value)
-    : handle_(handle),
-      unique_id_(unique_id),
-      has_smi_value_(false),
-      has_int32_value_(false),
-      has_double_value_(false),
-      is_internalized_string_(is_internalize_string),
-      is_not_in_new_space_(is_not_in_new_space),
-      is_cell_(is_cell),
-      boolean_value_(boolean_value) {
+  : handle_(handle),
+    unique_id_(unique_id),
+    has_smi_value_(false),
+    has_int32_value_(false),
+    has_double_value_(false),
+    has_external_reference_value_(false),
+    is_internalized_string_(is_internalize_string),
+    is_not_in_new_space_(is_not_in_new_space),
+    is_cell_(is_cell),
+    boolean_value_(boolean_value) {
   ASSERT(!handle.is_null());
   ASSERT(!type.IsTaggedNumber());
   set_type(type);
@@ -2699,17 +2702,18 @@
                      Representation r,
                      bool is_not_in_new_space,
                      Handle<Object> optional_handle)
-    : handle_(optional_handle),
-      unique_id_(),
-      has_smi_value_(Smi::IsValid(integer_value)),
-      has_int32_value_(true),
-      has_double_value_(true),
-      is_internalized_string_(false),
-      is_not_in_new_space_(is_not_in_new_space),
-      is_cell_(false),
-      boolean_value_(integer_value != 0),
-      int32_value_(integer_value),
-      double_value_(FastI2D(integer_value)) {
+  : handle_(optional_handle),
+    unique_id_(),
+    has_smi_value_(Smi::IsValid(integer_value)),
+    has_int32_value_(true),
+    has_double_value_(true),
+    has_external_reference_value_(false),
+    is_internalized_string_(false),
+    is_not_in_new_space_(is_not_in_new_space),
+    is_cell_(false),
+    boolean_value_(integer_value != 0),
+    int32_value_(integer_value),
+    double_value_(FastI2D(integer_value)) {
   set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber());
   Initialize(r);
 }
@@ -2719,20 +2723,36 @@
                      Representation r,
                      bool is_not_in_new_space,
                      Handle<Object> optional_handle)
-    : handle_(optional_handle),
-      unique_id_(),
-      has_int32_value_(IsInteger32(double_value)),
-      has_double_value_(true),
-      is_internalized_string_(false),
-      is_not_in_new_space_(is_not_in_new_space),
-      is_cell_(false),
-      boolean_value_(double_value != 0 && !std::isnan(double_value)),
-      int32_value_(DoubleToInt32(double_value)),
-      double_value_(double_value) {
+  : handle_(optional_handle),
+    unique_id_(),
+    has_int32_value_(IsInteger32(double_value)),
+    has_double_value_(true),
+    has_external_reference_value_(false),
+    is_internalized_string_(false),
+    is_not_in_new_space_(is_not_in_new_space),
+    is_cell_(false),
+    boolean_value_(double_value != 0 && !std::isnan(double_value)),
+    int32_value_(DoubleToInt32(double_value)),
+    double_value_(double_value) {
   has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
   set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber());
   Initialize(r);
 }
+
+
+HConstant::HConstant(ExternalReference reference)
+  : has_smi_value_(false),
+    has_int32_value_(false),
+    has_double_value_(false),
+    has_external_reference_value_(true),
+    is_internalized_string_(false),
+    is_not_in_new_space_(true),
+    is_cell_(false),
+    boolean_value_(true),
+    external_reference_value_(reference) {
+  set_type(HType::None());
+  Initialize(Representation::External());
+}


 void HConstant::Initialize(Representation r) {
@@ -2743,6 +2763,8 @@
       r = Representation::Integer32();
     } else if (has_double_value_) {
       r = Representation::Double();
+    } else if (has_external_reference_value_) {
+      r = Representation::External();
     } else {
       r = Representation::Tagged();
     }
@@ -2767,12 +2789,16 @@
   if (r.IsSmi() && !has_smi_value_) return NULL;
   if (r.IsInteger32() && !has_int32_value_) return NULL;
   if (r.IsDouble() && !has_double_value_) return NULL;
+  if (r.IsExternal() && !has_external_reference_value_) return NULL;
   if (has_int32_value_) {
return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, handle_);
   }
   if (has_double_value_) {
return new(zone) HConstant(double_value_, r, is_not_in_new_space_, handle_);
   }
+  if (has_external_reference_value_) {
+    return new(zone) HConstant(external_reference_value_);
+  }
   ASSERT(!handle_.is_null());
   return new(zone) HConstant(handle_,
                              unique_id_,
@@ -2825,6 +2851,9 @@
     stream->Add("%d ", int32_value_);
   } else if (has_double_value_) {
     stream->Add("%f ", FmtElm(double_value_));
+  } else if (has_external_reference_value_) {
+    stream->Add("%p ", reinterpret_cast<void*>(
+            external_reference_value_.address()));
   } else {
     handle()->ShortPrint(stream);
   }
@@ -4505,6 +4534,10 @@
       instr->SetGVNFlag(is_store
           ? kChangesMaps : kDependsOnMaps);
       break;
+    case kExternalMemory:
+      instr->SetGVNFlag(is_store
+          ? kChangesExternalMemory : kDependsOnExternalMemory);
+      break;
   }
 }

@@ -4531,6 +4564,9 @@
if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
       stream->Add("[backing-store]");
       break;
+    case kExternalMemory:
+      stream->Add("[external-memory]");
+      break;
   }

   stream->Add("@%d", offset());
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Jul 29 05:35:43 2013 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Mon Jul 29 06:56:51 2013
@@ -211,7 +211,7 @@
   V(GlobalVars)                                \
   V(InobjectFields)                            \
   V(OsrEntries)                                \
-  V(SpecializedArrayElements)
+  V(ExternalMemory)


 #define DECLARE_ABSTRACT_INSTRUCTION(type)          \
@@ -350,6 +350,7 @@

 class HType {
  public:
+  static HType None() { return HType(kNone); }
   static HType Tagged() { return HType(kTagged); }
   static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
   static HType TaggedNumber() { return HType(kTaggedNumber); }
@@ -447,6 +448,7 @@

  private:
   enum Type {
+    kNone = 0x0,             // 0000 0000 0000 0000
     kTagged = 0x1,           // 0000 0000 0000 0001
     kTaggedPrimitive = 0x5,  // 0000 0000 0000 0101
     kTaggedNumber = 0xd,     // 0000 0000 0000 1101
@@ -2692,6 +2694,10 @@
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
+
+  virtual HType CalculateInferredType() {
+    return HType::None();
+  }

   DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)

@@ -3478,6 +3484,7 @@
             bool is_not_in_new_space,
             bool is_cell,
             bool boolean_value);
+  explicit HConstant(ExternalReference reference);

   Handle<Object> handle() {
     if (handle_.is_null()) {
@@ -3542,6 +3549,7 @@
     if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
     if (HasInteger32Value()) return Representation::Integer32();
     if (HasNumberValue()) return Representation::Double();
+    if (HasExternalReferenceValue()) return Representation::External();
     return Representation::Tagged();
   }

@@ -3592,6 +3600,13 @@
   bool HasInternalizedStringValue() const {
     return HasStringValue() && is_internalized_string_;
   }
+
+  bool HasExternalReferenceValue() const {
+    return has_external_reference_value_;
+  }
+  ExternalReference ExternalReferenceValue() const {
+    return external_reference_value_;
+  }

   bool BooleanValue() const { return boolean_value_; }

@@ -3600,6 +3615,8 @@
       return static_cast<intptr_t>(int32_value_);
     } else if (has_double_value_) {
       return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
+    } else if (has_external_reference_value_) {
+ return reinterpret_cast<intptr_t>(external_reference_value_.address());
     } else {
       ASSERT(!handle_.is_null());
       return unique_id_.Hashcode();
@@ -3607,14 +3624,15 @@
   }

   virtual void FinalizeUniqueValueId() {
-    if (!has_double_value_) {
+    if (!has_double_value_ && !has_external_reference_value_) {
       ASSERT(!handle_.is_null());
       unique_id_ = UniqueValueId(handle_);
     }
   }

   bool UniqueValueIdsMatch(UniqueValueId other) {
-    return !has_double_value_ && unique_id_ == other;
+    return !has_double_value_ && !has_external_reference_value_ &&
+        unique_id_ == other;
   }

 #ifdef DEBUG
@@ -3635,6 +3653,10 @@
       return other_constant->has_double_value_ &&
           BitCast<int64_t>(double_value_) ==
           BitCast<int64_t>(other_constant->double_value_);
+    } else if (has_external_reference_value_) {
+      return other_constant->has_external_reference_value_ &&
+          external_reference_value_ ==
+          other_constant->external_reference_value_;
     } else {
       ASSERT(!handle_.is_null());
       return !other_constant->handle_.is_null() &&
@@ -3662,12 +3684,14 @@
   bool has_smi_value_ : 1;
   bool has_int32_value_ : 1;
   bool has_double_value_ : 1;
+  bool has_external_reference_value_ : 1;
bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
   bool is_not_in_new_space_ : 1;
   bool is_cell_ : 1;
   bool boolean_value_ : 1;
   int32_t int32_value_;
   double double_value_;
+  ExternalReference external_reference_value_;
 };


@@ -5564,7 +5588,11 @@
 class HObjectAccess {
  public:
   inline bool IsInobject() const {
-    return portion() != kBackingStore;
+    return portion() != kBackingStore && portion() != kExternalMemory;
+  }
+
+  inline bool IsExternalMemory() const {
+    return portion() == kExternalMemory;
   }

   inline int offset() const {
@@ -5639,6 +5667,10 @@
   static HObjectAccess ForAllocationMementoSite() {
return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
   }
+
+  static HObjectAccess ForCounter() {
+    return HObjectAccess(kExternalMemory, 0, Representation::Integer32());
+  }

   // Create an access to an offset in a fixed array header.
   static HObjectAccess ForFixedArrayHeader(int offset);
@@ -5678,7 +5710,8 @@
     kElementsPointer,  // elements pointer
     kBackingStore,     // some field in the backing store
     kDouble,           // some double field
-    kInobject          // some other in-object field
+    kInobject,         // some other in-object field
+    kExternalMemory    // some field in external memory
   };

   HObjectAccess(Portion portion, int offset,
@@ -5756,7 +5789,9 @@
     if (representation.IsSmi()) {
       set_type(HType::Smi());
       set_representation(representation);
-    } else if (representation.IsDouble()) {
+    } else if (representation.IsDouble() ||
+               representation.IsExternal() ||
+               representation.IsInteger32()) {
       set_representation(representation);
     } else if (FLAG_track_heap_object_fields &&
                representation.IsHeapObject()) {
@@ -5782,6 +5817,10 @@

   virtual bool HasEscapingOperandAt(int index) { return false; }
   virtual Representation RequiredInputRepresentation(int index) {
+    if (index == 0 && access().IsExternalMemory()) {
+      // object must be external in case of external memory access
+      return Representation::External();
+    }
     return Representation::Tagged();
   }
   virtual void PrintDataTo(StringStream* stream);
@@ -5955,7 +5994,7 @@
         set_representation(Representation::Integer32());
       }

-      SetGVNFlag(kDependsOnSpecializedArrayElements);
+      SetGVNFlag(kDependsOnExternalMemory);
       // Native code could change the specialized array.
       SetGVNFlag(kDependsOnCalls);
     }
@@ -6112,9 +6151,13 @@

   virtual bool HasEscapingOperandAt(int index) { return index == 1; }
   virtual Representation RequiredInputRepresentation(int index) {
-    if (index == 1 && field_representation().IsDouble()) {
-      return field_representation();
-    } else if (index == 1 && field_representation().IsSmi()) {
+    if (index == 0 && access().IsExternalMemory()) {
+      // object must be external in case of external memory access
+      return Representation::External();
+    } else if (index == 1 &&
+        (field_representation().IsDouble() ||
+         field_representation().IsSmi() ||
+         field_representation().IsInteger32())) {
       return field_representation();
     }
     return Representation::Tagged();
@@ -6152,6 +6195,7 @@
     if (IsSkipWriteBarrier()) return false;
     if (field_representation().IsDouble()) return false;
     if (field_representation().IsSmi()) return false;
+    if (field_representation().IsInteger32()) return false;
     return StoringValueNeedsWriteBarrier(value()) &&
         ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
   }
@@ -6232,7 +6276,7 @@
       SetGVNFlag(kDependsOnNewSpacePromotion);
     }
     if (is_external()) {
-      SetGVNFlag(kChangesSpecializedArrayElements);
+      SetGVNFlag(kChangesExternalMemory);
       SetFlag(kAllowUndefinedAsNaN);
     } else if (IsFastDoubleElementsKind(elements_kind)) {
       SetGVNFlag(kChangesDoubleArrayElements);
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Mon Jul 29 04:50:39 2013
+++ /branches/bleeding_edge/src/hydrogen.cc     Mon Jul 29 06:56:51 2013
@@ -984,6 +984,19 @@
   }
   return instr;
 }
+
+
+void HGraphBuilder::AddIncrementCounter(StatsCounter* counter,
+                                        HValue* context) {
+  if (FLAG_native_code_counters && counter->Enabled()) {
+    HValue* reference = Add<HConstant>(ExternalReference(counter));
+ HValue* old_value = AddLoad(reference, HObjectAccess::ForCounter(), NULL);
+    HValue* new_value = AddInstruction(
+        HAdd::New(zone(), context, old_value, graph()->GetConstant1()));
+    new_value->ClearFlag(HValue::kCanOverflow);  // Ignore counter overflow
+    AddStore(reference, HObjectAccess::ForCounter(), new_value);
+  }
+}


 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
=======================================
--- /branches/bleeding_edge/src/hydrogen.h      Thu Jul 25 07:11:53 2013
+++ /branches/bleeding_edge/src/hydrogen.h      Mon Jul 29 06:56:51 2013
@@ -1133,6 +1133,9 @@

   void FinishExitWithHardDeoptimization(HBasicBlock* continuation);

+  void AddIncrementCounter(StatsCounter* counter,
+                           HValue* context);
+
   class IfBuilder {
    public:
     explicit IfBuilder(HGraphBuilder* builder,
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Jul 29 02:12:16 2013 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Jul 29 06:56:51 2013
@@ -683,6 +683,13 @@
   ASSERT(constant->HasDoubleValue());
   return constant->DoubleValue();
 }
+
+
+ExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const {
+  HConstant* constant = chunk_->LookupConstant(op);
+  ASSERT(constant->HasExternalReferenceValue());
+  return constant->ExternalReferenceValue();
+}


 bool LCodeGen::IsInteger32(LConstantOperand* op) const {
@@ -1851,6 +1858,11 @@
     }
   }
 }
+
+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+ __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value()));
+}


 void LCodeGen::DoConstantT(LConstantT* instr) {
@@ -3049,6 +3061,19 @@
 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
   HObjectAccess access = instr->hydrogen()->access();
   int offset = access.offset();
+
+  if (access.IsExternalMemory()) {
+    Register result = ToRegister(instr->result());
+    if (instr->object()->IsConstantOperand()) {
+      ExternalReference external_reference = ToExternalReference(
+          LConstantOperand::cast(instr->object()));
+      __ mov(result, MemOperand::StaticVariable(external_reference));
+    } else {
+      __ mov(result, MemOperand(ToRegister(instr->object()), offset));
+    }
+    return;
+  }
+
   Register object = ToRegister(instr->object());
   if (FLAG_track_double_fields &&
       instr->hydrogen()->representation().IsDouble()) {
@@ -4328,10 +4353,25 @@
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Representation representation = instr->representation();

-  Register object = ToRegister(instr->object());
   HObjectAccess access = instr->hydrogen()->access();
   int offset = access.offset();

+  if (access.IsExternalMemory()) {
+    MemOperand operand = instr->object()->IsConstantOperand()
+        ? MemOperand::StaticVariable(
+            ToExternalReference(LConstantOperand::cast(instr->object())))
+        : MemOperand(ToRegister(instr->object()), offset);
+    if (instr->value()->IsConstantOperand()) {
+ LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
+      __ mov(operand, Immediate(ToInteger32(operand_value)));
+    } else {
+      Register value = ToRegister(instr->value());
+      __ mov(operand, value);
+    }
+    return;
+  }
+
+  Register object = ToRegister(instr->object());
   Handle<Map> transition = instr->transition();

   if (FLAG_track_fields && representation.IsSmi()) {
@@ -4396,8 +4436,7 @@
   Register write_register = object;
   if (!access.IsInobject()) {
     write_register = ToRegister(instr->temp());
-    __ mov(write_register,
-           FieldOperand(object, JSObject::kPropertiesOffset));
+ __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
   }

   if (instr->value()->IsConstantOperand()) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Thu Jul 25 04:53:38 2013 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Mon Jul 29 06:56:51 2013
@@ -297,6 +297,7 @@
   X87Register ToX87Register(int index) const;
int ToRepresentation(LConstantOperand* op, const Representation& r) const;
   int32_t ToInteger32(LConstantOperand* op) const;
+  ExternalReference ToExternalReference(LConstantOperand* op) const;

   Operand BuildFastArrayOperand(LOperand* elements_pointer,
                                 LOperand* key,
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Mon Jul 29 02:12:16 2013 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Mon Jul 29 06:56:51 2013
@@ -2146,6 +2146,8 @@
     bool value_is_zero = BitCast<uint64_t, double>(value) == 0;
     LOperand* temp = value_is_zero ? NULL : TempRegister();
     return DefineAsRegister(new(zone()) LConstantD(temp));
+  } else if (r.IsExternal()) {
+    return DefineAsRegister(new(zone()) LConstantE);
   } else if (r.IsTagged()) {
     return DefineAsRegister(new(zone()) LConstantT);
   } else {
@@ -2222,7 +2224,10 @@


 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
-  LOperand* obj = UseRegisterAtStart(instr->object());
+  LOperand* obj = (instr->access().IsExternalMemory() &&
+                   instr->access().offset() == 0)
+      ? UseRegisterOrConstantAtStart(instr->object())
+      : UseRegisterAtStart(instr->object());
   return DefineAsRegister(new(zone()) LLoadNamedField(obj));
 }

@@ -2436,6 +2441,8 @@

 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
   bool is_in_object = instr->access().IsInobject();
+  bool is_external_location = instr->access().IsExternalMemory() &&
+      instr->access().offset() == 0;
   bool needs_write_barrier = instr->NeedsWriteBarrier();
   bool needs_write_barrier_for_map = !instr->transition().is_null() &&
       instr->NeedsWriteBarrierForMap();
@@ -2445,6 +2452,11 @@
     obj = is_in_object
         ? UseRegister(instr->object())
         : UseTempRegister(instr->object());
+  } else if (is_external_location) {
+    ASSERT(!is_in_object);
+    ASSERT(!needs_write_barrier);
+    ASSERT(!needs_write_barrier_for_map);
+    obj = UseRegisterOrConstant(instr->object());
   } else {
     obj = needs_write_barrier_for_map
         ? UseRegister(instr->object())
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h     Mon Jul 29 04:57:42 2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h     Mon Jul 29 06:56:51 2013
@@ -80,6 +80,7 @@
   V(CmpMapAndBranch)                            \
   V(CmpT)                                       \
   V(ConstantD)                                  \
+  V(ConstantE)                                  \
   V(ConstantI)                                  \
   V(ConstantS)                                  \
   V(ConstantT)                                  \
@@ -1208,6 +1209,17 @@
 };


+class LConstantE: public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  ExternalReference value() const {
+    return hydrogen()->ExternalReferenceValue();
+  }
+};
+
+
 class LConstantT: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Mon Jul 29 02:12:16 2013 +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Mon Jul 29 06:56:51 2013
@@ -1656,6 +1656,11 @@
   double v = instr->value();
   __ Move(result, v);
 }
+
+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+  __ li(ToRegister(instr->result()), Operand(instr->value()));
+}


 void LCodeGen::DoConstantT(LConstantT* instr) {
@@ -2878,6 +2883,13 @@
   HObjectAccess access = instr->hydrogen()->access();
   int offset = access.offset();
   Register object = ToRegister(instr->object());
+
+  if (access.IsExternalMemory()) {
+    Register result = ToRegister(instr->result());
+    __ lw(result, MemOperand(object, offset));
+    return;
+  }
+
   if (instr->hydrogen()->representation().IsDouble()) {
     DoubleRegister result = ToDoubleRegister(instr->result());
     __ ldc1(result, FieldMemOperand(object, offset));
@@ -4115,6 +4127,12 @@
   HObjectAccess access = instr->hydrogen()->access();
   int offset = access.offset();

+  if (access.IsExternalMemory()) {
+    Register value = ToRegister(instr->value());
+    __ sw(value, MemOperand(object, offset));
+    return;
+  }
+
   Handle<Map> transition = instr->transition();

   if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Mon Jul 29 02:12:16 2013 +++ /branches/bleeding_edge/src/mips/lithium-mips.cc Mon Jul 29 06:56:51 2013
@@ -2017,6 +2017,8 @@
     return DefineAsRegister(new(zone()) LConstantI);
   } else if (r.IsDouble()) {
     return DefineAsRegister(new(zone()) LConstantD);
+  } else if (r.IsExternal()) {
+    return DefineAsRegister(new(zone()) LConstantE);
   } else if (r.IsTagged()) {
     return DefineAsRegister(new(zone()) LConstantT);
   } else {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.h     Mon Jul 29 04:57:42 2013
+++ /branches/bleeding_edge/src/mips/lithium-mips.h     Mon Jul 29 06:56:51 2013
@@ -79,6 +79,7 @@
   V(CmpMapAndBranch)                            \
   V(CmpT)                                       \
   V(ConstantD)                                  \
+  V(ConstantE)                                  \
   V(ConstantI)                                  \
   V(ConstantS)                                  \
   V(ConstantT)                                  \
@@ -1210,6 +1211,17 @@
 };


+class LConstantE: public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  ExternalReference value() const {
+    return hydrogen()->ExternalReferenceValue();
+  }
+};
+
+
 class LConstantT: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Jul 29 02:12:16 2013 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Jul 29 06:56:51 2013
@@ -427,6 +427,13 @@
   ASSERT(constant->HasDoubleValue());
   return constant->DoubleValue();
 }
+
+
+ExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const {
+  HConstant* constant = chunk_->LookupConstant(op);
+  ASSERT(constant->HasExternalReferenceValue());
+  return constant->ExternalReferenceValue();
+}


 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
@@ -1522,6 +1529,11 @@
   }
 }

+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+  __ LoadAddress(ToRegister(instr->result()), instr->value());
+}
+

 void LCodeGen::DoConstantT(LConstantT* instr) {
   Handle<Object> value = instr->value();
@@ -2689,6 +2701,19 @@
 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
   HObjectAccess access = instr->hydrogen()->access();
   int offset = access.offset();
+
+  if (access.IsExternalMemory()) {
+    Register result = ToRegister(instr->result());
+    if (instr->object()->IsConstantOperand()) {
+      ASSERT(result.is(rax));
+ __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
+    } else {
+      Register object = ToRegister(instr->object());
+      __ movq(result, MemOperand(object, offset));
+    }
+    return;
+  }
+
   Register object = ToRegister(instr->object());
   if (FLAG_track_double_fields &&
       instr->hydrogen()->representation().IsDouble()) {
@@ -3926,11 +3951,23 @@
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Representation representation = instr->representation();

-  Register object = ToRegister(instr->object());
-
   HObjectAccess access = instr->hydrogen()->access();
   int offset = access.offset();

+  if (access.IsExternalMemory()) {
+    Register value = ToRegister(instr->value());
+    if (instr->object()->IsConstantOperand()) {
+      ASSERT(value.is(rax));
+      LConstantOperand* object = LConstantOperand::cast(instr->object());
+      __ store_rax(ToExternalReference(object));
+    } else {
+      Register object = ToRegister(instr->object());
+      __ movq(MemOperand(object, offset), value);
+    }
+    return;
+  }
+
+  Register object = ToRegister(instr->object());
   Handle<Map> transition = instr->transition();

   if (FLAG_track_fields && representation.IsSmi()) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Thu Jul 25 04:53:38 2013 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Mon Jul 29 06:56:51 2013
@@ -106,6 +106,7 @@
   int32_t ToInteger32(LConstantOperand* op) const;
   Smi* ToSmi(LConstantOperand* op) const;
   double ToDouble(LConstantOperand* op) const;
+  ExternalReference ToExternalReference(LConstantOperand* op) const;
   bool IsTaggedConstant(LConstantOperand* op) const;
   Handle<Object> ToHandle(LConstantOperand* op) const;
   Operand ToOperand(LOperand* op) const;
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Mon Jul 29 02:12:16 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Mon Jul 29 06:56:51 2013
@@ -1997,6 +1997,8 @@
   } else if (r.IsDouble()) {
     LOperand* temp = TempRegister();
     return DefineAsRegister(new(zone()) LConstantD(temp));
+  } else if (r.IsExternal()) {
+    return DefineAsRegister(new(zone()) LConstantE);
   } else if (r.IsTagged()) {
     return DefineAsRegister(new(zone()) LConstantT);
   } else {
@@ -2074,6 +2076,10 @@


 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
+ if (instr->access().IsExternalMemory() && instr->access().offset() == 0) {
+    LOperand* obj = UseRegisterOrConstantAtStart(instr->object());
+    return DefineFixed(new(zone()) LLoadNamedField(obj), rax);
+  }
   LOperand* obj = UseRegisterAtStart(instr->object());
   return DefineAsRegister(new(zone()) LLoadNamedField(obj));
 }
@@ -2249,6 +2255,8 @@

 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
   bool is_in_object = instr->access().IsInobject();
+  bool is_external_location = instr->access().IsExternalMemory() &&
+      instr->access().offset() == 0;
   bool needs_write_barrier = instr->NeedsWriteBarrier();
   bool needs_write_barrier_for_map = !instr->transition().is_null() &&
       instr->NeedsWriteBarrierForMap();
@@ -2258,6 +2266,11 @@
     obj = is_in_object
         ? UseRegister(instr->object())
         : UseTempRegister(instr->object());
+  } else if (is_external_location) {
+    ASSERT(!is_in_object);
+    ASSERT(!needs_write_barrier);
+    ASSERT(!needs_write_barrier_for_map);
+    obj = UseRegisterOrConstant(instr->object());
   } else {
     obj = needs_write_barrier_for_map
         ? UseRegister(instr->object())
@@ -2271,6 +2284,8 @@
   LOperand* val;
   if (needs_write_barrier) {
     val = UseTempRegister(instr->value());
+  } else if (is_external_location) {
+    val = UseFixed(instr->value(), rax);
   } else if (can_be_constant) {
     val = UseRegisterOrConstant(instr->value());
   } else if (FLAG_track_fields && instr->field_representation().IsSmi()) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Mon Jul 29 04:57:42 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Mon Jul 29 06:56:51 2013
@@ -79,6 +79,7 @@
   V(CmpMapAndBranch)                            \
   V(CmpT)                                       \
   V(ConstantD)                                  \
+  V(ConstantE)                                  \
   V(ConstantI)                                  \
   V(ConstantS)                                  \
   V(ConstantT)                                  \
@@ -1166,6 +1167,17 @@
 };


+class LConstantE: public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  ExternalReference value() const {
+    return hydrogen()->ExternalReferenceValue();
+  }
+};
+
+
 class LConstantT: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to