Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart

Issue 14404004: Throw NoSuchMethod or ArgumentError instead of generating a bailout, when we know the next instruct… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * [InvokeDynamicSpecializer] and its subclasses are helpers to 8 * [InvokeDynamicSpecializer] and its subclasses are helpers to
9 * optimize intercepted dynamic calls. It knows what input types 9 * optimize intercepted dynamic calls. It knows what input types
10 * would be beneficial for performance, and how to change a invoke 10 * would be beneficial for performance, and how to change a invoke
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 // version is cheaper than having another bailout case. This is true, 95 // version is cheaper than having another bailout case. This is true,
96 // because the integer check will simply throw if it fails. 96 // because the integer check will simply throw if it fails.
97 return HType.UNKNOWN; 97 return HType.UNKNOWN;
98 } 98 }
99 99
100 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, 100 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
101 Compiler compiler) { 101 Compiler compiler) {
102 if (instruction.inputs[1].isMutableArray()) { 102 if (instruction.inputs[1].isMutableArray()) {
103 return new HIndexAssign(instruction.inputs[1], 103 return new HIndexAssign(instruction.inputs[1],
104 instruction.inputs[2], 104 instruction.inputs[2],
105 instruction.inputs[3]); 105 instruction.inputs[3],
106 instruction.selector);
106 } 107 }
107 return null; 108 return null;
108 } 109 }
109 } 110 }
110 111
111 class IndexSpecializer extends InvokeDynamicSpecializer { 112 class IndexSpecializer extends InvokeDynamicSpecializer {
112 const IndexSpecializer(); 113 const IndexSpecializer();
113 114
114 HType computeDesiredTypeForInput(HInvokeDynamic instruction, 115 HType computeDesiredTypeForInput(HInvokeDynamic instruction,
115 HInstruction input, 116 HInstruction input,
116 Compiler compiler) { 117 Compiler compiler) {
117 HInstruction index = instruction.inputs[2]; 118 HInstruction index = instruction.inputs[2];
118 if (input == instruction.inputs[1] && 119 if (input == instruction.inputs[1] &&
119 index.instructionType.canBePrimitiveNumber(compiler)) { 120 index.instructionType.canBePrimitiveNumber(compiler)) {
120 return HType.INDEXABLE_PRIMITIVE; 121 return HType.INDEXABLE_PRIMITIVE;
121 } 122 }
122 // The index should be an int when the receiver is a string or array. 123 // The index should be an int when the receiver is a string or array.
123 // However it turns out that inserting an integer check in the optimized 124 // However it turns out that inserting an integer check in the optimized
124 // version is cheaper than having another bailout case. This is true, 125 // version is cheaper than having another bailout case. This is true,
125 // because the integer check will simply throw if it fails. 126 // because the integer check will simply throw if it fails.
126 return HType.UNKNOWN; 127 return HType.UNKNOWN;
127 } 128 }
128 129
129 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, 130 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
130 Compiler compiler) { 131 Compiler compiler) {
131 if (instruction.inputs[1].isIndexablePrimitive()) { 132 if (instruction.inputs[1].isIndexablePrimitive()) {
132 return new HIndex(instruction.inputs[1], instruction.inputs[2]); 133 return new HIndex(
134 instruction.inputs[1], instruction.inputs[2], instruction.selector);
133 } 135 }
134 return null; 136 return null;
135 } 137 }
136 } 138 }
137 139
138 class BitNotSpecializer extends InvokeDynamicSpecializer { 140 class BitNotSpecializer extends InvokeDynamicSpecializer {
139 const BitNotSpecializer(); 141 const BitNotSpecializer();
140 142
141 UnaryOperation operation(ConstantSystem constantSystem) { 143 UnaryOperation operation(ConstantSystem constantSystem) {
142 return constantSystem.bitNot; 144 return constantSystem.bitNot;
(...skipping 15 matching lines...) Expand all
158 Compiler compiler) { 160 Compiler compiler) {
159 // All bitwise operations on primitive types either produce an 161 // All bitwise operations on primitive types either produce an
160 // integer or throw an error. 162 // integer or throw an error.
161 if (instruction.inputs[1].isPrimitive()) return HType.INTEGER; 163 if (instruction.inputs[1].isPrimitive()) return HType.INTEGER;
162 return instruction.instructionType; 164 return instruction.instructionType;
163 } 165 }
164 166
165 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, 167 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
166 Compiler compiler) { 168 Compiler compiler) {
167 HInstruction input = instruction.inputs[1]; 169 HInstruction input = instruction.inputs[1];
168 if (input.isNumber()) return new HBitNot(input); 170 if (input.isNumber()) return new HBitNot(input, instruction.selector);
169 return null; 171 return null;
170 } 172 }
171 } 173 }
172 174
173 class UnaryNegateSpecializer extends InvokeDynamicSpecializer { 175 class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
174 const UnaryNegateSpecializer(); 176 const UnaryNegateSpecializer();
175 177
176 UnaryOperation operation(ConstantSystem constantSystem) { 178 UnaryOperation operation(ConstantSystem constantSystem) {
177 return constantSystem.negate; 179 return constantSystem.negate;
178 } 180 }
(...skipping 15 matching lines...) Expand all
194 HType computeTypeFromInputTypes(HInvokeDynamic instruction, 196 HType computeTypeFromInputTypes(HInvokeDynamic instruction,
195 Compiler compiler) { 197 Compiler compiler) {
196 HType operandType = instruction.inputs[1].instructionType; 198 HType operandType = instruction.inputs[1].instructionType;
197 if (operandType.isNumber()) return operandType; 199 if (operandType.isNumber()) return operandType;
198 return instruction.instructionType; 200 return instruction.instructionType;
199 } 201 }
200 202
201 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, 203 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
202 Compiler compiler) { 204 Compiler compiler) {
203 HInstruction input = instruction.inputs[1]; 205 HInstruction input = instruction.inputs[1];
204 if (input.isNumber()) return new HNegate(input); 206 if (input.isNumber()) return new HNegate(input, instruction.selector);
205 return null; 207 return null;
206 } 208 }
207 } 209 }
208 210
209 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer { 211 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
210 const BinaryArithmeticSpecializer(); 212 const BinaryArithmeticSpecializer();
211 213
212 HType computeTypeFromInputTypes(HInvokeDynamic instruction, 214 HType computeTypeFromInputTypes(HInvokeDynamic instruction,
213 Compiler compiler) { 215 Compiler compiler) {
214 HInstruction left = instruction.inputs[1]; 216 HInstruction left = instruction.inputs[1];
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 } 252 }
251 253
252 bool isBuiltin(HInvokeDynamic instruction) { 254 bool isBuiltin(HInvokeDynamic instruction) {
253 return instruction.inputs[1].isNumber() 255 return instruction.inputs[1].isNumber()
254 && instruction.inputs[2].isNumber(); 256 && instruction.inputs[2].isNumber();
255 } 257 }
256 258
257 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, 259 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
258 Compiler compiler) { 260 Compiler compiler) {
259 if (isBuiltin(instruction)) { 261 if (isBuiltin(instruction)) {
260 HInstruction builtin = 262 HInstruction builtin = newBuiltinVariant(instruction);
261 newBuiltinVariant(instruction.inputs[1], instruction.inputs[2]);
262 if (builtin != null) return builtin; 263 if (builtin != null) return builtin;
263 // Even if there is no builtin equivalent instruction, we know 264 // Even if there is no builtin equivalent instruction, we know
264 // the instruction does not have any side effect, and that it 265 // the instruction does not have any side effect, and that it
265 // can be GVN'ed. 266 // can be GVN'ed.
266 instruction.clearAllSideEffects(); 267 instruction.clearAllSideEffects();
267 instruction.clearAllDependencies(); 268 instruction.clearAllDependencies();
268 instruction.setUseGvn(); 269 instruction.setUseGvn();
269 } 270 }
270 return null; 271 return null;
271 } 272 }
272 273
273 HInstruction newBuiltinVariant(HInstruction left, HInstruction right); 274 HInstruction newBuiltinVariant(HInvokeDynamic instruction);
274 } 275 }
275 276
276 class AddSpecializer extends BinaryArithmeticSpecializer { 277 class AddSpecializer extends BinaryArithmeticSpecializer {
277 const AddSpecializer(); 278 const AddSpecializer();
278 279
279 BinaryOperation operation(ConstantSystem constantSystem) { 280 BinaryOperation operation(ConstantSystem constantSystem) {
280 return constantSystem.add; 281 return constantSystem.add;
281 } 282 }
282 283
283 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 284 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
284 return new HAdd(left, right); 285 return new HAdd(
286 instruction.inputs[1], instruction.inputs[2], instruction.selector);
285 } 287 }
286 } 288 }
287 289
288 class DivideSpecializer extends BinaryArithmeticSpecializer { 290 class DivideSpecializer extends BinaryArithmeticSpecializer {
289 const DivideSpecializer(); 291 const DivideSpecializer();
290 292
291 BinaryOperation operation(ConstantSystem constantSystem) { 293 BinaryOperation operation(ConstantSystem constantSystem) {
292 return constantSystem.divide; 294 return constantSystem.divide;
293 } 295 }
294 296
295 HType computeTypeFromInputTypes(HInstruction instruction, 297 HType computeTypeFromInputTypes(HInstruction instruction,
296 Compiler compiler) { 298 Compiler compiler) {
297 HInstruction left = instruction.inputs[1]; 299 HInstruction left = instruction.inputs[1];
298 if (left.isNumber()) return HType.DOUBLE; 300 if (left.isNumber()) return HType.DOUBLE;
299 return instruction.instructionType; 301 return instruction.instructionType;
300 } 302 }
301 303
302 HType computeDesiredTypeForInput(HInstruction instruction, 304 HType computeDesiredTypeForInput(HInstruction instruction,
303 HInstruction input, 305 HInstruction input,
304 Compiler compiler) { 306 Compiler compiler) {
305 if (input == instruction.inputs[0]) return HType.UNKNOWN; 307 if (input == instruction.inputs[0]) return HType.UNKNOWN;
306 // A division can never return an integer. So don't ask for integer inputs. 308 // A division can never return an integer. So don't ask for integer inputs.
307 if (instruction.isInteger()) return HType.UNKNOWN; 309 if (instruction.isInteger()) return HType.UNKNOWN;
308 return super.computeDesiredTypeForInput( 310 return super.computeDesiredTypeForInput(
309 instruction, input, compiler); 311 instruction, input, compiler);
310 } 312 }
311 313
312 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 314 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
313 return new HDivide(left, right); 315 return new HDivide(
316 instruction.inputs[1], instruction.inputs[2], instruction.selector);
314 } 317 }
315 } 318 }
316 319
317 class ModuloSpecializer extends BinaryArithmeticSpecializer { 320 class ModuloSpecializer extends BinaryArithmeticSpecializer {
318 const ModuloSpecializer(); 321 const ModuloSpecializer();
319 322
320 BinaryOperation operation(ConstantSystem constantSystem) { 323 BinaryOperation operation(ConstantSystem constantSystem) {
321 return constantSystem.modulo; 324 return constantSystem.modulo;
322 } 325 }
323 326
324 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 327 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
325 // Modulo cannot be mapped to the native operator (different semantics). 328 // Modulo cannot be mapped to the native operator (different semantics).
326 return null; 329 return null;
327 } 330 }
328 } 331 }
329 332
330 class MultiplySpecializer extends BinaryArithmeticSpecializer { 333 class MultiplySpecializer extends BinaryArithmeticSpecializer {
331 const MultiplySpecializer(); 334 const MultiplySpecializer();
332 335
333 BinaryOperation operation(ConstantSystem constantSystem) { 336 BinaryOperation operation(ConstantSystem constantSystem) {
334 return constantSystem.multiply; 337 return constantSystem.multiply;
335 } 338 }
336 339
337 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 340 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
338 return new HMultiply(left, right); 341 return new HMultiply(
342 instruction.inputs[1], instruction.inputs[2], instruction.selector);
339 } 343 }
340 } 344 }
341 345
342 class SubtractSpecializer extends BinaryArithmeticSpecializer { 346 class SubtractSpecializer extends BinaryArithmeticSpecializer {
343 const SubtractSpecializer(); 347 const SubtractSpecializer();
344 348
345 BinaryOperation operation(ConstantSystem constantSystem) { 349 BinaryOperation operation(ConstantSystem constantSystem) {
346 return constantSystem.subtract; 350 return constantSystem.subtract;
347 } 351 }
348 352
349 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 353 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
350 return new HSubtract(left, right); 354 return new HSubtract(
355 instruction.inputs[1], instruction.inputs[2], instruction.selector);
351 } 356 }
352 } 357 }
353 358
354 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { 359 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
355 const TruncatingDivideSpecializer(); 360 const TruncatingDivideSpecializer();
356 361
357 BinaryOperation operation(ConstantSystem constantSystem) { 362 BinaryOperation operation(ConstantSystem constantSystem) {
358 return constantSystem.truncatingDivide; 363 return constantSystem.truncatingDivide;
359 } 364 }
360 365
361 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 366 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
362 // Truncating divide does not have a JS equivalent. 367 // Truncating divide does not have a JS equivalent.
363 return null; 368 return null;
364 } 369 }
365 } 370 }
366 371
367 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { 372 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
368 const BinaryBitOpSpecializer(); 373 const BinaryBitOpSpecializer();
369 374
370 HType computeTypeFromInputTypes(HInvokeDynamic instruction, 375 HType computeTypeFromInputTypes(HInvokeDynamic instruction,
371 Compiler compiler) { 376 Compiler compiler) {
(...skipping 28 matching lines...) Expand all
400 405
401 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, 406 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
402 Compiler compiler) { 407 Compiler compiler) {
403 HInstruction left = instruction.inputs[1]; 408 HInstruction left = instruction.inputs[1];
404 HInstruction right = instruction.inputs[2]; 409 HInstruction right = instruction.inputs[2];
405 if (!left.isNumber() || !right.isConstantInteger()) return null; 410 if (!left.isNumber() || !right.isConstantInteger()) return null;
406 HConstant rightConstant = right; 411 HConstant rightConstant = right;
407 IntConstant intConstant = rightConstant.constant; 412 IntConstant intConstant = rightConstant.constant;
408 int count = intConstant.value; 413 int count = intConstant.value;
409 if (count >= 0 && count <= 31) { 414 if (count >= 0 && count <= 31) {
410 return newBuiltinVariant(left, right); 415 return newBuiltinVariant(instruction);
411 } 416 }
412 return null; 417 return null;
413 } 418 }
414 419
415 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 420 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
416 return new HShiftLeft(left, right); 421 return new HShiftLeft(
422 instruction.inputs[1], instruction.inputs[2], instruction.selector);
417 } 423 }
418 } 424 }
419 425
420 class ShiftRightSpecializer extends BinaryBitOpSpecializer { 426 class ShiftRightSpecializer extends BinaryBitOpSpecializer {
421 const ShiftRightSpecializer(); 427 const ShiftRightSpecializer();
422 428
423 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 429 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
424 // Shift right cannot be mapped to the native operator easily. 430 // Shift right cannot be mapped to the native operator easily.
425 return null; 431 return null;
426 } 432 }
427 433
428 BinaryOperation operation(ConstantSystem constantSystem) { 434 BinaryOperation operation(ConstantSystem constantSystem) {
429 return constantSystem.shiftRight; 435 return constantSystem.shiftRight;
430 } 436 }
431 } 437 }
432 438
433 class BitOrSpecializer extends BinaryBitOpSpecializer { 439 class BitOrSpecializer extends BinaryBitOpSpecializer {
434 const BitOrSpecializer(); 440 const BitOrSpecializer();
435 441
436 BinaryOperation operation(ConstantSystem constantSystem) { 442 BinaryOperation operation(ConstantSystem constantSystem) {
437 return constantSystem.bitOr; 443 return constantSystem.bitOr;
438 } 444 }
439 445
440 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 446 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
441 return new HBitOr(left, right); 447 return new HBitOr(
448 instruction.inputs[1], instruction.inputs[2], instruction.selector);
442 } 449 }
443 } 450 }
444 451
445 class BitAndSpecializer extends BinaryBitOpSpecializer { 452 class BitAndSpecializer extends BinaryBitOpSpecializer {
446 const BitAndSpecializer(); 453 const BitAndSpecializer();
447 454
448 BinaryOperation operation(ConstantSystem constantSystem) { 455 BinaryOperation operation(ConstantSystem constantSystem) {
449 return constantSystem.bitAnd; 456 return constantSystem.bitAnd;
450 } 457 }
451 458
452 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 459 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
453 return new HBitAnd(left, right); 460 return new HBitAnd(
461 instruction.inputs[1], instruction.inputs[2], instruction.selector);
454 } 462 }
455 } 463 }
456 464
457 class BitXorSpecializer extends BinaryBitOpSpecializer { 465 class BitXorSpecializer extends BinaryBitOpSpecializer {
458 const BitXorSpecializer(); 466 const BitXorSpecializer();
459 467
460 BinaryOperation operation(ConstantSystem constantSystem) { 468 BinaryOperation operation(ConstantSystem constantSystem) {
461 return constantSystem.bitXor; 469 return constantSystem.bitXor;
462 } 470 }
463 471
464 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 472 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
465 return new HBitXor(left, right); 473 return new HBitXor(
474 instruction.inputs[1], instruction.inputs[2], instruction.selector);
466 } 475 }
467 } 476 }
468 477
469 abstract class RelationalSpecializer extends InvokeDynamicSpecializer { 478 abstract class RelationalSpecializer extends InvokeDynamicSpecializer {
470 const RelationalSpecializer(); 479 const RelationalSpecializer();
471 480
472 HType computeTypeFromInputTypes(HInvokeDynamic instruction, 481 HType computeTypeFromInputTypes(HInvokeDynamic instruction,
473 Compiler compiler) { 482 Compiler compiler) {
474 if (instruction.inputs[1].instructionType.isPrimitiveOrNull()) { 483 if (instruction.inputs[1].instructionType.isPrimitiveOrNull()) {
475 return HType.BOOLEAN; 484 return HType.BOOLEAN;
(...skipping 16 matching lines...) Expand all
492 } 501 }
493 } 502 }
494 return HType.UNKNOWN; 503 return HType.UNKNOWN;
495 } 504 }
496 505
497 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, 506 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
498 Compiler compiler) { 507 Compiler compiler) {
499 HInstruction left = instruction.inputs[1]; 508 HInstruction left = instruction.inputs[1];
500 HInstruction right = instruction.inputs[2]; 509 HInstruction right = instruction.inputs[2];
501 if (left.isNumber() && right.isNumber()) { 510 if (left.isNumber() && right.isNumber()) {
502 return newBuiltinVariant(left, right); 511 return newBuiltinVariant(instruction);
503 } 512 }
504 return null; 513 return null;
505 } 514 }
506 515
507 HInstruction newBuiltinVariant(HInstruction left, HInstruction right); 516 HInstruction newBuiltinVariant(HInvokeDynamic instruction);
508 } 517 }
509 518
510 class EqualsSpecializer extends RelationalSpecializer { 519 class EqualsSpecializer extends RelationalSpecializer {
511 const EqualsSpecializer(); 520 const EqualsSpecializer();
512 521
513 HType computeDesiredTypeForInput(HInvokeDynamic instruction, 522 HType computeDesiredTypeForInput(HInvokeDynamic instruction,
514 HInstruction input, 523 HInstruction input,
515 Compiler compiler) { 524 Compiler compiler) {
516 HInstruction left = instruction.inputs[1]; 525 HInstruction left = instruction.inputs[1];
517 HInstruction right = instruction.inputs[2]; 526 HInstruction right = instruction.inputs[2];
(...skipping 17 matching lines...) Expand all
535 } 544 }
536 return HType.UNKNOWN; 545 return HType.UNKNOWN;
537 } 546 }
538 547
539 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, 548 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
540 Compiler compiler) { 549 Compiler compiler) {
541 HInstruction left = instruction.inputs[1]; 550 HInstruction left = instruction.inputs[1];
542 HInstruction right = instruction.inputs[2]; 551 HInstruction right = instruction.inputs[2];
543 HType instructionType = left.instructionType; 552 HType instructionType = left.instructionType;
544 if (right.isConstantNull() || instructionType.isPrimitiveOrNull()) { 553 if (right.isConstantNull() || instructionType.isPrimitiveOrNull()) {
545 return newBuiltinVariant(left, right); 554 return newBuiltinVariant(instruction);
546 } 555 }
547 TypeMask mask = instructionType.computeMask(compiler); 556 TypeMask mask = instructionType.computeMask(compiler);
548 Selector selector = new TypedSelector(mask, instruction.selector); 557 Selector selector = new TypedSelector(mask, instruction.selector);
549 World world = compiler.world; 558 World world = compiler.world;
550 JavaScriptBackend backend = compiler.backend; 559 JavaScriptBackend backend = compiler.backend;
551 Iterable<Element> matches = world.allFunctions.filter(selector); 560 Iterable<Element> matches = world.allFunctions.filter(selector);
552 // This test relies the on `Object.==` and `Interceptor.==` always being 561 // This test relies the on `Object.==` and `Interceptor.==` always being
553 // implemented because if the selector matches by subtype, it still will be 562 // implemented because if the selector matches by subtype, it still will be
554 // a regular object or an interceptor. 563 // a regular object or an interceptor.
555 if (matches.every(backend.isDefaultEqualityImplementation)) { 564 if (matches.every(backend.isDefaultEqualityImplementation)) {
556 return newBuiltinVariant(left, right); 565 return newBuiltinVariant(instruction);
557 } 566 }
558 return null; 567 return null;
559 } 568 }
560 569
561 BinaryOperation operation(ConstantSystem constantSystem) { 570 BinaryOperation operation(ConstantSystem constantSystem) {
562 return constantSystem.equal; 571 return constantSystem.equal;
563 } 572 }
564 573
565 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 574 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
566 return new HIdentity(left, right); 575 return new HIdentity(
576 instruction.inputs[1], instruction.inputs[2], instruction.selector);
567 } 577 }
568 } 578 }
569 579
570 class LessSpecializer extends RelationalSpecializer { 580 class LessSpecializer extends RelationalSpecializer {
571 const LessSpecializer(); 581 const LessSpecializer();
572 582
573 BinaryOperation operation(ConstantSystem constantSystem) { 583 BinaryOperation operation(ConstantSystem constantSystem) {
574 return constantSystem.less; 584 return constantSystem.less;
575 } 585 }
576 586
577 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 587 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
578 return new HLess(left, right); 588 return new HLess(
589 instruction.inputs[1], instruction.inputs[2], instruction.selector);
579 } 590 }
580 } 591 }
581 592
582 class GreaterSpecializer extends RelationalSpecializer { 593 class GreaterSpecializer extends RelationalSpecializer {
583 const GreaterSpecializer(); 594 const GreaterSpecializer();
584 595
585 BinaryOperation operation(ConstantSystem constantSystem) { 596 BinaryOperation operation(ConstantSystem constantSystem) {
586 return constantSystem.greater; 597 return constantSystem.greater;
587 } 598 }
588 599
589 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 600 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
590 return new HGreater(left, right); 601 return new HGreater(
602 instruction.inputs[1], instruction.inputs[2], instruction.selector);
591 } 603 }
592 } 604 }
593 605
594 class GreaterEqualSpecializer extends RelationalSpecializer { 606 class GreaterEqualSpecializer extends RelationalSpecializer {
595 const GreaterEqualSpecializer(); 607 const GreaterEqualSpecializer();
596 608
597 BinaryOperation operation(ConstantSystem constantSystem) { 609 BinaryOperation operation(ConstantSystem constantSystem) {
598 return constantSystem.greaterEqual; 610 return constantSystem.greaterEqual;
599 } 611 }
600 612
601 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 613 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
602 return new HGreaterEqual(left, right); 614 return new HGreaterEqual(
615 instruction.inputs[1], instruction.inputs[2], instruction.selector);
603 } 616 }
604 } 617 }
605 618
606 class LessEqualSpecializer extends RelationalSpecializer { 619 class LessEqualSpecializer extends RelationalSpecializer {
607 const LessEqualSpecializer(); 620 const LessEqualSpecializer();
608 621
609 BinaryOperation operation(ConstantSystem constantSystem) { 622 BinaryOperation operation(ConstantSystem constantSystem) {
610 return constantSystem.lessEqual; 623 return constantSystem.lessEqual;
611 } 624 }
612 625
613 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { 626 HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
614 return new HLessEqual(left, right); 627 return new HLessEqual(
628 instruction.inputs[1], instruction.inputs[2], instruction.selector);
615 } 629 }
616 } 630 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698