deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / ic / ic-state.h
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_IC_STATE_H_
6 #define V8_IC_STATE_H_
7
8 #include "src/macro-assembler.h"
9
10 namespace v8 {
11 namespace internal {
12
13
14 const int kMaxKeyedPolymorphism = 4;
15
16
17 class ICUtility : public AllStatic {
18  public:
19   // Clear the inline cache to initial state.
20   static void Clear(Isolate* isolate, Address address,
21                     ConstantPoolArray* constant_pool);
22 };
23
24
25 class CallICState FINAL BASE_EMBEDDED {
26  public:
27   explicit CallICState(ExtraICState extra_ic_state);
28
29   enum CallType { METHOD, FUNCTION };
30
31   CallICState(int argc, CallType call_type)
32       : argc_(argc), call_type_(call_type) {}
33
34   ExtraICState GetExtraICState() const;
35
36   static void GenerateAheadOfTime(Isolate*,
37                                   void (*Generate)(Isolate*,
38                                                    const CallICState&));
39
40   int arg_count() const { return argc_; }
41   CallType call_type() const { return call_type_; }
42
43   bool CallAsMethod() const { return call_type_ == METHOD; }
44
45  private:
46   class ArgcBits : public BitField<int, 0, Code::kArgumentsBits> {};
47   class CallTypeBits : public BitField<CallType, Code::kArgumentsBits, 1> {};
48
49   const int argc_;
50   const CallType call_type_;
51 };
52
53
54 std::ostream& operator<<(std::ostream& os, const CallICState& s);
55
56
57 class BinaryOpICState FINAL BASE_EMBEDDED {
58  public:
59   BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
60
61   BinaryOpICState(Isolate* isolate, Token::Value op)
62       : op_(op),
63         left_kind_(NONE),
64         right_kind_(NONE),
65         result_kind_(NONE),
66         fixed_right_arg_(Nothing<int>()),
67         isolate_(isolate) {
68     DCHECK_LE(FIRST_TOKEN, op);
69     DCHECK_LE(op, LAST_TOKEN);
70   }
71
72   InlineCacheState GetICState() const {
73     if (Max(left_kind_, right_kind_) == NONE) {
74       return ::v8::internal::UNINITIALIZED;
75     }
76     if (Max(left_kind_, right_kind_) == GENERIC) {
77       return ::v8::internal::MEGAMORPHIC;
78     }
79     if (Min(left_kind_, right_kind_) == GENERIC) {
80       return ::v8::internal::GENERIC;
81     }
82     return ::v8::internal::MONOMORPHIC;
83   }
84
85   ExtraICState GetExtraICState() const;
86
87   static void GenerateAheadOfTime(Isolate*,
88                                   void (*Generate)(Isolate*,
89                                                    const BinaryOpICState&));
90
91   // Returns true if the IC _could_ create allocation mementos.
92   bool CouldCreateAllocationMementos() const {
93     if (left_kind_ == STRING || right_kind_ == STRING) {
94       DCHECK_EQ(Token::ADD, op_);
95       return true;
96     }
97     return false;
98   }
99
100   // Returns true if the IC _should_ create allocation mementos.
101   bool ShouldCreateAllocationMementos() const {
102     return FLAG_allocation_site_pretenuring && CouldCreateAllocationMementos();
103   }
104
105   bool HasSideEffects() const {
106     return Max(left_kind_, right_kind_) == GENERIC;
107   }
108
109   // Returns true if the IC should enable the inline smi code (i.e. if either
110   // parameter may be a smi).
111   bool UseInlinedSmiCode() const {
112     return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
113   }
114
115   static const int FIRST_TOKEN = Token::BIT_OR;
116   static const int LAST_TOKEN = Token::MOD;
117
118   Token::Value op() const { return op_; }
119   Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
120
121   Type* GetLeftType(Zone* zone) const { return KindToType(left_kind_, zone); }
122   Type* GetRightType(Zone* zone) const { return KindToType(right_kind_, zone); }
123   Type* GetResultType(Zone* zone) const;
124
125   void Update(Handle<Object> left, Handle<Object> right, Handle<Object> result);
126
127   Isolate* isolate() const { return isolate_; }
128
129  private:
130   friend std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
131
132   enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
133
134   Kind UpdateKind(Handle<Object> object, Kind kind) const;
135
136   static const char* KindToString(Kind kind);
137   static Type* KindToType(Kind kind, Zone* zone);
138   static bool KindMaybeSmi(Kind kind) {
139     return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
140   }
141
142   // We truncate the last bit of the token.
143   STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
144   class OpField : public BitField<int, 0, 4> {};
145   class ResultKindField : public BitField<Kind, 4, 3> {};
146   class LeftKindField : public BitField<Kind, 7, 3> {};
147   // When fixed right arg is set, we don't need to store the right kind.
148   // Thus the two fields can overlap.
149   class HasFixedRightArgField : public BitField<bool, 10, 1> {};
150   class FixedRightArgValueField : public BitField<int, 11, 4> {};
151   class RightKindField : public BitField<Kind, 11, 3> {};
152
153   Token::Value op_;
154   Kind left_kind_;
155   Kind right_kind_;
156   Kind result_kind_;
157   Maybe<int> fixed_right_arg_;
158   Isolate* isolate_;
159 };
160
161
162 std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
163
164
165 class CompareICState {
166  public:
167   // The type/state lattice is defined by the following inequations:
168   //   UNINITIALIZED < ...
169   //   ... < GENERIC
170   //   SMI < NUMBER
171   //   INTERNALIZED_STRING < STRING
172   //   KNOWN_OBJECT < OBJECT
173   enum State {
174     UNINITIALIZED,
175     SMI,
176     NUMBER,
177     STRING,
178     INTERNALIZED_STRING,
179     UNIQUE_NAME,   // Symbol or InternalizedString
180     OBJECT,        // JSObject
181     KNOWN_OBJECT,  // JSObject with specific map (faster check)
182     GENERIC
183   };
184
185   static Type* StateToType(Zone* zone, State state,
186                            Handle<Map> map = Handle<Map>());
187
188   static State NewInputState(State old_state, Handle<Object> value);
189
190   static const char* GetStateName(CompareICState::State state);
191
192   static State TargetState(State old_state, State old_left, State old_right,
193                            Token::Value op, bool has_inlined_smi_code,
194                            Handle<Object> x, Handle<Object> y);
195 };
196
197
198 class LoadICState FINAL BASE_EMBEDDED {
199  public:
200   explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
201
202   explicit LoadICState(ContextualMode mode)
203       : state_(ContextualModeBits::encode(mode)) {}
204
205   ExtraICState GetExtraICState() const { return state_; }
206
207   ContextualMode contextual_mode() const {
208     return ContextualModeBits::decode(state_);
209   }
210
211   static ContextualMode GetContextualMode(ExtraICState state) {
212     return LoadICState(state).contextual_mode();
213   }
214
215  private:
216   class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
217   STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
218
219   const ExtraICState state_;
220 };
221 }
222 }
223
224 #endif  // V8_IC_STATE_H_