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