Reviewers: Dmitry Lomov (chromium),

Message:
Hi Dmitry,
Can you have a look at this? It is a fix for an interesting super constructor
issue. Thanks very much!
--Michael

Description:
Super Constructor Calls need to use a vector slot, not an ic slot.

The Ast Call node is accustomed to using a vector IC slot for the
cases when it uses a CallIC. The super constructor work alters this
somewhat by using a CallConstructStub instead, however the
CallConstructStub expects a vector slot and not a vector ic slot.
This distinction needs to be maintained because slots and ic slots
have different clearing strategies and are handled differently.

[email protected]
BUG=
LOG=N

Please review this at https://codereview.chromium.org/892113002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+45, -20 lines):
  M src/arm/full-codegen-arm.cc
  M src/arm64/full-codegen-arm64.cc
  M src/ast.h
  M src/ast.cc
  M src/hydrogen.cc
  M src/ia32/full-codegen-ia32.cc
  M src/mips/full-codegen-mips.cc
  M src/type-feedback-vector.h
  M src/typing.cc
  M src/x64/full-codegen-x64.cc


Index: src/arm/full-codegen-arm.cc
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 6139806f909405a612bcfb68cc6f267a496c40a4..d0dace6b38283cd182d5a04e1e8bb9ee29d919a0 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -3003,7 +3003,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Record source position of the IC call.
   SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
-  __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
+  __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
   __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
// Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
Index: src/arm64/full-codegen-arm64.cc
diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index 491e9000d39fbd2ce62bddffb3971385f81ab87b..c3c86cc16f16861c738dd0d76e5624636fed047d 100644
--- a/src/arm64/full-codegen-arm64.cc
+++ b/src/arm64/full-codegen-arm64.cc
@@ -2691,7 +2691,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   SetSourcePosition(expr->position());

Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
-  __ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot()));
+  __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot()));
   __ Peek(x1, (arg_count + 1) * kXRegSize);
// Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index 4280a983649608aae812c1b9d260f83ca4581d49..bba49fe6340b71a7f405000acd6c6ab3094353c0 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -578,15 +578,28 @@ void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
 }


-bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const {
+bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const {
   CallType call_type = GetCallType(isolate);
-  return (call_type != POSSIBLY_EVAL_CALL);
+ if (IsUsingCallFeedbackSlot(isolate) || call_type == POSSIBLY_EVAL_CALL) {
+    return false;
+  }
+  return true;
+}
+
+
+bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const {
+  // SuperConstructorCall uses a CallConstructStub, which wants
+  // a Slot, not an IC slot.
+  return FLAG_experimental_classes && GetCallType(isolate) == SUPER_CALL;
 }


FeedbackVectorRequirements Call::ComputeFeedbackRequirements(Isolate* isolate) {
-  int ic_slots = IsUsingCallFeedbackSlot(isolate) ? 1 : 0;
-  return FeedbackVectorRequirements(0, ic_slots);
+  int ic_slots = IsUsingCallFeedbackICSlot(isolate) ? 1 : 0;
+  int slots = IsUsingCallFeedbackSlot(isolate) ? 1 : 0;
+  // A Call uses either a slot or an IC slot.
+  DCHECK((ic_slots & slots) == 0);
+  return FeedbackVectorRequirements(slots, ic_slots);
 }


Index: src/ast.h
diff --git a/src/ast.h b/src/ast.h
index 02f7df64b0d62bbaa9c1eb717ce1db6f8d4939b5..9aa45dbf500282a1a6f9aba5c6c1d29c77fd0b45 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1813,14 +1813,21 @@ class Call FINAL : public Expression {
   virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
       Isolate* isolate) OVERRIDE;
   void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
-    call_feedback_slot_ = slot;
+    ic_slot_or_slot_ = slot.ToInt();
+  }
+  void SetFirstFeedbackSlot(FeedbackVectorSlot slot) OVERRIDE {
+    ic_slot_or_slot_ = slot.ToInt();
   }
Code::Kind FeedbackICSlotKind(int index) OVERRIDE { return Code::CALL_IC; }

- bool HasCallFeedbackSlot() const { return !call_feedback_slot_.IsInvalid(); }
-  FeedbackVectorICSlot CallFeedbackSlot() const {
-    DCHECK(!call_feedback_slot_.IsInvalid());
-    return call_feedback_slot_;
+  FeedbackVectorSlot CallFeedbackSlot() const {
+    DCHECK(ic_slot_or_slot_ != FeedbackVectorSlot::Invalid().ToInt());
+    return FeedbackVectorSlot(ic_slot_or_slot_);
+  }
+
+  FeedbackVectorICSlot CallFeedbackICSlot() const {
+    DCHECK(ic_slot_or_slot_ != FeedbackVectorICSlot::Invalid().ToInt());
+    return FeedbackVectorICSlot(ic_slot_or_slot_);
   }

   SmallMapList* GetReceiverTypes() OVERRIDE {
@@ -1881,6 +1888,7 @@ class Call FINAL : public Expression {
   // Helpers to determine how to handle the call.
   CallType GetCallType(Isolate* isolate) const;
   bool IsUsingCallFeedbackSlot(Isolate* isolate) const;
+  bool IsUsingCallFeedbackICSlot(Isolate* isolate) const;

 #ifdef DEBUG
   // Used to assert that the FullCodeGenerator records the return site.
@@ -1891,7 +1899,7 @@ class Call FINAL : public Expression {
Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
        int pos)
       : Expression(zone, pos),
-        call_feedback_slot_(FeedbackVectorICSlot::Invalid()),
+        ic_slot_or_slot_(FeedbackVectorICSlot::Invalid().ToInt()),
         expression_(expression),
         arguments_(arguments),
         bit_field_(IsUninitializedField::encode(false)) {
@@ -1904,7 +1912,9 @@ class Call FINAL : public Expression {
  private:
   int local_id(int n) const { return base_id() + parent_num_ids() + n; }

-  FeedbackVectorICSlot call_feedback_slot_;
+  // We store this as an integer because we don't know if we have a slot or
+  // an ic slot until scoping time.
+  int ic_slot_or_slot_;
   Expression* expression_;
   ZoneList<Expression*>* arguments_;
   Handle<JSFunction> target_;
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 57be6b4051043c1d21efd8e3fac9ee5a78c51074..fec78c73d7ca32561d9562e2ef9e4b2187c5bacc 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -9345,14 +9345,15 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
       HCallFunction* call_function =
           New<HCallFunction>(function, argument_count);
       call = call_function;
-      if (expr->is_uninitialized() && expr->HasCallFeedbackSlot()) {
+      if (expr->is_uninitialized() &&
+          expr->IsUsingCallFeedbackICSlot(isolate())) {
// We've never seen this call before, so let's have Crankshaft learn
         // through the type vector.
         Handle<SharedFunctionInfo> current_shared =
             function_state()->compilation_info()->shared_info();
         Handle<TypeFeedbackVector> vector =
             handle(current_shared->feedback_vector(), isolate());
-        FeedbackVectorICSlot slot = expr->CallFeedbackSlot();
+        FeedbackVectorICSlot slot = expr->CallFeedbackICSlot();
         call_function->SetVectorAndSlot(vector, slot);
       }
     }
Index: src/ia32/full-codegen-ia32.cc
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 5a161e9763928ab2f49cfc16670dd3b2e244a94e..0dd7cb7b8b3a81d2cf84a3779754d122441d012d 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -2900,7 +2900,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Record source position of the IC call.
   SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
-  __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot())));
+  __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
   __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
// Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
Index: src/mips/full-codegen-mips.cc
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 9fde09d80bec70cca2cbe19b89957db71ab87e52..6488db9ec3fb8ec0a5cbccd151b52568408dae93 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -2978,7 +2978,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Record source position of the IC call.
   SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
-  __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
+  __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
   __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
// Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
Index: src/type-feedback-vector.h
diff --git a/src/type-feedback-vector.h b/src/type-feedback-vector.h
index fee985191f6122890c598aa06424a38ecb325dda..c8f68bd1fbca8a40f5c92cd0743e65dfeb75d161 100644
--- a/src/type-feedback-vector.h
+++ b/src/type-feedback-vector.h
@@ -120,6 +120,7 @@ class TypeFeedbackVector : public FixedArray {
// Conversion from a slot or ic slot to an integer index to the underlying
   // array.
   int GetIndex(FeedbackVectorSlot slot) const {
+    DCHECK(slot.ToInt() < first_ic_slot_index());
     return kReservedIndexCount + ic_metadata_length() + slot.ToInt();
   }

Index: src/typing.cc
diff --git a/src/typing.cc b/src/typing.cc
index ec0196e8c0c2fbc129b32b33c830d398c129a227..0a7ba618390a8df4852be5b1f6da35832f6bb740 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -532,8 +532,8 @@ void AstTyper::VisitCall(Call* expr) {
   // Collect type feedback.
   RECURSE(Visit(expr->expression()));
   bool is_uninitialized = true;
-  if (expr->IsUsingCallFeedbackSlot(isolate())) {
-    FeedbackVectorICSlot slot = expr->CallFeedbackSlot();
+  if (expr->IsUsingCallFeedbackICSlot(isolate())) {
+    FeedbackVectorICSlot slot = expr->CallFeedbackICSlot();
     is_uninitialized = oracle()->CallIsUninitialized(slot);
     if (!expr->expression()->IsProperty() &&
         oracle()->CallIsMonomorphic(slot)) {
Index: src/x64/full-codegen-x64.cc
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 3a93117e385542c259016c087242a171bed3c289..a99c922887d81da1eb698bc1b58416fb17ea3e43 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -2902,7 +2902,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Record source position of the IC call.
   SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
-  __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot()));
+  __ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot()));
   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
// Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.


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

Reply via email to