| Index: src/type-feedback-vector.h
|
| diff --git a/src/type-feedback-vector.h b/src/type-feedback-vector.h
|
| index de5a7e151266ed2ad32cea574b6b315c022f0211..888fe971bddbeb06e93e82ff8b4feee609616ac9 100644
|
| --- a/src/type-feedback-vector.h
|
| +++ b/src/type-feedback-vector.h
|
| @@ -5,6 +5,8 @@
|
| #ifndef V8_TYPE_FEEDBACK_VECTOR_H_
|
| #define V8_TYPE_FEEDBACK_VECTOR_H_
|
|
|
| +#include <vector>
|
| +
|
| #include "src/checks.h"
|
| #include "src/elements-kind.h"
|
| #include "src/heap/heap.h"
|
| @@ -14,6 +16,40 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| +class FeedbackVectorSpec {
|
| + public:
|
| + FeedbackVectorSpec() : slots_(0), ic_slots_(0) {}
|
| + FeedbackVectorSpec(int slots, int ic_slots)
|
| + : slots_(slots), ic_slots_(ic_slots) {
|
| + if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots);
|
| + }
|
| +
|
| + int slots() const { return slots_; }
|
| + void increase_slots(int count) { slots_ += count; }
|
| +
|
| + int ic_slots() const { return ic_slots_; }
|
| + void increase_ic_slots(int count) {
|
| + ic_slots_ += count;
|
| + if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots_);
|
| + }
|
| +
|
| + void SetKind(int ic_slot, Code::Kind kind) {
|
| + DCHECK(FLAG_vector_ics);
|
| + ic_slot_kinds_[ic_slot] = kind;
|
| + }
|
| +
|
| + Code::Kind GetKind(int ic_slot) const {
|
| + DCHECK(FLAG_vector_ics);
|
| + return static_cast<Code::Kind>(ic_slot_kinds_.at(ic_slot));
|
| + }
|
| +
|
| + private:
|
| + int slots_;
|
| + int ic_slots_;
|
| + std::vector<unsigned char> ic_slot_kinds_;
|
| +};
|
| +
|
| +
|
| // The shape of the TypeFeedbackVector is an array with:
|
| // 0: first_ic_slot_index (== length() if no ic slots are present)
|
| // 1: ics_with_types
|
| @@ -118,17 +154,11 @@ class TypeFeedbackVector : public FixedArray {
|
| set(GetIndex(slot), value, mode);
|
| }
|
|
|
| - // IC slots need metadata to recognize the type of IC. Set a Kind for every
|
| - // slot. If GetKind() returns Code::NUMBER_OF_KINDS, then there is
|
| - // no kind associated with this slot. This may happen in the current design
|
| - // if a decision is made at compile time not to emit an IC that was planned
|
| - // for at parse time. This can be eliminated if we encode kind at parse
|
| - // time.
|
| + // IC slots need metadata to recognize the type of IC.
|
| Code::Kind GetKind(FeedbackVectorICSlot slot) const;
|
| - void SetKind(FeedbackVectorICSlot slot, Code::Kind kind);
|
|
|
| - static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, int slot_count,
|
| - int ic_slot_count);
|
| + static Handle<TypeFeedbackVector> Allocate(Isolate* isolate,
|
| + const FeedbackVectorSpec& spec);
|
|
|
| static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
|
| Handle<TypeFeedbackVector> vector);
|
| @@ -168,6 +198,8 @@ class TypeFeedbackVector : public FixedArray {
|
| static const int kVectorICKindBits = 2;
|
| static VectorICKind FromCodeKind(Code::Kind kind);
|
| static Code::Kind FromVectorICKind(VectorICKind kind);
|
| + void SetKind(FeedbackVectorICSlot slot, Code::Kind kind);
|
| +
|
| typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize,
|
| uint32_t> VectorICComputer;
|
|
|
| @@ -202,6 +234,9 @@ class FeedbackNexus {
|
| return NULL;
|
| }
|
|
|
| + // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review.
|
| + void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); }
|
| +
|
| virtual InlineCacheState StateFromFeedback() const = 0;
|
| virtual int ExtractMaps(MapHandleList* maps) const = 0;
|
| virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const = 0;
|
| @@ -250,6 +285,8 @@ class CallICNexus : public FeedbackNexus {
|
| DCHECK(vector->GetKind(slot) == Code::CALL_IC);
|
| }
|
|
|
| + void Clear(Code* host);
|
| +
|
| void ConfigureUninitialized();
|
| void ConfigureGeneric();
|
| void ConfigureMonomorphicArray();
|
| @@ -269,6 +306,65 @@ class CallICNexus : public FeedbackNexus {
|
| return length == 0;
|
| }
|
| };
|
| +
|
| +
|
| +class LoadICNexus : public FeedbackNexus {
|
| + public:
|
| + LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
|
| + : FeedbackNexus(vector, slot) {
|
| + DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
|
| + }
|
| + LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
|
| + : FeedbackNexus(vector, slot) {
|
| + DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
|
| + }
|
| +
|
| + void Clear(Code* host);
|
| +
|
| + void ConfigureMegamorphic();
|
| + void ConfigurePremonomorphic();
|
| + void ConfigureMonomorphic(Handle<HeapType> type, Handle<Code> handler);
|
| +
|
| + void ConfigurePolymorphic(TypeHandleList* types, CodeHandleList* handlers);
|
| +
|
| + virtual InlineCacheState StateFromFeedback() const OVERRIDE;
|
| + virtual int ExtractMaps(MapHandleList* maps) const OVERRIDE;
|
| + virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE;
|
| + virtual bool FindHandlers(CodeHandleList* code_list,
|
| + int length = -1) const OVERRIDE;
|
| +};
|
| +
|
| +
|
| +class KeyedLoadICNexus : public FeedbackNexus {
|
| + public:
|
| + KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
|
| + : FeedbackNexus(vector, slot) {
|
| + DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
|
| + }
|
| + KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
|
| + : FeedbackNexus(vector, slot) {
|
| + DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
|
| + }
|
| +
|
| + void Clear(Code* host);
|
| +
|
| + void ConfigureMegamorphic();
|
| + void ConfigureGeneric();
|
| + void ConfigurePremonomorphic();
|
| + // name can be a null handle for element loads.
|
| + void ConfigureMonomorphic(Handle<Name> name, Handle<HeapType> type,
|
| + Handle<Code> handler);
|
| + // name can be null.
|
| + void ConfigurePolymorphic(Handle<Name> name, TypeHandleList* types,
|
| + CodeHandleList* handlers);
|
| +
|
| + virtual InlineCacheState StateFromFeedback() const OVERRIDE;
|
| + virtual int ExtractMaps(MapHandleList* maps) const OVERRIDE;
|
| + virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE;
|
| + virtual bool FindHandlers(CodeHandleList* code_list,
|
| + int length = -1) const OVERRIDE;
|
| + virtual Name* FindFirstName() const OVERRIDE;
|
| +};
|
| }
|
| } // namespace v8::internal
|
|
|
|
|