blob: b12b17d3e20b2eb3a04cecbc27189ceed5a1ffb3 [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) {}
Ben Murdoch097c5b22016-05-18 11:27:45 +010028 CallICState(int argc, ConvertReceiverMode convert_mode,
29 TailCallMode tail_call_mode)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000030 : bit_field_(ArgcBits::encode(argc) |
Ben Murdoch097c5b22016-05-18 11:27:45 +010031 ConvertModeBits::encode(convert_mode) |
32 TailCallModeBits::encode(tail_call_mode)) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000034 ExtraICState GetExtraICState() const { return bit_field_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035
36 static void GenerateAheadOfTime(Isolate*,
37 void (*Generate)(Isolate*,
38 const CallICState&));
39
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 int argc() const { return ArgcBits::decode(bit_field_); }
41 ConvertReceiverMode convert_mode() const {
42 return ConvertModeBits::decode(bit_field_);
43 }
Ben Murdoch097c5b22016-05-18 11:27:45 +010044 TailCallMode tail_call_mode() const {
45 return TailCallModeBits::decode(bit_field_);
46 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047
48 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049 typedef BitField<int, 0, Code::kArgumentsBits> ArgcBits;
Ben Murdoch097c5b22016-05-18 11:27:45 +010050 typedef BitField<ConvertReceiverMode, ArgcBits::kNext, 2> ConvertModeBits;
51 typedef BitField<TailCallMode, ConvertModeBits::kNext, 1> TailCallModeBits;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053 int const bit_field_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054};
55
56
Emily Bernierd0a1eb72015-03-24 16:35:39 -040057std::ostream& operator<<(std::ostream& os, const CallICState& s);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058
59
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060class BinaryOpICState final BASE_EMBEDDED {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 public:
62 BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
Ben Murdoch097c5b22016-05-18 11:27:45 +010063 BinaryOpICState(Isolate* isolate, Token::Value op)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000064 : op_(op),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065 left_kind_(NONE),
66 right_kind_(NONE),
67 result_kind_(NONE),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 fixed_right_arg_(Nothing<int>()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 isolate_(isolate) {
70 DCHECK_LE(FIRST_TOKEN, op);
71 DCHECK_LE(op, LAST_TOKEN);
72 }
73
74 InlineCacheState GetICState() const {
75 if (Max(left_kind_, right_kind_) == NONE) {
76 return ::v8::internal::UNINITIALIZED;
77 }
78 if (Max(left_kind_, right_kind_) == GENERIC) {
79 return ::v8::internal::MEGAMORPHIC;
80 }
81 if (Min(left_kind_, right_kind_) == GENERIC) {
82 return ::v8::internal::GENERIC;
83 }
84 return ::v8::internal::MONOMORPHIC;
85 }
86
87 ExtraICState GetExtraICState() const;
88
89 static void GenerateAheadOfTime(Isolate*,
90 void (*Generate)(Isolate*,
91 const BinaryOpICState&));
92
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093 // Returns true if the IC _could_ create allocation mementos.
94 bool CouldCreateAllocationMementos() const {
95 if (left_kind_ == STRING || right_kind_ == STRING) {
96 DCHECK_EQ(Token::ADD, op_);
97 return true;
98 }
99 return false;
100 }
101
102 // Returns true if the IC _should_ create allocation mementos.
103 bool ShouldCreateAllocationMementos() const {
104 return FLAG_allocation_site_pretenuring && CouldCreateAllocationMementos();
105 }
106
107 bool HasSideEffects() const {
108 return Max(left_kind_, right_kind_) == GENERIC;
109 }
110
111 // 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> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 // When fixed right arg is set, we don't need to store the right kind.
150 // Thus the two fields can overlap.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100151 class HasFixedRightArgField : public BitField<bool, 10, 1> {};
152 class FixedRightArgValueField : public BitField<int, 11, 4> {};
153 class RightKindField : public BitField<Kind, 11, 3> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000154
155 Token::Value op_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156 Kind left_kind_;
157 Kind right_kind_;
158 Kind result_kind_;
159 Maybe<int> fixed_right_arg_;
160 Isolate* isolate_;
161};
162
163
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400164std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165
166
167class CompareICState {
168 public:
169 // The type/state lattice is defined by the following inequations:
170 // UNINITIALIZED < ...
171 // ... < GENERIC
172 // SMI < NUMBER
173 // INTERNALIZED_STRING < STRING
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000174 // INTERNALIZED_STRING < UNIQUE_NAME
175 // KNOWN_RECEIVER < RECEIVER
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176 enum State {
177 UNINITIALIZED,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000178 BOOLEAN,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179 SMI,
180 NUMBER,
181 STRING,
182 INTERNALIZED_STRING,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 UNIQUE_NAME, // Symbol or InternalizedString
184 RECEIVER, // JSReceiver
185 KNOWN_RECEIVER, // JSReceiver with specific map (faster check)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186 GENERIC
187 };
188
189 static Type* StateToType(Zone* zone, State state,
190 Handle<Map> map = Handle<Map>());
191
192 static State NewInputState(State old_state, Handle<Object> value);
193
194 static const char* GetStateName(CompareICState::State state);
195
Ben Murdoch61f157c2016-09-16 13:49:30 +0100196 static State TargetState(Isolate* isolate, State old_state, State old_left,
197 State old_right, Token::Value op,
198 bool has_inlined_smi_code, Handle<Object> x,
199 Handle<Object> y);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000200};
201
Ben Murdoch61f157c2016-09-16 13:49:30 +0100202class LoadGlobalICState final BASE_EMBEDDED {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203 private:
204 class TypeofModeBits : public BitField<TypeofMode, 0, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000205 STATIC_ASSERT(static_cast<int>(INSIDE_TYPEOF) == 0);
206 const ExtraICState state_;
207
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100209 static const uint32_t kNextBitFieldOffset = TypeofModeBits::kNext;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210
Ben Murdoch61f157c2016-09-16 13:49:30 +0100211 explicit LoadGlobalICState(ExtraICState extra_ic_state)
212 : state_(extra_ic_state) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213
Ben Murdoch61f157c2016-09-16 13:49:30 +0100214 explicit LoadGlobalICState(TypeofMode typeof_mode)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100215 : state_(TypeofModeBits::encode(typeof_mode)) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000216
217 ExtraICState GetExtraICState() const { return state_; }
218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 TypeofMode typeof_mode() const { return TypeofModeBits::decode(state_); }
220
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221 static TypeofMode GetTypeofMode(ExtraICState state) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100222 return LoadGlobalICState(state).typeof_mode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224};
225
226
227class StoreICState final BASE_EMBEDDED {
228 public:
229 explicit StoreICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
230
231 explicit StoreICState(LanguageMode mode)
232 : state_(LanguageModeState::encode(mode)) {}
233
234 ExtraICState GetExtraICState() const { return state_; }
235
236 LanguageMode language_mode() const {
237 return LanguageModeState::decode(state_);
238 }
239
240 static LanguageMode GetLanguageMode(ExtraICState state) {
241 return StoreICState(state).language_mode();
242 }
243
244 class LanguageModeState : public BitField<LanguageMode, 1, 2> {};
245 STATIC_ASSERT(i::LANGUAGE_END == 3);
246
247 // For convenience, a statically declared encoding of strict mode extra
248 // IC state.
249 static const ExtraICState kStrictModeState = STRICT
250 << LanguageModeState::kShift;
251
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000252 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000253 const ExtraICState state_;
254};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000255
256} // namespace internal
257} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000258
259#endif // V8_IC_STATE_H_