Index: src/code-stubs.h |
diff --git a/src/code-stubs.h b/src/code-stubs.h |
index d197c841b1187027a254ca6c8637e62d4992bcc3..881218e4121719346d74575758f9cb9d1b8378a6 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,73 @@ class FastNewBlockContextStub : public PlatformCodeStub { |
}; |
+class UnaryOpStub : public HydrogenCodeStub { |
+ public: |
+ // Stub without type info available -> construct uninitialized |
+ explicit UnaryOpStub(Token::Value operation) |
+ : HydrogenCodeStub(UNINITIALIZED), operation_(operation) { } |
+ explicit UnaryOpStub(Code::ExtraICState ic_state) : |
+ state_(StateBits::decode(ic_state)), |
+ operation_(OperatorBits::decode(ic_state)) { } |
+ |
+ virtual void InitializeInterfaceDescriptor( |
+ Isolate* isolate, |
+ CodeStubInterfaceDescriptor* descriptor); |
+ |
+ virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; } |
+ virtual InlineCacheState GetICState() { |
+ if (state_.Contains(GENERIC)) { |
+ return MEGAMORPHIC; |
+ } else if (state_.IsEmpty()) { |
+ return PREMONOMORPHIC; |
+ } else { |
+ return MONOMORPHIC; |
+ } |
+ } |
+ virtual Code::ExtraICState GetExtraICState() { |
+ return OperatorBits::encode(operation_) | |
+ StateBits::encode(state_.ToIntegral()); |
+ } |
+ |
+ Token::Value operation() { return operation_; } |
+ Handle<JSFunction> ToJSFunction(Isolate* isolate); |
+ Builtins::JavaScript ToJSBuiltin(); |
+ |
+ 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 UnaryOpType { |
+ SMI, |
+ HEAP_NUMBER, |
+ GENERIC, |
+ NUMBER_OF_TYPES |
+ }; |
+ |
+ class State : public EnumSet<UnaryOpType, byte> { |
+ public: |
+ State() : EnumSet<UnaryOpType, byte>() { } |
+ explicit State(byte bits) : EnumSet<UnaryOpType, byte>(bits) { } |
+ void Print(StringStream* stream) const; |
+ }; |
+ |
+ class StateBits : public BitField<int, 0, NUMBER_OF_TYPES> { }; |
+ class OperatorBits : public BitField<Token::Value, NUMBER_OF_TYPES, 8> { }; |
+ |
+ 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. |
@@ -1143,7 +1214,6 @@ class CompareNilICStub : public HydrogenCodeStub { |
} |
void Print(StringStream* stream) const; |
- void TraceTransition(State to) const; |
}; |
static Handle<Type> StateToType( |
@@ -1206,14 +1276,15 @@ class CompareNilICStub : public HydrogenCodeStub { |
return NilValueField::decode(state); |
} |
- 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; |
@@ -2009,8 +2080,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(); } |
@@ -2023,7 +2093,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(); |
@@ -2032,7 +2102,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; } |