OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/ic/ic.h" | 7 #include "src/ic/ic.h" |
8 #include "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 30 matching lines...) Expand all Loading... |
41 | 41 |
42 | 42 |
43 // static | 43 // static |
44 STATIC_CONST_MEMBER_DEFINITION const int BinaryOpICState::LAST_TOKEN; | 44 STATIC_CONST_MEMBER_DEFINITION const int BinaryOpICState::LAST_TOKEN; |
45 | 45 |
46 | 46 |
47 BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state) | 47 BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state) |
48 : isolate_(isolate) { | 48 : isolate_(isolate) { |
49 op_ = | 49 op_ = |
50 static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state)); | 50 static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state)); |
51 mode_ = OverwriteModeField::decode(extra_ic_state); | |
52 fixed_right_arg_ = | 51 fixed_right_arg_ = |
53 Maybe<int>(HasFixedRightArgField::decode(extra_ic_state), | 52 Maybe<int>(HasFixedRightArgField::decode(extra_ic_state), |
54 1 << FixedRightArgValueField::decode(extra_ic_state)); | 53 1 << FixedRightArgValueField::decode(extra_ic_state)); |
55 left_kind_ = LeftKindField::decode(extra_ic_state); | 54 left_kind_ = LeftKindField::decode(extra_ic_state); |
56 if (fixed_right_arg_.has_value) { | 55 if (fixed_right_arg_.has_value) { |
57 right_kind_ = Smi::IsValid(fixed_right_arg_.value) ? SMI : INT32; | 56 right_kind_ = Smi::IsValid(fixed_right_arg_.value) ? SMI : INT32; |
58 } else { | 57 } else { |
59 right_kind_ = RightKindField::decode(extra_ic_state); | 58 right_kind_ = RightKindField::decode(extra_ic_state); |
60 } | 59 } |
61 result_kind_ = ResultKindField::decode(extra_ic_state); | 60 result_kind_ = ResultKindField::decode(extra_ic_state); |
62 DCHECK_LE(FIRST_TOKEN, op_); | 61 DCHECK_LE(FIRST_TOKEN, op_); |
63 DCHECK_LE(op_, LAST_TOKEN); | 62 DCHECK_LE(op_, LAST_TOKEN); |
64 } | 63 } |
65 | 64 |
66 | 65 |
67 ExtraICState BinaryOpICState::GetExtraICState() const { | 66 ExtraICState BinaryOpICState::GetExtraICState() const { |
68 ExtraICState extra_ic_state = | 67 ExtraICState extra_ic_state = |
69 OpField::encode(op_ - FIRST_TOKEN) | OverwriteModeField::encode(mode_) | | 68 OpField::encode(op_ - FIRST_TOKEN) | LeftKindField::encode(left_kind_) | |
70 LeftKindField::encode(left_kind_) | | |
71 ResultKindField::encode(result_kind_) | | 69 ResultKindField::encode(result_kind_) | |
72 HasFixedRightArgField::encode(fixed_right_arg_.has_value); | 70 HasFixedRightArgField::encode(fixed_right_arg_.has_value); |
73 if (fixed_right_arg_.has_value) { | 71 if (fixed_right_arg_.has_value) { |
74 extra_ic_state = FixedRightArgValueField::update( | 72 extra_ic_state = FixedRightArgValueField::update( |
75 extra_ic_state, WhichPowerOf2(fixed_right_arg_.value)); | 73 extra_ic_state, WhichPowerOf2(fixed_right_arg_.value)); |
76 } else { | 74 } else { |
77 extra_ic_state = RightKindField::update(extra_ic_state, right_kind_); | 75 extra_ic_state = RightKindField::update(extra_ic_state, right_kind_); |
78 } | 76 } |
79 return extra_ic_state; | 77 return extra_ic_state; |
80 } | 78 } |
81 | 79 |
82 | 80 |
83 // static | 81 // static |
84 void BinaryOpICState::GenerateAheadOfTime( | 82 void BinaryOpICState::GenerateAheadOfTime( |
85 Isolate* isolate, void (*Generate)(Isolate*, const BinaryOpICState&)) { | 83 Isolate* isolate, void (*Generate)(Isolate*, const BinaryOpICState&)) { |
86 // TODO(olivf) We should investigate why adding stubs to the snapshot is so | 84 // TODO(olivf) We should investigate why adding stubs to the snapshot is so |
87 // expensive at runtime. When solved we should be able to add most binops to | 85 // expensive at runtime. When solved we should be able to add most binops to |
88 // the snapshot instead of hand-picking them. | 86 // the snapshot instead of hand-picking them. |
89 // Generated list of commonly used stubs | 87 // Generated list of commonly used stubs |
90 #define GENERATE(op, left_kind, right_kind, result_kind, mode) \ | 88 #define GENERATE(op, left_kind, right_kind, result_kind) \ |
91 do { \ | 89 do { \ |
92 BinaryOpICState state(isolate, op, mode); \ | 90 BinaryOpICState state(isolate, op); \ |
93 state.left_kind_ = left_kind; \ | 91 state.left_kind_ = left_kind; \ |
94 state.fixed_right_arg_.has_value = false; \ | 92 state.fixed_right_arg_.has_value = false; \ |
95 state.right_kind_ = right_kind; \ | 93 state.right_kind_ = right_kind; \ |
96 state.result_kind_ = result_kind; \ | 94 state.result_kind_ = result_kind; \ |
97 Generate(isolate, state); \ | 95 Generate(isolate, state); \ |
98 } while (false) | 96 } while (false) |
99 GENERATE(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE); | 97 GENERATE(Token::ADD, INT32, INT32, INT32); |
100 GENERATE(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT); | 98 GENERATE(Token::ADD, INT32, INT32, NUMBER); |
101 GENERATE(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE); | 99 GENERATE(Token::ADD, INT32, NUMBER, NUMBER); |
102 GENERATE(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT); | 100 GENERATE(Token::ADD, INT32, SMI, INT32); |
103 GENERATE(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE); | 101 GENERATE(Token::ADD, NUMBER, INT32, NUMBER); |
104 GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT); | 102 GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER); |
105 GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT); | 103 GENERATE(Token::ADD, NUMBER, SMI, NUMBER); |
106 GENERATE(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE); | 104 GENERATE(Token::ADD, SMI, INT32, INT32); |
107 GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT); | 105 GENERATE(Token::ADD, SMI, INT32, NUMBER); |
108 GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT); | 106 GENERATE(Token::ADD, SMI, NUMBER, NUMBER); |
109 GENERATE(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE); | 107 GENERATE(Token::ADD, SMI, SMI, INT32); |
110 GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT); | 108 GENERATE(Token::ADD, SMI, SMI, SMI); |
111 GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT); | 109 GENERATE(Token::BIT_AND, INT32, INT32, INT32); |
112 GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE); | 110 GENERATE(Token::BIT_AND, INT32, INT32, SMI); |
113 GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT); | 111 GENERATE(Token::BIT_AND, INT32, SMI, INT32); |
114 GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT); | 112 GENERATE(Token::BIT_AND, INT32, SMI, SMI); |
115 GENERATE(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE); | 113 GENERATE(Token::BIT_AND, NUMBER, INT32, INT32); |
116 GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); | 114 GENERATE(Token::BIT_AND, NUMBER, SMI, SMI); |
117 GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT); | 115 GENERATE(Token::BIT_AND, SMI, INT32, INT32); |
118 GENERATE(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE); | 116 GENERATE(Token::BIT_AND, SMI, INT32, SMI); |
119 GENERATE(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT); | 117 GENERATE(Token::BIT_AND, SMI, NUMBER, SMI); |
120 GENERATE(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE); | 118 GENERATE(Token::BIT_AND, SMI, SMI, SMI); |
121 GENERATE(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE); | 119 GENERATE(Token::BIT_OR, INT32, INT32, INT32); |
122 GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT); | 120 GENERATE(Token::BIT_OR, INT32, INT32, SMI); |
123 GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT); | 121 GENERATE(Token::BIT_OR, INT32, SMI, INT32); |
124 GENERATE(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT); | 122 GENERATE(Token::BIT_OR, INT32, SMI, SMI); |
125 GENERATE(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT); | 123 GENERATE(Token::BIT_OR, NUMBER, SMI, INT32); |
126 GENERATE(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE); | 124 GENERATE(Token::BIT_OR, NUMBER, SMI, SMI); |
127 GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT); | 125 GENERATE(Token::BIT_OR, SMI, INT32, INT32); |
128 GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT); | 126 GENERATE(Token::BIT_OR, SMI, INT32, SMI); |
129 GENERATE(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE); | 127 GENERATE(Token::BIT_OR, SMI, SMI, SMI); |
130 GENERATE(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT); | 128 GENERATE(Token::BIT_XOR, INT32, INT32, INT32); |
131 GENERATE(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE); | 129 GENERATE(Token::BIT_XOR, INT32, INT32, SMI); |
132 GENERATE(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT); | 130 GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI); |
133 GENERATE(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE); | 131 GENERATE(Token::BIT_XOR, INT32, SMI, INT32); |
134 GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT); | 132 GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32); |
135 GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT); | 133 GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32); |
136 GENERATE(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT); | 134 GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI); |
137 GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE); | 135 GENERATE(Token::BIT_XOR, SMI, INT32, INT32); |
138 GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT); | 136 GENERATE(Token::BIT_XOR, SMI, INT32, SMI); |
139 GENERATE(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE); | 137 GENERATE(Token::BIT_XOR, SMI, SMI, SMI); |
140 GENERATE(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT); | 138 GENERATE(Token::DIV, INT32, INT32, INT32); |
141 GENERATE(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT); | 139 GENERATE(Token::DIV, INT32, INT32, NUMBER); |
142 GENERATE(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE); | 140 GENERATE(Token::DIV, INT32, NUMBER, NUMBER); |
143 GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT); | 141 GENERATE(Token::DIV, INT32, SMI, INT32); |
144 GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT); | 142 GENERATE(Token::DIV, INT32, SMI, NUMBER); |
145 GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT); | 143 GENERATE(Token::DIV, NUMBER, INT32, NUMBER); |
146 GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT); | 144 GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER); |
147 GENERATE(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT); | 145 GENERATE(Token::DIV, NUMBER, SMI, NUMBER); |
148 GENERATE(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE); | 146 GENERATE(Token::DIV, SMI, INT32, INT32); |
149 GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT); | 147 GENERATE(Token::DIV, SMI, INT32, NUMBER); |
150 GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT); | 148 GENERATE(Token::DIV, SMI, NUMBER, NUMBER); |
151 GENERATE(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE); | 149 GENERATE(Token::DIV, SMI, SMI, NUMBER); |
152 GENERATE(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT); | 150 GENERATE(Token::DIV, SMI, SMI, SMI); |
153 GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE); | 151 GENERATE(Token::MOD, NUMBER, SMI, NUMBER); |
154 GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT); | 152 GENERATE(Token::MOD, SMI, SMI, SMI); |
155 GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT); | 153 GENERATE(Token::MUL, INT32, INT32, INT32); |
156 GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE); | 154 GENERATE(Token::MUL, INT32, INT32, NUMBER); |
157 GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT); | 155 GENERATE(Token::MUL, INT32, NUMBER, NUMBER); |
158 GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT); | 156 GENERATE(Token::MUL, INT32, SMI, INT32); |
159 GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT); | 157 GENERATE(Token::MUL, INT32, SMI, NUMBER); |
160 GENERATE(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT); | 158 GENERATE(Token::MUL, NUMBER, INT32, NUMBER); |
161 GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT); | 159 GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER); |
162 GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT); | 160 GENERATE(Token::MUL, NUMBER, SMI, NUMBER); |
163 GENERATE(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE); | 161 GENERATE(Token::MUL, SMI, INT32, INT32); |
164 GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT); | 162 GENERATE(Token::MUL, SMI, INT32, NUMBER); |
165 GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT); | 163 GENERATE(Token::MUL, SMI, NUMBER, NUMBER); |
166 GENERATE(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE); | 164 GENERATE(Token::MUL, SMI, SMI, INT32); |
167 GENERATE(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT); | 165 GENERATE(Token::MUL, SMI, SMI, NUMBER); |
168 GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE); | 166 GENERATE(Token::MUL, SMI, SMI, SMI); |
169 GENERATE(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE); | 167 GENERATE(Token::SAR, INT32, SMI, INT32); |
170 GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT); | 168 GENERATE(Token::SAR, INT32, SMI, SMI); |
171 GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT); | 169 GENERATE(Token::SAR, NUMBER, SMI, SMI); |
172 GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE); | 170 GENERATE(Token::SAR, SMI, SMI, SMI); |
173 GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE); | 171 GENERATE(Token::SHL, INT32, SMI, INT32); |
174 GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE); | 172 GENERATE(Token::SHL, INT32, SMI, SMI); |
175 GENERATE(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE); | 173 GENERATE(Token::SHL, NUMBER, SMI, SMI); |
176 GENERATE(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT); | 174 GENERATE(Token::SHL, SMI, SMI, INT32); |
177 GENERATE(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT); | 175 GENERATE(Token::SHL, SMI, SMI, SMI); |
178 GENERATE(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE); | 176 GENERATE(Token::SHR, INT32, SMI, SMI); |
179 GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT); | 177 GENERATE(Token::SHR, NUMBER, SMI, INT32); |
180 GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT); | 178 GENERATE(Token::SHR, NUMBER, SMI, SMI); |
181 GENERATE(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE); | 179 GENERATE(Token::SHR, SMI, SMI, SMI); |
182 GENERATE(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE); | 180 GENERATE(Token::SUB, INT32, INT32, INT32); |
183 GENERATE(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE); | 181 GENERATE(Token::SUB, INT32, NUMBER, NUMBER); |
184 GENERATE(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT); | 182 GENERATE(Token::SUB, INT32, SMI, INT32); |
185 GENERATE(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE); | 183 GENERATE(Token::SUB, NUMBER, INT32, NUMBER); |
186 GENERATE(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE); | 184 GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER); |
187 GENERATE(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE); | 185 GENERATE(Token::SUB, NUMBER, SMI, NUMBER); |
188 GENERATE(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT); | 186 GENERATE(Token::SUB, SMI, INT32, INT32); |
189 GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE); | 187 GENERATE(Token::SUB, SMI, NUMBER, NUMBER); |
190 GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT); | 188 GENERATE(Token::SUB, SMI, SMI, SMI); |
191 GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT); | |
192 GENERATE(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE); | |
193 GENERATE(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); | |
194 GENERATE(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE); | |
195 GENERATE(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE); | |
196 GENERATE(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT); | |
197 GENERATE(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE); | |
198 GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT); | |
199 GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT); | |
200 GENERATE(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE); | |
201 GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT); | |
202 GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT); | |
203 GENERATE(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE); | |
204 GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT); | |
205 GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT); | |
206 GENERATE(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); | |
207 GENERATE(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE); | |
208 GENERATE(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT); | |
209 GENERATE(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE); | |
210 GENERATE(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE); | |
211 GENERATE(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE); | |
212 GENERATE(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT); | |
213 GENERATE(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE); | |
214 GENERATE(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT); | |
215 GENERATE(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE); | |
216 GENERATE(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE); | |
217 GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT); | |
218 GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT); | |
219 GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE); | |
220 GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT); | |
221 GENERATE(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE); | |
222 GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); | |
223 GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT); | |
224 GENERATE(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE); | |
225 GENERATE(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT); | |
226 GENERATE(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE); | |
227 GENERATE(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE); | |
228 GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT); | |
229 GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT); | |
230 GENERATE(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE); | |
231 GENERATE(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE); | |
232 GENERATE(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT); | |
233 GENERATE(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE); | |
234 GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT); | |
235 GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT); | |
236 GENERATE(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT); | |
237 GENERATE(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE); | |
238 GENERATE(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT); | |
239 GENERATE(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE); | |
240 GENERATE(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT); | |
241 GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT); | |
242 GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT); | |
243 GENERATE(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE); | |
244 GENERATE(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT); | |
245 GENERATE(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE); | |
246 GENERATE(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT); | |
247 GENERATE(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT); | |
248 GENERATE(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE); | |
249 GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT); | |
250 GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT); | |
251 GENERATE(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE); | |
252 GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT); | |
253 GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT); | |
254 GENERATE(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE); | |
255 GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT); | |
256 GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT); | |
257 GENERATE(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE); | |
258 GENERATE(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT); | |
259 GENERATE(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT); | |
260 GENERATE(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE); | |
261 GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT); | |
262 GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT); | |
263 GENERATE(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE); | |
264 GENERATE(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT); | |
265 GENERATE(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE); | |
266 GENERATE(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT); | |
267 GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT); | |
268 GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT); | |
269 GENERATE(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE); | |
270 GENERATE(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT); | |
271 GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE); | |
272 GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT); | |
273 GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT); | |
274 GENERATE(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE); | |
275 GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); | |
276 GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT); | |
277 GENERATE(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE); | |
278 GENERATE(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE); | |
279 GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT); | |
280 GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT); | |
281 GENERATE(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE); | |
282 GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT); | |
283 GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT); | |
284 #undef GENERATE | 189 #undef GENERATE |
285 #define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \ | 190 #define GENERATE(op, left_kind, fixed_right_arg_value, result_kind) \ |
286 do { \ | 191 do { \ |
287 BinaryOpICState state(isolate, op, mode); \ | 192 BinaryOpICState state(isolate, op); \ |
288 state.left_kind_ = left_kind; \ | 193 state.left_kind_ = left_kind; \ |
289 state.fixed_right_arg_.has_value = true; \ | 194 state.fixed_right_arg_.has_value = true; \ |
290 state.fixed_right_arg_.value = fixed_right_arg_value; \ | 195 state.fixed_right_arg_.value = fixed_right_arg_value; \ |
291 state.right_kind_ = SMI; \ | 196 state.right_kind_ = SMI; \ |
292 state.result_kind_ = result_kind; \ | 197 state.result_kind_ = result_kind; \ |
293 Generate(isolate, state); \ | 198 Generate(isolate, state); \ |
294 } while (false) | 199 } while (false) |
295 GENERATE(Token::MOD, SMI, 2, SMI, NO_OVERWRITE); | 200 GENERATE(Token::MOD, SMI, 2, SMI); |
296 GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE); | 201 GENERATE(Token::MOD, SMI, 4, SMI); |
297 GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT); | 202 GENERATE(Token::MOD, SMI, 8, SMI); |
298 GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE); | 203 GENERATE(Token::MOD, SMI, 16, SMI); |
299 GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT); | 204 GENERATE(Token::MOD, SMI, 32, SMI); |
300 GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE); | 205 GENERATE(Token::MOD, SMI, 2048, SMI); |
301 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); | |
302 #undef GENERATE | 206 #undef GENERATE |
303 } | 207 } |
304 | 208 |
305 | 209 |
306 Type* BinaryOpICState::GetResultType(Zone* zone) const { | 210 Type* BinaryOpICState::GetResultType(Zone* zone) const { |
307 Kind result_kind = result_kind_; | 211 Kind result_kind = result_kind_; |
308 if (HasSideEffects()) { | 212 if (HasSideEffects()) { |
309 result_kind = NONE; | 213 result_kind = NONE; |
310 } else if (result_kind == GENERIC && op_ == Token::ADD) { | 214 } else if (result_kind == GENERIC && op_ == Token::ADD) { |
311 return Type::Union(Type::Number(zone), Type::String(zone), zone); | 215 return Type::Union(Type::Number(zone), Type::String(zone), zone); |
312 } else if (result_kind == NUMBER && op_ == Token::SHR) { | 216 } else if (result_kind == NUMBER && op_ == Token::SHR) { |
313 return Type::Unsigned32(zone); | 217 return Type::Unsigned32(zone); |
314 } | 218 } |
315 DCHECK_NE(GENERIC, result_kind); | 219 DCHECK_NE(GENERIC, result_kind); |
316 return KindToType(result_kind, zone); | 220 return KindToType(result_kind, zone); |
317 } | 221 } |
318 | 222 |
319 | 223 |
320 std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s) { | 224 std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s) { |
321 os << "(" << Token::Name(s.op_); | 225 os << "(" << Token::Name(s.op_); |
322 if (s.mode_ == OVERWRITE_LEFT) | |
323 os << "_ReuseLeft"; | |
324 else if (s.mode_ == OVERWRITE_RIGHT) | |
325 os << "_ReuseRight"; | |
326 if (s.CouldCreateAllocationMementos()) os << "_CreateAllocationMementos"; | 226 if (s.CouldCreateAllocationMementos()) os << "_CreateAllocationMementos"; |
327 os << ":" << BinaryOpICState::KindToString(s.left_kind_) << "*"; | 227 os << ":" << BinaryOpICState::KindToString(s.left_kind_) << "*"; |
328 if (s.fixed_right_arg_.has_value) { | 228 if (s.fixed_right_arg_.has_value) { |
329 os << s.fixed_right_arg_.value; | 229 os << s.fixed_right_arg_.value; |
330 } else { | 230 } else { |
331 os << BinaryOpICState::KindToString(s.right_kind_); | 231 os << BinaryOpICState::KindToString(s.right_kind_); |
332 } | 232 } |
333 return os << "->" << BinaryOpICState::KindToString(s.result_kind_) << ")"; | 233 return os << "->" << BinaryOpICState::KindToString(s.result_kind_) << ")"; |
334 } | 234 } |
335 | 235 |
(...skipping 29 matching lines...) Expand all Loading... |
365 if (left_kind_ == STRING && right_kind_ == INT32) { | 265 if (left_kind_ == STRING && right_kind_ == INT32) { |
366 DCHECK_EQ(STRING, result_kind_); | 266 DCHECK_EQ(STRING, result_kind_); |
367 DCHECK_EQ(Token::ADD, op_); | 267 DCHECK_EQ(Token::ADD, op_); |
368 right_kind_ = NUMBER; | 268 right_kind_ = NUMBER; |
369 } else if (right_kind_ == STRING && left_kind_ == INT32) { | 269 } else if (right_kind_ == STRING && left_kind_ == INT32) { |
370 DCHECK_EQ(STRING, result_kind_); | 270 DCHECK_EQ(STRING, result_kind_); |
371 DCHECK_EQ(Token::ADD, op_); | 271 DCHECK_EQ(Token::ADD, op_); |
372 left_kind_ = NUMBER; | 272 left_kind_ = NUMBER; |
373 } | 273 } |
374 | 274 |
375 // Reset overwrite mode unless we can actually make use of it, or may be able | |
376 // to make use of it at some point in the future. | |
377 if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) || | |
378 (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) || | |
379 result_kind_ > NUMBER) { | |
380 mode_ = NO_OVERWRITE; | |
381 } | |
382 | |
383 if (old_extra_ic_state == GetExtraICState()) { | 275 if (old_extra_ic_state == GetExtraICState()) { |
384 // Tagged operations can lead to non-truncating HChanges | 276 // Tagged operations can lead to non-truncating HChanges |
385 if (left->IsUndefined() || left->IsBoolean()) { | 277 if (left->IsUndefined() || left->IsBoolean()) { |
386 left_kind_ = GENERIC; | 278 left_kind_ = GENERIC; |
387 } else { | 279 } else { |
388 DCHECK(right->IsUndefined() || right->IsBoolean()); | 280 DCHECK(right->IsUndefined() || right->IsBoolean()); |
389 right_kind_ = GENERIC; | 281 right_kind_ = GENERIC; |
390 } | 282 } |
391 } | 283 } |
392 } | 284 } |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 case UNIQUE_NAME: | 506 case UNIQUE_NAME: |
615 case OBJECT: | 507 case OBJECT: |
616 case GENERIC: | 508 case GENERIC: |
617 return GENERIC; | 509 return GENERIC; |
618 } | 510 } |
619 UNREACHABLE(); | 511 UNREACHABLE(); |
620 return GENERIC; // Make the compiler happy. | 512 return GENERIC; // Make the compiler happy. |
621 } | 513 } |
622 } | 514 } |
623 } // namespace v8::internal | 515 } // namespace v8::internal |
OLD | NEW |