Line data Source code
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 : #include "src/parsing/token.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 : class AstType;
15 :
16 : const int kMaxKeyedPolymorphism = 4;
17 :
18 :
19 : class ICUtility : public AllStatic {
20 : public:
21 : // Clear the inline cache to initial state.
22 : static void Clear(Isolate* isolate, Address address, Address constant_pool);
23 : };
24 :
25 :
26 : class BinaryOpICState final BASE_EMBEDDED {
27 : public:
28 : BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
29 : BinaryOpICState(Isolate* isolate, Token::Value op)
30 : : op_(op),
31 : left_kind_(NONE),
32 : right_kind_(NONE),
33 : result_kind_(NONE),
34 : fixed_right_arg_(Nothing<int>()),
35 843205 : isolate_(isolate) {
36 : DCHECK_LE(FIRST_TOKEN, op);
37 : DCHECK_LE(op, LAST_TOKEN);
38 : }
39 :
40 : InlineCacheState GetICState() const {
41 1305418 : if (Max(left_kind_, right_kind_) == NONE) {
42 : return ::v8::internal::UNINITIALIZED;
43 : }
44 466360 : if (Max(left_kind_, right_kind_) == GENERIC) {
45 : return ::v8::internal::MEGAMORPHIC;
46 : }
47 456835 : if (Min(left_kind_, right_kind_) == GENERIC) {
48 : return ::v8::internal::GENERIC;
49 : }
50 : return ::v8::internal::MONOMORPHIC;
51 : }
52 :
53 : ExtraICState GetExtraICState() const;
54 : std::string ToString() const;
55 :
56 : static void GenerateAheadOfTime(Isolate*,
57 : void (*Generate)(Isolate*,
58 : const BinaryOpICState&));
59 :
60 : // Returns true if the IC _could_ create allocation mementos.
61 : bool CouldCreateAllocationMementos() const {
62 498491 : if (left_kind_ == STRING || right_kind_ == STRING) {
63 : DCHECK_EQ(Token::ADD, op_);
64 : return true;
65 : }
66 : return false;
67 : }
68 :
69 : // Returns true if the IC _should_ create allocation mementos.
70 433347 : bool ShouldCreateAllocationMementos() const {
71 866694 : return FLAG_allocation_site_pretenuring && CouldCreateAllocationMementos();
72 : }
73 :
74 : bool HasSideEffects() const {
75 : return Max(left_kind_, right_kind_) == GENERIC;
76 : }
77 :
78 : // Returns true if the IC should enable the inline smi code (i.e. if either
79 : // parameter may be a smi).
80 : bool UseInlinedSmiCode() const {
81 1418676 : return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
82 : }
83 :
84 : static const int FIRST_TOKEN = Token::BIT_OR;
85 : static const int LAST_TOKEN = Token::MOD;
86 :
87 : Token::Value op() const { return op_; }
88 : Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
89 :
90 820516 : AstType* GetLeftType() const { return KindToType(left_kind_); }
91 774535 : AstType* GetRightType() const { return KindToType(right_kind_); }
92 : AstType* GetResultType() const;
93 :
94 : void Update(Handle<Object> left, Handle<Object> right, Handle<Object> result);
95 :
96 : Isolate* isolate() const { return isolate_; }
97 :
98 : enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
99 : Kind kind() const {
100 : return KindGeneralize(KindGeneralize(left_kind_, right_kind_),
101 : result_kind_);
102 : }
103 :
104 : private:
105 : friend std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
106 :
107 : Kind UpdateKind(Handle<Object> object, Kind kind) const;
108 :
109 : static const char* KindToString(Kind kind);
110 : static AstType* KindToType(Kind kind);
111 : static bool KindMaybeSmi(Kind kind) {
112 1365687 : return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
113 : }
114 : static bool KindLessGeneralThan(Kind kind1, Kind kind2) {
115 : if (kind1 == NONE) return true;
116 : if (kind1 == kind2) return true;
117 : if (kind2 == GENERIC) return true;
118 : if (kind2 == STRING) return false;
119 : return kind1 <= kind2;
120 : }
121 : static Kind KindGeneralize(Kind kind1, Kind kind2) {
122 : if (KindLessGeneralThan(kind1, kind2)) return kind2;
123 : if (KindLessGeneralThan(kind2, kind1)) return kind1;
124 : return GENERIC;
125 : }
126 :
127 : // We truncate the last bit of the token.
128 : STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
129 : class OpField : public BitField<int, 0, 4> {};
130 : class ResultKindField : public BitField<Kind, 4, 3> {};
131 : class LeftKindField : public BitField<Kind, 7, 3> {};
132 : // When fixed right arg is set, we don't need to store the right kind.
133 : // Thus the two fields can overlap.
134 : class HasFixedRightArgField : public BitField<bool, 10, 1> {};
135 : class FixedRightArgValueField : public BitField<int, 11, 4> {};
136 : class RightKindField : public BitField<Kind, 11, 3> {};
137 :
138 : Token::Value op_;
139 : Kind left_kind_;
140 : Kind right_kind_;
141 : Kind result_kind_;
142 : Maybe<int> fixed_right_arg_;
143 : Isolate* isolate_;
144 : };
145 :
146 :
147 : std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
148 :
149 :
150 : class CompareICState {
151 : public:
152 : // The type/state lattice is defined by the following inequations:
153 : // UNINITIALIZED < ...
154 : // ... < GENERIC
155 : // SMI < NUMBER
156 : // INTERNALIZED_STRING < STRING
157 : // INTERNALIZED_STRING < UNIQUE_NAME
158 : // KNOWN_RECEIVER < RECEIVER
159 : enum State {
160 : UNINITIALIZED,
161 : BOOLEAN,
162 : SMI,
163 : NUMBER,
164 : STRING,
165 : INTERNALIZED_STRING,
166 : UNIQUE_NAME, // Symbol or InternalizedString
167 : RECEIVER, // JSReceiver
168 : KNOWN_RECEIVER, // JSReceiver with specific map (faster check)
169 : GENERIC
170 : };
171 :
172 : static AstType* StateToType(Zone* zone, State state,
173 : Handle<Map> map = Handle<Map>());
174 :
175 : static State NewInputState(State old_state, Handle<Object> value);
176 :
177 : static const char* GetStateName(CompareICState::State state);
178 :
179 : static State TargetState(Isolate* isolate, State old_state, State old_left,
180 : State old_right, Token::Value op,
181 : bool has_inlined_smi_code, Handle<Object> x,
182 : Handle<Object> y);
183 : };
184 :
185 : } // namespace internal
186 : } // namespace v8
187 :
188 : #endif // V8_IC_STATE_H_
|