Add more missing deopts
authorjarin@chromium.org <jarin@chromium.org>
Sun, 26 Oct 2014 10:24:49 +0000 (10:24 +0000)
committerjarin@chromium.org <jarin@chromium.org>
Sun, 26 Oct 2014 10:25:48 +0000 (10:25 +0000)
BUG=
R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#24886}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24886 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

19 files changed:
src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/ast.h
src/compiler.cc
src/compiler/ast-graph-builder.cc
src/compiler/common-operator.h
src/compiler/instruction-selector-impl.h
src/compiler/instruction-selector.cc
src/compiler/instruction-selector.h
src/compiler/linkage.cc
src/compiler/operator-properties-inl.h
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/mips64/full-codegen-mips64.cc
src/x64/full-codegen-x64.cc
src/x87/full-codegen-x87.cc
test/mjsunit/harmony/proxies.js
test/mjsunit/regress/regress-417709a.js
test/unittests/compiler/js-operator-unittest.cc

index da9e9f0f651f8b0a0be3fda57ee224d2a8f4f9e5..47d705fa8872ddf7cde8935e6e8f7e3d69f8af49 100644 (file)
@@ -1131,6 +1131,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ push(r0);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(r0);
 
   // Check for proxies.
@@ -1155,6 +1156,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ bind(&call_runtime);
   __ push(r0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1698,6 +1700,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in r0.
index 13682666148e85c2ebfd68dc0239ca6be1f61439..0a8e1ca3b2fe63fa088cd8cb2177e4dca9cc2fd3 100644 (file)
@@ -1124,6 +1124,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ Push(x0);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ Bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ Push(x0);
 
   // Check for proxies.
@@ -1147,6 +1148,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ Bind(&call_runtime);
   __ Push(x0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1678,6 +1680,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in x0.
index f997c44a82d418c76a9bf79b23d050727b860e81..ae7ec1a659bf7bb70ae4faeeadc6763c8bef88a0 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -957,9 +957,11 @@ class ForInStatement FINAL : public ForEachStatement {
   ForInType for_in_type() const { return for_in_type_; }
   void set_for_in_type(ForInType type) { for_in_type_ = type; }
 
-  static int num_ids() { return parent_num_ids() + 2; }
+  static int num_ids() { return parent_num_ids() + 4; }
   BailoutId BodyId() const { return BailoutId(local_id(0)); }
   BailoutId PrepareId() const { return BailoutId(local_id(1)); }
+  BailoutId EnumId() const { return BailoutId(local_id(2)); }
+  BailoutId ToObjectId() const { return BailoutId(local_id(3)); }
   virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
   virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
 
@@ -1568,11 +1570,15 @@ class ObjectLiteral FINAL : public MaterializedLiteral {
   };
 
   struct Accessors: public ZoneObject {
-    Accessors() : getter(NULL), setter(NULL) { }
+    Accessors() : getter(NULL), setter(NULL) {}
     Expression* getter;
     Expression* setter;
   };
 
+  BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
+
+  static int num_ids() { return parent_num_ids() + 1; }
+
  protected:
   ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
                 int boilerplate_properties, bool has_function, int pos)
@@ -1582,8 +1588,10 @@ class ObjectLiteral FINAL : public MaterializedLiteral {
         fast_elements_(false),
         may_store_doubles_(false),
         has_function_(has_function) {}
+  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   Handle<FixedArray> constant_properties_;
   ZoneList<Property*>* properties_;
   int boilerplate_properties_;
index 3cfc19336e306f3ef8c789038246313a88863a0b..92331c6a02d8296ab78b7982651e7a35ae93cd12 100644 (file)
@@ -414,9 +414,6 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
     compiler::Pipeline pipeline(info());
     pipeline.GenerateCode();
     if (!info()->code().is_null()) {
-      if (FLAG_turbo_deoptimization) {
-        info()->context()->native_context()->AddOptimizedCode(*info()->code());
-      }
       return SetLastStatus(SUCCEEDED);
     }
   }
@@ -485,6 +482,9 @@ OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() {
   DCHECK(last_status() == SUCCEEDED);
   // TODO(turbofan): Currently everything is done in the first phase.
   if (!info()->code().is_null()) {
+    if (FLAG_turbo_deoptimization) {
+      info()->context()->native_context()->AddOptimizedCode(*info()->code());
+    }
     RecordOptimizationStats();
     return last_status();
   }
index 50a3720c58e9c333e8ce6bb373b28568711b9988..b97260111ea45ffb0ea1683b4347183bb90be733 100644 (file)
@@ -642,11 +642,14 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
     // Convert object to jsobject.
     // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
     obj = NewNode(javascript()->ToObject(), obj);
+    PrepareFrameState(obj, stmt->ToObjectId(), OutputFrameStateCombine::Push());
     environment()->Push(obj);
     // TODO(dcarney): should do a fast enum cache check here to skip runtime.
     environment()->Push(obj);
     Node* cache_type = ProcessArguments(
         javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), 1);
+    PrepareFrameState(cache_type, stmt->EnumId(),
+                      OutputFrameStateCombine::Push());
     // TODO(dcarney): these next runtime calls should be removed in favour of
     //                a few simplified instructions.
     environment()->Push(obj);
@@ -882,6 +885,8 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
   const Operator* op =
       javascript()->CallRuntime(Runtime::kCreateObjectLiteral, 4);
   Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
+  PrepareFrameState(literal, expr->CreateLiteralId(),
+                    OutputFrameStateCombine::Push());
 
   // The object is expected on the operand stack during computation of the
   // property values and is the value of the entire expression.
@@ -943,7 +948,10 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
         if (property->emit_store()) {
           const Operator* op =
               javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
-          NewNode(op, receiver, value);
+          Node* set_prototype = NewNode(op, receiver, value);
+          // SetPrototype should not lazy deopt on an object
+          // literal.
+          PrepareFrameState(set_prototype, BailoutId::None());
         }
         break;
       }
@@ -970,7 +978,8 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
     const Operator* op =
         javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
     Node* call = NewNode(op, literal, name, getter, setter, attr);
-    PrepareFrameState(call, it->first->id());
+    // This should not lazy deopt on a new literal.
+    PrepareFrameState(call, BailoutId::None());
   }
 
   // Transform literals that contain functions to fast properties.
@@ -1237,7 +1246,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
       receiver_value = NewNode(common()->Projection(1), pair);
 
       PrepareFrameState(pair, expr->EvalOrLookupId(),
-                        OutputFrameStateCombine::Push());
+                        OutputFrameStateCombine::Push(2));
       break;
     }
     case Call::PROPERTY_CALL: {
index c59ca49f5c9d67368b38b7df16bc9d0b70564d53..9b077c314f7703439974703648f982176cac25f5 100644 (file)
@@ -67,6 +67,10 @@ class OutputFrameStateCombine {
     return kind_ == kPushOutput && parameter_ == 0;
   }
 
+  size_t ConsumedOutputCount() const {
+    return kind_ == kPushOutput ? GetPushCount() : 1;
+  }
+
   bool operator==(OutputFrameStateCombine const& other) const {
     return kind_ == other.kind_ && parameter_ == other.parameter_;
   }
index b5459590f7640b1a35686d391d202a8867cc585e..53d508a52b7d5b19a7735eac9fb1e54f3ea1b717 100644 (file)
@@ -128,6 +128,12 @@ class OperandGenerator {
     return ImmediateOperand::Create(index, zone());
   }
 
+  InstructionOperand* TempLocation(LinkageLocation location, MachineType type) {
+    UnallocatedOperand* op = ToUnallocatedOperand(location, type);
+    op->set_virtual_register(sequence()->NextVirtualRegister());
+    return op;
+  }
+
   InstructionOperand* Label(BasicBlock* block) {
     // TODO(bmeurer): We misuse ImmediateOperand here.
     return TempImmediate(block->rpo_number());
index 17c227acc70d4636d409b94487ae48b96a6a33fc..4baa5958cacfdc92b156a92ac2413490ff6b0058 100644 (file)
@@ -219,6 +219,23 @@ void InstructionSelector::MarkAsReference(Node* node) {
 }
 
 
+void InstructionSelector::MarkAsRepresentation(MachineType rep,
+                                               InstructionOperand* op) {
+  UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
+  switch (RepresentationOf(rep)) {
+    case kRepFloat32:
+    case kRepFloat64:
+      sequence()->MarkAsDouble(unalloc->virtual_register());
+      break;
+    case kRepTagged:
+      sequence()->MarkAsReference(unalloc->virtual_register());
+      break;
+    default:
+      break;
+  }
+}
+
+
 void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) {
   DCHECK_NOT_NULL(node);
   switch (RepresentationOf(rep)) {
@@ -274,15 +291,27 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
     }
 
     // Filter out the outputs that aren't live because no projection uses them.
+    size_t outputs_needed_by_framestate =
+        buffer->frame_state_descriptor == NULL
+            ? 0
+            : buffer->frame_state_descriptor->state_combine()
+                  .ConsumedOutputCount();
     for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
-      if (buffer->output_nodes[i] != NULL) {
-        Node* output = buffer->output_nodes[i];
+      bool output_is_live =
+          buffer->output_nodes[i] != NULL || i < outputs_needed_by_framestate;
+      if (output_is_live) {
         MachineType type =
             buffer->descriptor->GetReturnType(static_cast<int>(i));
         LinkageLocation location =
             buffer->descriptor->GetReturnLocation(static_cast<int>(i));
-        MarkAsRepresentation(type, output);
-        buffer->outputs.push_back(g.DefineAsLocation(output, location, type));
+
+        Node* output = buffer->output_nodes[i];
+        InstructionOperand* op =
+            output == NULL ? g.TempLocation(location, type)
+                           : g.DefineAsLocation(output, location, type);
+        MarkAsRepresentation(type, op);
+
+        buffer->outputs.push_back(op);
       }
     }
   }
index e4bd409764b0eeb00c97c88f2d48753109d8ea91..5af2c9d27e7c95a1b1cbb1de91ea945e1ec80733 100644 (file)
@@ -139,6 +139,10 @@ class InstructionSelector FINAL {
   // by {node}.
   void MarkAsRepresentation(MachineType rep, Node* node);
 
+  // Inform the register allocation of the representation of the unallocated
+  // operand {op}.
+  void MarkAsRepresentation(MachineType rep, InstructionOperand* op);
+
   // Initialize the call buffer with the InstructionOperands, nodes, etc,
   // corresponding
   // to the inputs and outputs of the call.
index 5b7bc686bd808291179c28694d9b3adc8b14fd64..3f4d53b41cdee00e2cc962e8492ce51011dff05a 100644 (file)
@@ -125,6 +125,7 @@ bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
     case Runtime::kCompileLazy:
     case Runtime::kCompileOptimized:
     case Runtime::kCompileString:
+    case Runtime::kCreateObjectLiteral:
     case Runtime::kDebugBreak:
     case Runtime::kDataViewSetInt8:
     case Runtime::kDataViewSetUint8:
@@ -143,23 +144,39 @@ bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
     case Runtime::kDataViewGetFloat32:
     case Runtime::kDataViewGetFloat64:
     case Runtime::kDebugEvaluate:
+    case Runtime::kDebugEvaluateGlobal:
     case Runtime::kDebugGetLoadedScripts:
     case Runtime::kDebugGetPropertyDetails:
     case Runtime::kDebugPromiseEvent:
+    case Runtime::kDefineAccessorPropertyUnchecked:
+    case Runtime::kDefineDataPropertyUnchecked:
     case Runtime::kDeleteProperty:
     case Runtime::kDeoptimizeFunction:
     case Runtime::kFunctionBindArguments:
+    case Runtime::kGetDefaultReceiver:
     case Runtime::kGetFrameCount:
+    case Runtime::kGetImplFromInitializedIntlObject:
     case Runtime::kGetOwnProperty:
+    case Runtime::kGetOwnPropertyNames:
+    case Runtime::kGetPropertyNamesFast:
+    case Runtime::kGetPrototype:
+    case Runtime::kInlineArguments:
     case Runtime::kInlineCallFunction:
     case Runtime::kInlineDateField:
     case Runtime::kInlineRegExpExec:
+    case Runtime::kInternalSetPrototype:
+    case Runtime::kInterrupt:
+    case Runtime::kIsPropertyEnumerable:
+    case Runtime::kIsSloppyModeFunction:
     case Runtime::kLiveEditGatherCompileInfo:
     case Runtime::kLoadLookupSlot:
     case Runtime::kLoadLookupSlotNoReferenceError:
     case Runtime::kMaterializeRegExpLiteral:
+    case Runtime::kNewObject:
     case Runtime::kNewObjectFromBound:
+    case Runtime::kNewObjectWithAllocationSite:
     case Runtime::kObjectFreeze:
+    case Runtime::kOwnKeys:
     case Runtime::kParseJson:
     case Runtime::kPrepareStep:
     case Runtime::kPreventExtensions:
@@ -168,22 +185,25 @@ bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
     case Runtime::kRegExpCompile:
     case Runtime::kRegExpExecMultiple:
     case Runtime::kResolvePossiblyDirectEval:
-    // case Runtime::kSetPrototype:
+    case Runtime::kSetPrototype:
     case Runtime::kSetScriptBreakPoint:
+    case Runtime::kSparseJoinWithSeparator:
     case Runtime::kStackGuard:
+    case Runtime::kStoreKeyedToSuper_Sloppy:
+    case Runtime::kStoreKeyedToSuper_Strict:
+    case Runtime::kStoreToSuper_Sloppy:
+    case Runtime::kStoreToSuper_Strict:
     case Runtime::kStoreLookupSlot:
     case Runtime::kStringBuilderConcat:
+    case Runtime::kStringBuilderJoin:
     case Runtime::kStringReplaceGlobalRegExpWithString:
+    case Runtime::kThrowNonMethodError:
+    case Runtime::kThrowNotDateError:
     case Runtime::kThrowReferenceError:
+    case Runtime::kThrowUnsupportedSuperError:
     case Runtime::kThrow:
     case Runtime::kTypedArraySetFastCases:
     case Runtime::kTypedArrayInitializeFromArrayLike:
-    case Runtime::kDebugEvaluateGlobal:
-    case Runtime::kOwnKeys:
-    case Runtime::kGetOwnPropertyNames:
-    case Runtime::kIsPropertyEnumerable:
-    case Runtime::kGetPrototype:
-    case Runtime::kSparseJoinWithSeparator:
       return true;
     default:
       return false;
index 4d851716df43968ab64614515b5b7d8c5cf99539..771f5600916f7f959d004e73600b2615016d886a 100644 (file)
@@ -81,6 +81,9 @@ inline bool OperatorProperties::HasFrameStateInput(const Operator* op) {
     case IrOpcode::kJSStoreProperty:
     case IrOpcode::kJSSubtract:
 
+    // Conversions
+    case IrOpcode::kJSToObject:
+
     // Other
     case IrOpcode::kJSDeleteProperty:
       return true;
index e5618a7ffede2aa7eaeb1639783547a19775e9c5..c033fd5a3e28d06d08b4dff5c9d38d2ad76b521e 100644 (file)
@@ -1062,6 +1062,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ push(eax);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(eax);
 
   // Check for proxies.
@@ -1083,6 +1084,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ bind(&call_runtime);
   __ push(eax);
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
   __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
          isolate()->factory()->meta_map());
   __ j(not_equal, &fixed_array);
@@ -1629,6 +1631,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in eax.
index deafb7c9687a137c42602e6d8a83f51b78b9e8da..6760b3c00ab55a4298f44bd813372fbab2c34879 100644 (file)
@@ -1121,6 +1121,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ mov(a0, v0);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(a0);
 
   // Check for proxies.
@@ -1145,6 +1146,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ bind(&call_runtime);
   __ push(a0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1683,6 +1685,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in v0.
index 959edc0d5490306d1ed0ea501117024a05ef731b..4779b1cb63ab4b09efacf0aa93ba5cee28445346 100644 (file)
@@ -1116,6 +1116,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ mov(a0, v0);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(a0);
 
   // Check for proxies.
@@ -1140,6 +1141,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ bind(&call_runtime);
   __ push(a0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1680,6 +1682,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in v0.
index 4cbdecb84dba3005711b274ced2d29055e73cc41..4229f445b39b0fd283bb0a51264ca739a3d56cc8 100644 (file)
@@ -1086,6 +1086,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ Push(rax);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ Push(rax);
 
   // Check for proxies.
@@ -1110,6 +1111,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ bind(&call_runtime);
   __ Push(rax);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1663,6 +1665,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in rax.
index c2575dfb60a0477d354d684da1e39a88041e7a3f..9240fc8a5d92f6445c5beca15cd0f5f355596ac3 100644 (file)
@@ -1051,6 +1051,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ push(eax);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(eax);
 
   // Check for proxies.
@@ -1072,6 +1073,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   __ bind(&call_runtime);
   __ push(eax);
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
   __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
          isolate()->factory()->meta_map());
   __ j(not_equal, &fixed_array);
@@ -1618,6 +1620,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in eax.
index b082c066969f0f5f0d6c982f8ac9affb64dbaa6a..2b0ec76fea8e0eb0cca0999f1c6159b238b8fbe6 100644 (file)
@@ -29,7 +29,7 @@
 // test enters an infinite recursion which goes through the runtime and we
 // overflow the system stack before the simulator stack.
 
-// Flags: --harmony-proxies --sim-stack-size=500
+// Flags: --harmony-proxies --sim-stack-size=500 --turbo-deoptimization
 
 
 // Helper.
index d210c10429ad2a49d8df3436f054dca82d7583bd..7c4d4f728ec57e9308eccd46d841619e8e9ff881 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --stack-size=100
+// Flags: --stack-size=100 --turbo-deoptimization
 
 var a = [];
 
index 8e601bad87957eb868f29f3b53a17e5717a96706..5de42357280666be41cd9aa83ed809da5029dd50 100644 (file)
@@ -66,12 +66,12 @@ const SharedOperator kSharedOperators[] = {
     SHARED(ToNumber, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
     SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
     SHARED(ToName, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
-    SHARED(ToObject, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
+    SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1),
     SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
     SHARED(Create, Operator::kEliminatable, 0, 0, 1, 0, 1, 1),
-    SHARED(HasProperty, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
+    SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
     SHARED(TypeOf, Operator::kPure, 1, 0, 0, 0, 1, 0),
-    SHARED(InstanceOf, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
+    SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
     SHARED(Debugger, Operator::kNoProperties, 0, 0, 1, 1, 0, 1),
     SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
     SHARED(CreateWithContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),