Line data Source code
1 : // Copyright 2016 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 : #include "src/ic/binary-op-assembler.h"
6 :
7 : #include "src/globals.h"
8 :
9 : namespace v8 {
10 : namespace internal {
11 :
12 : using compiler::Node;
13 :
14 336 : Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs,
15 : Node* rhs, Node* slot_id,
16 : Node* feedback_vector,
17 : bool rhs_is_smi) {
18 : // Shared entry for floating point addition.
19 672 : Label do_fadd(this), if_lhsisnotnumber(this, Label::kDeferred),
20 336 : check_rhsisoddball(this, Label::kDeferred),
21 336 : call_with_oddball_feedback(this), call_with_any_feedback(this),
22 336 : call_add_stub(this), end(this), bigint(this, Label::kDeferred);
23 672 : VARIABLE(var_fadd_lhs, MachineRepresentation::kFloat64);
24 672 : VARIABLE(var_fadd_rhs, MachineRepresentation::kFloat64);
25 672 : VARIABLE(var_type_feedback, MachineRepresentation::kTaggedSigned);
26 672 : VARIABLE(var_result, MachineRepresentation::kTagged);
27 :
28 : // Check if the {lhs} is a Smi or a HeapObject.
29 336 : Label if_lhsissmi(this);
30 : // If rhs is known to be an Smi we want to fast path Smi operation. This is
31 : // for AddSmi operation. For the normal Add operation, we want to fast path
32 : // both Smi and Number operations, so this path should not be marked as
33 : // Deferred.
34 : Label if_lhsisnotsmi(this,
35 672 : rhs_is_smi ? Label::kDeferred : Label::kNonDeferred);
36 672 : Branch(TaggedIsNotSmi(lhs), &if_lhsisnotsmi, &if_lhsissmi);
37 :
38 336 : BIND(&if_lhsissmi);
39 : {
40 336 : Comment("lhs is Smi");
41 336 : if (!rhs_is_smi) {
42 : // Check if the {rhs} is also a Smi.
43 168 : Label if_rhsissmi(this), if_rhsisnotsmi(this);
44 336 : Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
45 :
46 168 : BIND(&if_rhsisnotsmi);
47 : {
48 : // Check if the {rhs} is a HeapNumber.
49 336 : GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball);
50 :
51 336 : var_fadd_lhs.Bind(SmiToFloat64(lhs));
52 336 : var_fadd_rhs.Bind(LoadHeapNumberValue(rhs));
53 168 : Goto(&do_fadd);
54 : }
55 :
56 168 : BIND(&if_rhsissmi);
57 : }
58 :
59 : {
60 336 : Comment("perform smi operation");
61 : // If rhs is known to be an Smi we want to fast path Smi operation. This
62 : // is for AddSmi operation. For the normal Add operation, we want to fast
63 : // path both Smi and Number operations, so this path should not be marked
64 : // as Deferred.
65 : Label if_overflow(this,
66 672 : rhs_is_smi ? Label::kDeferred : Label::kNonDeferred);
67 336 : TNode<Smi> smi_result = TrySmiAdd(CAST(lhs), CAST(rhs), &if_overflow);
68 : // Not overflowed.
69 : {
70 : var_type_feedback.Bind(
71 336 : SmiConstant(BinaryOperationFeedback::kSignedSmall));
72 336 : var_result.Bind(smi_result);
73 336 : Goto(&end);
74 : }
75 :
76 336 : BIND(&if_overflow);
77 : {
78 672 : var_fadd_lhs.Bind(SmiToFloat64(lhs));
79 672 : var_fadd_rhs.Bind(SmiToFloat64(rhs));
80 336 : Goto(&do_fadd);
81 : }
82 : }
83 : }
84 :
85 336 : BIND(&if_lhsisnotsmi);
86 : {
87 : // Check if {lhs} is a HeapNumber.
88 672 : GotoIfNot(IsHeapNumber(lhs), &if_lhsisnotnumber);
89 :
90 336 : if (!rhs_is_smi) {
91 : // Check if the {rhs} is Smi.
92 168 : Label if_rhsissmi(this), if_rhsisnotsmi(this);
93 336 : Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
94 :
95 168 : BIND(&if_rhsisnotsmi);
96 : {
97 : // Check if the {rhs} is a HeapNumber.
98 336 : GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball);
99 :
100 336 : var_fadd_lhs.Bind(LoadHeapNumberValue(lhs));
101 336 : var_fadd_rhs.Bind(LoadHeapNumberValue(rhs));
102 168 : Goto(&do_fadd);
103 : }
104 :
105 168 : BIND(&if_rhsissmi);
106 : }
107 : {
108 672 : var_fadd_lhs.Bind(LoadHeapNumberValue(lhs));
109 672 : var_fadd_rhs.Bind(SmiToFloat64(rhs));
110 336 : Goto(&do_fadd);
111 : }
112 : }
113 :
114 336 : BIND(&do_fadd);
115 : {
116 336 : var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber));
117 1344 : Node* value = Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value());
118 672 : Node* result = AllocateHeapNumberWithValue(value);
119 336 : var_result.Bind(result);
120 336 : Goto(&end);
121 : }
122 :
123 336 : BIND(&if_lhsisnotnumber);
124 : {
125 : // No checks on rhs are done yet. We just know lhs is not a number or Smi.
126 336 : Label if_lhsisoddball(this), if_lhsisnotoddball(this);
127 672 : Node* lhs_instance_type = LoadInstanceType(lhs);
128 672 : Node* lhs_is_oddball = InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE);
129 336 : Branch(lhs_is_oddball, &if_lhsisoddball, &if_lhsisnotoddball);
130 :
131 336 : BIND(&if_lhsisoddball);
132 : {
133 672 : GotoIf(TaggedIsSmi(rhs), &call_with_oddball_feedback);
134 :
135 : // Check if {rhs} is a HeapNumber.
136 672 : Branch(IsHeapNumber(rhs), &call_with_oddball_feedback,
137 336 : &check_rhsisoddball);
138 : }
139 :
140 336 : BIND(&if_lhsisnotoddball);
141 : {
142 336 : Label lhs_is_string(this), lhs_is_bigint(this);
143 672 : GotoIf(IsStringInstanceType(lhs_instance_type), &lhs_is_string);
144 672 : GotoIf(IsBigIntInstanceType(lhs_instance_type), &lhs_is_bigint);
145 336 : Goto(&call_with_any_feedback);
146 :
147 336 : BIND(&lhs_is_bigint);
148 : {
149 672 : GotoIf(TaggedIsSmi(rhs), &call_with_any_feedback);
150 672 : Branch(IsBigInt(rhs), &bigint, &call_with_any_feedback);
151 : }
152 :
153 336 : BIND(&lhs_is_string);
154 : // Check if the {rhs} is a smi, and exit the string check early if it is.
155 672 : GotoIf(TaggedIsSmi(rhs), &call_with_any_feedback);
156 :
157 672 : Node* rhs_instance_type = LoadInstanceType(rhs);
158 :
159 : // Exit unless {rhs} is a string. Since {lhs} is a string we no longer
160 : // need an Oddball check.
161 672 : GotoIfNot(IsStringInstanceType(rhs_instance_type),
162 336 : &call_with_any_feedback);
163 : var_result.Bind(
164 672 : StringAdd(context, CAST(lhs), CAST(rhs), &var_type_feedback));
165 336 : Goto(&end);
166 : }
167 : }
168 :
169 336 : BIND(&check_rhsisoddball);
170 : {
171 : // Check if rhs is an oddball. At this point we know lhs is either a
172 : // Smi or number or oddball and rhs is not a number or Smi.
173 672 : Node* rhs_instance_type = LoadInstanceType(rhs);
174 672 : Node* rhs_is_oddball = InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE);
175 336 : GotoIf(rhs_is_oddball, &call_with_oddball_feedback);
176 672 : Branch(IsBigIntInstanceType(rhs_instance_type), &bigint,
177 336 : &call_with_any_feedback);
178 : }
179 :
180 336 : BIND(&bigint);
181 : {
182 336 : var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kBigInt));
183 : var_result.Bind(CallRuntime(Runtime::kBigIntBinaryOp, context, lhs, rhs,
184 336 : SmiConstant(Operation::kAdd)));
185 336 : Goto(&end);
186 : }
187 :
188 336 : BIND(&call_with_oddball_feedback);
189 : {
190 : var_type_feedback.Bind(
191 336 : SmiConstant(BinaryOperationFeedback::kNumberOrOddball));
192 336 : Goto(&call_add_stub);
193 : }
194 :
195 336 : BIND(&call_with_any_feedback);
196 : {
197 336 : var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kAny));
198 336 : Goto(&call_add_stub);
199 : }
200 :
201 336 : BIND(&call_add_stub);
202 : {
203 672 : var_result.Bind(CallBuiltin(Builtins::kAdd, context, lhs, rhs));
204 336 : Goto(&end);
205 : }
206 :
207 336 : BIND(&end);
208 336 : UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_id);
209 672 : return var_result.value();
210 : }
211 :
212 1344 : Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback(
213 : Node* context, Node* lhs, Node* rhs, Node* slot_id, Node* feedback_vector,
214 : const SmiOperation& smiOperation, const FloatOperation& floatOperation,
215 : Operation op, bool rhs_is_smi) {
216 2688 : Label do_float_operation(this), end(this), call_stub(this),
217 1344 : check_rhsisoddball(this, Label::kDeferred), call_with_any_feedback(this),
218 1344 : if_lhsisnotnumber(this, Label::kDeferred),
219 1344 : if_bigint(this, Label::kDeferred);
220 2688 : VARIABLE(var_float_lhs, MachineRepresentation::kFloat64);
221 2688 : VARIABLE(var_float_rhs, MachineRepresentation::kFloat64);
222 2688 : VARIABLE(var_type_feedback, MachineRepresentation::kTaggedSigned);
223 2688 : VARIABLE(var_result, MachineRepresentation::kTagged);
224 :
225 1344 : Label if_lhsissmi(this);
226 : // If rhs is known to be an Smi (in the SubSmi, MulSmi, DivSmi, ModSmi
227 : // bytecode handlers) we want to fast path Smi operation. For the normal
228 : // operation, we want to fast path both Smi and Number operations, so this
229 : // path should not be marked as Deferred.
230 : Label if_lhsisnotsmi(this,
231 2688 : rhs_is_smi ? Label::kDeferred : Label::kNonDeferred);
232 2688 : Branch(TaggedIsNotSmi(lhs), &if_lhsisnotsmi, &if_lhsissmi);
233 :
234 : // Check if the {lhs} is a Smi or a HeapObject.
235 1344 : BIND(&if_lhsissmi);
236 : {
237 1344 : Comment("lhs is Smi");
238 1344 : if (!rhs_is_smi) {
239 : // Check if the {rhs} is also a Smi.
240 672 : Label if_rhsissmi(this), if_rhsisnotsmi(this);
241 1344 : Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
242 672 : BIND(&if_rhsisnotsmi);
243 : {
244 : // Check if {rhs} is a HeapNumber.
245 1344 : GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball);
246 :
247 : // Perform a floating point operation.
248 1344 : var_float_lhs.Bind(SmiToFloat64(lhs));
249 1344 : var_float_rhs.Bind(LoadHeapNumberValue(rhs));
250 672 : Goto(&do_float_operation);
251 : }
252 :
253 672 : BIND(&if_rhsissmi);
254 : }
255 :
256 : {
257 1344 : Comment("perform smi operation");
258 1344 : var_result.Bind(smiOperation(lhs, rhs, &var_type_feedback));
259 1344 : Goto(&end);
260 : }
261 : }
262 :
263 1344 : BIND(&if_lhsisnotsmi);
264 : {
265 1344 : Comment("lhs is not Smi");
266 : // Check if the {lhs} is a HeapNumber.
267 2688 : GotoIfNot(IsHeapNumber(lhs), &if_lhsisnotnumber);
268 :
269 1344 : if (!rhs_is_smi) {
270 : // Check if the {rhs} is a Smi.
271 672 : Label if_rhsissmi(this), if_rhsisnotsmi(this);
272 1344 : Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
273 :
274 672 : BIND(&if_rhsisnotsmi);
275 : {
276 : // Check if the {rhs} is a HeapNumber.
277 1344 : GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball);
278 :
279 : // Perform a floating point operation.
280 1344 : var_float_lhs.Bind(LoadHeapNumberValue(lhs));
281 1344 : var_float_rhs.Bind(LoadHeapNumberValue(rhs));
282 672 : Goto(&do_float_operation);
283 : }
284 :
285 672 : BIND(&if_rhsissmi);
286 : }
287 :
288 : {
289 : // Perform floating point operation.
290 2688 : var_float_lhs.Bind(LoadHeapNumberValue(lhs));
291 2688 : var_float_rhs.Bind(SmiToFloat64(rhs));
292 1344 : Goto(&do_float_operation);
293 : }
294 : }
295 :
296 1344 : BIND(&do_float_operation);
297 : {
298 1344 : var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber));
299 1344 : Node* lhs_value = var_float_lhs.value();
300 1344 : Node* rhs_value = var_float_rhs.value();
301 : Node* value = floatOperation(lhs_value, rhs_value);
302 2688 : var_result.Bind(AllocateHeapNumberWithValue(value));
303 1344 : Goto(&end);
304 : }
305 :
306 1344 : BIND(&if_lhsisnotnumber);
307 : {
308 : // No checks on rhs are done yet. We just know lhs is not a number or Smi.
309 1344 : Label if_left_bigint(this), if_left_oddball(this);
310 2688 : Node* lhs_instance_type = LoadInstanceType(lhs);
311 2688 : GotoIf(IsBigIntInstanceType(lhs_instance_type), &if_left_bigint);
312 2688 : Node* lhs_is_oddball = InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE);
313 1344 : Branch(lhs_is_oddball, &if_left_oddball, &call_with_any_feedback);
314 :
315 1344 : BIND(&if_left_oddball);
316 : {
317 1344 : Label if_rhsissmi(this), if_rhsisnotsmi(this);
318 2688 : Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
319 :
320 1344 : BIND(&if_rhsissmi);
321 : {
322 : var_type_feedback.Bind(
323 1344 : SmiConstant(BinaryOperationFeedback::kNumberOrOddball));
324 1344 : Goto(&call_stub);
325 : }
326 :
327 1344 : BIND(&if_rhsisnotsmi);
328 : {
329 : // Check if {rhs} is a HeapNumber.
330 2688 : GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball);
331 :
332 : var_type_feedback.Bind(
333 1344 : SmiConstant(BinaryOperationFeedback::kNumberOrOddball));
334 1344 : Goto(&call_stub);
335 : }
336 : }
337 :
338 1344 : BIND(&if_left_bigint);
339 : {
340 2688 : GotoIf(TaggedIsSmi(rhs), &call_with_any_feedback);
341 2688 : Branch(IsBigInt(rhs), &if_bigint, &call_with_any_feedback);
342 : }
343 : }
344 :
345 1344 : BIND(&check_rhsisoddball);
346 : {
347 : // Check if rhs is an oddball. At this point we know lhs is either a
348 : // Smi or number or oddball and rhs is not a number or Smi.
349 2688 : Node* rhs_instance_type = LoadInstanceType(rhs);
350 2688 : GotoIf(IsBigIntInstanceType(rhs_instance_type), &if_bigint);
351 2688 : Node* rhs_is_oddball = InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE);
352 1344 : GotoIfNot(rhs_is_oddball, &call_with_any_feedback);
353 :
354 : var_type_feedback.Bind(
355 1344 : SmiConstant(BinaryOperationFeedback::kNumberOrOddball));
356 1344 : Goto(&call_stub);
357 : }
358 :
359 : // This handles the case where at least one input is a BigInt.
360 1344 : BIND(&if_bigint);
361 : {
362 1344 : var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kBigInt));
363 : var_result.Bind(CallRuntime(Runtime::kBigIntBinaryOp, context, lhs, rhs,
364 1344 : SmiConstant(op)));
365 1344 : Goto(&end);
366 : }
367 :
368 1344 : BIND(&call_with_any_feedback);
369 : {
370 1344 : var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kAny));
371 1344 : Goto(&call_stub);
372 : }
373 :
374 1344 : BIND(&call_stub);
375 : {
376 : Node* result;
377 1344 : switch (op) {
378 : case Operation::kSubtract:
379 672 : result = CallBuiltin(Builtins::kSubtract, context, lhs, rhs);
380 336 : break;
381 : case Operation::kMultiply:
382 672 : result = CallBuiltin(Builtins::kMultiply, context, lhs, rhs);
383 336 : break;
384 : case Operation::kDivide:
385 672 : result = CallBuiltin(Builtins::kDivide, context, lhs, rhs);
386 336 : break;
387 : case Operation::kModulus:
388 672 : result = CallBuiltin(Builtins::kModulus, context, lhs, rhs);
389 336 : break;
390 : default:
391 0 : UNREACHABLE();
392 : }
393 1344 : var_result.Bind(result);
394 1344 : Goto(&end);
395 : }
396 :
397 1344 : BIND(&end);
398 1344 : UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_id);
399 2688 : return var_result.value();
400 : }
401 :
402 336 : Node* BinaryOpAssembler::Generate_SubtractWithFeedback(Node* context, Node* lhs,
403 : Node* rhs, Node* slot_id,
404 : Node* feedback_vector,
405 : bool rhs_is_smi) {
406 336 : auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) {
407 5040 : Label end(this);
408 : TVARIABLE(Number, var_result);
409 : // If rhs is known to be an Smi (for SubSmi) we want to fast path Smi
410 : // operation. For the normal Sub operation, we want to fast path both
411 : // Smi and Number operations, so this path should not be marked as Deferred.
412 : Label if_overflow(this,
413 672 : rhs_is_smi ? Label::kDeferred : Label::kNonDeferred);
414 672 : var_result = TrySmiSub(CAST(lhs), CAST(rhs), &if_overflow);
415 672 : var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall));
416 336 : Goto(&end);
417 :
418 336 : BIND(&if_overflow);
419 : {
420 672 : var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNumber));
421 1344 : Node* value = Float64Sub(SmiToFloat64(lhs), SmiToFloat64(rhs));
422 672 : var_result = AllocateHeapNumberWithValue(value);
423 336 : Goto(&end);
424 : }
425 :
426 336 : BIND(&end);
427 336 : return var_result.value();
428 336 : };
429 : auto floatFunction = [=](Node* lhs, Node* rhs) {
430 672 : return Float64Sub(lhs, rhs);
431 336 : };
432 1008 : return Generate_BinaryOperationWithFeedback(
433 : context, lhs, rhs, slot_id, feedback_vector, smiFunction, floatFunction,
434 672 : Operation::kSubtract, rhs_is_smi);
435 : }
436 :
437 336 : Node* BinaryOpAssembler::Generate_MultiplyWithFeedback(Node* context, Node* lhs,
438 : Node* rhs, Node* slot_id,
439 : Node* feedback_vector,
440 : bool rhs_is_smi) {
441 336 : auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) {
442 1008 : TNode<Number> result = SmiMul(CAST(lhs), CAST(rhs));
443 : var_type_feedback->Bind(SelectSmiConstant(
444 672 : TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall,
445 672 : BinaryOperationFeedback::kNumber));
446 336 : return result;
447 : };
448 : auto floatFunction = [=](Node* lhs, Node* rhs) {
449 672 : return Float64Mul(lhs, rhs);
450 336 : };
451 1008 : return Generate_BinaryOperationWithFeedback(
452 : context, lhs, rhs, slot_id, feedback_vector, smiFunction, floatFunction,
453 672 : Operation::kMultiply, rhs_is_smi);
454 : }
455 :
456 336 : Node* BinaryOpAssembler::Generate_DivideWithFeedback(
457 : Node* context, Node* dividend, Node* divisor, Node* slot_id,
458 : Node* feedback_vector, bool rhs_is_smi) {
459 336 : auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) {
460 5040 : VARIABLE(var_result, MachineRepresentation::kTagged);
461 : // If rhs is known to be an Smi (for DivSmi) we want to fast path Smi
462 : // operation. For the normal Div operation, we want to fast path both
463 : // Smi and Number operations, so this path should not be marked as Deferred.
464 672 : Label bailout(this, rhs_is_smi ? Label::kDeferred : Label::kNonDeferred),
465 336 : end(this);
466 672 : var_result.Bind(TrySmiDiv(CAST(lhs), CAST(rhs), &bailout));
467 672 : var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall));
468 336 : Goto(&end);
469 :
470 336 : BIND(&bailout);
471 : {
472 : var_type_feedback->Bind(
473 672 : SmiConstant(BinaryOperationFeedback::kSignedSmallInputs));
474 1344 : Node* value = Float64Div(SmiToFloat64(lhs), SmiToFloat64(rhs));
475 672 : var_result.Bind(AllocateHeapNumberWithValue(value));
476 336 : Goto(&end);
477 : }
478 :
479 336 : BIND(&end);
480 672 : return var_result.value();
481 336 : };
482 : auto floatFunction = [=](Node* lhs, Node* rhs) {
483 672 : return Float64Div(lhs, rhs);
484 336 : };
485 1008 : return Generate_BinaryOperationWithFeedback(
486 : context, dividend, divisor, slot_id, feedback_vector, smiFunction,
487 672 : floatFunction, Operation::kDivide, rhs_is_smi);
488 : }
489 :
490 336 : Node* BinaryOpAssembler::Generate_ModulusWithFeedback(
491 : Node* context, Node* dividend, Node* divisor, Node* slot_id,
492 : Node* feedback_vector, bool rhs_is_smi) {
493 336 : auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) {
494 1008 : TNode<Number> result = SmiMod(CAST(lhs), CAST(rhs));
495 : var_type_feedback->Bind(SelectSmiConstant(
496 672 : TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall,
497 672 : BinaryOperationFeedback::kNumber));
498 336 : return result;
499 : };
500 : auto floatFunction = [=](Node* lhs, Node* rhs) {
501 672 : return Float64Mod(lhs, rhs);
502 336 : };
503 1008 : return Generate_BinaryOperationWithFeedback(
504 : context, dividend, divisor, slot_id, feedback_vector, smiFunction,
505 672 : floatFunction, Operation::kModulus, rhs_is_smi);
506 : }
507 :
508 336 : Node* BinaryOpAssembler::Generate_ExponentiateWithFeedback(
509 : Node* context, Node* base, Node* exponent, Node* slot_id,
510 : Node* feedback_vector, bool rhs_is_smi) {
511 : // We currently don't optimize exponentiation based on feedback.
512 336 : Node* dummy_feedback = SmiConstant(BinaryOperationFeedback::kAny);
513 336 : UpdateFeedback(dummy_feedback, feedback_vector, slot_id);
514 672 : return CallBuiltin(Builtins::kExponentiate, context, base, exponent);
515 : }
516 :
517 : } // namespace internal
518 59456 : } // namespace v8
|