Chromium Code Reviews| Index: src/code-stubs.h |
| diff --git a/src/code-stubs.h b/src/code-stubs.h |
| index 646aee23eb2b87c4ae6ba26c901dd84fdb773cf2..e075efc9cbb8af0bee199a6f770255cb14ebbc34 100644 |
| --- a/src/code-stubs.h |
| +++ b/src/code-stubs.h |
| @@ -1047,41 +1047,59 @@ class ICCompareStub: public PlatformCodeStub { |
| class CompareNilICStub : public HydrogenCodeStub { |
| public: |
| - enum Types { |
| - kCompareAgainstNull = 1 << 0, |
| - kCompareAgainstUndefined = 1 << 1, |
| - kCompareAgainstMonomorphicMap = 1 << 2, |
| - kCompareAgainstUndetectable = 1 << 3, |
| - kFullCompare = kCompareAgainstNull | kCompareAgainstUndefined | |
| - kCompareAgainstUndetectable |
| + enum Type { |
| + UNDEFINED, |
| + NULL_TYPE, |
| + MONOMORPHIC_MAP, |
| + UNDETECTABLE, |
| + NUMBER_OF_TYPES |
| }; |
| - CompareNilICStub(EqualityKind kind, NilValue nil, Types types) |
| - : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS), bit_field_(0) { |
| - bit_field_ = EqualityKindField::encode(kind) | |
| - NilValueField::encode(nil) | |
| - TypesField::encode(types); |
| - } |
| + class Types : public EnumSet<Type, byte> { |
| + public: |
| + Types() : EnumSet<Type, byte>(0) { } |
| + explicit Types(byte bits) : EnumSet<Type, byte>(bits) { } |
| + |
| + static const Types FullCompare() { |
|
Sven Panne
2013/05/14 09:18:42
No need for "const" here, we have an implicit copy
|
| + Types set; |
| + set.Add(UNDEFINED); |
| + set.Add(NULL_TYPE); |
| + set.Add(UNDETECTABLE); |
| + return set; |
| + } |
| - virtual InlineCacheState GetICState() { |
| - Types types = GetTypes(); |
| - if (types == kFullCompare) { |
| - return MEGAMORPHIC; |
| - } else if ((types & kCompareAgainstMonomorphicMap) != 0) { |
| - return MONOMORPHIC; |
| - } else { |
| - return PREMONOMORPHIC; |
| + bool IsFullCompare() const { |
|
Sven Panne
2013/05/14 09:18:42
No need for this function, we have FullCompare() a
|
| + return this->ToByte() == FullCompare().ToByte(); |
| } |
| - } |
| - virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } |
| + void SetTo(Type type); |
|
Sven Panne
2013/05/14 09:18:42
We don't need this, pretending that Types is immut
|
| + byte ToByte() const { return ToIntegral(); } |
|
Sven Panne
2013/05/14 09:18:42
Remove this, just use ToIntegral().
|
| - Handle<Code> GenerateCode(); |
| + void Print(StringStream* stream) const; |
| + }; |
| + |
| + // At most 6 different types can be distinguished, because the Code object |
| + // only has room for a single byte to hold a set and there are two more |
| + // boolean flags we need to store. :-P |
| + STATIC_ASSERT(NUMBER_OF_TYPES <= 6); |
| + |
| + CompareNilICStub(EqualityKind kind, NilValue nil, Types types) |
| + : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS), types_(types) { |
| + equality_kind_ = kind; |
| + nil_value_ = nil; |
| + } |
| + |
| + explicit CompareNilICStub(Code::ExtraICState ic_state) |
| + : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS) { |
| + equality_kind_ = EqualityKindField::decode(ic_state); |
| + nil_value_ = NilValueField::decode(ic_state); |
| + types_ = Types(ExtractTypesFromExtraICState(ic_state)); |
| + } |
| static Handle<Code> GetUninitialized(Isolate* isolate, |
| EqualityKind kind, |
| NilValue nil) { |
| - return CompareNilICStub(kind, nil).GetCode(isolate); |
| + return CompareNilICStub(kind, nil, CODE_STUB_IS_MISS).GetCode(isolate); |
| } |
| virtual void InitializeInterfaceDescriptor( |
| @@ -1089,53 +1107,76 @@ class CompareNilICStub : public HydrogenCodeStub { |
| CodeStubInterfaceDescriptor* descriptor); |
| static void InitializeForIsolate(Isolate* isolate) { |
| - CompareNilICStub compare_stub(kStrictEquality, kNullValue); |
| + CompareNilICStub compare_stub(kStrictEquality, kNullValue, |
| + CODE_STUB_IS_MISS); |
| compare_stub.InitializeInterfaceDescriptor( |
| isolate, |
| isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); |
| } |
| - virtual Code::ExtraICState GetExtraICState() { |
| - return bit_field_; |
| + virtual InlineCacheState GetICState() { |
| + if (types_.IsFullCompare()) { |
| + return MEGAMORPHIC; |
| + } else if (types_.Contains(MONOMORPHIC_MAP)) { |
| + return MONOMORPHIC; |
| + } else { |
| + return PREMONOMORPHIC; |
| + } |
| } |
| - EqualityKind GetKind() { return EqualityKindField::decode(bit_field_); } |
| - NilValue GetNilValue() { return NilValueField::decode(bit_field_); } |
| - Types GetTypes() { return TypesField::decode(bit_field_); } |
| + virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } |
| - static Types TypesFromExtraICState( |
| - Code::ExtraICState state) { |
| - return TypesField::decode(state); |
| + Handle<Code> GenerateCode(); |
| + |
| + // extra ic state = nil_value | equality_kind | type_n-1 | ... | type_0 |
| + virtual Code::ExtraICState GetExtraICState() { |
| + return NilValueField::encode(nil_value_) | |
| + EqualityKindField::encode(equality_kind_) | |
| + types_.ToByte(); |
| } |
| - static EqualityKind EqualityKindFromExtraICState( |
| + static byte ExtractTypesFromExtraICState( |
| Code::ExtraICState state) { |
| - return EqualityKindField::decode(state); |
| - } |
| - static NilValue NilValueFromExtraICState(Code::ExtraICState state) { |
| - return NilValueField::decode(state); |
| + return state & ((1<<NUMBER_OF_TYPES)-1); |
| } |
| - static Types GetPatchedICFlags(Code::ExtraICState extra_ic_state, |
| - Handle<Object> object, |
| - bool* already_monomorphic); |
| + void Record(Handle<Object> object); |
| + |
| + bool IsMonomorphic() const { return types_.Contains(MONOMORPHIC_MAP); } |
| + EqualityKind GetKind() const { return equality_kind_; } |
| + NilValue GetNilValue() const { return nil_value_; } |
| + const Types GetTypes() const { return types_; } |
|
Sven Panne
2013/05/14 09:18:42
The first 'const' doesn't really make sense: It do
|
| + void ClearTypes() { types_.RemoveAll(); } |
| + void SetKind(EqualityKind kind) { equality_kind_ = kind; } |
| + |
| + virtual void PrintName(StringStream* stream); |
| private: |
| friend class CompareNilIC; |
| - class EqualityKindField : public BitField<EqualityKind, 0, 1> {}; |
| - class NilValueField : public BitField<NilValue, 1, 1> {}; |
| - class TypesField : public BitField<Types, 3, 4> {}; |
| + CompareNilICStub(EqualityKind kind, NilValue nil, |
| + InitializationState init_state) |
| + : HydrogenCodeStub(init_state), types_(0) { |
| + equality_kind_ = kind; |
| + nil_value_ = nil; |
| + } |
| - CompareNilICStub(EqualityKind kind, NilValue nil) |
| - : HydrogenCodeStub(CODE_STUB_IS_MISS), bit_field_(0) { |
| - bit_field_ = EqualityKindField::encode(kind) | |
| - NilValueField::encode(nil); |
| + CompareNilICStub(Code::ExtraICState ic_state, InitializationState init_state) |
| + : HydrogenCodeStub(init_state) { |
| + equality_kind_ = EqualityKindField::decode(ic_state); |
| + nil_value_ = NilValueField::decode(ic_state); |
| + types_ = Types(ExtractTypesFromExtraICState(ic_state)); |
| } |
| + class EqualityKindField : public BitField<EqualityKind, NUMBER_OF_TYPES, 1> { |
| + }; |
| + class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES+1, 1> {}; |
| + |
| virtual CodeStub::Major MajorKey() { return CompareNilIC; } |
| - virtual int NotMissMinorKey() { return bit_field_; } |
| + virtual int NotMissMinorKey() { return GetExtraICState(); } |
| - int bit_field_; |
| + EqualityKind equality_kind_; |
| + NilValue nil_value_; |
| + Types types_; |
| DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); |
| }; |
| @@ -1795,26 +1836,17 @@ class ToBooleanStub: public PlatformCodeStub { |
| // only has room for a single byte to hold a set of these types. :-P |
| STATIC_ASSERT(NUMBER_OF_TYPES <= 8); |
| - class Types { |
| + class Types : public EnumSet<Type, byte> { |
| public: |
| Types() {} |
| - explicit Types(byte bits) : set_(bits) {} |
| + explicit Types(byte bits) : EnumSet<Type, byte>(bits) {} |
| - bool IsEmpty() const { return set_.IsEmpty(); } |
| - bool Contains(Type type) const { return set_.Contains(type); } |
| - bool ContainsAnyOf(Types types) const { |
| - return set_.ContainsAnyOf(types.set_); |
| - } |
| - void Add(Type type) { set_.Add(type); } |
| - byte ToByte() const { return set_.ToIntegral(); } |
| + byte ToByte() const { return ToIntegral(); } |
|
Sven Panne
2013/05/14 09:18:42
Just using ToIntegral() is easier here, too. (I kn
oliv
2013/05/14 13:28:11
This is still called from platform dependant code,
|
| void Print(StringStream* stream) const; |
| void TraceTransition(Types to) const; |
| bool Record(Handle<Object> object); |
| bool NeedsMap() const; |
| bool CanBeUndetectable() const; |
| - |
| - private: |
| - EnumSet<Type, byte> set_; |
| }; |
| static Types no_types() { return Types(); } |