Commit 1d7c9c81 authored by ishell's avatar ishell Committed by Commit bot

The metadata part of TypeFeedbackVector is extracted to TypeFeedbackMetadata array.

Thus TypeFeedbackMetadata can now be shared between different native contexts.

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

Cr-Commit-Position: refs/heads/master@{#31143}
parent c5528ac1
......@@ -245,13 +245,15 @@ bool CompilationInfo::ShouldSelfOptimize() {
void CompilationInfo::EnsureFeedbackVector() {
if (feedback_vector_.is_null()) {
feedback_vector_ =
TypeFeedbackVector::New(isolate(), literal()->feedback_vector_spec());
Handle<TypeFeedbackMetadata> feedback_metadata =
TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec());
feedback_vector_ = TypeFeedbackVector::New(isolate(), feedback_metadata);
}
// It's very important that recompiles do not alter the structure of the
// type feedback vector.
CHECK(!feedback_vector_->SpecDiffersFrom(literal()->feedback_vector_spec()));
CHECK(!feedback_vector_->metadata()->SpecDiffersFrom(
literal()->feedback_vector_spec()));
}
......
......@@ -2138,8 +2138,10 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER);
StaticFeedbackVectorSpec empty_spec;
Handle<TypeFeedbackMetadata> feedback_metadata =
TypeFeedbackMetadata::New(isolate(), &empty_spec);
Handle<TypeFeedbackVector> feedback_vector =
TypeFeedbackVector::New(isolate(), &empty_spec);
TypeFeedbackVector::New(isolate(), feedback_metadata);
share->set_feedback_vector(*feedback_vector, SKIP_WRITE_BARRIER);
#if TRACE_MAPS
share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
......
......@@ -2759,8 +2759,10 @@ void Heap::CreateInitialObjects() {
DCHECK_EQ(keyed_store_ic_slot,
FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
Handle<TypeFeedbackMetadata> dummy_metadata =
TypeFeedbackMetadata::New(isolate(), &spec);
Handle<TypeFeedbackVector> dummy_vector =
TypeFeedbackVector::New(isolate(), &spec);
TypeFeedbackVector::New(isolate(), dummy_metadata);
Object* megamorphic = *TypeFeedbackVector::MegamorphicSentinel(isolate());
dummy_vector->Set(load_ic_slot, megamorphic, SKIP_WRITE_BARRIER);
......
......@@ -730,6 +730,9 @@ bool Object::IsTransitionArray() const {
bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); }
bool Object::IsTypeFeedbackMetadata() const { return IsFixedArray(); }
bool Object::IsLiteralsArray() const { return IsFixedArray(); }
bool Object::IsBindingsArray() const { return IsFixedArray(); }
......
......@@ -539,6 +539,32 @@ void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) { // NOLINT
}
void TypeFeedbackMetadata::Print() {
OFStream os(stdout);
TypeFeedbackMetadataPrint(os);
os << std::flush;
}
void TypeFeedbackMetadata::TypeFeedbackMetadataPrint(
std::ostream& os) { // NOLINT
HeapObject::PrintHeader(os, "TypeFeedbackMetadata");
os << " - length: " << length();
if (length() == 0) {
os << " (empty)\n";
return;
}
TypeFeedbackMetadataIterator iter(this);
while (iter.HasNext()) {
FeedbackVectorSlot slot = iter.Next();
FeedbackVectorSlotKind kind = iter.kind();
os << "\n Slot " << slot << " " << kind;
}
os << "\n";
}
void TypeFeedbackVector::Print() {
OFStream os(stdout);
TypeFeedbackVectorPrint(os);
......@@ -557,12 +583,12 @@ void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) { // NOLINT
os << "\n - ics with type info: " << ic_with_type_info_count();
os << "\n - generic ics: " << ic_generic_count();
TypeFeedbackMetadataIterator iter(this);
TypeFeedbackMetadataIterator iter(metadata());
while (iter.HasNext()) {
FeedbackVectorSlot slot = iter.Next();
FeedbackVectorSlotKind kind = iter.kind();
os << "\n ICSlot " << slot.ToInt() << " " << kind << " ";
os << "\n Slot " << slot << " " << kind << " ";
switch (kind) {
case FeedbackVectorSlotKind::LOAD_IC: {
LoadICNexus nexus(this, slot);
......
......@@ -88,6 +88,7 @@
// - OrderedHashSet
// - OrderedHashMap
// - Context
// - TypeFeedbackMetadata
// - TypeFeedbackVector
// - ScopeInfo
// - TransitionArray
......@@ -945,6 +946,7 @@ template <class C> inline bool Is(Object* obj);
V(BindingsArray) \
V(TransitionArray) \
V(LiteralsArray) \
V(TypeFeedbackMetadata) \
V(TypeFeedbackVector) \
V(DeoptimizationInputData) \
V(DeoptimizationOutputData) \
......
......@@ -17,7 +17,7 @@ FeedbackVectorSlot FeedbackVectorSpecBase<Derived>::AddSlot(
Derived* derived = static_cast<Derived*>(this);
int slot = derived->slots();
int entries_per_slot = TypeFeedbackVector::GetSlotSize(kind);
int entries_per_slot = TypeFeedbackMetadata::GetSlotSize(kind);
derived->append(kind);
for (int i = 1; i < entries_per_slot; i++) {
derived->append(FeedbackVectorSlotKind::INVALID);
......@@ -26,6 +26,20 @@ FeedbackVectorSlot FeedbackVectorSpecBase<Derived>::AddSlot(
}
// static
TypeFeedbackMetadata* TypeFeedbackMetadata::cast(Object* obj) {
DCHECK(obj->IsTypeFeedbackVector());
return reinterpret_cast<TypeFeedbackMetadata*>(obj);
}
int TypeFeedbackMetadata::slot_count() const {
if (length() == 0) return 0;
DCHECK(length() > kReservedIndexCount);
return Smi::cast(get(kSlotsCountIndex))->value();
}
// static
TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) {
DCHECK(obj->IsTypeFeedbackVector());
......@@ -33,7 +47,7 @@ TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) {
}
int TypeFeedbackVector::GetSlotSize(FeedbackVectorSlotKind kind) {
int TypeFeedbackMetadata::GetSlotSize(FeedbackVectorSlotKind kind) {
DCHECK_NE(FeedbackVectorSlotKind::INVALID, kind);
DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, kind);
return kind == FeedbackVectorSlotKind::GENERAL ? 1 : 2;
......@@ -42,15 +56,28 @@ int TypeFeedbackVector::GetSlotSize(FeedbackVectorSlotKind kind) {
bool TypeFeedbackVector::is_empty() const {
if (length() == 0) return true;
DCHECK(length() >= kReservedIndexCount);
DCHECK(length() > kReservedIndexCount);
return false;
}
int TypeFeedbackVector::Slots() const {
int TypeFeedbackVector::slot_count() const {
if (length() == 0) return 0;
DCHECK(length() >= kReservedIndexCount);
return Smi::cast(get(kSlotsCountIndex))->value();
DCHECK(length() > kReservedIndexCount);
return length() - kReservedIndexCount;
}
TypeFeedbackMetadata* TypeFeedbackVector::metadata() const {
return is_empty() ? TypeFeedbackMetadata::cast(GetHeap()->empty_fixed_array())
: TypeFeedbackMetadata::cast(get(kMetadataIndex));
}
FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
FeedbackVectorSlot slot) const {
DCHECK(!is_empty());
return metadata()->GetKind(slot);
}
......@@ -83,23 +110,17 @@ void TypeFeedbackVector::change_ic_generic_count(int delta) {
}
int TypeFeedbackVector::ic_metadata_length() const {
return VectorICComputer::word_count(Slots());
}
int TypeFeedbackVector::GetIndex(FeedbackVectorSlot slot) const {
DCHECK(slot.ToInt() < Slots());
return kReservedIndexCount + ic_metadata_length() + slot.ToInt();
DCHECK(slot.ToInt() < slot_count());
return kReservedIndexCount + slot.ToInt();
}
// Conversion from an integer index to either a slot or an ic slot. The caller
// should know what kind she expects.
FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) const {
DCHECK(index >= kReservedIndexCount + ic_metadata_length() &&
index < length());
return FeedbackVectorSlot(index - ic_metadata_length() - kReservedIndexCount);
DCHECK(index >= kReservedIndexCount && index < length());
return FeedbackVectorSlot(index - kReservedIndexCount);
}
......@@ -140,7 +161,7 @@ Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); }
Object* FeedbackNexus::GetFeedbackExtra() const {
#ifdef DEBUG
FeedbackVectorSlotKind kind = vector()->GetKind(slot());
DCHECK_LT(1, TypeFeedbackVector::GetSlotSize(kind));
DCHECK_LT(1, TypeFeedbackMetadata::GetSlotSize(kind));
#endif
int extra_index = vector()->GetIndex(slot()) + 1;
return vector()->get(extra_index);
......@@ -156,7 +177,7 @@ void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
WriteBarrierMode mode) {
#ifdef DEBUG
FeedbackVectorSlotKind kind = vector()->GetKind(slot());
DCHECK_LT(1, TypeFeedbackVector::GetSlotSize(kind));
DCHECK_LT(1, TypeFeedbackMetadata::GetSlotSize(kind));
#endif
int index = vector()->GetIndex(slot()) + 1;
vector()->set(index, feedback_extra, mode);
......
......@@ -14,11 +14,11 @@ namespace v8 {
namespace internal {
std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) {
return os << TypeFeedbackVector::Kind2String(kind);
return os << TypeFeedbackMetadata::Kind2String(kind);
}
FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind(
FeedbackVectorSlot slot) const {
int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
int data = Smi::cast(get(index))->value();
......@@ -26,8 +26,8 @@ FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
}
void TypeFeedbackVector::SetKind(FeedbackVectorSlot slot,
FeedbackVectorSlotKind kind) {
void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot 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(), kind);
......@@ -35,27 +35,27 @@ void TypeFeedbackVector::SetKind(FeedbackVectorSlot slot,
}
template Handle<TypeFeedbackVector> TypeFeedbackVector::New(
template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
Isolate* isolate, const StaticFeedbackVectorSpec* spec);
template Handle<TypeFeedbackVector> TypeFeedbackVector::New(
template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
Isolate* isolate, const FeedbackVectorSpec* spec);
// static
template <typename Spec>
Handle<TypeFeedbackVector> TypeFeedbackVector::New(Isolate* isolate,
const Spec* spec) {
Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate,
const Spec* spec) {
const int slot_count = spec->slots();
const int index_count = VectorICComputer::word_count(slot_count);
const int length = slot_count + index_count + kReservedIndexCount;
const int slot_kinds_length = VectorICComputer::word_count(slot_count);
const int length = slot_kinds_length + kReservedIndexCount;
if (length == kReservedIndexCount) {
return Handle<TypeFeedbackVector>::cast(
return Handle<TypeFeedbackMetadata>::cast(
isolate->factory()->empty_fixed_array());
}
#ifdef DEBUG
for (int i = 0; i < slot_count;) {
FeedbackVectorSlotKind kind = spec->GetKind(i);
int entry_size = TypeFeedbackVector::GetSlotSize(kind);
int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
for (int j = 1; j < entry_size; j++) {
FeedbackVectorSlotKind kind = spec->GetKind(i + j);
DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind);
......@@ -66,41 +66,97 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::New(Isolate* isolate,
Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED);
array->set(kSlotsCountIndex, Smi::FromInt(slot_count));
array->set(kWithTypesIndex, Smi::FromInt(0));
array->set(kGenericCountIndex, Smi::FromInt(0));
// Fill the indexes with zeros.
for (int i = 0; i < index_count; i++) {
// Fill the bit-vector part with zeros.
for (int i = 0; i < slot_kinds_length; i++) {
array->set(kReservedIndexCount + i, Smi::FromInt(0));
}
Handle<TypeFeedbackMetadata> metadata =
Handle<TypeFeedbackMetadata>::cast(array);
for (int i = 0; i < slot_count; i++) {
metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i));
}
return metadata;
}
bool TypeFeedbackMetadata::SpecDiffersFrom(
const FeedbackVectorSpec* other_spec) const {
if (other_spec->slots() != slot_count()) {
return true;
}
int slots = slot_count();
for (int i = 0; i < slots; i++) {
if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) {
return true;
}
}
return false;
}
const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) {
switch (kind) {
case FeedbackVectorSlotKind::INVALID:
return "INVALID";
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::GENERAL:
return "STUB";
case FeedbackVectorSlotKind::KINDS_NUMBER:
break;
}
UNREACHABLE();
return "?";
}
// static
Handle<TypeFeedbackVector> TypeFeedbackVector::New(
Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) {
Factory* factory = isolate->factory();
const int slot_count = metadata->slot_count();
const int length = slot_count + kReservedIndexCount;
if (length == kReservedIndexCount) {
return Handle<TypeFeedbackVector>::cast(factory->empty_fixed_array());
}
Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
array->set(kMetadataIndex, *metadata);
array->set(kWithTypesIndex, Smi::FromInt(0));
array->set(kGenericCountIndex, Smi::FromInt(0));
// Ensure we can skip the write barrier
Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel);
for (int i = kReservedIndexCount + index_count; i < length; i++) {
DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel);
for (int i = kReservedIndexCount; i < length; i++) {
array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
}
Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array);
for (int i = 0; i < slot_count; i++) {
vector->SetKind(FeedbackVectorSlot(i), spec->GetKind(i));
}
return vector;
return Handle<TypeFeedbackVector>::cast(array);
}
// static
int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec,
FeedbackVectorSlot slot) {
const int slot_count = spec->slots();
const int index_count = VectorICComputer::word_count(slot_count);
return kReservedIndexCount + index_count + slot.ToInt();
return kReservedIndexCount + slot.ToInt();
}
// static
int TypeFeedbackVector::PushAppliedArgumentsIndex() {
const int index_count = VectorICComputer::word_count(1);
return kReservedIndexCount + index_count;
return kReservedIndexCount;
}
......@@ -109,8 +165,11 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector(
Isolate* isolate) {
StaticFeedbackVectorSpec spec;
FeedbackVectorSlot slot = spec.AddKeyedLoadICSlot();
// TODO(ishell): allocate this metadata only once.
Handle<TypeFeedbackMetadata> feedback_metadata =
TypeFeedbackMetadata::New(isolate, &spec);
Handle<TypeFeedbackVector> feedback_vector =
TypeFeedbackVector::New(isolate, &spec);
TypeFeedbackVector::New(isolate, feedback_metadata);
DCHECK_EQ(PushAppliedArgumentsIndex(), feedback_vector->GetIndex(slot));
USE(slot);
return feedback_vector;
......@@ -127,22 +186,6 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
}
bool TypeFeedbackVector::SpecDiffersFrom(
const FeedbackVectorSpec* other_spec) const {
if (other_spec->slots() != Slots()) {
return true;
}
int slots = Slots();
for (int i = 0; i < slots; i++) {
if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) {
return true;
}
}
return false;
}
// This logic is copied from
// StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
static bool ClearLogic(Isolate* isolate) {
......@@ -159,7 +202,7 @@ void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
Object* uninitialized_sentinel =
TypeFeedbackVector::RawUninitializedSentinel(isolate);
TypeFeedbackMetadataIterator iter(this);
TypeFeedbackMetadataIterator iter(metadata());
while (iter.HasNext()) {
FeedbackVectorSlot slot = iter.Next();
FeedbackVectorSlotKind kind = iter.kind();
......@@ -236,7 +279,7 @@ void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) {
Object* uninitialized_sentinel =
TypeFeedbackVector::RawUninitializedSentinel(isolate);
TypeFeedbackMetadataIterator iter(this);
TypeFeedbackMetadataIterator iter(metadata());
while (iter.HasNext()) {
FeedbackVectorSlot slot = iter.Next();
FeedbackVectorSlotKind kind = iter.kind();
......@@ -257,30 +300,6 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) {
}
const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) {
switch (kind) {
case FeedbackVectorSlotKind::INVALID:
return "INVALID";
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::GENERAL:
return "STUB";
case FeedbackVectorSlotKind::KINDS_NUMBER:
break;
}
UNREACHABLE();
return "?";
}
Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
Isolate* isolate = GetIsolate();
Handle<Object> feedback = handle(GetFeedback(), isolate);
......
......@@ -121,13 +121,60 @@ class FeedbackVectorSpec : public FeedbackVectorSpecBase<FeedbackVectorSpec> {
};
// The shape of the TypeFeedbackVector is an array with:
// The shape of the TypeFeedbackMetadata is an array with:
// 0: slot_count
// 1..N: slot kinds packed into a bit vector
//
class TypeFeedbackMetadata : public FixedArray {
public:
// Casting.
static inline TypeFeedbackMetadata* cast(Object* obj);
static const int kSlotsCountIndex = 0;
static const int kReservedIndexCount = 1;
// Returns number of feedback vector elements used by given slot kind.
static inline int GetSlotSize(FeedbackVectorSlotKind kind);
bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const;
// Returns number of slots in the vector.
inline int slot_count() const;
// Returns slot kind for given slot.
FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
template <typename Spec>
static Handle<TypeFeedbackMetadata> New(Isolate* isolate, const Spec* spec);
#ifdef OBJECT_PRINT
// For gdb debugging.
void Print();
#endif // OBJECT_PRINT
DECLARE_PRINTER(TypeFeedbackMetadata)
static const char* Kind2String(FeedbackVectorSlotKind kind);
private:
static const int kFeedbackVectorSlotKindBits = 3;
STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) <
(1 << kFeedbackVectorSlotKindBits));
void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind);
typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits,
kSmiValueSize, uint32_t> VectorICComputer;
DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackMetadata);
};
// The shape of the TypeFeedbackVector is an array with:
// 0: feedback metadata
// 1: ics_with_types
// 2: ics_with_generic_info
// 3: slots metadata (a bit vector of slot kinds)
// ...
// N: feedback slot #0 (N >= 3)
// 3: feedback slot #0 (N >= 3)
// ...
// N + slot_count - 1: feedback slot #(slot_count-1)
//
......@@ -136,26 +183,22 @@ class TypeFeedbackVector : public FixedArray {
// Casting.
static inline TypeFeedbackVector* cast(Object* obj);
static const int kSlotsCountIndex = 0;
static const int kMetadataIndex = 0;
static const int kWithTypesIndex = 1;
static const int kGenericCountIndex = 2;
static const int kReservedIndexCount = 3;
// Returns number of feedback vector elements used by given slot kind.
static inline int GetSlotSize(FeedbackVectorSlotKind kind);
inline int ic_with_type_info_count();
inline void change_ic_with_type_info_count(int delta);
inline int ic_generic_count();
inline void change_ic_generic_count(int delta);
inline int ic_metadata_length() const;
bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const;
inline bool is_empty() const;
// Returns number of slots in the vector.
inline int Slots() const;
inline int slot_count() const;
inline TypeFeedbackMetadata* metadata() const;
// Conversion from a slot to an integer index to the underlying array.
inline int GetIndex(FeedbackVectorSlot slot) const;
......@@ -169,10 +212,10 @@ class TypeFeedbackVector : public FixedArray {
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Returns slot kind for given slot.
FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
inline FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
template <typename Spec>
static Handle<TypeFeedbackVector> New(Isolate* isolate, const Spec* spec);
static Handle<TypeFeedbackVector> New(Isolate* isolate,
Handle<TypeFeedbackMetadata> metadata);
static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
Handle<TypeFeedbackVector> vector);
......@@ -222,18 +265,7 @@ class TypeFeedbackVector : public FixedArray {
static Handle<TypeFeedbackVector> CreatePushAppliedArgumentsVector(
Isolate* isolate);
static const char* Kind2String(FeedbackVectorSlotKind kind);
private:
static const int kFeedbackVectorSlotKindBits = 3;
STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) <
(1 << kFeedbackVectorSlotKindBits));
void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind);
typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits,
kSmiValueSize, uint32_t> VectorICComputer;
void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector);
......@@ -257,17 +289,17 @@ STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
class TypeFeedbackMetadataIterator {
public:
explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackVector> metadata)
explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackMetadata> metadata)
: metadata_handle_(metadata),
slot_(FeedbackVectorSlot(0)),
slot_kind_(FeedbackVectorSlotKind::INVALID) {}
explicit TypeFeedbackMetadataIterator(TypeFeedbackVector* metadata)
explicit TypeFeedbackMetadataIterator(TypeFeedbackMetadata* metadata)
: metadata_(metadata),
slot_(FeedbackVectorSlot(0)),
slot_kind_(FeedbackVectorSlotKind::INVALID) {}
bool HasNext() const { return slot_.ToInt() < metadata()->Slots(); }
bool HasNext() const { return slot_.ToInt() < metadata()->slot_count(); }
FeedbackVectorSlot Next() {
DCHECK(HasNext());
......@@ -285,18 +317,18 @@ class TypeFeedbackMetadataIterator {
}
// Returns entry size of the last slot returned by Next().
int entry_size() const { return TypeFeedbackVector::GetSlotSize(kind()); }
int entry_size() const { return TypeFeedbackMetadata::GetSlotSize(kind()); }
private:
TypeFeedbackVector* metadata() const {
TypeFeedbackMetadata* metadata() const {
return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_;
}
// The reason for having a handle and a raw pointer to the meta data is
// to have a single iterator implementation for both "handlified" and raw
// pointer use cases.
Handle<TypeFeedbackVector> metadata_handle_;
TypeFeedbackVector* metadata_;
Handle<TypeFeedbackMetadata> metadata_handle_;
TypeFeedbackMetadata* metadata_;
FeedbackVectorSlot slot_;
FeedbackVectorSlotKind slot_kind_;
};
......
......@@ -424,7 +424,7 @@ TEST(PropertyLoads) {
FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot();
Handle<i::TypeFeedbackVector> vector =
i::TypeFeedbackVector::New(helper.isolate(), &feedback_spec);
i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
ExpectedSnippet<const char*> snippets[] = {
{"function f(a) { return a.name; }\nf({name : \"test\"})",
......@@ -547,7 +547,7 @@ TEST(PropertyStores) {
FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
Handle<i::TypeFeedbackVector> vector =
i::TypeFeedbackVector::New(helper.isolate(), &feedback_spec);
i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
ExpectedSnippet<const char*> snippets[] = {
{"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})",
......@@ -696,7 +696,7 @@ TEST(PropertyCall) {
USE(slot1);
Handle<i::TypeFeedbackVector> vector =
i::TypeFeedbackVector::New(helper.isolate(), &feedback_spec);
i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
ExpectedSnippet<const char*> snippets[] = {
{"function f(a) { return a.func(); }\nf(" FUNC_ARG ")",
......
......@@ -9,6 +9,7 @@
#include "src/interpreter/bytecode-array-builder.h"
#include "src/interpreter/interpreter.h"
#include "test/cctest/cctest.h"
#include "test/cctest/test-feedback-vector.h"
namespace v8 {
namespace internal {
......@@ -598,7 +599,7 @@ TEST(InterpreterLoadNamedProperty) {
i::FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
Handle<i::TypeFeedbackVector> vector =
i::TypeFeedbackVector::New(isolate, &feedback_spec);
i::NewTypeFeedbackVector(isolate, &feedback_spec);
Handle<i::String> name = factory->NewStringFromAsciiChecked("val");
name = factory->string_table()->LookupString(isolate, name);
......@@ -654,7 +655,7 @@ TEST(InterpreterLoadKeyedProperty) {
i::FeedbackVectorSlot slot = feedback_spec.AddKeyedLoadICSlot();
Handle<i::TypeFeedbackVector> vector =
i::TypeFeedbackVector::New(isolate, &feedback_spec);
i::NewTypeFeedbackVector(isolate, &feedback_spec);
Handle<i::String> key = factory->NewStringFromAsciiChecked("key");
key = factory->string_table()->LookupString(isolate, key);
......@@ -698,7 +699,7 @@ TEST(InterpreterStoreNamedProperty) {
i::FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot();
Handle<i::TypeFeedbackVector> vector =
i::TypeFeedbackVector::New(isolate, &feedback_spec);
i::NewTypeFeedbackVector(isolate, &feedback_spec);
Handle<i::String> name = factory->NewStringFromAsciiChecked("val");
name = factory->string_table()->LookupString(isolate, name);
......@@ -760,7 +761,7 @@ TEST(InterpreterStoreKeyedProperty) {
i::FeedbackVectorSlot slot = feedback_spec.AddKeyedStoreICSlot();
Handle<i::TypeFeedbackVector> vector =
i::TypeFeedbackVector::New(isolate, &feedback_spec);
i::NewTypeFeedbackVector(isolate, &feedback_spec);
Handle<i::String> name = factory->NewStringFromAsciiChecked("val");
name = factory->string_table()->LookupString(isolate, name);
......@@ -809,7 +810,7 @@ TEST(InterpreterCall) {
i::FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
Handle<i::TypeFeedbackVector> vector =
i::TypeFeedbackVector::New(isolate, &feedback_spec);
i::NewTypeFeedbackVector(isolate, &feedback_spec);
int slot_index = vector->GetIndex(slot);
Handle<i::String> name = factory->NewStringFromAsciiChecked("func");
......
......@@ -31,7 +31,7 @@ TEST(VectorStructure) {
// Empty vectors are the empty fixed array.
StaticFeedbackVectorSpec empty;
Handle<TypeFeedbackVector> vector = TypeFeedbackVector::New(isolate, &empty);
Handle<TypeFeedbackVector> vector = NewTypeFeedbackVector(isolate, &empty);
CHECK(Handle<FixedArray>::cast(vector)
.is_identical_to(factory->empty_fixed_array()));
// Which can nonetheless be queried.
......@@ -42,7 +42,7 @@ TEST(VectorStructure) {
{
FeedbackVectorSpec one_slot(zone);
one_slot.AddGeneralSlot();
vector = TypeFeedbackVector::New(isolate, &one_slot);
vector = NewTypeFeedbackVector(isolate, &one_slot);
FeedbackVectorHelper helper(vector);
CHECK_EQ(1, helper.slot_count());
}
......@@ -50,7 +50,7 @@ TEST(VectorStructure) {
{
FeedbackVectorSpec one_icslot(zone);
one_icslot.AddCallICSlot();
vector = TypeFeedbackVector::New(isolate, &one_icslot);
vector = NewTypeFeedbackVector(isolate, &one_icslot);
FeedbackVectorHelper helper(vector);
CHECK_EQ(1, helper.slot_count());
}
......@@ -63,32 +63,28 @@ TEST(VectorStructure) {
for (int i = 0; i < 5; i++) {
spec.AddCallICSlot();
}
vector = TypeFeedbackVector::New(isolate, &spec);
vector = NewTypeFeedbackVector(isolate, &spec);
FeedbackVectorHelper helper(vector);
CHECK_EQ(8, helper.slot_count());
int metadata_length = vector->ic_metadata_length();
CHECK(metadata_length > 0);
int index = vector->GetIndex(helper.slot(0));
CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length, index);
CHECK(helper.slot(0) == vector->ToSlot(index));
CHECK_EQ(TypeFeedbackVector::kReservedIndexCount, index);
CHECK_EQ(helper.slot(0), vector->ToSlot(index));
index = vector->GetIndex(helper.slot(3));
CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length + 3,
index);
CHECK(helper.slot(3) == vector->ToSlot(index));
CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + 3, index);
CHECK_EQ(helper.slot(3), vector->ToSlot(index));
index = vector->GetIndex(helper.slot(7));
CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length + 3 +
4 * TypeFeedbackVector::GetSlotSize(
CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + 3 +
4 * TypeFeedbackMetadata::GetSlotSize(
FeedbackVectorSlotKind::CALL_IC),
index);
CHECK(helper.slot(7) == vector->ToSlot(index));
CHECK_EQ(helper.slot(7), vector->ToSlot(index));
CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length + 3 +
5 * TypeFeedbackVector::GetSlotSize(
CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + 3 +
5 * TypeFeedbackMetadata::GetSlotSize(
FeedbackVectorSlotKind::CALL_IC),
vector->length());
}
......@@ -121,7 +117,7 @@ TEST(VectorICMetadata) {
}
}
Handle<TypeFeedbackVector> vector = TypeFeedbackVector::New(isolate, &spec);
Handle<TypeFeedbackVector> vector = NewTypeFeedbackVector(isolate, &spec);
FeedbackVectorHelper helper(vector);
CHECK_EQ(40, helper.slot_count());
......@@ -166,7 +162,7 @@ TEST(VectorSlotClearing) {
for (int i = 0; i < 5; i++) {
spec.AddGeneralSlot();
}
Handle<TypeFeedbackVector> vector = TypeFeedbackVector::New(isolate, &spec);
Handle<TypeFeedbackVector> vector = NewTypeFeedbackVector(isolate, &spec);
FeedbackVectorHelper helper(vector);
// Fill with information
......
......@@ -17,9 +17,9 @@ class FeedbackVectorHelper {
public:
explicit FeedbackVectorHelper(Handle<TypeFeedbackVector> vector)
: vector_(vector) {
int slot_count = vector->Slots();
int slot_count = vector->slot_count();
slots_.reserve(slot_count);
TypeFeedbackMetadataIterator iter(vector);
TypeFeedbackMetadataIterator iter(vector->metadata());
while (iter.HasNext()) {
FeedbackVectorSlot slot = iter.Next();
slots_.push_back(slot);
......@@ -39,6 +39,14 @@ class FeedbackVectorHelper {
std::vector<FeedbackVectorSlot> slots_;
};
template <typename Spec>
Handle<TypeFeedbackVector> NewTypeFeedbackVector(Isolate* isolate, Spec* spec) {
Handle<TypeFeedbackMetadata> metadata =
TypeFeedbackMetadata::New(isolate, spec);
return TypeFeedbackVector::New(isolate, metadata);
}
} // namespace internal
} // namespace v8
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment