blob: 1982fbe08b3d9a9dd5c30828dd4ae4167e9d85ef [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
10namespace v8 {
11namespace internal {
12
13
14const int kMaxKeyedPolymorphism = 4;
15
16
17class ICUtility : public AllStatic {
18 public:
19 // Clear the inline cache to initial state.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020 static void Clear(Isolate* isolate, Address address, Address constant_pool);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021};
22
23
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024class CallICState final BASE_EMBEDDED {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026 explicit CallICState(ExtraICState extra_ic_state)
27 : bit_field_(extra_ic_state) {}
28 CallICState(int argc, ConvertReceiverMode convert_mode)
29 : bit_field_(ArgcBits::encode(argc) |
30 ConvertModeBits::encode(convert_mode)) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032 ExtraICState GetExtraICState() const { return bit_field_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033
34 static void GenerateAheadOfTime(Isolate*,
35 void (*Generate)(Isolate*,
36 const CallICState&));
37
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 int argc() const { return ArgcBits::decode(bit_field_); }
39 ConvertReceiverMode convert_mode() const {
40 return ConvertModeBits::decode(bit_field_);
41 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042
43 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 typedef BitField<int, 0, Code::kArgumentsBits> ArgcBits;
45 typedef BitField<ConvertReceiverMode, Code::kArgumentsBits, 2>
46 ConvertModeBits;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048 int const bit_field_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000049};
50
51
Emily Bernierd0a1eb72015-03-24 16:35:39 -040052std::ostream& operator<<(std::ostream& os, const CallICState& s);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053
54
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000055class BinaryOpICState final BASE_EMBEDDED {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000056 public:
57 BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058 BinaryOpICState(Isolate* isolate, Token::Value op, Strength strength)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 : op_(op),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060 strong_(is_strong(strength)),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 left_kind_(NONE),
62 right_kind_(NONE),
63 result_kind_(NONE),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 fixed_right_arg_(Nothing<int>()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065 isolate_(isolate) {
66 DCHECK_LE(FIRST_TOKEN, op);
67 DCHECK_LE(op, LAST_TOKEN);
68 }
69
70 InlineCacheState GetICState() const {
71 if (Max(left_kind_, right_kind_) == NONE) {
72 return ::v8::internal::UNINITIALIZED;
73 }
74 if (Max(left_kind_, right_kind_) == GENERIC) {
75 return ::v8::internal::MEGAMORPHIC;
76 }
77 if (Min(left_kind_, right_kind_) == GENERIC) {
78 return ::v8::internal::GENERIC;
79 }
80 return ::v8::internal::MONOMORPHIC;
81 }
82
83 ExtraICState GetExtraICState() const;
84
85 static void GenerateAheadOfTime(Isolate*,
86 void (*Generate)(Isolate*,
87 const BinaryOpICState&));
88
Ben Murdochb8a8cc12014-11-26 15:28:44 +000089 // Returns true if the IC _could_ create allocation mementos.
90 bool CouldCreateAllocationMementos() const {
91 if (left_kind_ == STRING || right_kind_ == STRING) {
92 DCHECK_EQ(Token::ADD, op_);
93 return true;
94 }
95 return false;
96 }
97
98 // Returns true if the IC _should_ create allocation mementos.
99 bool ShouldCreateAllocationMementos() const {
100 return FLAG_allocation_site_pretenuring && CouldCreateAllocationMementos();
101 }
102
103 bool HasSideEffects() const {
104 return Max(left_kind_, right_kind_) == GENERIC;
105 }
106
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 Strength strength() const {
108 return strong_ ? Strength::STRONG : Strength::WEAK;
109 }
110
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 // Returns true if the IC should enable the inline smi code (i.e. if either
112 // parameter may be a smi).
113 bool UseInlinedSmiCode() const {
114 return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
115 }
116
117 static const int FIRST_TOKEN = Token::BIT_OR;
118 static const int LAST_TOKEN = Token::MOD;
119
120 Token::Value op() const { return op_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
122
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 Type* GetLeftType() const { return KindToType(left_kind_); }
124 Type* GetRightType() const { return KindToType(right_kind_); }
125 Type* GetResultType() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126
127 void Update(Handle<Object> left, Handle<Object> right, Handle<Object> result);
128
129 Isolate* isolate() const { return isolate_; }
130
131 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400132 friend std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000133
134 enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
135
136 Kind UpdateKind(Handle<Object> object, Kind kind) const;
137
138 static const char* KindToString(Kind kind);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000139 static Type* KindToType(Kind kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140 static bool KindMaybeSmi(Kind kind) {
141 return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
142 }
143
144 // We truncate the last bit of the token.
145 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
146 class OpField : public BitField<int, 0, 4> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147 class ResultKindField : public BitField<Kind, 4, 3> {};
148 class LeftKindField : public BitField<Kind, 7, 3> {};
149 class StrengthField : public BitField<bool, 10, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150 // When fixed right arg is set, we don't need to store the right kind.
151 // Thus the two fields can overlap.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152 class HasFixedRightArgField : public BitField<bool, 11, 1> {};
153 class FixedRightArgValueField : public BitField<int, 12, 4> {};
154 class RightKindField : public BitField<Kind, 12, 3> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000155
156 Token::Value op_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000157 bool strong_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158 Kind left_kind_;
159 Kind right_kind_;
160 Kind result_kind_;
161 Maybe<int> fixed_right_arg_;
162 Isolate* isolate_;
163};
164
165
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400166std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000167
168
169class CompareICState {
170 public:
171 // The type/state lattice is defined by the following inequations:
172 // UNINITIALIZED < ...
173 // ... < GENERIC
174 // SMI < NUMBER
175 // INTERNALIZED_STRING < STRING
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 // INTERNALIZED_STRING < UNIQUE_NAME
177 // KNOWN_RECEIVER < RECEIVER
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178 enum State {
179 UNINITIALIZED,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000180 BOOLEAN,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000181 SMI,
182 NUMBER,
183 STRING,
184 INTERNALIZED_STRING,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000185 UNIQUE_NAME, // Symbol or InternalizedString
186 RECEIVER, // JSReceiver
187 KNOWN_RECEIVER, // JSReceiver with specific map (faster check)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000188 GENERIC
189 };
190
191 static Type* StateToType(Zone* zone, State state,
192 Handle<Map> map = Handle<Map>());
193
194 static State NewInputState(State old_state, Handle<Object> value);
195
196 static const char* GetStateName(CompareICState::State state);
197
198 static State TargetState(State old_state, State old_left, State old_right,
199 Token::Value op, bool has_inlined_smi_code,
200 Handle<Object> x, Handle<Object> y);
201};
202
203
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000204class LoadICState final BASE_EMBEDDED {
205 private:
206 class TypeofModeBits : public BitField<TypeofMode, 0, 1> {};
207 class LanguageModeBits
208 : public BitField<LanguageMode, TypeofModeBits::kNext, 2> {};
209 STATIC_ASSERT(static_cast<int>(INSIDE_TYPEOF) == 0);
210 const ExtraICState state_;
211
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000212 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000213 static const uint32_t kNextBitFieldOffset = LanguageModeBits::kNext;
214
215 static const ExtraICState kStrongModeState = STRONG
216 << LanguageModeBits::kShift;
217
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218 explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
219
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000220 explicit LoadICState(TypeofMode typeof_mode, LanguageMode language_mode)
221 : state_(TypeofModeBits::encode(typeof_mode) |
222 LanguageModeBits::encode(language_mode)) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223
224 ExtraICState GetExtraICState() const { return state_; }
225
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000226 TypeofMode typeof_mode() const { return TypeofModeBits::decode(state_); }
227
228 LanguageMode language_mode() const {
229 return LanguageModeBits::decode(state_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000230 }
231
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000232 static TypeofMode GetTypeofMode(ExtraICState state) {
233 return LoadICState(state).typeof_mode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234 }
235
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000236 static LanguageMode GetLanguageMode(ExtraICState state) {
237 return LoadICState(state).language_mode();
238 }
239};
240
241
242class StoreICState final BASE_EMBEDDED {
243 public:
244 explicit StoreICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
245
246 explicit StoreICState(LanguageMode mode)
247 : state_(LanguageModeState::encode(mode)) {}
248
249 ExtraICState GetExtraICState() const { return state_; }
250
251 LanguageMode language_mode() const {
252 return LanguageModeState::decode(state_);
253 }
254
255 static LanguageMode GetLanguageMode(ExtraICState state) {
256 return StoreICState(state).language_mode();
257 }
258
259 class LanguageModeState : public BitField<LanguageMode, 1, 2> {};
260 STATIC_ASSERT(i::LANGUAGE_END == 3);
261
262 // For convenience, a statically declared encoding of strict mode extra
263 // IC state.
264 static const ExtraICState kStrictModeState = STRICT
265 << LanguageModeState::kShift;
266
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000267 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000268 const ExtraICState state_;
269};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270
271} // namespace internal
272} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000273
274#endif // V8_IC_STATE_H_