Revert "Fix compilation with C++11." and "Allocation site support for monomorphic...
authorbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 2 Jan 2014 10:38:45 +0000 (10:38 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 2 Jan 2014 10:38:45 +0000 (10:38 +0000)
This reverts commit r18431 and r18432 for breaking
the Linux nosnapshot build.

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/122463004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18434 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

20 files changed:
src/arm/code-stubs-arm.cc
src/ast.h
src/code-stubs-hydrogen.cc
src/code-stubs.cc
src/code-stubs.h
src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen.cc
src/hydrogen.h
src/ia32/code-stubs-ia32.cc
src/ia32/lithium-codegen-ia32.cc
src/ic.cc
src/ic.h
src/objects-inl.h
src/objects.cc
src/objects.h
src/type-info.cc
src/type-info.h
src/typing.cc
src/x64/code-stubs-x64.cc

index f70271bd506ecb9148a7773dc566c3f379b6c63c..f658291f84cefb3f4d0d92324f6e6c1eededb2e0 100644 (file)
@@ -193,6 +193,18 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
 }
 
 
+void BinaryOpICStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  static Register registers[] = { r1, r0 };
+  descriptor->register_param_count_ = 2;
+  descriptor->register_params_ = registers;
+  descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
+  descriptor->SetMissHandler(
+      ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
+}
+
+
 static void InitializeArrayConstructorDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor,
@@ -327,29 +339,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
 }
 
 
-void BinaryOpICStub::InitializeInterfaceDescriptor(
-    Isolate* isolate,
-    CodeStubInterfaceDescriptor* descriptor) {
-  static Register registers[] = { r1, r0 };
-  descriptor->register_param_count_ = 2;
-  descriptor->register_params_ = registers;
-  descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
-  descriptor->SetMissHandler(
-      ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
-}
-
-
-void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
-    Isolate* isolate,
-    CodeStubInterfaceDescriptor* descriptor) {
-  static Register registers[] = { r2, r1, r0 };
-  descriptor->register_param_count_ = 3;
-  descriptor->register_params_ = registers;
-  descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
-}
-
-
 void NewStringAddStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -1453,7 +1442,6 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
   ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
   CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
   BinaryOpICStub::GenerateAheadOfTime(isolate);
-  BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
 }
 
 
@@ -4174,38 +4162,6 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
 }
 
 
-void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- r1    : left
-  //  -- r0    : right
-  //  -- lr    : return address
-  // -----------------------------------
-  Isolate* isolate = masm->isolate();
-
-  // Load r2 with the allocation site.  We stick an undefined dummy value here
-  // and replace it with the real allocation site later when we instantiate this
-  // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
-  __ Move(r2, handle(isolate->heap()->undefined_value()));
-
-  // Make sure that we actually patched the allocation site.
-  if (FLAG_debug_code) {
-    __ tst(r2, Operand(kSmiTagMask));
-    __ Assert(ne, kExpectedAllocationSite);
-    __ push(r2);
-    __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
-    __ LoadRoot(ip, Heap::kAllocationSiteMapRootIndex);
-    __ cmp(r2, ip);
-    __ pop(r2);
-    __ Assert(eq, kExpectedAllocationSite);
-  }
-
-  // Tail call into the stub that handles binary operations with allocation
-  // sites.
-  BinaryOpWithAllocationSiteStub stub(state_);
-  __ TailCallStub(&stub);
-}
-
-
 void StringAddStub::Generate(MacroAssembler* masm) {
   Label call_runtime, call_builtin;
   Builtins::JavaScript builtin_id = Builtins::ADD;
index 3fabfddec26fe91696b8c3990b22311fab183e46..f8de9be0e9cba4293c8c5498afcd8f9b4c707388 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1936,10 +1936,6 @@ class BinaryOperation V8_FINAL : public Expression {
   Token::Value op() const { return op_; }
   Expression* left() const { return left_; }
   Expression* right() const { return right_; }
-  Handle<AllocationSite> allocation_site() const { return allocation_site_; }
-  void set_allocation_site(Handle<AllocationSite> allocation_site) {
-    allocation_site_ = allocation_site;
-  }
 
   BailoutId RightId() const { return right_id_; }
 
@@ -1968,7 +1964,6 @@ class BinaryOperation V8_FINAL : public Expression {
   Token::Value op_;
   Expression* left_;
   Expression* right_;
-  Handle<AllocationSite> allocation_site_;
 
   // TODO(rossberg): the fixed arg should probably be represented as a Constant
   // type for the RHS.
index 374f55f06879ffe12ecf7685f39f450d4eaa98dc..f66a9e3a27a37834927eb3322f82789c63265e61 100644 (file)
@@ -911,7 +911,6 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
          (state.HasSideEffects() || !result_type->Is(Type::None())));
 
   HValue* result = NULL;
-  HAllocationMode allocation_mode(NOT_TENURED);
   if (state.op() == Token::ADD &&
       (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) &&
       !left_type->Is(Type::String()) && !right_type->Is(Type::String())) {
@@ -925,15 +924,14 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
         Push(BuildBinaryOperation(
                     state.op(), left, right,
                     handle(Type::String(), isolate()), right_type,
-                    result_type, state.fixed_right_arg(),
-                    allocation_mode));
+                    result_type, state.fixed_right_arg()));
       }
       if_leftisstring.Else();
       {
         Push(BuildBinaryOperation(
                     state.op(), left, right,
                     left_type, right_type, result_type,
-                    state.fixed_right_arg(), allocation_mode));
+                    state.fixed_right_arg()));
       }
       if_leftisstring.End();
       result = Pop();
@@ -945,15 +943,14 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
         Push(BuildBinaryOperation(
                     state.op(), left, right,
                     left_type, handle(Type::String(), isolate()),
-                    result_type, state.fixed_right_arg(),
-                    allocation_mode));
+                    result_type, state.fixed_right_arg()));
       }
       if_rightisstring.Else();
       {
         Push(BuildBinaryOperation(
                     state.op(), left, right,
                     left_type, right_type, result_type,
-                    state.fixed_right_arg(), allocation_mode));
+                    state.fixed_right_arg()));
       }
       if_rightisstring.End();
       result = Pop();
@@ -962,7 +959,7 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
     result = BuildBinaryOperation(
             state.op(), left, right,
             left_type, right_type, result_type,
-            state.fixed_right_arg(), allocation_mode);
+            state.fixed_right_arg());
   }
 
   // If we encounter a generic argument, the number conversion is
@@ -1009,31 +1006,6 @@ Handle<Code> BinaryOpICStub::GenerateCode(Isolate* isolate) {
 }
 
 
-template <>
-HValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() {
-  BinaryOpIC::State state = casted_stub()->state();
-
-  HValue* allocation_site = GetParameter(
-      BinaryOpWithAllocationSiteStub::kAllocationSite);
-  HValue* left = GetParameter(BinaryOpWithAllocationSiteStub::kLeft);
-  HValue* right = GetParameter(BinaryOpWithAllocationSiteStub::kRight);
-
-  Handle<Type> left_type = state.GetLeftType(isolate());
-  Handle<Type> right_type = state.GetRightType(isolate());
-  Handle<Type> result_type = state.GetResultType(isolate());
-  HAllocationMode allocation_mode(allocation_site);
-
-  return BuildBinaryOperation(state.op(), left, right,
-                              left_type, right_type, result_type,
-                              state.fixed_right_arg(), allocation_mode);
-}
-
-
-Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode(Isolate* isolate) {
-  return DoGenerateCode(isolate, this);
-}
-
-
 template <>
 HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() {
   NewStringAddStub* stub = casted_stub();
@@ -1051,7 +1023,7 @@ HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() {
     right = BuildCheckString(right);
   }
 
-  return BuildStringAdd(left, right, HAllocationMode(pretenure_flag));
+  return BuildStringAdd(left, right, pretenure_flag);
 }
 
 
index e366e88b481f6be5ca022d6719cd72d8845404df..900385240da4631d21be27f6b3a2402d68b4d999 100644 (file)
@@ -247,28 +247,6 @@ void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
 }
 
 
-// static
-void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
-  // Generate special versions of the stub.
-  BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
-}
-
-
-void BinaryOpICWithAllocationSiteStub::PrintState(StringStream* stream) {
-  state_.Print(stream);
-}
-
-
-// static
-void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(
-    Isolate* isolate, const BinaryOpIC::State& state) {
-  if (state.CouldCreateAllocationMementos()) {
-    BinaryOpICWithAllocationSiteStub stub(state);
-    stub.GetCode(isolate);
-  }
-}
-
-
 void NewStringAddStub::PrintBaseName(StringStream* stream) {
   stream->Add("NewStringAddStub");
   if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
index bb9ff78f47f0d42af112f1c9468ebb92ddca9873..4e49680652fbd5518b983a47447d8be85d1db89c 100644 (file)
@@ -42,8 +42,6 @@ namespace internal {
   V(CallFunction)                        \
   V(CallConstruct)                       \
   V(BinaryOpIC)                          \
-  V(BinaryOpICWithAllocationSite)        \
-  V(BinaryOpWithAllocationSite)          \
   V(StringAdd)                           \
   V(NewStringAdd)                        \
   V(SubString)                           \
@@ -1064,7 +1062,7 @@ class KeyedArrayCallStub: public HICStub {
 };
 
 
-class BinaryOpICStub : public HydrogenCodeStub {
+class BinaryOpICStub V8_FINAL : public HydrogenCodeStub {
  public:
   BinaryOpICStub(Token::Value op, OverwriteMode mode)
       : HydrogenCodeStub(UNINITIALIZED), state_(op, mode) {}
@@ -1082,15 +1080,15 @@ class BinaryOpICStub : public HydrogenCodeStub {
     return Code::BINARY_OP_IC;
   }
 
-  virtual InlineCacheState GetICState() V8_FINAL V8_OVERRIDE {
+  virtual InlineCacheState GetICState() V8_OVERRIDE {
     return state_.GetICState();
   }
 
-  virtual ExtraICState GetExtraICState() V8_FINAL V8_OVERRIDE {
+  virtual ExtraICState GetExtraICState() V8_OVERRIDE {
     return state_.GetExtraICState();
   }
 
-  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_FINAL V8_OVERRIDE {
+  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
     ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
   }
 
@@ -1098,12 +1096,7 @@ class BinaryOpICStub : public HydrogenCodeStub {
 
   const BinaryOpIC::State& state() const { return state_; }
 
-  virtual void PrintState(StringStream* stream) V8_FINAL V8_OVERRIDE;
-
-  virtual Major MajorKey() V8_OVERRIDE { return BinaryOpIC; }
-  virtual int NotMissMinorKey() V8_FINAL V8_OVERRIDE {
-    return GetExtraICState();
-  }
+  virtual void PrintState(StringStream* stream) V8_OVERRIDE;
 
   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
   static const int kLeft = 0;
@@ -1113,86 +1106,12 @@ class BinaryOpICStub : public HydrogenCodeStub {
   static void GenerateAheadOfTime(Isolate* isolate,
                                   const BinaryOpIC::State& state);
 
-  BinaryOpIC::State state_;
-
-  DISALLOW_COPY_AND_ASSIGN(BinaryOpICStub);
-};
-
-
-// TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
-// call support for stubs in Hydrogen.
-class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub {
- public:
-  explicit BinaryOpICWithAllocationSiteStub(const BinaryOpIC::State& state)
-      : state_(state) {}
-
-  static void GenerateAheadOfTime(Isolate* isolate);
-
-  Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate,
-                                       Handle<AllocationSite> allocation_site) {
-    Handle<Code> code = CodeStub::GetCodeCopyFromTemplate(isolate);
-    // Replace the placeholder oddball with the actual allocation site.
-    code->ReplaceNthObject(1, isolate->heap()->oddball_map(), *allocation_site);
-    return code;
-  }
-
-  virtual Code::Kind GetCodeKind() const V8_OVERRIDE {
-    return Code::BINARY_OP_IC;
-  }
-
-  virtual InlineCacheState GetICState() V8_OVERRIDE {
-    return state_.GetICState();
-  }
-
-  virtual ExtraICState GetExtraICState() V8_OVERRIDE {
-    return state_.GetExtraICState();
-  }
-
-  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
-    ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
-  }
-
-  virtual void Generate(MacroAssembler* masm) V8_OVERRIDE;
-
-  virtual void PrintState(StringStream* stream) V8_OVERRIDE;
-
-  virtual Major MajorKey() V8_OVERRIDE { return BinaryOpICWithAllocationSite; }
-  virtual int MinorKey() V8_OVERRIDE { return GetExtraICState(); }
-
- private:
-  static void GenerateAheadOfTime(Isolate* isolate,
-                                  const BinaryOpIC::State& state);
+  virtual Major MajorKey() V8_OVERRIDE { return BinaryOpIC; }
+  virtual int NotMissMinorKey() V8_OVERRIDE { return GetExtraICState(); }
 
   BinaryOpIC::State state_;
 
-  DISALLOW_COPY_AND_ASSIGN(BinaryOpICWithAllocationSiteStub);
-};
-
-
-class BinaryOpWithAllocationSiteStub V8_FINAL : public BinaryOpICStub {
- public:
-  explicit BinaryOpWithAllocationSiteStub(const BinaryOpIC::State& state)
-      : BinaryOpICStub(state) {}
-
-  virtual void InitializeInterfaceDescriptor(
-      Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
-
-  static void InstallDescriptors(Isolate* isolate);
-
-  virtual Code::Kind GetCodeKind() const V8_FINAL V8_OVERRIDE {
-    return Code::STUB;
-  }
-
-  virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
-
-  virtual Major MajorKey() V8_OVERRIDE {
-    return BinaryOpWithAllocationSite;
-  }
-
-  // Parameters accessed via CodeStubGraphBuilder::GetParameter()
-  static const int kAllocationSite = 0;
-  static const int kLeft = 1;
-  static const int kRight = 2;
+  DISALLOW_COPY_AND_ASSIGN(BinaryOpICStub);
 };
 
 
@@ -1211,10 +1130,6 @@ class NewStringAddStub V8_FINAL : public HydrogenCodeStub {
     return PretenureFlagBits::decode(bit_field_);
   }
 
-  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
-    ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
-  }
-
   virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
 
   virtual void InitializeInterfaceDescriptor(
index 49916687696b4d6b05cf4caf524bc74ce7e3db25..a3bc56ca4306d77c8914da1ce5cc1a1a14f102e8 100644 (file)
@@ -3815,9 +3815,7 @@ HInstruction* HStringAdd::New(Zone* zone,
                               HValue* context,
                               HValue* left,
                               HValue* right,
-                              PretenureFlag pretenure_flag,
-                              StringAddFlags flags,
-                              Handle<AllocationSite> allocation_site) {
+                              StringAddFlags flags) {
   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
     HConstant* c_right = HConstant::cast(right);
     HConstant* c_left = HConstant::cast(left);
@@ -3827,23 +3825,7 @@ HInstruction* HStringAdd::New(Zone* zone,
       return HConstant::New(zone, context, concat);
     }
   }
-  return new(zone) HStringAdd(
-      context, left, right, pretenure_flag, flags, allocation_site);
-}
-
-
-void HStringAdd::PrintDataTo(StringStream* stream) {
-  if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
-    stream->Add("_CheckBoth");
-  } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) {
-    stream->Add("_CheckLeft");
-  } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_RIGHT) {
-    stream->Add("_CheckRight");
-  }
-  stream->Add(" (");
-  if (pretenure_flag() == NOT_TENURED) stream->Add("N");
-  else if (pretenure_flag() == TENURED) stream->Add("D");
-  stream->Add(")");
+  return new(zone) HStringAdd(context, left, right, flags);
 }
 
 
index a32a418606a058f5368a29d0ca0782a2400136e6..086f9a1a4cea430882d2b3b8d74938ce23581386 100644 (file)
@@ -6992,55 +6992,45 @@ class HStringAdd V8_FINAL : public HBinaryOperation {
                            HValue* context,
                            HValue* left,
                            HValue* right,
-                           PretenureFlag pretenure_flag = NOT_TENURED,
-                           StringAddFlags flags = STRING_ADD_CHECK_BOTH,
-                           Handle<AllocationSite> allocation_site =
-                               Handle<AllocationSite>::null());
+                           StringAddFlags flags = STRING_ADD_CHECK_NONE);
 
   StringAddFlags flags() const { return flags_; }
-  PretenureFlag pretenure_flag() const { return pretenure_flag_; }
 
   virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-
   DECLARE_CONCRETE_INSTRUCTION(StringAdd)
 
  protected:
-  virtual bool DataEquals(HValue* other) V8_OVERRIDE {
-    return flags_ == HStringAdd::cast(other)->flags_ &&
-        pretenure_flag_ == HStringAdd::cast(other)->pretenure_flag_;
-  }
+  virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
 
  private:
-  HStringAdd(HValue* context,
-             HValue* left,
-             HValue* right,
-             PretenureFlag pretenure_flag,
-             StringAddFlags flags,
-             Handle<AllocationSite> allocation_site)
-      : HBinaryOperation(context, left, right, HType::String()),
-        flags_(flags), pretenure_flag_(pretenure_flag) {
+  HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags)
+      : HBinaryOperation(context, left, right, HType::String()), flags_(flags) {
     set_representation(Representation::Tagged());
-    SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnMaps);
-    SetGVNFlag(kChangesNewSpacePromotion);
-    if (FLAG_trace_pretenuring) {
-      PrintF("HStringAdd with AllocationSite %p %s\n",
-             allocation_site.is_null()
-                 ? static_cast<void*>(NULL)
-                 : static_cast<void*>(*allocation_site),
-             pretenure_flag == TENURED ? "tenured" : "not tenured");
+    if (MightHaveSideEffects()) {
+      SetAllSideEffects();
+    } else {
+      SetFlag(kUseGVN);
+      SetGVNFlag(kDependsOnMaps);
+      SetGVNFlag(kChangesNewSpacePromotion);
     }
   }
 
+  bool MightHaveSideEffects() const {
+    return flags_ != STRING_ADD_CHECK_NONE &&
+      (left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved());
+  }
+
   // No side-effects except possible allocation:
-  virtual bool IsDeletable() const V8_OVERRIDE { return true; }
+  // NOTE: this instruction does not call ToString() on its inputs, when flags_
+  // is set to STRING_ADD_CHECK_NONE.
+  virtual bool IsDeletable() const V8_OVERRIDE {
+    return !MightHaveSideEffects();
+  }
 
   const StringAddFlags flags_;
-  const PretenureFlag pretenure_flag_;
 };
 
 
index 7bdc02f79c7da451c614949dac604c742906c1fc..3fcce8046d354b469411f19d8927e3a97dfd578d 100644 (file)
@@ -1693,131 +1693,22 @@ HValue* HGraphBuilder::BuildNumberToString(HValue* object,
 }
 
 
-HAllocate* HGraphBuilder::BuildAllocate(
-    HValue* object_size,
-    HType type,
-    InstanceType instance_type,
-    HAllocationMode allocation_mode) {
-  // Compute the effective allocation size.
-  HValue* size = object_size;
-  if (allocation_mode.CreateAllocationMementos()) {
-    size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize));
+HValue* HGraphBuilder::BuildSeqStringSizeFor(HValue* length,
+                                             String::Encoding encoding) {
+  STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
+  HValue* size = length;
+  if (encoding == String::TWO_BYTE_ENCODING) {
+    size = AddUncasted<HShl>(length, graph()->GetConstant1());
     size->ClearFlag(HValue::kCanOverflow);
+    size->SetFlag(HValue::kUint32);
   }
-
-  // Perform the actual allocation.
-  HAllocate* object = Add<HAllocate>(
-      size, type, allocation_mode.GetPretenureMode(),
-      instance_type, allocation_mode.feedback_site());
-
-  // Setup the allocation memento.
-  if (allocation_mode.CreateAllocationMementos()) {
-    BuildCreateAllocationMemento(
-        object, object_size, allocation_mode.current_site());
-  }
-
-  return object;
-}
-
-
-HValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length,
-                                             HValue* right_length) {
-  // Compute the combined string length. If the result is larger than the max
-  // supported string length, we bailout to the runtime. This is done implicitly
-  // when converting the result back to a smi in case the max string length
-  // equals the max smi value. Otherwise, for platforms with 32-bit smis, we do
-  HValue* length = AddUncasted<HAdd>(left_length, right_length);
-  STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
-  if (String::kMaxLength != Smi::kMaxValue) {
-    IfBuilder if_nooverflow(this);
-    if_nooverflow.If<HCompareNumericAndBranch>(
-        length, Add<HConstant>(String::kMaxLength), Token::LTE);
-    if_nooverflow.Then();
-    if_nooverflow.ElseDeopt("String length exceeds limit");
-  }
-  return length;
-}
-
-
-HValue* HGraphBuilder::BuildCreateConsString(
-    HValue* length,
-    HValue* left,
-    HValue* right,
-    HAllocationMode allocation_mode) {
-  // Determine the string instance types.
-  HInstruction* left_instance_type = AddLoadStringInstanceType(left);
-  HInstruction* right_instance_type = AddLoadStringInstanceType(right);
-
-  // Allocate the cons string object. HAllocate does not care whether we
-  // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
-  // CONS_STRING_TYPE here. Below we decide whether the cons string is
-  // one-byte or two-byte and set the appropriate map.
-  ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE,
-                                            CONS_ASCII_STRING_TYPE));
-  HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize),
-                                    HType::String(), CONS_STRING_TYPE,
-                                    allocation_mode);
-
-  // Compute intersection and difference of instance types.
-  HValue* anded_instance_types = AddUncasted<HBitwise>(
-      Token::BIT_AND, left_instance_type, right_instance_type);
-  HValue* xored_instance_types = AddUncasted<HBitwise>(
-      Token::BIT_XOR, left_instance_type, right_instance_type);
-
-  // We create a one-byte cons string if
-  // 1. both strings are one-byte, or
-  // 2. at least one of the strings is two-byte, but happens to contain only
-  //    one-byte characters.
-  // To do this, we check
-  // 1. if both strings are one-byte, or if the one-byte data hint is set in
-  //    both strings, or
-  // 2. if one of the strings has the one-byte data hint set and the other
-  //    string is one-byte.
-  IfBuilder if_onebyte(this);
-  STATIC_ASSERT(kOneByteStringTag != 0);
-  STATIC_ASSERT(kOneByteDataHintMask != 0);
-  if_onebyte.If<HCompareNumericAndBranch>(
-      AddUncasted<HBitwise>(
-          Token::BIT_AND, anded_instance_types,
-          Add<HConstant>(static_cast<int32_t>(
-                  kStringEncodingMask | kOneByteDataHintMask))),
-      graph()->GetConstant0(), Token::NE);
-  if_onebyte.Or();
-  STATIC_ASSERT(kOneByteStringTag != 0 &&
-                kOneByteDataHintTag != 0 &&
-                kOneByteDataHintTag != kOneByteStringTag);
-  if_onebyte.If<HCompareNumericAndBranch>(
-      AddUncasted<HBitwise>(
-          Token::BIT_AND, xored_instance_types,
-          Add<HConstant>(static_cast<int32_t>(
-                  kOneByteStringTag | kOneByteDataHintTag))),
-      Add<HConstant>(static_cast<int32_t>(
-              kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
-  if_onebyte.Then();
-  {
-    // We can safely skip the write barrier for storing the map here.
-    Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
-    AddStoreMapConstantNoWriteBarrier(result, map);
-  }
-  if_onebyte.Else();
-  {
-    // We can safely skip the write barrier for storing the map here.
-    Handle<Map> map = isolate()->factory()->cons_string_map();
-    AddStoreMapConstantNoWriteBarrier(result, map);
-  }
-  if_onebyte.End();
-
-  // Initialize the cons string fields.
-  Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
-                        Add<HConstant>(String::kEmptyHashField));
-  Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
-  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left);
-  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right);
-
-  // Count the native string addition.
-  AddIncrementCounter(isolate()->counters()->string_add_native());
-
-  return result;
+  size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
+              SeqString::kHeaderSize + kObjectAlignmentMask)));
+  size->ClearFlag(HValue::kCanOverflow);
+  size = AddUncasted<HBitwise>(
+      Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
+              ~kObjectAlignmentMask)));
+  return size;
 }
 
 
@@ -1843,54 +1734,123 @@ void HGraphBuilder::BuildCopySeqStringChars(HValue* src,
 }
 
 
-HValue* HGraphBuilder::BuildUncheckedStringAdd(
-    HValue* left,
-    HValue* right,
-    HAllocationMode allocation_mode) {
+HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left,
+                                               HValue* right,
+                                               PretenureFlag pretenure_flag) {
   // Determine the string lengths.
-  HValue* left_length = AddLoadStringLength(left);
-  HValue* right_length = AddLoadStringLength(right);
+  HValue* left_length = Add<HLoadNamedField>(
+      left, HObjectAccess::ForStringLength());
+  HValue* right_length = Add<HLoadNamedField>(
+      right, HObjectAccess::ForStringLength());
 
-  // Compute the combined string length.
-  HValue* length = BuildAddStringLengths(left_length, right_length);
-
-  // Do some manual constant folding here.
-  if (left_length->IsConstant()) {
-    HConstant* c_left_length = HConstant::cast(left_length);
-    ASSERT_NE(0, c_left_length->Integer32Value());
-    if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) {
-      // The right string contains at least one character.
-      return BuildCreateConsString(length, left, right, allocation_mode);
-    }
-  } else if (right_length->IsConstant()) {
-    HConstant* c_right_length = HConstant::cast(right_length);
-    ASSERT_NE(0, c_right_length->Integer32Value());
-    if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) {
-      // The left string contains at least one character.
-      return BuildCreateConsString(length, left, right, allocation_mode);
-    }
+  // Compute the combined string length. If the result is larger than the max
+  // supported string length, we bailout to the runtime. This is done implicitly
+  // when converting the result back to a smi in case the max string length
+  // equals the max smi valie. Otherwise, for platforms with 32-bit smis, we do
+  HValue* length = AddUncasted<HAdd>(left_length, right_length);
+  STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
+  if (String::kMaxLength != Smi::kMaxValue) {
+    IfBuilder if_nooverflow(this);
+    if_nooverflow.If<HCompareNumericAndBranch>(
+        length, Add<HConstant>(String::kMaxLength), Token::LTE);
+    if_nooverflow.Then();
+    if_nooverflow.ElseDeopt("String length exceeds limit");
   }
 
+  // Determine the string instance types.
+  HLoadNamedField* left_instance_type = Add<HLoadNamedField>(
+      Add<HLoadNamedField>(left, HObjectAccess::ForMap()),
+      HObjectAccess::ForMapInstanceType());
+  HLoadNamedField* right_instance_type = Add<HLoadNamedField>(
+      Add<HLoadNamedField>(right, HObjectAccess::ForMap()),
+      HObjectAccess::ForMapInstanceType());
+
+  // Compute difference of instance types.
+  HValue* xored_instance_types = AddUncasted<HBitwise>(
+      Token::BIT_XOR, left_instance_type, right_instance_type);
+
   // Check if we should create a cons string.
   IfBuilder if_createcons(this);
   if_createcons.If<HCompareNumericAndBranch>(
       length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
   if_createcons.Then();
   {
-    // Create a cons string.
-    Push(BuildCreateConsString(length, left, right, allocation_mode));
+    // Allocate the cons string object. HAllocate does not care whether we
+    // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
+    // CONS_STRING_TYPE here. Below we decide whether the cons string is
+    // one-byte or two-byte and set the appropriate map.
+    ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE,
+                                              CONS_ASCII_STRING_TYPE));
+    HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize),
+                                       HType::String(), pretenure_flag,
+                                       CONS_STRING_TYPE);
+
+    // Compute the intersection of instance types.
+    HValue* anded_instance_types = AddUncasted<HBitwise>(
+        Token::BIT_AND, left_instance_type, right_instance_type);
+
+    // We create a one-byte cons string if
+    // 1. both strings are one-byte, or
+    // 2. at least one of the strings is two-byte, but happens to contain only
+    //    one-byte characters.
+    // To do this, we check
+    // 1. if both strings are one-byte, or if the one-byte data hint is set in
+    //    both strings, or
+    // 2. if one of the strings has the one-byte data hint set and the other
+    //    string is one-byte.
+    IfBuilder if_onebyte(this);
+    STATIC_ASSERT(kOneByteStringTag != 0);
+    STATIC_ASSERT(kOneByteDataHintMask != 0);
+    if_onebyte.If<HCompareNumericAndBranch>(
+        AddUncasted<HBitwise>(
+            Token::BIT_AND, anded_instance_types,
+            Add<HConstant>(static_cast<int32_t>(
+                    kStringEncodingMask | kOneByteDataHintMask))),
+        graph()->GetConstant0(), Token::NE);
+    if_onebyte.Or();
+    STATIC_ASSERT(kOneByteStringTag != 0 &&
+                  kOneByteDataHintTag != 0 &&
+                  kOneByteDataHintTag != kOneByteStringTag);
+    if_onebyte.If<HCompareNumericAndBranch>(
+        AddUncasted<HBitwise>(
+            Token::BIT_AND, xored_instance_types,
+            Add<HConstant>(static_cast<int32_t>(
+                    kOneByteStringTag | kOneByteDataHintTag))),
+        Add<HConstant>(static_cast<int32_t>(
+                kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
+    if_onebyte.Then();
+    {
+      // We can safely skip the write barrier for storing the map here.
+      Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
+      AddStoreMapConstantNoWriteBarrier(string, map);
+    }
+    if_onebyte.Else();
+    {
+      // We can safely skip the write barrier for storing the map here.
+      Handle<Map> map = isolate()->factory()->cons_string_map();
+      AddStoreMapConstantNoWriteBarrier(string, map);
+    }
+    if_onebyte.End();
+
+    // Initialize the cons string fields.
+    Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
+                          Add<HConstant>(String::kEmptyHashField));
+    Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(), length);
+    Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left);
+    Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(),
+                          right);
+
+    // Count the native string addition.
+    AddIncrementCounter(isolate()->counters()->string_add_native());
+
+    // Cons string is result.
+    Push(string);
   }
   if_createcons.Else();
   {
-    // Determine the string instance types.
-    HValue* left_instance_type = AddLoadStringInstanceType(left);
-    HValue* right_instance_type = AddLoadStringInstanceType(right);
-
-    // Compute union and difference of instance types.
+    // Compute union of instance types.
     HValue* ored_instance_types = AddUncasted<HBitwise>(
         Token::BIT_OR, left_instance_type, right_instance_type);
-    HValue* xored_instance_types = AddUncasted<HBitwise>(
-        Token::BIT_XOR, left_instance_type, right_instance_type);
 
     // Check if both strings have the same encoding and both are
     // sequential.
@@ -1909,12 +1869,7 @@ HValue* HGraphBuilder::BuildUncheckedStringAdd(
         graph()->GetConstant0(), Token::EQ);
     if_sameencodingandsequential.Then();
     {
-      HConstant* string_map =
-          Add<HConstant>(isolate()->factory()->string_map());
-      HConstant* ascii_string_map =
-          Add<HConstant>(isolate()->factory()->ascii_string_map());
-
-      // Determine map and size depending on whether result is one-byte string.
+      // Check if the result is a one-byte string.
       IfBuilder if_onebyte(this);
       STATIC_ASSERT(kOneByteStringTag != 0);
       if_onebyte.If<HCompareNumericAndBranch>(
@@ -1924,84 +1879,90 @@ HValue* HGraphBuilder::BuildUncheckedStringAdd(
           graph()->GetConstant0(), Token::NE);
       if_onebyte.Then();
       {
-        // Allocate sequential one-byte string object.
-        Push(length);
-        Push(ascii_string_map);
-      }
-      if_onebyte.Else();
-      {
-        // Allocate sequential two-byte string object.
-        HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1());
-        size->ClearFlag(HValue::kCanOverflow);
-        size->SetFlag(HValue::kUint32);
-        Push(size);
-        Push(string_map);
-      }
-      if_onebyte.End();
-      HValue* map = Pop();
-
-      // Calculate the number of bytes needed for the characters in the
-      // string while observing object alignment.
-      STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
-      HValue* size = Pop();
-      size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
-                  SeqString::kHeaderSize + kObjectAlignmentMask)));
-      size->ClearFlag(HValue::kCanOverflow);
-      size = AddUncasted<HBitwise>(
-          Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
-                  ~kObjectAlignmentMask)));
-
-      // Allocate the string object. HAllocate does not care whether we pass
-      // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here.
-      HAllocate* result = BuildAllocate(
-          size, HType::String(), STRING_TYPE, allocation_mode);
-
-      // We can safely skip the write barrier for storing map here.
-      AddStoreMapNoWriteBarrier(result, map);
-
-      // Initialize the string fields.
-      Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
-                            Add<HConstant>(String::kEmptyHashField));
-      Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
-
-      // Copy characters to the result string.
-      IfBuilder if_twobyte(this);
-      if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map);
-      if_twobyte.Then();
-      {
-        // Copy characters from the left string.
+        // Calculate the number of bytes needed for the characters in the
+        // string while observing object alignment.
+        HValue* size = BuildSeqStringSizeFor(
+            length, String::ONE_BYTE_ENCODING);
+
+        // Allocate the ASCII string object.
+        Handle<Map> map = isolate()->factory()->ascii_string_map();
+        HAllocate* string = Add<HAllocate>(size, HType::String(),
+                                           pretenure_flag, ASCII_STRING_TYPE);
+        string->set_known_initial_map(map);
+
+        // We can safely skip the write barrier for storing map here.
+        AddStoreMapConstantNoWriteBarrier(string, map);
+
+        // Length must be stored into the string before we copy characters to
+        // make debug verification code happy.
+        Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
+                              length);
+
+        // Copy bytes from the left string.
         BuildCopySeqStringChars(
-            left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
-            result, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
+            left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
+            string, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
             left_length);
 
-        // Copy characters from the right string.
+        // Copy bytes from the right string.
         BuildCopySeqStringChars(
-            right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
-            result, left_length, String::TWO_BYTE_ENCODING,
+            right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
+            string, left_length, String::ONE_BYTE_ENCODING,
             right_length);
+
+        // Count the native string addition.
+        AddIncrementCounter(isolate()->counters()->string_add_native());
+
+        // Return the string.
+        Push(string);
       }
-      if_twobyte.Else();
+      if_onebyte.Else();
       {
-        // Copy characters from the left string.
+        // Calculate the number of bytes needed for the characters in the
+        // string while observing object alignment.
+        HValue* size = BuildSeqStringSizeFor(
+            length, String::TWO_BYTE_ENCODING);
+
+        // Allocate the two-byte string object.
+        Handle<Map> map = isolate()->factory()->string_map();
+        HAllocate* string = Add<HAllocate>(size, HType::String(),
+                                           pretenure_flag, STRING_TYPE);
+        string->set_known_initial_map(map);
+
+        // We can safely skip the write barrier for storing map here.
+        AddStoreMapConstantNoWriteBarrier(string, map);
+
+        // Length must be stored into the string before we copy characters to
+        // make debug verification code happy.
+        Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
+                              length);
+
+        // Copy bytes from the left string.
         BuildCopySeqStringChars(
-            left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
-            result, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
+            left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
+            string, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
             left_length);
 
-        // Copy characters from the right string.
+        // Copy bytes from the right string.
         BuildCopySeqStringChars(
-            right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
-            result, left_length, String::ONE_BYTE_ENCODING,
+            right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
+            string, left_length, String::TWO_BYTE_ENCODING,
             right_length);
+
+        // Return the string.
+        Push(string);
       }
-      if_twobyte.End();
+      if_onebyte.End();
+
+      // Initialize the (common) string fields.
+      HValue* string = Pop();
+      Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
+                            Add<HConstant>(String::kEmptyHashField));
 
       // Count the native string addition.
       AddIncrementCounter(isolate()->counters()->string_add_native());
 
-      // Return the sequential string.
-      Push(result);
+      Push(string);
     }
     if_sameencodingandsequential.Else();
     {
@@ -2020,21 +1981,20 @@ HValue* HGraphBuilder::BuildUncheckedStringAdd(
 }
 
 
-HValue* HGraphBuilder::BuildStringAdd(
-    HValue* left,
-    HValue* right,
-    HAllocationMode allocation_mode) {
-  NoObservableSideEffectsScope no_effects(this);
-
-  // Determine string lengths.
-  HValue* left_length = AddLoadStringLength(left);
-  HValue* right_length = AddLoadStringLength(right);
+HValue* HGraphBuilder::BuildStringAdd(HValue* left,
+                                      HValue* right,
+                                      PretenureFlag pretenure_flag) {
+  // Determine the string lengths.
+  HValue* left_length = Add<HLoadNamedField>(
+      left, HObjectAccess::ForStringLength());
+  HValue* right_length = Add<HLoadNamedField>(
+      right, HObjectAccess::ForStringLength());
 
   // Check if left string is empty.
-  IfBuilder if_leftempty(this);
-  if_leftempty.If<HCompareNumericAndBranch>(
+  IfBuilder if_leftisempty(this);
+  if_leftisempty.If<HCompareNumericAndBranch>(
       left_length, graph()->GetConstant0(), Token::EQ);
-  if_leftempty.Then();
+  if_leftisempty.Then();
   {
     // Count the native string addition.
     AddIncrementCounter(isolate()->counters()->string_add_native());
@@ -2042,13 +2002,13 @@ HValue* HGraphBuilder::BuildStringAdd(
     // Just return the right string.
     Push(right);
   }
-  if_leftempty.Else();
+  if_leftisempty.Else();
   {
     // Check if right string is empty.
-    IfBuilder if_rightempty(this);
-    if_rightempty.If<HCompareNumericAndBranch>(
+    IfBuilder if_rightisempty(this);
+    if_rightisempty.If<HCompareNumericAndBranch>(
         right_length, graph()->GetConstant0(), Token::EQ);
-    if_rightempty.Then();
+    if_rightisempty.Then();
     {
       // Count the native string addition.
       AddIncrementCounter(isolate()->counters()->string_add_native());
@@ -2056,14 +2016,14 @@ HValue* HGraphBuilder::BuildStringAdd(
       // Just return the left string.
       Push(left);
     }
-    if_rightempty.Else();
+    if_rightisempty.Else();
     {
-      // Add the two non-empty strings.
-      Push(BuildUncheckedStringAdd(left, right, allocation_mode));
+      // Concatenate the two non-empty strings.
+      Push(BuildUncheckedStringAdd(left, right, pretenure_flag));
     }
-    if_rightempty.End();
+    if_rightisempty.End();
   }
-  if_leftempty.End();
+  if_leftisempty.End();
 
   return Pop();
 }
@@ -6140,27 +6100,15 @@ HInstruction* HGraphBuilder::AddLoadNamedField(HValue* object,
 }
 
 
-HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) {
-  if (string->IsConstant()) {
-    HConstant* c_string = HConstant::cast(string);
-    if (c_string->HasStringValue()) {
-      return Add<HConstant>(c_string->StringValue()->map()->instance_type());
+HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object,
+                                                   HValue* checked_string) {
+  if (FLAG_fold_constants && object->IsConstant()) {
+    HConstant* constant = HConstant::cast(object);
+    if (constant->HasStringValue()) {
+      return New<HConstant>(constant->StringValue()->length());
     }
   }
-  return AddLoadNamedField(
-      AddLoadNamedField(string, HObjectAccess::ForMap()),
-      HObjectAccess::ForMapInstanceType());
-}
-
-
-HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) {
-  if (string->IsConstant()) {
-    HConstant* c_string = HConstant::cast(string);
-    if (c_string->HasStringValue()) {
-      return Add<HConstant>(c_string->StringValue()->length());
-    }
-  }
-  return AddLoadNamedField(string, HObjectAccess::ForStringLength());
+  return BuildLoadNamedField(checked_string, HObjectAccess::ForStringLength());
 }
 
 
@@ -8608,9 +8556,13 @@ HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
       return New<HConstant>(s->Get(i));
     }
   }
-  string = BuildCheckString(string);
-  index = Add<HBoundsCheck>(index, AddLoadStringLength(string));
-  return New<HStringCharCodeAt>(string, index);
+  BuildCheckHeapObject(string);
+  HValue* checkstring =
+      Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING);
+  HInstruction* length = BuildLoadStringLength(string, checkstring);
+  AddInstruction(length);
+  HInstruction* checked_index = Add<HBoundsCheck>(index, length);
+  return New<HStringCharCodeAt>(string, checked_index);
 }
 
 
@@ -8741,18 +8693,10 @@ HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
   Handle<Type> right_type = expr->right()->bounds().lower;
   Handle<Type> result_type = expr->bounds().lower;
   Maybe<int> fixed_right_arg = expr->fixed_right_arg();
-  Handle<AllocationSite> allocation_site = expr->allocation_site();
-
-  HAllocationMode allocation_mode =
-      FLAG_allocation_site_pretenuring
-      ? (allocation_site.is_null()
-         ? HAllocationMode(NOT_TENURED)
-         : HAllocationMode(allocation_site))
-      : HAllocationMode(isolate()->heap()->GetPretenureMode());
 
   HValue* result = HGraphBuilder::BuildBinaryOperation(
-      expr->op(), left, right, left_type, right_type, result_type,
-      fixed_right_arg, allocation_mode);
+      expr->op(), left, right, left_type, right_type,
+      result_type, fixed_right_arg);
   // Add a simulate after instructions with observable side effects, and
   // after phis, which are the result of BuildBinaryOperation when we
   // inlined some complex subgraph.
@@ -8772,8 +8716,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
     Handle<Type> left_type,
     Handle<Type> right_type,
     Handle<Type> result_type,
-    Maybe<int> fixed_right_arg,
-    HAllocationMode allocation_mode) {
+    Maybe<int> fixed_right_arg) {
 
   Representation left_rep = Representation::FromType(left_type);
   Representation right_rep = Representation::FromType(right_type);
@@ -8839,48 +8782,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
       return AddUncasted<HInvokeFunction>(function, 2);
     }
 
-    // Inline the string addition into the stub when creating allocation
-    // mementos to gather allocation site feedback.
-    if (graph()->info()->IsStub() &&
-        allocation_mode.CreateAllocationMementos()) {
-      return BuildStringAdd(left, right, allocation_mode);
-    }
-
-    // Register the dependent code with the allocation site.
-    if (!allocation_mode.feedback_site().is_null()) {
-      ASSERT(!graph()->info()->IsStub());
-      allocation_mode.feedback_site()->AddDependentCompilationInfo(
-          AllocationSite::TENURING, top_info());
-    }
-
-    // Inline string addition if we know that we'll create a cons string.
-    if (left->IsConstant()) {
-      HConstant* c_left = HConstant::cast(left);
-      if (c_left->HasStringValue()) {
-        int c_left_length = c_left->StringValue()->length();
-        if (c_left_length == 0) {
-          return right;
-        } else if (c_left_length + 1 >= ConsString::kMinLength) {
-          return BuildStringAdd(left, right, allocation_mode);
-        }
-      }
-    }
-    if (right->IsConstant()) {
-      HConstant* c_right = HConstant::cast(right);
-      if (c_right->HasStringValue()) {
-        int c_right_length = c_right->StringValue()->length();
-        if (c_right_length == 0) {
-          return left;
-        } else if (c_right_length + 1 >= ConsString::kMinLength) {
-          return BuildStringAdd(left, right, allocation_mode);
-        }
-      }
-    }
-
-    // Fallback to using the string add stub.
-    return AddUncasted<HStringAdd>(
-        left, right, allocation_mode.GetPretenureMode(),
-        STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
+    return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE);
   }
 
   if (graph()->info()->IsStub()) {
@@ -10109,7 +10011,8 @@ void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
   CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
   HValue* right = Pop();
   HValue* left = Pop();
-  HInstruction* result = NewUncasted<HStringAdd>(left, right);
+  HInstruction* result =
+      NewUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_BOTH);
   return ast_context()->ReturnInstruction(result, call->id());
 }
 
index ca3fb4349b67a180218a856faa1cc81cb5a411ee..ea4da9abf1c75870cdd7c5060b869b9b882b19b9 100644 (file)
@@ -995,35 +995,6 @@ class HIfContinuation V8_FINAL {
 };
 
 
-class HAllocationMode V8_FINAL BASE_EMBEDDED {
- public:
-  explicit HAllocationMode(Handle<AllocationSite> feedback_site)
-      : current_site_(NULL), feedback_site_(feedback_site),
-        pretenure_flag_(NOT_TENURED) {}
-  explicit HAllocationMode(HValue* current_site)
-      : current_site_(current_site), pretenure_flag_(NOT_TENURED) {}
-  explicit HAllocationMode(PretenureFlag pretenure_flag)
-      : current_site_(NULL), pretenure_flag_(pretenure_flag) {}
-
-  HValue* current_site() const { return current_site_; }
-  Handle<AllocationSite> feedback_site() const { return feedback_site_; }
-
-  bool CreateAllocationMementos() const V8_WARN_UNUSED_RESULT {
-    return current_site() != NULL;
-  }
-
-  PretenureFlag GetPretenureMode() const V8_WARN_UNUSED_RESULT {
-    if (!feedback_site().is_null()) return feedback_site()->GetPretenureMode();
-    return pretenure_flag_;
-  }
-
- private:
-  HValue* current_site_;
-  Handle<AllocationSite> feedback_site_;
-  PretenureFlag pretenure_flag_;
-};
-
-
 class HGraphBuilder {
  public:
   explicit HGraphBuilder(CompilationInfo* info)
@@ -1320,18 +1291,9 @@ class HGraphBuilder {
   HValue* BuildUncheckedDictionaryElementLoad(HValue* receiver,
                                               HValue* key);
 
-  // Allocates a new object according with the given allocation properties.
-  HAllocate* BuildAllocate(HValue* object_size,
-                           HType type,
-                           InstanceType instance_type,
-                           HAllocationMode allocation_mode);
-  // Computes the sum of two string lengths, taking care of overflow handling.
-  HValue* BuildAddStringLengths(HValue* left_length, HValue* right_length);
-  // Creates a cons string using the two input strings.
-  HValue* BuildCreateConsString(HValue* length,
-                                HValue* left,
-                                HValue* right,
-                                HAllocationMode allocation_mode);
+  // Computes the size for a sequential string of the given length and encoding.
+  HValue* BuildSeqStringSizeFor(HValue* length,
+                                String::Encoding encoding);
   // Copies characters from one sequential string to another.
   void BuildCopySeqStringChars(HValue* src,
                                HValue* src_offset,
@@ -1343,11 +1305,11 @@ class HGraphBuilder {
   // Both operands are non-empty strings.
   HValue* BuildUncheckedStringAdd(HValue* left,
                                   HValue* right,
-                                  HAllocationMode allocation_mode);
-  // Add two strings using allocation mode, validating type feedback.
+                                  PretenureFlag pretenure_flag);
+  // Both operands are strings.
   HValue* BuildStringAdd(HValue* left,
                          HValue* right,
-                         HAllocationMode allocation_mode);
+                         PretenureFlag pretenure_flag);
 
   HInstruction* BuildUncheckedMonomorphicElementAccess(
       HValue* checked_object,
@@ -1370,14 +1332,7 @@ class HGraphBuilder {
 
   HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess access);
   HInstruction* AddLoadNamedField(HValue* object, HObjectAccess access);
-  HInstruction* AddLoadStringInstanceType(HValue* string);
-  HInstruction* AddLoadStringLength(HValue* string);
-  HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) {
-    HStoreNamedField* store_map = Add<HStoreNamedField>(
-        object, HObjectAccess::ForMap(), map);
-    store_map->SkipWriteBarrier();
-    return store_map;
-  }
+  HInstruction* BuildLoadStringLength(HValue* object, HValue* checked_value);
   HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map> map);
   HStoreNamedField* AddStoreMapConstantNoWriteBarrier(HValue* object,
                                                       Handle<Map> map) {
@@ -1398,8 +1353,7 @@ class HGraphBuilder {
                                Handle<Type> left_type,
                                Handle<Type> right_type,
                                Handle<Type> result_type,
-                               Maybe<int> fixed_right_arg,
-                               HAllocationMode allocation_mode);
+                               Maybe<int> fixed_right_arg);
 
   HLoadNamedField* AddLoadFixedArrayLength(HValue *object);
 
index 305a6d854c34a3e370610ac4f719f139bc271e87..208bd91a0db7cc6a74fc879e681a8bece0e930e6 100644 (file)
@@ -342,17 +342,6 @@ void BinaryOpICStub::InitializeInterfaceDescriptor(
 }
 
 
-void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
-    Isolate* isolate,
-    CodeStubInterfaceDescriptor* descriptor) {
-  static Register registers[] = { ecx, edx, eax };
-  descriptor->register_param_count_ = 3;
-  descriptor->register_params_ = registers;
-  descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
-}
-
-
 void NewStringAddStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -2663,10 +2652,8 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
   if (Serializer::enabled()) {
     PlatformFeatureScope sse2(SSE2);
     BinaryOpICStub::GenerateAheadOfTime(isolate);
-    BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
   } else {
     BinaryOpICStub::GenerateAheadOfTime(isolate);
-    BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
   }
 }
 
@@ -4398,35 +4385,6 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
 }
 
 
-void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- edx    : left
-  //  -- eax    : right
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Isolate* isolate = masm->isolate();
-
-  // Load ecx with the allocation site.  We stick an undefined dummy value here
-  // and replace it with the real allocation site later when we instantiate this
-  // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
-  __ mov(ecx, handle(isolate->heap()->undefined_value()));
-
-  // Make sure that we actually patched the allocation site.
-  if (FLAG_debug_code) {
-    __ test(ecx, Immediate(kSmiTagMask));
-    __ Assert(not_equal, kExpectedAllocationSite);
-    __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
-           isolate->factory()->allocation_site_map());
-    __ Assert(equal, kExpectedAllocationSite);
-  }
-
-  // Tail call into the stub that handles binary operations with allocation
-  // sites.
-  BinaryOpWithAllocationSiteStub stub(state_);
-  __ TailCallStub(&stub);
-}
-
-
 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
   ASSERT(state_ == CompareIC::SMI);
   Label miss;
index 1a20fc3b6815c1d2c69a0dfdfb2a209e1f2098e4..86118ebf6bdbeeb185b7aec0a762389dcc9da356 100644 (file)
@@ -4912,7 +4912,7 @@ void LCodeGen::DoStringAdd(LStringAdd* instr) {
     ASSERT(ToRegister(instr->left()).is(edx));
     ASSERT(ToRegister(instr->right()).is(eax));
     NewStringAddStub stub(instr->hydrogen()->flags(),
-                          instr->hydrogen()->pretenure_flag());
+                          isolate()->heap()->GetPretenureMode());
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
   } else {
     EmitPushTaggedOperand(instr->left());
index b548aa64c4785b885c6d72a74962d58837707ace..af9b19eac4e55eb37194fa4e0863ab182c1dbec5 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -2398,11 +2398,6 @@ void BinaryOpIC::State::GenerateAheadOfTime(
   GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
   GENERATE(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT);
   GENERATE(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, STRING, SMI, STRING, NO_OVERWRITE);
-  GENERATE(Token::ADD, SMI, STRING, STRING, NO_OVERWRITE);
-  GENERATE(Token::ADD, STRING, NUMBER, STRING, NO_OVERWRITE);
-  GENERATE(Token::ADD, NUMBER, STRING, STRING, NO_OVERWRITE);
-  GENERATE(Token::ADD, STRING, STRING, STRING, NO_OVERWRITE);
   GENERATE(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE);
   GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT);
   GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT);
@@ -2602,7 +2597,6 @@ void BinaryOpIC::State::Print(StringStream* stream) const {
   stream->Add("(%s", Token::Name(op_));
   if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft");
   else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight");
-  if (CouldCreateAllocationMementos()) stream->Add("_CreateAllocationMementos");
   stream->Add(":%s*", KindToString(left_kind_));
   if (fixed_right_arg_.has_value) {
     stream->Add("%d", fixed_right_arg_.value);
@@ -2642,18 +2636,6 @@ void BinaryOpIC::State::Update(Handle<Object> left,
     }
   }
 
-  // We don't want to distinguish INT32 and NUMBER for string add (because
-  // NumberToString can't make use of this anyway).
-  if (left_kind_ == STRING && right_kind_ == INT32) {
-    ASSERT_EQ(STRING, result_kind_);
-    ASSERT_EQ(Token::ADD, op_);
-    right_kind_ = NUMBER;
-  } else if (right_kind_ == STRING && left_kind_ == INT32) {
-    ASSERT_EQ(STRING, result_kind_);
-    ASSERT_EQ(Token::ADD, op_);
-    left_kind_ = NUMBER;
-  }
-
   // Reset overwrite mode unless we can actually make use of it, or may be able
   // to make use of it at some point in the future.
   if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) ||
@@ -2739,9 +2721,7 @@ Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) {
 }
 
 
-MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
-                                    Handle<Object> left,
-                                    Handle<Object> right) {
+MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) {
   State state(target()->extended_extra_ic_state());
 
   // Compute the actual result using the builtin for the binary operation.
@@ -2757,29 +2737,9 @@ MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
   State old_state = state;
   state.Update(left, right, result);
 
-  // Check if we have a string operation here.
-  Handle<Code> target;
-  if (!allocation_site.is_null() || state.ShouldCreateAllocationMementos()) {
-    // Setup the allocation site on-demand.
-    if (allocation_site.is_null()) {
-      allocation_site = isolate()->factory()->NewAllocationSite();
-    }
-
-    // Install the stub with an allocation site.
-    BinaryOpICWithAllocationSiteStub stub(state);
-    target = stub.GetCodeCopyFromTemplate(isolate(), allocation_site);
-
-    // Sanity check the trampoline stub.
-    ASSERT_EQ(*allocation_site, target->FindFirstAllocationSite());
-  } else {
-    // Install the generic stub.
-    BinaryOpICStub stub(state);
-    target = stub.GetCode(isolate());
-
-    // Sanity check the generic stub.
-    ASSERT_EQ(NULL, target->FindFirstAllocationSite());
-  }
-  set_target(*target);
+  // Install the new stub.
+  BinaryOpICStub stub(state);
+  set_target(*stub.GetCode(isolate()));
 
   if (FLAG_trace_ic) {
     char buffer[150];
@@ -2790,12 +2750,9 @@ MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
     old_state.Print(&stream);
     stream.Add(" => ");
     state.Print(&stream);
-    stream.Add(" @ %p <- ", static_cast<void*>(*target));
+    stream.Add(" @ %p <- ", static_cast<void*>(*target()));
     stream.OutputToStdOut();
     JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
-    if (!allocation_site.is_null()) {
-      PrintF(" using allocation site %p", static_cast<void*>(*allocation_site));
-    }
     PrintF("]\n");
   }
 
@@ -2812,25 +2769,10 @@ MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
 
 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) {
   HandleScope scope(isolate);
-  ASSERT_EQ(2, args.length());
   Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft);
   Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight);
   BinaryOpIC ic(isolate);
-  return ic.Transition(Handle<AllocationSite>::null(), left, right);
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite) {
-  HandleScope scope(isolate);
-  ASSERT_EQ(3, args.length());
-  Handle<AllocationSite> allocation_site = args.at<AllocationSite>(
-      BinaryOpWithAllocationSiteStub::kAllocationSite);
-  Handle<Object> left = args.at<Object>(
-      BinaryOpWithAllocationSiteStub::kLeft);
-  Handle<Object> right = args.at<Object>(
-      BinaryOpWithAllocationSiteStub::kRight);
-  BinaryOpIC ic(isolate);
-  return ic.Transition(allocation_site, left, right);
+  return ic.Transition(left, right);
 }
 
 
index 308ab9530898caf8e00ea7f74216d5113c9e1703..d1d2b6139d06c09e526a130bf8e2d7dc8e3467a0 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -861,27 +861,10 @@ class BinaryOpIC: public IC {
             right_kind_ > SMI && right_kind_ <= NUMBER));
     }
 
-    // Returns true if the IC _could_ create allocation mementos.
-    bool CouldCreateAllocationMementos() const {
-      if (left_kind_ == STRING || right_kind_ == STRING) {
-        ASSERT_EQ(Token::ADD, op_);
-        return true;
-      }
-      return false;
-    }
-
-    // Returns true if the IC _should_ create allocation mementos.
-    bool ShouldCreateAllocationMementos() const {
-      return FLAG_allocation_site_pretenuring &&
-          CouldCreateAllocationMementos();
-    }
-
     bool HasSideEffects() const {
       return Max(left_kind_, right_kind_) == GENERIC;
     }
 
-    // Returns true if the IC should enable the inline smi code (i.e. if either
-    // parameter may be a smi).
     bool UseInlinedSmiCode() const {
       return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
     }
@@ -943,9 +926,8 @@ class BinaryOpIC: public IC {
 
   static Builtins::JavaScript TokenToJSBuiltin(Token::Value op);
 
-  MaybeObject* Transition(Handle<AllocationSite> allocation_site,
-                          Handle<Object> left,
-                          Handle<Object> right) V8_WARN_UNUSED_RESULT;
+  MUST_USE_RESULT MaybeObject* Transition(Handle<Object> left,
+                                          Handle<Object> right);
 };
 
 
@@ -1054,7 +1036,6 @@ DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure);
 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure);
 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss);
 DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite);
 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss);
 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss);
 
index dbf21d2c833ccf820cf17b103091962005bfc151..5975d80fad0c01dc6cfa29e6334f314604ca5906 100644 (file)
@@ -1349,9 +1349,7 @@ AllocationSiteMode AllocationSite::GetMode(ElementsKind from,
 
 inline bool AllocationSite::CanTrack(InstanceType type) {
   if (FLAG_allocation_site_pretenuring) {
-    return type == JS_ARRAY_TYPE ||
-        type == JS_OBJECT_TYPE ||
-        type < FIRST_NONSTRING_TYPE;
+    return type == JS_ARRAY_TYPE || type == JS_OBJECT_TYPE;
   }
   return type == JS_ARRAY_TYPE;
 }
index cf21e802ebc14b32afd64beb0a891939bc213ea5..b295bae9fc97b527f57bcb57b4e0d6f237a7570c 100644 (file)
@@ -10477,12 +10477,6 @@ Object* Code::FindNthObject(int n, Map* match_map) {
 }
 
 
-AllocationSite* Code::FindFirstAllocationSite() {
-  Object* result = FindNthObject(1, GetHeap()->allocation_site_map());
-  return (result != NULL) ? AllocationSite::cast(result) : NULL;
-}
-
-
 Map* Code::FindFirstMap() {
   Object* result = FindNthObject(1, GetHeap()->meta_map());
   return (result != NULL) ? Map::cast(result) : NULL;
index 91a2aea2b8868b221bf13dcd31e9953d148f313d..17b92d0cc87e5d6258b551fb7bb534f8de76228c 100644 (file)
@@ -1104,10 +1104,9 @@ class MaybeObject BASE_EMBEDDED {
     "DoPushArgument not implemented for double type")                         \
   V(kEmitLoadRegisterUnsupportedDoubleImmediate,                              \
     "EmitLoadRegister: Unsupported double immediate")                         \
-  V(kEval, "eval")                                                            \
+  V(kEval, "Eval")                                                            \
   V(kExpected0AsASmiSentinel, "Expected 0 as a Smi sentinel")                 \
-  V(kExpectedAlignmentMarker, "expected alignment marker")                    \
-  V(kExpectedAllocationSite, "expected allocation site")                      \
+  V(kExpectedAlignmentMarker, "Expected alignment marker")                    \
   V(kExpectedAllocationSiteInCell,                                            \
     "Expected AllocationSite in property cell")                               \
   V(kExpectedPropertyCellInRegisterA2,                                        \
@@ -5248,9 +5247,6 @@ class Code: public HeapObject {
   Object* FindNthObject(int n, Map* match_map);
   void ReplaceNthObject(int n, Map* match_map, Object* replace_with);
 
-  // Find the first allocation site in an IC stub.
-  AllocationSite* FindFirstAllocationSite();
-
   // Find the first map in an IC stub.
   Map* FindFirstMap();
   void FindAllMaps(MapHandleList* maps);
index 7f1d3b5ea304a21c0b892b3056a9e4be623d8659..3cdcf8e436a69765c942db553a257b85dd61e22e 100644 (file)
@@ -283,7 +283,6 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
                                     Handle<Type>* right,
                                     Handle<Type>* result,
                                     Maybe<int>* fixed_right_arg,
-                                    Handle<AllocationSite>* allocation_site,
                                     Token::Value op) {
   Handle<Object> object = GetInfo(id);
   if (!object->IsCode()) {
@@ -293,7 +292,6 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
            op > BinaryOpIC::State::LAST_TOKEN);
     *left = *right = *result = handle(Type::None(), isolate_);
     *fixed_right_arg = Maybe<int>();
-    *allocation_site = Handle<AllocationSite>::null();
     return;
   }
   Handle<Code> code = Handle<Code>::cast(object);
@@ -305,13 +303,6 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
   *right = state.GetRightType(isolate());
   *result = state.GetResultType(isolate());
   *fixed_right_arg = state.fixed_right_arg();
-
-  AllocationSite* first_allocation_site = code->FindFirstAllocationSite();
-  if (first_allocation_site != NULL) {
-    *allocation_site = handle(first_allocation_site);
-  } else {
-    *allocation_site = Handle<AllocationSite>::null();
-  }
 }
 
 
index 6e6c67d160ddf5ea3b21c5d39dbf2cf4b7c51dac..635be1a8076231f1a4fdb29fed0e2b4390aecbc2 100644 (file)
@@ -112,7 +112,6 @@ class TypeFeedbackOracle: public ZoneObject {
                   Handle<Type>* right,
                   Handle<Type>* result,
                   Maybe<int>* fixed_right_arg,
-                  Handle<AllocationSite>* allocation_site,
                   Token::Value operation);
 
   void CompareType(TypeFeedbackId id,
index c692f485e63fa5b313f419872eee9272a07ad86f..de9f4041e7755cb915af24739d912cc94583aa7c 100644 (file)
@@ -629,14 +629,11 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
   // Collect type feedback.
   Handle<Type> type, left_type, right_type;
   Maybe<int> fixed_right_arg;
-  Handle<AllocationSite> allocation_site;
   oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
-      &left_type, &right_type, &type, &fixed_right_arg,
-      &allocation_site, expr->op());
+      &left_type, &right_type, &type, &fixed_right_arg, expr->op());
   NarrowLowerType(expr, type);
   NarrowLowerType(expr->left(), left_type);
   NarrowLowerType(expr->right(), right_type);
-  expr->set_allocation_site(allocation_site);
   expr->set_fixed_right_arg(fixed_right_arg);
   if (expr->op() == Token::OR || expr->op() == Token::AND) {
     expr->left()->RecordToBooleanTypeFeedback(oracle());
index 920843dfe3f77560dd7ac3fa5cab6a03f4877e97..5b5212c7e07c9cc2b2e8522897b11c600030a739 100644 (file)
@@ -180,6 +180,18 @@ void TransitionElementsKindStub::InitializeInterfaceDescriptor(
 }
 
 
+void BinaryOpICStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  static Register registers[] = { rdx, rax };
+  descriptor->register_param_count_ = 2;
+  descriptor->register_params_ = registers;
+  descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
+  descriptor->SetMissHandler(
+      ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
+}
+
+
 static void InitializeArrayConstructorDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor,
@@ -327,29 +339,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
 }
 
 
-void BinaryOpICStub::InitializeInterfaceDescriptor(
-    Isolate* isolate,
-    CodeStubInterfaceDescriptor* descriptor) {
-  static Register registers[] = { rdx, rax };
-  descriptor->register_param_count_ = 2;
-  descriptor->register_params_ = registers;
-  descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
-  descriptor->SetMissHandler(
-      ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
-}
-
-
-void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
-    Isolate* isolate,
-    CodeStubInterfaceDescriptor* descriptor) {
-  static Register registers[] = { rcx, rdx, rax };
-  descriptor->register_param_count_ = 3;
-  descriptor->register_params_ = registers;
-  descriptor->deoptimization_handler_ =
-      FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
-}
-
-
 void NewStringAddStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -2494,7 +2483,6 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
   ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
   CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
   BinaryOpICStub::GenerateAheadOfTime(isolate);
-  BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
 }
 
 
@@ -4241,35 +4229,6 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
 }
 
 
-void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rdx    : left
-  //  -- rax    : right
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Isolate* isolate = masm->isolate();
-
-  // Load rcx with the allocation site.  We stick an undefined dummy value here
-  // and replace it with the real allocation site later when we instantiate this
-  // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
-  __ Move(rcx, handle(isolate->heap()->undefined_value()));
-
-  // Make sure that we actually patched the allocation site.
-  if (FLAG_debug_code) {
-    __ testb(rcx, Immediate(kSmiTagMask));
-    __ Assert(zero, kExpectedAllocationSite);
-    __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset),
-           isolate->factory()->allocation_site_map());
-    __ Assert(equal, kExpectedAllocationSite);
-  }
-
-  // Tail call into the stub that handles binary operations with allocation
-  // sites.
-  BinaryOpWithAllocationSiteStub stub(state_);
-  __ TailCallStub(&stub);
-}
-
-
 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
   ASSERT(state_ == CompareIC::SMI);
   Label miss;