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.