Chromium Code Reviews| Index: src/code-stubs.h |
| diff --git a/src/code-stubs.h b/src/code-stubs.h |
| index c4f0c4d38a25658b34e9e73bb46472f6f46c3221..265aa179b7cd3443b7795b15941921fe7af935c2 100644 |
| --- a/src/code-stubs.h |
| +++ b/src/code-stubs.h |
| @@ -123,8 +123,6 @@ namespace internal { |
| // Mode to overwrite BinaryExpression values. |
| enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; |
| -enum UnaryOverwriteMode { UNARY_OVERWRITE, UNARY_NO_OVERWRITE }; |
| - |
| // Stub is base classes of all stubs. |
| class CodeStub BASE_EMBEDDED { |
| @@ -197,6 +195,8 @@ class CodeStub BASE_EMBEDDED { |
| return -1; |
| } |
| + virtual void PrintName(StringStream* stream); |
| + |
| protected: |
| static bool CanUseFPRegisters(); |
| @@ -208,6 +208,11 @@ class CodeStub BASE_EMBEDDED { |
| // a fixed (non-moveable) code object. |
| virtual bool NeedsImmovableCode() { return false; } |
| + // Returns a name for logging/debugging purposes. |
| + SmartArrayPointer<const char> GetName(); |
| + virtual void PrintBaseName(StringStream* stream); |
| + virtual void PrintState(StringStream* stream) { } |
| + |
| private: |
| // Perform bookkeeping required after code generation when stub code is |
| // initially generated. |
| @@ -236,10 +241,6 @@ class CodeStub BASE_EMBEDDED { |
| // If a stub uses a special cache override this. |
| virtual bool UseSpecialCache() { return false; } |
| - // Returns a name for logging/debugging purposes. |
| - SmartArrayPointer<const char> GetName(); |
| - virtual void PrintName(StringStream* stream); |
| - |
| // Computes the key based on major and minor. |
| uint32_t GetKey() { |
| ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); |
| @@ -354,6 +355,9 @@ class HydrogenCodeStub : public CodeStub { |
| Handle<Code> GenerateLightweightMissCode(Isolate* isolate); |
| + template<class StateType> |
| + void TraceTransition(StateType from, StateType to); |
| + |
| private: |
| class MinorKeyBits: public BitField<int, 0, kStubMinorKeyBits - 1> {}; |
| class IsMissBits: public BitField<bool, kStubMinorKeyBits - 1, 1> {}; |
| @@ -520,6 +524,90 @@ class FastNewBlockContextStub : public PlatformCodeStub { |
| }; |
| +class UnaryOpStub : public HydrogenCodeStub { |
| + public: |
| + enum UnaryOpType { |
| + SMI, |
| + HEAP_NUMBER, |
| + GENERIC, |
| + NUMBER_OF_TYPES |
| + }; |
| + |
| + // At most 7 different Types can be distinguished, because the Code object |
| + // only has room for a single byte to hold and we need to store the operator. |
| + STATIC_ASSERT(NUMBER_OF_TYPES <= 7); |
| + |
| + class State : public EnumSet<UnaryOpType, byte> { |
| + public: |
| + State() : EnumSet<UnaryOpType, byte>(0) { } |
| + explicit State(byte bits) : EnumSet<UnaryOpType, byte>(bits) { } |
| + bool IsGeneric() const { return Contains(GENERIC); } |
| + |
| + void Print(StringStream* stream) const; |
| + }; |
| + |
| + // Stub without type info available -> construct uninitialized |
| + explicit UnaryOpStub(Token::Value operation) |
| + : HydrogenCodeStub(UNINITIALIZED), operation_(operation) { } |
| + explicit UnaryOpStub(Code::ExtraICState ic_state) : |
| + state_(State(ic_state & ((1 << NUMBER_OF_TYPES) - 1))) { |
| + operation_ = OperatorBits::decode(ic_state) == UNARY_NOT ? |
| + Token::BIT_NOT : Token::SUB; |
| + } |
| + |
| + virtual void InitializeInterfaceDescriptor( |
| + Isolate* isolate, |
| + CodeStubInterfaceDescriptor* descriptor); |
| + |
| + virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; } |
| + virtual InlineCacheState GetICState() { |
| + if (state_.IsGeneric()) { |
| + return MEGAMORPHIC; |
| + } else if (state_.IsEmpty()) { |
| + return PREMONOMORPHIC; |
| + } else { |
| + return MONOMORPHIC; |
| + } |
| + } |
| + virtual Code::ExtraICState GetExtraICState() { |
| + return OperatorBits::encode((operation_ == Token::BIT_NOT) ? |
| + UNARY_NOT : UNARY_MINUS) | |
| + state_.ToIntegral(); |
| + } |
| + |
| + Token::Value operation() { return operation_; } |
| + Handle<JSFunction> ToJSFunction(Isolate* isolate); |
| + |
| + void UpdateStatus(Handle<Object> object); |
| + MaybeObject* Result(Handle<Object> object, Isolate* isolate); |
| + Handle<Code> GenerateCode(); |
| + Handle<Type> GetType(Isolate* isolate); |
| + |
| + protected: |
| + void PrintState(StringStream* stream); |
| + void PrintBaseName(StringStream* stream); |
| + |
| + private: |
| + enum SupportedOperations { |
| + UNARY_MINUS, |
| + UNARY_NOT, |
| + NUMBER_OF_OPERATIONS |
| + }; |
| + // There is only one bit reserved for the operation |
| + STATIC_ASSERT(NUMBER_OF_OPERATIONS == 2); |
| + |
| + Builtins::JavaScript ToJSBuiltin(); |
| + |
| + class OperatorBits : public BitField<byte, NUMBER_OF_TYPES, 1> {}; |
|
danno
2013/06/27 13:31:06
This isn't right. The NUMBER_OF_TYPES doesn't dire
oliv
2013/06/27 17:20:48
I think the code is correct. The encoding of the s
|
| + |
| + State state_; |
| + Token::Value operation_; |
| + |
| + virtual CodeStub::Major MajorKey() { return UnaryOp; } |
| + virtual int NotMissMinorKey() { return GetExtraICState(); } |
| +}; |
| + |
| + |
| class FastCloneShallowArrayStub : public HydrogenCodeStub { |
| public: |
| // Maximum length of copied elements array. |
| @@ -1148,7 +1236,6 @@ class CompareNilICStub : public HydrogenCodeStub { |
| } |
| void Print(StringStream* stream) const; |
| - void TraceTransition(State to) const; |
| }; |
| static Handle<Type> StateToType( |
| @@ -1208,14 +1295,15 @@ class CompareNilICStub : public HydrogenCodeStub { |
| return state & ((1 << NUMBER_OF_TYPES) - 1); |
| } |
| - void Record(Handle<Object> object); |
| + void UpdateStatus(Handle<Object> object); |
| bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); } |
| NilValue GetNilValue() const { return nil_value_; } |
| State GetState() const { return state_; } |
| void ClearState() { state_.RemoveAll(); } |
| - virtual void PrintName(StringStream* stream); |
| + virtual void PrintState(StringStream* stream); |
| + virtual void PrintBaseName(StringStream* stream); |
| private: |
| friend class CompareNilIC; |
| @@ -1978,8 +2066,7 @@ class ToBooleanStub: public HydrogenCodeStub { |
| byte ToByte() const { return ToIntegral(); } |
| void Print(StringStream* stream) const; |
| - void TraceTransition(Types to) const; |
| - bool Record(Handle<Object> object); |
| + bool UpdateStatus(Handle<Object> object); |
| bool NeedsMap() const; |
| bool CanBeUndetectable() const; |
| bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); } |
| @@ -1992,7 +2079,7 @@ class ToBooleanStub: public HydrogenCodeStub { |
| explicit ToBooleanStub(Code::ExtraICState state) |
| : types_(static_cast<byte>(state)) { } |
| - bool Record(Handle<Object> object); |
| + bool UpdateStatus(Handle<Object> object); |
| Types GetTypes() { return types_; } |
| virtual Handle<Code> GenerateCode(); |
| @@ -2001,7 +2088,7 @@ class ToBooleanStub: public HydrogenCodeStub { |
| CodeStubInterfaceDescriptor* descriptor); |
| virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; } |
| - virtual void PrintName(StringStream* stream); |
| + virtual void PrintState(StringStream* stream); |
| virtual bool SometimesSetsUpAFrame() { return false; } |