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.
8 #include "src/macro-assembler.h"
14 const int kMaxKeyedPolymorphism = 4;
17 class ICUtility : public AllStatic {
19 // Clear the inline cache to initial state.
20 static void Clear(Isolate* isolate, Address address, Address constant_pool);
24 class CallICState final BASE_EMBEDDED {
26 explicit CallICState(ExtraICState extra_ic_state);
28 enum CallType { METHOD, FUNCTION };
30 CallICState(int argc, CallType call_type)
31 : argc_(argc), call_type_(call_type) {}
33 ExtraICState GetExtraICState() const;
35 static void GenerateAheadOfTime(Isolate*,
36 void (*Generate)(Isolate*,
39 int arg_count() const { return argc_; }
40 CallType call_type() const { return call_type_; }
42 bool CallAsMethod() const { return call_type_ == METHOD; }
45 class ArgcBits : public BitField<int, 0, Code::kArgumentsBits> {};
46 class CallTypeBits : public BitField<CallType, Code::kArgumentsBits, 1> {};
49 const CallType call_type_;
53 std::ostream& operator<<(std::ostream& os, const CallICState& s);
56 class BinaryOpICState final BASE_EMBEDDED {
58 BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
59 BinaryOpICState(Isolate* isolate, Token::Value op, Strength strength)
61 strong_(is_strong(strength)),
65 fixed_right_arg_(Nothing<int>()),
67 DCHECK_LE(FIRST_TOKEN, op);
68 DCHECK_LE(op, LAST_TOKEN);
71 InlineCacheState GetICState() const {
72 if (Max(left_kind_, right_kind_) == NONE) {
73 return ::v8::internal::UNINITIALIZED;
75 if (Max(left_kind_, right_kind_) == GENERIC) {
76 return ::v8::internal::MEGAMORPHIC;
78 if (Min(left_kind_, right_kind_) == GENERIC) {
79 return ::v8::internal::GENERIC;
81 return ::v8::internal::MONOMORPHIC;
84 ExtraICState GetExtraICState() const;
86 static void GenerateAheadOfTime(Isolate*,
87 void (*Generate)(Isolate*,
88 const BinaryOpICState&));
90 // Returns true if the IC _could_ create allocation mementos.
91 bool CouldCreateAllocationMementos() const {
92 if (left_kind_ == STRING || right_kind_ == STRING) {
93 DCHECK_EQ(Token::ADD, op_);
99 // Returns true if the IC _should_ create allocation mementos.
100 bool ShouldCreateAllocationMementos() const {
101 return FLAG_allocation_site_pretenuring && CouldCreateAllocationMementos();
104 bool HasSideEffects() const {
105 return Max(left_kind_, right_kind_) == GENERIC;
108 Strength strength() const {
109 return strong_ ? Strength::STRONG : Strength::WEAK;
112 // Returns true if the IC should enable the inline smi code (i.e. if either
113 // parameter may be a smi).
114 bool UseInlinedSmiCode() const {
115 return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
118 static const int FIRST_TOKEN = Token::BIT_OR;
119 static const int LAST_TOKEN = Token::MOD;
121 Token::Value op() const { return op_; }
122 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
124 Type* GetLeftType(Zone* zone) const { return KindToType(left_kind_, zone); }
125 Type* GetRightType(Zone* zone) const { return KindToType(right_kind_, zone); }
126 Type* GetResultType(Zone* zone) const;
128 void Update(Handle<Object> left, Handle<Object> right, Handle<Object> result);
130 Isolate* isolate() const { return isolate_; }
133 friend std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
135 enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
137 Kind UpdateKind(Handle<Object> object, Kind kind) const;
139 static const char* KindToString(Kind kind);
140 static Type* KindToType(Kind kind, Zone* zone);
141 static bool KindMaybeSmi(Kind kind) {
142 return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
145 // We truncate the last bit of the token.
146 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
147 class OpField : public BitField<int, 0, 4> {};
148 class ResultKindField : public BitField<Kind, 4, 3> {};
149 class LeftKindField : public BitField<Kind, 7, 3> {};
150 class StrengthField : public BitField<bool, 10, 1> {};
151 // When fixed right arg is set, we don't need to store the right kind.
152 // Thus the two fields can overlap.
153 class HasFixedRightArgField : public BitField<bool, 11, 1> {};
154 class FixedRightArgValueField : public BitField<int, 12, 4> {};
155 class RightKindField : public BitField<Kind, 12, 3> {};
162 Maybe<int> fixed_right_arg_;
167 std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
170 class CompareICState {
172 // The type/state lattice is defined by the following inequations:
173 // UNINITIALIZED < ...
176 // INTERNALIZED_STRING < STRING
177 // INTERNALIZED_STRING < UNIQUE_NAME
178 // KNOWN_OBJECT < OBJECT
186 UNIQUE_NAME, // Symbol or InternalizedString
188 KNOWN_OBJECT, // JSObject with specific map (faster check)
192 static Type* StateToType(Zone* zone, State state,
193 Handle<Map> map = Handle<Map>());
195 static State NewInputState(State old_state, Handle<Object> value);
197 static const char* GetStateName(CompareICState::State state);
199 static State TargetState(State old_state, State old_left, State old_right,
200 Token::Value op, bool has_inlined_smi_code,
201 Handle<Object> x, Handle<Object> y);
205 class LoadICState final BASE_EMBEDDED {
207 class TypeofModeBits : public BitField<TypeofMode, 0, 1> {};
208 class LanguageModeBits
209 : public BitField<LanguageMode, TypeofModeBits::kNext, 2> {};
210 STATIC_ASSERT(static_cast<int>(INSIDE_TYPEOF) == 0);
211 const ExtraICState state_;
214 static const uint32_t kNextBitFieldOffset = LanguageModeBits::kNext;
216 static const ExtraICState kStrongModeState = STRONG
217 << LanguageModeBits::kShift;
219 explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
221 explicit LoadICState(TypeofMode typeof_mode, LanguageMode language_mode)
222 : state_(TypeofModeBits::encode(typeof_mode) |
223 LanguageModeBits::encode(language_mode)) {}
225 ExtraICState GetExtraICState() const { return state_; }
227 TypeofMode typeof_mode() const { return TypeofModeBits::decode(state_); }
229 LanguageMode language_mode() const {
230 return LanguageModeBits::decode(state_);
233 static TypeofMode GetTypeofMode(ExtraICState state) {
234 return LoadICState(state).typeof_mode();
237 static LanguageMode GetLanguageMode(ExtraICState state) {
238 return LoadICState(state).language_mode();
243 class StoreICState final BASE_EMBEDDED {
245 explicit StoreICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
247 explicit StoreICState(LanguageMode mode)
248 : state_(LanguageModeState::encode(mode)) {}
250 ExtraICState GetExtraICState() const { return state_; }
252 LanguageMode language_mode() const {
253 return LanguageModeState::decode(state_);
256 static LanguageMode GetLanguageMode(ExtraICState state) {
257 return StoreICState(state).language_mode();
260 class LanguageModeState : public BitField<LanguageMode, 1, 2> {};
261 STATIC_ASSERT(i::LANGUAGE_END == 3);
263 // For convenience, a statically declared encoding of strict mode extra
265 static const ExtraICState kStrictModeState = STRICT
266 << LanguageModeState::kShift;
269 const ExtraICState state_;
272 } // namespace internal
275 #endif // V8_IC_STATE_H_