Use FeedbackVectorSlotKind instead of Code::Kind for type feedback vector.
This is a first step towards merging FeedbackVectorSlot and FeedbackVectorICSlot. Review URL: https://codereview.chromium.org/1369973002 Cr-Commit-Position: refs/heads/master@{#30964}
This commit is contained in:
parent
6a20034d24
commit
6ca00aac1a
11
src/ast.cc
11
src/ast.cc
@ -141,9 +141,10 @@ static int GetStoreICSlots(Expression* expr) {
|
||||
}
|
||||
|
||||
|
||||
static Code::Kind GetStoreICKind(Expression* expr) {
|
||||
static FeedbackVectorSlotKind GetStoreICKind(Expression* expr) {
|
||||
LhsKind assign_type = Property::GetAssignType(expr->AsProperty());
|
||||
return assign_type == KEYED_PROPERTY ? Code::KEYED_STORE_IC : Code::STORE_IC;
|
||||
return assign_type == KEYED_PROPERTY ? FeedbackVectorSlotKind::KEYED_STORE_IC
|
||||
: FeedbackVectorSlotKind::STORE_IC;
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +155,7 @@ FeedbackVectorRequirements ForEachStatement::ComputeFeedbackRequirements(
|
||||
}
|
||||
|
||||
|
||||
Code::Kind ForEachStatement::FeedbackICSlotKind(int index) {
|
||||
FeedbackVectorSlotKind ForEachStatement::FeedbackICSlotKind(int index) {
|
||||
return GetStoreICKind(each());
|
||||
}
|
||||
|
||||
@ -178,7 +179,7 @@ FeedbackVectorRequirements Assignment::ComputeFeedbackRequirements(
|
||||
}
|
||||
|
||||
|
||||
Code::Kind Assignment::FeedbackICSlotKind(int index) {
|
||||
FeedbackVectorSlotKind Assignment::FeedbackICSlotKind(int index) {
|
||||
return GetStoreICKind(target());
|
||||
}
|
||||
|
||||
@ -190,7 +191,7 @@ FeedbackVectorRequirements CountOperation::ComputeFeedbackRequirements(
|
||||
}
|
||||
|
||||
|
||||
Code::Kind CountOperation::FeedbackICSlotKind(int index) {
|
||||
FeedbackVectorSlotKind CountOperation::FeedbackICSlotKind(int index) {
|
||||
return GetStoreICKind(expression());
|
||||
}
|
||||
|
||||
|
40
src/ast.h
40
src/ast.h
@ -197,7 +197,9 @@ class AstProperties final BASE_EMBEDDED {
|
||||
|
||||
int ic_slots() const { return spec_.ic_slots(); }
|
||||
void increase_ic_slots(int count) { spec_.increase_ic_slots(count); }
|
||||
void SetKind(int ic_slot, Code::Kind kind) { spec_.SetKind(ic_slot, kind); }
|
||||
void SetKind(int ic_slot, FeedbackVectorSlotKind kind) {
|
||||
spec_.SetKind(ic_slot, kind);
|
||||
}
|
||||
const ZoneFeedbackVectorSpec* get_spec() const { return &spec_; }
|
||||
|
||||
private:
|
||||
@ -257,9 +259,9 @@ class AstNode: public ZoneObject {
|
||||
UNREACHABLE();
|
||||
}
|
||||
// Each ICSlot stores a kind of IC which the participating node should know.
|
||||
virtual Code::Kind FeedbackICSlotKind(int index) {
|
||||
virtual FeedbackVectorSlotKind FeedbackICSlotKind(int index) {
|
||||
UNREACHABLE();
|
||||
return Code::NUMBER_OF_KINDS;
|
||||
return FeedbackVectorSlotKind::UNUSED;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -812,7 +814,7 @@ class ForEachStatement : public IterationStatement {
|
||||
ICSlotCache* cache) override {
|
||||
each_slot_ = slot;
|
||||
}
|
||||
Code::Kind FeedbackICSlotKind(int index) override;
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override;
|
||||
FeedbackVectorICSlot EachFeedbackSlot() const { return each_slot_; }
|
||||
|
||||
protected:
|
||||
@ -1554,7 +1556,9 @@ class ObjectLiteral final : public MaterializedLiteral {
|
||||
ICSlotCache* cache) override {
|
||||
slot_ = slot;
|
||||
}
|
||||
Code::Kind FeedbackICSlotKind(int index) override { return Code::STORE_IC; }
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
|
||||
return FeedbackVectorSlotKind::STORE_IC;
|
||||
}
|
||||
|
||||
// After feedback slots were assigned, propagate information to the properties
|
||||
// which need it.
|
||||
@ -1732,7 +1736,9 @@ class VariableProxy final : public Expression {
|
||||
|
||||
void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
|
||||
ICSlotCache* cache) override;
|
||||
Code::Kind FeedbackICSlotKind(int index) override { return Code::LOAD_IC; }
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
|
||||
return FeedbackVectorSlotKind::LOAD_IC;
|
||||
}
|
||||
FeedbackVectorICSlot VariableFeedbackSlot() {
|
||||
return variable_feedback_slot_;
|
||||
}
|
||||
@ -1837,8 +1843,9 @@ class Property final : public Expression {
|
||||
ICSlotCache* cache) override {
|
||||
property_feedback_slot_ = slot;
|
||||
}
|
||||
Code::Kind FeedbackICSlotKind(int index) override {
|
||||
return key()->IsPropertyName() ? Code::LOAD_IC : Code::KEYED_LOAD_IC;
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
|
||||
return key()->IsPropertyName() ? FeedbackVectorSlotKind::LOAD_IC
|
||||
: FeedbackVectorSlotKind::KEYED_LOAD_IC;
|
||||
}
|
||||
|
||||
FeedbackVectorICSlot PropertyFeedbackSlot() const {
|
||||
@ -1894,7 +1901,9 @@ class Call final : public Expression {
|
||||
ic_slot_ = slot;
|
||||
}
|
||||
void SetFirstFeedbackSlot(FeedbackVectorSlot slot) override { slot_ = slot; }
|
||||
Code::Kind FeedbackICSlotKind(int index) override { return Code::CALL_IC; }
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
|
||||
return FeedbackVectorSlotKind::CALL_IC;
|
||||
}
|
||||
|
||||
FeedbackVectorSlot CallFeedbackSlot() const { return slot_; }
|
||||
|
||||
@ -2244,7 +2253,7 @@ class CountOperation final : public Expression {
|
||||
ICSlotCache* cache) override {
|
||||
slot_ = slot;
|
||||
}
|
||||
Code::Kind FeedbackICSlotKind(int index) override;
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override;
|
||||
FeedbackVectorICSlot CountSlot() const { return slot_; }
|
||||
|
||||
protected:
|
||||
@ -2422,7 +2431,7 @@ class Assignment final : public Expression {
|
||||
ICSlotCache* cache) override {
|
||||
slot_ = slot;
|
||||
}
|
||||
Code::Kind FeedbackICSlotKind(int index) override;
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override;
|
||||
FeedbackVectorICSlot AssignmentSlot() const { return slot_; }
|
||||
|
||||
protected:
|
||||
@ -2474,8 +2483,9 @@ class Yield final : public Expression {
|
||||
ICSlotCache* cache) override {
|
||||
yield_first_feedback_slot_ = slot;
|
||||
}
|
||||
Code::Kind FeedbackICSlotKind(int index) override {
|
||||
return index == 0 ? Code::KEYED_LOAD_IC : Code::LOAD_IC;
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
|
||||
return index == 0 ? FeedbackVectorSlotKind::KEYED_LOAD_IC
|
||||
: FeedbackVectorSlotKind::LOAD_IC;
|
||||
}
|
||||
|
||||
FeedbackVectorICSlot KeyedLoadFeedbackSlot() {
|
||||
@ -2749,7 +2759,9 @@ class ClassLiteral final : public Expression {
|
||||
ICSlotCache* cache) override {
|
||||
slot_ = slot;
|
||||
}
|
||||
Code::Kind FeedbackICSlotKind(int index) override { return Code::STORE_IC; }
|
||||
FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
|
||||
return FeedbackVectorSlotKind::STORE_IC;
|
||||
}
|
||||
|
||||
bool NeedsProxySlot() const {
|
||||
return FLAG_vector_stores && scope() != NULL &&
|
||||
|
@ -2696,8 +2696,10 @@ void Heap::CreateInitialObjects() {
|
||||
set_microtask_queue(empty_fixed_array());
|
||||
|
||||
{
|
||||
Code::Kind kinds[] = {Code::LOAD_IC, Code::KEYED_LOAD_IC, Code::STORE_IC,
|
||||
Code::KEYED_STORE_IC};
|
||||
FeedbackVectorSlotKind kinds[] = {FeedbackVectorSlotKind::LOAD_IC,
|
||||
FeedbackVectorSlotKind::KEYED_LOAD_IC,
|
||||
FeedbackVectorSlotKind::STORE_IC,
|
||||
FeedbackVectorSlotKind::KEYED_STORE_IC};
|
||||
FeedbackVectorSpec spec(0, 4, kinds);
|
||||
Handle<TypeFeedbackVector> dummy_vector =
|
||||
factory->NewTypeFeedbackVector(&spec);
|
||||
|
@ -7276,7 +7276,8 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
|
||||
return result;
|
||||
} else {
|
||||
if (FLAG_vector_stores &&
|
||||
current_feedback_vector()->GetKind(slot) == Code::KEYED_STORE_IC) {
|
||||
current_feedback_vector()->GetKind(slot) ==
|
||||
FeedbackVectorSlotKind::KEYED_STORE_IC) {
|
||||
// It's possible that a keyed store of a constant string was converted
|
||||
// to a named store. Here, at the last minute, we need to make sure to
|
||||
// use a generic Keyed Store if we are using the type vector, because
|
||||
|
20
src/ic/ic.cc
20
src/ic/ic.cc
@ -2372,13 +2372,14 @@ RUNTIME_FUNCTION(Runtime_LoadIC_Miss) {
|
||||
// A monomorphic or polymorphic KeyedLoadIC with a string key can call the
|
||||
// LoadIC miss handler if the handler misses. Since the vector Nexus is
|
||||
// set up outside the IC, handle that here.
|
||||
if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
|
||||
if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::LOAD_IC) {
|
||||
LoadICNexus nexus(vector, vector_slot);
|
||||
LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
|
||||
ic.UpdateState(receiver, key);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
||||
} else {
|
||||
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC,
|
||||
vector->GetKind(vector_slot));
|
||||
KeyedLoadICNexus nexus(vector, vector_slot);
|
||||
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
|
||||
ic.UpdateState(receiver, key);
|
||||
@ -2442,14 +2443,15 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Miss) {
|
||||
Handle<Smi> slot = args.at<Smi>(3);
|
||||
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
|
||||
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
|
||||
if (vector->GetKind(vector_slot) == Code::STORE_IC) {
|
||||
if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) {
|
||||
StoreICNexus nexus(vector, vector_slot);
|
||||
StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
|
||||
ic.UpdateState(receiver, key);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
|
||||
ic.Store(receiver, key, value));
|
||||
} else {
|
||||
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_STORE_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC,
|
||||
vector->GetKind(vector_slot));
|
||||
KeyedStoreICNexus nexus(vector, vector_slot);
|
||||
KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
|
||||
ic.UpdateState(receiver, key);
|
||||
@ -2480,14 +2482,15 @@ RUNTIME_FUNCTION(Runtime_StoreIC_MissFromStubFailure) {
|
||||
Handle<Smi> slot = args.at<Smi>(3);
|
||||
Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
|
||||
FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
|
||||
if (vector->GetKind(vector_slot) == Code::STORE_IC) {
|
||||
if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) {
|
||||
StoreICNexus nexus(vector, vector_slot);
|
||||
StoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
|
||||
ic.UpdateState(receiver, key);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
|
||||
ic.Store(receiver, key, value));
|
||||
} else {
|
||||
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_STORE_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC,
|
||||
vector->GetKind(vector_slot));
|
||||
KeyedStoreICNexus nexus(vector, vector_slot);
|
||||
KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
|
||||
ic.UpdateState(receiver, key);
|
||||
@ -3110,13 +3113,14 @@ RUNTIME_FUNCTION(Runtime_LoadIC_MissFromStubFailure) {
|
||||
// A monomorphic or polymorphic KeyedLoadIC with a string key can call the
|
||||
// LoadIC miss handler if the handler misses. Since the vector Nexus is
|
||||
// set up outside the IC, handle that here.
|
||||
if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
|
||||
if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::LOAD_IC) {
|
||||
LoadICNexus nexus(vector, vector_slot);
|
||||
LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
|
||||
ic.UpdateState(receiver, key);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
||||
} else {
|
||||
DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC,
|
||||
vector->GetKind(vector_slot));
|
||||
KeyedLoadICNexus nexus(vector, vector_slot);
|
||||
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
|
||||
ic.UpdateState(receiver, key);
|
||||
|
@ -570,26 +570,38 @@ void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) { // NOLINT
|
||||
|
||||
for (int i = 0; i < ICSlots(); i++) {
|
||||
FeedbackVectorICSlot slot(i);
|
||||
Code::Kind kind = GetKind(slot);
|
||||
os << "\n ICSlot " << i;
|
||||
if (kind == Code::LOAD_IC) {
|
||||
LoadICNexus nexus(this, slot);
|
||||
os << " LOAD_IC " << Code::ICState2String(nexus.StateFromFeedback());
|
||||
} else if (kind == Code::KEYED_LOAD_IC) {
|
||||
KeyedLoadICNexus nexus(this, slot);
|
||||
os << " KEYED_LOAD_IC "
|
||||
<< Code::ICState2String(nexus.StateFromFeedback());
|
||||
} else if (kind == Code::CALL_IC) {
|
||||
CallICNexus nexus(this, slot);
|
||||
os << " CALL_IC " << Code::ICState2String(nexus.StateFromFeedback());
|
||||
} else if (kind == Code::STORE_IC) {
|
||||
StoreICNexus nexus(this, slot);
|
||||
os << " STORE_IC " << Code::ICState2String(nexus.StateFromFeedback());
|
||||
} else {
|
||||
DCHECK(kind == Code::KEYED_STORE_IC);
|
||||
KeyedStoreICNexus nexus(this, slot);
|
||||
os << " KEYED_STORE_IC "
|
||||
<< Code::ICState2String(nexus.StateFromFeedback());
|
||||
FeedbackVectorSlotKind kind = GetKind(slot);
|
||||
os << "\n ICSlot " << i << " " << kind << " ";
|
||||
switch (kind) {
|
||||
case FeedbackVectorSlotKind::LOAD_IC: {
|
||||
LoadICNexus nexus(this, slot);
|
||||
os << Code::ICState2String(nexus.StateFromFeedback());
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::KEYED_LOAD_IC: {
|
||||
KeyedLoadICNexus nexus(this, slot);
|
||||
os << Code::ICState2String(nexus.StateFromFeedback());
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::CALL_IC: {
|
||||
CallICNexus nexus(this, slot);
|
||||
os << Code::ICState2String(nexus.StateFromFeedback());
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::STORE_IC: {
|
||||
StoreICNexus nexus(this, slot);
|
||||
os << Code::ICState2String(nexus.StateFromFeedback());
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::KEYED_STORE_IC: {
|
||||
KeyedStoreICNexus nexus(this, slot);
|
||||
os << Code::ICState2String(nexus.StateFromFeedback());
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::UNUSED:
|
||||
case FeedbackVectorSlotKind::KINDS_NUMBER:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
os << "\n [" << GetIndex(slot) << "]: " << Brief(Get(slot));
|
||||
|
@ -434,7 +434,8 @@ static int FormatICSlotNode(Vector<char>* buf, Expression* node,
|
||||
const char* node_name, FeedbackVectorICSlot slot) {
|
||||
int pos = SNPrintF(*buf, "%s", node_name);
|
||||
if (!slot.IsInvalid()) {
|
||||
const char* str = Code::Kind2String(node->FeedbackICSlotKind(0));
|
||||
const char* str =
|
||||
TypeFeedbackVector::Kind2String(node->FeedbackICSlotKind(0));
|
||||
pos = SNPrintF(*buf + pos, " ICSlot(%d, %s)", slot.ToInt(), str);
|
||||
}
|
||||
return pos;
|
||||
|
@ -13,65 +13,24 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// static
|
||||
TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind(
|
||||
Code::Kind kind) {
|
||||
switch (kind) {
|
||||
case Code::CALL_IC:
|
||||
return KindCallIC;
|
||||
case Code::LOAD_IC:
|
||||
return KindLoadIC;
|
||||
case Code::KEYED_LOAD_IC:
|
||||
return KindKeyedLoadIC;
|
||||
case Code::STORE_IC:
|
||||
return KindStoreIC;
|
||||
case Code::KEYED_STORE_IC:
|
||||
return KindKeyedStoreIC;
|
||||
default:
|
||||
// Shouldn't get here.
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return KindUnused;
|
||||
std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) {
|
||||
return os << TypeFeedbackVector::Kind2String(kind);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
Code::Kind TypeFeedbackVector::FromVectorICKind(VectorICKind kind) {
|
||||
switch (kind) {
|
||||
case KindCallIC:
|
||||
return Code::CALL_IC;
|
||||
case KindLoadIC:
|
||||
return Code::LOAD_IC;
|
||||
case KindKeyedLoadIC:
|
||||
return Code::KEYED_LOAD_IC;
|
||||
case KindStoreIC:
|
||||
DCHECK(FLAG_vector_stores);
|
||||
return Code::STORE_IC;
|
||||
case KindKeyedStoreIC:
|
||||
DCHECK(FLAG_vector_stores);
|
||||
return Code::KEYED_STORE_IC;
|
||||
case KindUnused:
|
||||
break;
|
||||
}
|
||||
// Sentinel for no information.
|
||||
return Code::NUMBER_OF_KINDS;
|
||||
}
|
||||
|
||||
|
||||
Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const {
|
||||
FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
|
||||
FeedbackVectorICSlot slot) const {
|
||||
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
|
||||
int data = Smi::cast(get(index))->value();
|
||||
VectorICKind b = VectorICComputer::decode(data, slot.ToInt());
|
||||
return FromVectorICKind(b);
|
||||
return VectorICComputer::decode(data, slot.ToInt());
|
||||
}
|
||||
|
||||
|
||||
void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) {
|
||||
VectorICKind b = FromCodeKind(kind);
|
||||
void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot,
|
||||
FeedbackVectorSlotKind kind) {
|
||||
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
|
||||
int data = Smi::cast(get(index))->value();
|
||||
int new_data = VectorICComputer::encode(data, slot.ToInt(), b);
|
||||
int new_data = VectorICComputer::encode(data, slot.ToInt(), kind);
|
||||
set(index, Smi::FromInt(new_data));
|
||||
}
|
||||
|
||||
@ -163,7 +122,7 @@ int TypeFeedbackVector::PushAppliedArgumentsIndex() {
|
||||
// static
|
||||
Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector(
|
||||
Isolate* isolate) {
|
||||
Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
|
||||
FeedbackVectorSlotKind kinds[] = {FeedbackVectorSlotKind::KEYED_LOAD_IC};
|
||||
FeedbackVectorSpec spec(0, 1, kinds);
|
||||
Handle<TypeFeedbackVector> feedback_vector =
|
||||
isolate->factory()->NewTypeFeedbackVector(&spec);
|
||||
@ -247,24 +206,39 @@ void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared,
|
||||
FeedbackVectorICSlot slot(i);
|
||||
Object* obj = Get(slot);
|
||||
if (obj != uninitialized_sentinel) {
|
||||
Code::Kind kind = GetKind(slot);
|
||||
if (kind == Code::CALL_IC) {
|
||||
CallICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
} else if (kind == Code::LOAD_IC) {
|
||||
LoadICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
} else if (kind == Code::KEYED_LOAD_IC) {
|
||||
KeyedLoadICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
} else if (kind == Code::STORE_IC) {
|
||||
DCHECK(FLAG_vector_stores);
|
||||
StoreICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
} else if (kind == Code::KEYED_STORE_IC) {
|
||||
DCHECK(FLAG_vector_stores);
|
||||
KeyedStoreICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
FeedbackVectorSlotKind kind = GetKind(slot);
|
||||
switch (kind) {
|
||||
case FeedbackVectorSlotKind::CALL_IC: {
|
||||
CallICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::LOAD_IC: {
|
||||
LoadICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::KEYED_LOAD_IC: {
|
||||
KeyedLoadICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::STORE_IC: {
|
||||
DCHECK(FLAG_vector_stores);
|
||||
StoreICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::KEYED_STORE_IC: {
|
||||
DCHECK(FLAG_vector_stores);
|
||||
KeyedStoreICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::UNUSED:
|
||||
case FeedbackVectorSlotKind::KINDS_NUMBER:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,8 +268,8 @@ void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) {
|
||||
FeedbackVectorICSlot slot(i);
|
||||
Object* obj = Get(slot);
|
||||
if (obj != uninitialized_sentinel) {
|
||||
Code::Kind kind = GetKind(slot);
|
||||
if (kind == Code::KEYED_STORE_IC) {
|
||||
FeedbackVectorSlotKind kind = GetKind(slot);
|
||||
if (kind == FeedbackVectorSlotKind::KEYED_STORE_IC) {
|
||||
DCHECK(FLAG_vector_stores);
|
||||
KeyedStoreICNexus nexus(this, slot);
|
||||
nexus.Clear(host);
|
||||
@ -311,6 +285,28 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) {
|
||||
}
|
||||
|
||||
|
||||
const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) {
|
||||
switch (kind) {
|
||||
case FeedbackVectorSlotKind::UNUSED:
|
||||
return "UNUSED";
|
||||
case FeedbackVectorSlotKind::CALL_IC:
|
||||
return "CALL_IC";
|
||||
case FeedbackVectorSlotKind::LOAD_IC:
|
||||
return "LOAD_IC";
|
||||
case FeedbackVectorSlotKind::KEYED_LOAD_IC:
|
||||
return "KEYED_LOAD_IC";
|
||||
case FeedbackVectorSlotKind::STORE_IC:
|
||||
return "STORE_IC";
|
||||
case FeedbackVectorSlotKind::KEYED_STORE_IC:
|
||||
return "KEYED_STORE_IC";
|
||||
case FeedbackVectorSlotKind::KINDS_NUMBER:
|
||||
break;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return "?";
|
||||
}
|
||||
|
||||
|
||||
Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
|
||||
Isolate* isolate = GetIsolate();
|
||||
Handle<Object> feedback = handle(GetFeedback(), isolate);
|
||||
|
@ -17,19 +17,36 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
enum class FeedbackVectorSlotKind {
|
||||
UNUSED,
|
||||
CALL_IC,
|
||||
LOAD_IC,
|
||||
KEYED_LOAD_IC,
|
||||
STORE_IC,
|
||||
KEYED_STORE_IC,
|
||||
|
||||
KINDS_NUMBER // Last value indicating number of kinds.
|
||||
};
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind);
|
||||
|
||||
|
||||
class FeedbackVectorSpec {
|
||||
public:
|
||||
FeedbackVectorSpec() : slots_(0), ic_slots_(0), ic_kinds_(NULL) {}
|
||||
explicit FeedbackVectorSpec(int slots)
|
||||
: slots_(slots), ic_slots_(0), ic_kinds_(NULL) {}
|
||||
FeedbackVectorSpec(int slots, int ic_slots, Code::Kind* ic_slot_kinds)
|
||||
FeedbackVectorSpec(int slots, int ic_slots,
|
||||
FeedbackVectorSlotKind* ic_slot_kinds)
|
||||
: slots_(slots), ic_slots_(ic_slots), ic_kinds_(ic_slot_kinds) {}
|
||||
|
||||
int slots() const { return slots_; }
|
||||
|
||||
int ic_slots() const { return ic_slots_; }
|
||||
|
||||
Code::Kind GetKind(int ic_slot) const {
|
||||
FeedbackVectorSlotKind GetKind(int ic_slot) const {
|
||||
DCHECK(ic_slots_ > 0 && ic_slot < ic_slots_);
|
||||
return ic_kinds_[ic_slot];
|
||||
}
|
||||
@ -37,7 +54,7 @@ class FeedbackVectorSpec {
|
||||
private:
|
||||
int slots_;
|
||||
int ic_slots_;
|
||||
Code::Kind* ic_kinds_;
|
||||
FeedbackVectorSlotKind* ic_kinds_;
|
||||
};
|
||||
|
||||
|
||||
@ -58,12 +75,12 @@ class ZoneFeedbackVectorSpec {
|
||||
ic_slot_kinds_.resize(ic_slots_);
|
||||
}
|
||||
|
||||
void SetKind(int ic_slot, Code::Kind kind) {
|
||||
ic_slot_kinds_[ic_slot] = kind;
|
||||
void SetKind(int ic_slot, FeedbackVectorSlotKind kind) {
|
||||
ic_slot_kinds_[ic_slot] = static_cast<unsigned char>(kind);
|
||||
}
|
||||
|
||||
Code::Kind GetKind(int ic_slot) const {
|
||||
return static_cast<Code::Kind>(ic_slot_kinds_.at(ic_slot));
|
||||
FeedbackVectorSlotKind GetKind(int ic_slot) const {
|
||||
return static_cast<FeedbackVectorSlotKind>(ic_slot_kinds_.at(ic_slot));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -130,7 +147,7 @@ class TypeFeedbackVector : public FixedArray {
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
|
||||
// IC slots need metadata to recognize the type of IC.
|
||||
Code::Kind GetKind(FeedbackVectorICSlot slot) const;
|
||||
FeedbackVectorSlotKind GetKind(FeedbackVectorICSlot slot) const;
|
||||
|
||||
template <typename Spec>
|
||||
static Handle<TypeFeedbackVector> Allocate(Isolate* isolate,
|
||||
@ -190,23 +207,17 @@ class TypeFeedbackVector : public FixedArray {
|
||||
static Handle<TypeFeedbackVector> CreatePushAppliedArgumentsVector(
|
||||
Isolate* isolate);
|
||||
|
||||
static const char* Kind2String(FeedbackVectorSlotKind kind);
|
||||
|
||||
private:
|
||||
enum VectorICKind {
|
||||
KindUnused = 0x0,
|
||||
KindCallIC = 0x1,
|
||||
KindLoadIC = 0x2,
|
||||
KindKeyedLoadIC = 0x3,
|
||||
KindStoreIC = 0x4,
|
||||
KindKeyedStoreIC = 0x5,
|
||||
};
|
||||
static const int kFeedbackVectorSlotKindBits = 3;
|
||||
STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) <
|
||||
(1 << kFeedbackVectorSlotKindBits));
|
||||
|
||||
static const int kVectorICKindBits = 3;
|
||||
static VectorICKind FromCodeKind(Code::Kind kind);
|
||||
static Code::Kind FromVectorICKind(VectorICKind kind);
|
||||
void SetKind(FeedbackVectorICSlot slot, Code::Kind kind);
|
||||
void SetKind(FeedbackVectorICSlot slot, FeedbackVectorSlotKind kind);
|
||||
|
||||
typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize,
|
||||
uint32_t> VectorICComputer;
|
||||
typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits,
|
||||
kSmiValueSize, uint32_t> VectorICComputer;
|
||||
|
||||
void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
|
||||
void ClearICSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
|
||||
@ -305,11 +316,11 @@ class CallICNexus : public FeedbackNexus {
|
||||
|
||||
CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::CALL_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
|
||||
}
|
||||
CallICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::CALL_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
|
||||
}
|
||||
|
||||
void Clear(Code* host);
|
||||
@ -338,7 +349,7 @@ class LoadICNexus : public FeedbackNexus {
|
||||
public:
|
||||
LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
|
||||
}
|
||||
explicit LoadICNexus(Isolate* isolate)
|
||||
: FeedbackNexus(TypeFeedbackVector::DummyVector(isolate),
|
||||
@ -346,7 +357,7 @@ class LoadICNexus : public FeedbackNexus {
|
||||
TypeFeedbackVector::kDummyLoadICSlot)) {}
|
||||
LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
|
||||
}
|
||||
|
||||
void Clear(Code* host);
|
||||
@ -363,11 +374,11 @@ class KeyedLoadICNexus : public FeedbackNexus {
|
||||
public:
|
||||
KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
|
||||
}
|
||||
KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
|
||||
}
|
||||
|
||||
void Clear(Code* host);
|
||||
@ -388,7 +399,7 @@ class StoreICNexus : public FeedbackNexus {
|
||||
public:
|
||||
StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::STORE_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
|
||||
}
|
||||
explicit StoreICNexus(Isolate* isolate)
|
||||
: FeedbackNexus(TypeFeedbackVector::DummyVector(isolate),
|
||||
@ -396,7 +407,7 @@ class StoreICNexus : public FeedbackNexus {
|
||||
TypeFeedbackVector::kDummyStoreICSlot)) {}
|
||||
StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::STORE_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
|
||||
}
|
||||
|
||||
void Clear(Code* host);
|
||||
@ -414,7 +425,7 @@ class KeyedStoreICNexus : public FeedbackNexus {
|
||||
KeyedStoreICNexus(Handle<TypeFeedbackVector> vector,
|
||||
FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::KEYED_STORE_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
|
||||
}
|
||||
explicit KeyedStoreICNexus(Isolate* isolate)
|
||||
: FeedbackNexus(TypeFeedbackVector::DummyVector(isolate),
|
||||
@ -422,7 +433,7 @@ class KeyedStoreICNexus : public FeedbackNexus {
|
||||
TypeFeedbackVector::kDummyKeyedStoreICSlot)) {}
|
||||
KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
|
||||
: FeedbackNexus(vector, slot) {
|
||||
DCHECK(vector->GetKind(slot) == Code::KEYED_STORE_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
|
||||
}
|
||||
|
||||
void Clear(Code* host);
|
||||
|
@ -107,11 +107,11 @@ InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(TypeFeedbackId id) {
|
||||
InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(
|
||||
FeedbackVectorICSlot slot) {
|
||||
if (!slot.IsInvalid()) {
|
||||
Code::Kind kind = feedback_vector_->GetKind(slot);
|
||||
if (kind == Code::LOAD_IC) {
|
||||
FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot);
|
||||
if (kind == FeedbackVectorSlotKind::LOAD_IC) {
|
||||
LoadICNexus nexus(feedback_vector_, slot);
|
||||
return nexus.StateFromFeedback();
|
||||
} else if (kind == Code::KEYED_LOAD_IC) {
|
||||
} else if (kind == FeedbackVectorSlotKind::KEYED_LOAD_IC) {
|
||||
KeyedLoadICNexus nexus(feedback_vector_, slot);
|
||||
return nexus.StateFromFeedback();
|
||||
}
|
||||
@ -133,11 +133,11 @@ bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) {
|
||||
|
||||
bool TypeFeedbackOracle::StoreIsUninitialized(FeedbackVectorICSlot slot) {
|
||||
if (!slot.IsInvalid()) {
|
||||
Code::Kind kind = feedback_vector_->GetKind(slot);
|
||||
if (kind == Code::STORE_IC) {
|
||||
FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot);
|
||||
if (kind == FeedbackVectorSlotKind::STORE_IC) {
|
||||
StoreICNexus nexus(feedback_vector_, slot);
|
||||
return nexus.StateFromFeedback() == UNINITIALIZED;
|
||||
} else if (kind == Code::KEYED_STORE_IC) {
|
||||
} else if (kind == FeedbackVectorSlotKind::KEYED_STORE_IC) {
|
||||
KeyedStoreICNexus nexus(feedback_vector_, slot);
|
||||
return nexus.StateFromFeedback() == UNINITIALIZED;
|
||||
}
|
||||
@ -197,7 +197,8 @@ void TypeFeedbackOracle::GetStoreModeAndKeyType(
|
||||
FeedbackVectorICSlot slot, KeyedAccessStoreMode* store_mode,
|
||||
IcCheckType* key_type) {
|
||||
if (!slot.IsInvalid() &&
|
||||
feedback_vector_->GetKind(slot) == Code::KEYED_STORE_IC) {
|
||||
feedback_vector_->GetKind(slot) ==
|
||||
FeedbackVectorSlotKind::KEYED_STORE_IC) {
|
||||
KeyedStoreICNexus nexus(feedback_vector_, slot);
|
||||
*store_mode = nexus.GetKeyedAccessStoreMode();
|
||||
*key_type = nexus.GetKeyType();
|
||||
@ -468,12 +469,12 @@ void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
|
||||
|
||||
void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorICSlot slot,
|
||||
SmallMapList* types) {
|
||||
Code::Kind kind = feedback_vector_->GetKind(slot);
|
||||
if (kind == Code::STORE_IC) {
|
||||
FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot);
|
||||
if (kind == FeedbackVectorSlotKind::STORE_IC) {
|
||||
StoreICNexus nexus(feedback_vector_, slot);
|
||||
CollectReceiverTypes<FeedbackNexus>(&nexus, types);
|
||||
} else {
|
||||
DCHECK(kind == Code::KEYED_STORE_IC);
|
||||
DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, kind);
|
||||
KeyedStoreICNexus nexus(feedback_vector_, slot);
|
||||
CollectReceiverTypes<FeedbackNexus>(&nexus, types);
|
||||
}
|
||||
|
@ -392,7 +392,8 @@ TEST(PropertyLoads) {
|
||||
InitializedHandleScope handle_scope;
|
||||
BytecodeGeneratorHelper helper;
|
||||
|
||||
Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC };
|
||||
FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::LOAD_IC,
|
||||
i::FeedbackVectorSlotKind::LOAD_IC};
|
||||
FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
helper.factory()->NewTypeFeedbackVector(&feedback_spec);
|
||||
@ -479,7 +480,8 @@ TEST(PropertyStores) {
|
||||
InitializedHandleScope handle_scope;
|
||||
BytecodeGeneratorHelper helper;
|
||||
|
||||
Code::Kind ic_kinds[] = { i::Code::STORE_IC, i::Code::STORE_IC };
|
||||
FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::STORE_IC,
|
||||
i::FeedbackVectorSlotKind::STORE_IC};
|
||||
FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
helper.factory()->NewTypeFeedbackVector(&feedback_spec);
|
||||
@ -584,7 +586,8 @@ TEST(PropertyCall) {
|
||||
InitializedHandleScope handle_scope;
|
||||
BytecodeGeneratorHelper helper; //
|
||||
|
||||
Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC };
|
||||
FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::LOAD_IC,
|
||||
i::FeedbackVectorSlotKind::LOAD_IC};
|
||||
FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
helper.factory()->NewTypeFeedbackVector(&feedback_spec);
|
||||
|
@ -552,7 +552,7 @@ TEST(InterpreterLoadNamedProperty) {
|
||||
i::Isolate* isolate = handles.main_isolate();
|
||||
i::Factory* factory = isolate->factory();
|
||||
|
||||
i::Code::Kind ic_kinds[] = {i::Code::LOAD_IC};
|
||||
i::FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::LOAD_IC};
|
||||
i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
factory->NewTypeFeedbackVector(&feedback_spec);
|
||||
@ -606,7 +606,8 @@ TEST(InterpreterLoadKeyedProperty) {
|
||||
i::Isolate* isolate = handles.main_isolate();
|
||||
i::Factory* factory = isolate->factory();
|
||||
|
||||
i::Code::Kind ic_kinds[] = { i::Code::KEYED_LOAD_IC };
|
||||
i::FeedbackVectorSlotKind ic_kinds[] = {
|
||||
i::FeedbackVectorSlotKind::KEYED_LOAD_IC};
|
||||
i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
factory->NewTypeFeedbackVector(&feedback_spec);
|
||||
@ -648,7 +649,7 @@ TEST(InterpreterStoreNamedProperty) {
|
||||
i::Isolate* isolate = handles.main_isolate();
|
||||
i::Factory* factory = isolate->factory();
|
||||
|
||||
i::Code::Kind ic_kinds[] = {i::Code::STORE_IC};
|
||||
i::FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::STORE_IC};
|
||||
i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
factory->NewTypeFeedbackVector(&feedback_spec);
|
||||
@ -708,7 +709,8 @@ TEST(InterpreterStoreKeyedProperty) {
|
||||
i::Isolate* isolate = handles.main_isolate();
|
||||
i::Factory* factory = isolate->factory();
|
||||
|
||||
i::Code::Kind ic_kinds[] = {i::Code::KEYED_STORE_IC};
|
||||
i::FeedbackVectorSlotKind ic_kinds[] = {
|
||||
i::FeedbackVectorSlotKind::KEYED_STORE_IC};
|
||||
i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
factory->NewTypeFeedbackVector(&feedback_spec);
|
||||
@ -755,7 +757,7 @@ TEST(InterpreterCall) {
|
||||
i::Isolate* isolate = handles.main_isolate();
|
||||
i::Factory* factory = isolate->factory();
|
||||
|
||||
i::Code::Kind ic_kinds[] = { i::Code::LOAD_IC };
|
||||
i::FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::LOAD_IC};
|
||||
i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
factory->NewTypeFeedbackVector(&feedback_spec);
|
||||
|
@ -17,6 +17,10 @@ using namespace v8::internal;
|
||||
|
||||
namespace {
|
||||
|
||||
#define CHECK_SLOT_KIND(vector, slot, expected_kind) \
|
||||
CHECK_EQ(expected_kind, vector->GetKind(FeedbackVectorICSlot(slot)));
|
||||
|
||||
|
||||
TEST(VectorStructure) {
|
||||
LocalContext context;
|
||||
v8::HandleScope scope(context->GetIsolate());
|
||||
@ -41,13 +45,13 @@ TEST(VectorStructure) {
|
||||
CHECK_EQ(0, vector->ICSlots());
|
||||
|
||||
ZoneFeedbackVectorSpec one_icslot(zone, 0, 1);
|
||||
one_icslot.SetKind(0, Code::CALL_IC);
|
||||
one_icslot.SetKind(0, FeedbackVectorSlotKind::CALL_IC);
|
||||
vector = factory->NewTypeFeedbackVector(&one_icslot);
|
||||
CHECK_EQ(0, vector->Slots());
|
||||
CHECK_EQ(1, vector->ICSlots());
|
||||
|
||||
ZoneFeedbackVectorSpec spec(zone, 3, 5);
|
||||
for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC);
|
||||
for (int i = 0; i < 5; i++) spec.SetKind(i, FeedbackVectorSlotKind::CALL_IC);
|
||||
vector = factory->NewTypeFeedbackVector(&spec);
|
||||
CHECK_EQ(3, vector->Slots());
|
||||
CHECK_EQ(5, vector->ICSlots());
|
||||
@ -81,13 +85,13 @@ TEST(VectorICMetadata) {
|
||||
ZoneFeedbackVectorSpec spec(zone, 10, 3 * 10);
|
||||
// Set metadata.
|
||||
for (int i = 0; i < 30; i++) {
|
||||
Code::Kind kind;
|
||||
FeedbackVectorSlotKind kind;
|
||||
if (i % 3 == 0) {
|
||||
kind = Code::CALL_IC;
|
||||
kind = FeedbackVectorSlotKind::CALL_IC;
|
||||
} else if (i % 3 == 1) {
|
||||
kind = Code::LOAD_IC;
|
||||
kind = FeedbackVectorSlotKind::LOAD_IC;
|
||||
} else {
|
||||
kind = Code::KEYED_LOAD_IC;
|
||||
kind = FeedbackVectorSlotKind::KEYED_LOAD_IC;
|
||||
}
|
||||
spec.SetKind(i, kind);
|
||||
}
|
||||
@ -104,13 +108,13 @@ TEST(VectorICMetadata) {
|
||||
|
||||
// Verify the metadata is correctly set up from the spec.
|
||||
for (int i = 0; i < 30; i++) {
|
||||
Code::Kind kind = vector->GetKind(FeedbackVectorICSlot(i));
|
||||
FeedbackVectorSlotKind kind = vector->GetKind(FeedbackVectorICSlot(i));
|
||||
if (i % 3 == 0) {
|
||||
CHECK_EQ(Code::CALL_IC, kind);
|
||||
CHECK_EQ(FeedbackVectorSlotKind::CALL_IC, kind);
|
||||
} else if (i % 3 == 1) {
|
||||
CHECK_EQ(Code::LOAD_IC, kind);
|
||||
CHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, kind);
|
||||
} else {
|
||||
CHECK_EQ(Code::KEYED_LOAD_IC, kind);
|
||||
CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -418,14 +422,14 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
handle(f->shared()->feedback_vector(), isolate);
|
||||
if (FLAG_vector_stores) {
|
||||
CHECK_EQ(4, feedback_vector->ICSlots());
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::STORE_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::STORE_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::STORE_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::STORE_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 3, FeedbackVectorSlotKind::LOAD_IC);
|
||||
} else {
|
||||
CHECK_EQ(2, feedback_vector->ICSlots());
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC);
|
||||
}
|
||||
|
||||
CompileRun(
|
||||
@ -458,17 +462,17 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
feedback_vector = handle(f->shared()->feedback_vector(), isolate);
|
||||
if (FLAG_vector_stores) {
|
||||
CHECK_EQ(5, feedback_vector->ICSlots());
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::CALL_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::STORE_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::CALL_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(4)) == Code::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::CALL_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::STORE_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 3, FeedbackVectorSlotKind::CALL_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 4, FeedbackVectorSlotKind::LOAD_IC);
|
||||
} else {
|
||||
CHECK_EQ(4, feedback_vector->ICSlots());
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::CALL_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::CALL_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::CALL_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::CALL_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 3, FeedbackVectorSlotKind::LOAD_IC);
|
||||
}
|
||||
|
||||
CompileRun(
|
||||
@ -485,16 +489,13 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
feedback_vector = handle(f->shared()->feedback_vector(), isolate);
|
||||
if (FLAG_vector_stores) {
|
||||
CHECK_EQ(3, feedback_vector->ICSlots());
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) ==
|
||||
Code::KEYED_STORE_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) ==
|
||||
Code::KEYED_LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::KEYED_STORE_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC);
|
||||
} else {
|
||||
CHECK_EQ(2, feedback_vector->ICSlots());
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) ==
|
||||
Code::KEYED_LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::KEYED_LOAD_IC);
|
||||
}
|
||||
|
||||
CompileRun(
|
||||
@ -510,17 +511,17 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
feedback_vector = handle(f->shared()->feedback_vector(), isolate);
|
||||
if (FLAG_vector_stores) {
|
||||
CHECK_EQ(6, feedback_vector->ICSlots());
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::STORE_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::STORE_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::STORE_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(4)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(5)) == Code::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::STORE_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::STORE_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 3, FeedbackVectorSlotKind::STORE_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 4, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 5, FeedbackVectorSlotKind::LOAD_IC);
|
||||
} else {
|
||||
CHECK_EQ(3, feedback_vector->ICSlots());
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC);
|
||||
CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC);
|
||||
CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::LOAD_IC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3810,11 +3810,11 @@ static void CheckVectorIC(Handle<JSFunction> f, int ic_slot_index,
|
||||
Handle<TypeFeedbackVector> vector =
|
||||
Handle<TypeFeedbackVector>(f->shared()->feedback_vector());
|
||||
FeedbackVectorICSlot slot(ic_slot_index);
|
||||
if (vector->GetKind(slot) == Code::LOAD_IC) {
|
||||
if (vector->GetKind(slot) == FeedbackVectorSlotKind::LOAD_IC) {
|
||||
LoadICNexus nexus(vector, slot);
|
||||
CHECK(nexus.StateFromFeedback() == desired_state);
|
||||
} else {
|
||||
CHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
|
||||
CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
|
||||
KeyedLoadICNexus nexus(vector, slot);
|
||||
CHECK(nexus.StateFromFeedback() == desired_state);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user