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

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

Issue 11365170: Start new design for interceptors and implement String.charCodeAt with it. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 * The [LiveRange] class covers a range where an instruction is live. 8 * The [LiveRange] class covers a range where an instruction is live.
9 */ 9 */
10 class LiveRange { 10 class LiveRange {
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 copyHandlers.putIfAbsent(block, () => new CopyHandler()); 434 copyHandlers.putIfAbsent(block, () => new CopyHandler());
435 handler.addAssignment(source, destination); 435 handler.addAssignment(source, destination);
436 } 436 }
437 } 437 }
438 438
439 /** 439 /**
440 * Allocates variable names for instructions, making sure they don't collide. 440 * Allocates variable names for instructions, making sure they don't collide.
441 */ 441 */
442 class VariableNamer { 442 class VariableNamer {
443 final VariableNames names; 443 final VariableNames names;
444 final Compiler compiler;
444 final Set<String> usedNames; 445 final Set<String> usedNames;
445 final Map<Element, String> parameterNames; 446 final Map<Element, String> parameterNames;
446 final List<String> freeTemporaryNames; 447 final List<String> freeTemporaryNames;
447 int temporaryIndex = 0; 448 int temporaryIndex = 0;
448 static final RegExp regexp = new RegExp('t[0-9]+'); 449 static final RegExp regexp = new RegExp('t[0-9]+');
449 450
450 VariableNamer(LiveEnvironment environment, this.names, this.parameterNames) 451 VariableNamer(LiveEnvironment environment,
452 this.names,
453 this.parameterNames,
454 this.compiler)
451 : usedNames = new Set<String>(), 455 : usedNames = new Set<String>(),
452 freeTemporaryNames = new List<String>() { 456 freeTemporaryNames = new List<String>() {
453 // [VariableNames.swapTemp] is used when there is a cycle in a copy handler. 457 // [VariableNames.swapTemp] is used when there is a cycle in a copy handler.
454 // Therefore we make sure no one uses it. 458 // Therefore we make sure no one uses it.
455 usedNames.add(names.swapTemp); 459 usedNames.add(names.swapTemp);
456 // [VariableNames.stateName] is being used throughout a bailout function. 460 // [VariableNames.stateName] is being used throughout a bailout function.
457 // Whenever a bailout-target is reached we set the state-variable to 0. We 461 // Whenever a bailout-target is reached we set the state-variable to 0. We
458 // must therefore not have any local variable that could clash with the 462 // must therefore not have any local variable that could clash with the
459 // state variable. 463 // state variable.
460 // Therefore we make sure no one uses it at any time. 464 // Therefore we make sure no one uses it at any time.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 // Special case this instruction to use the name of its 509 // Special case this instruction to use the name of its
506 // input if it has one. 510 // input if it has one.
507 var temp = instruction; 511 var temp = instruction;
508 do { 512 do {
509 temp = temp.checkedInput; 513 temp = temp.checkedInput;
510 name = names.ownName[temp]; 514 name = names.ownName[temp];
511 } while (name == null && temp is HCheck); 515 } while (name == null && temp is HCheck);
512 if (name != null) return addAllocatedName(instruction, name); 516 if (name != null) return addAllocatedName(instruction, name);
513 } 517 }
514 518
515 // The dom/html libraries have inline JS code that reference» 519 if (instruction is HThis) {
516 // parameter names directly. Long-term such code will be rejected. 520 name = "this";
517 // Now, just don't mangle the parameter name. 521 if (instruction.sourceElement != null) {
518 if (instruction is HParameterValue 522 Element cls = instruction.sourceElement.getEnclosingClass();
523 // Change the name of [:this:] in a method of a foreign class
524 // to use the first parameter of the method, which is the
525 // actual receiver.
526 JavaScriptBackend backend = compiler.backend;
527 if (backend.isInterceptorClass(cls)) {
528 name = "primitive";
529 }
530 }
531 } else if (instruction is HParameterValue
519 && instruction.sourceElement.enclosingElement.isNative()) { 532 && instruction.sourceElement.enclosingElement.isNative()) {
533 // The dom/html libraries have inline JS code that reference
534 // parameter names directly. Long-term such code will be rejected.
535 // Now, just don't mangle the parameter name.
520 name = instruction.sourceElement.name.slowToString(); 536 name = instruction.sourceElement.name.slowToString();
521 } else if (instruction.sourceElement != null) { 537 } else if (instruction.sourceElement != null) {
522 name = allocateWithHint(instruction.sourceElement.name.slowToString()); 538 name = allocateWithHint(instruction.sourceElement.name.slowToString());
523 } else { 539 } else {
524 // We could not find an element for the instruction. If the 540 // We could not find an element for the instruction. If the
525 // instruction is used by a phi, try to use the name of the phi. 541 // instruction is used by a phi, try to use the name of the phi.
526 // Otherwise, just allocate a temporary name. 542 // Otherwise, just allocate a temporary name.
527 HPhi phi = firstPhiUserWithElement(instruction); 543 HPhi phi = firstPhiUserWithElement(instruction);
528 if (phi != null) { 544 if (phi != null) {
529 name = allocateWithHint(phi.sourceElement.name.slowToString()); 545 name = allocateWithHint(phi.sourceElement.name.slowToString());
530 } else { 546 } else {
531 name = allocateTemporary(); 547 name = allocateTemporary();
532 } 548 }
533 } 549 }
534
535 return addAllocatedName(instruction, name); 550 return addAllocatedName(instruction, name);
536 } 551 }
537 552
538 String addAllocatedName(HInstruction instruction, String name) { 553 String addAllocatedName(HInstruction instruction, String name) {
539 if (instruction is HParameterValue) { 554 if (instruction is HParameterValue && name != 'this') {
540 parameterNames[instruction.sourceElement] = name; 555 parameterNames[instruction.sourceElement] = name;
541 } 556 }
542 usedNames.add(name); 557 usedNames.add(name);
543 names.addNameUsed(name); 558 names.addNameUsed(name);
544 names.ownName[instruction] = name; 559 names.ownName[instruction] = name;
545 return name; 560 return name;
546 } 561 }
547 562
548 /** 563 /**
549 * Frees [instruction]'s name so it can be used for other instructions. 564 * Frees [instruction]'s name so it can be used for other instructions.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 parameterNames) 607 parameterNames)
593 : this.names = new VariableNames(parameterNames), 608 : this.names = new VariableNames(parameterNames),
594 this.parameterNames = parameterNames; 609 this.parameterNames = parameterNames;
595 610
596 void visitGraph(HGraph graph) { 611 void visitGraph(HGraph graph) {
597 visitDominatorTree(graph); 612 visitDominatorTree(graph);
598 } 613 }
599 614
600 void visitBasicBlock(HBasicBlock block) { 615 void visitBasicBlock(HBasicBlock block) {
601 VariableNamer namer = new VariableNamer( 616 VariableNamer namer = new VariableNamer(
602 liveInstructions[block], names, parameterNames); 617 liveInstructions[block], names, parameterNames, compiler);
603 618
604 block.forEachPhi((HPhi phi) { 619 block.forEachPhi((HPhi phi) {
605 handlePhi(phi, namer); 620 handlePhi(phi, namer);
606 }); 621 });
607 622
608 block.forEachInstruction((HInstruction instruction) { 623 block.forEachInstruction((HInstruction instruction) {
609 handleInstruction(instruction, namer); 624 handleInstruction(instruction, namer);
610 }); 625 });
611 } 626 }
612 627
613 /** 628 /**
614 * Returns whether [instruction] needs a name. Instructions that 629 * Returns whether [instruction] needs a name. Instructions that
615 * have no users or that are generated at use site does not need a name. 630 * have no users or that are generated at use site does not need a name.
616 */ 631 */
617 bool needsName(HInstruction instruction) { 632 bool needsName(HInstruction instruction) {
618 // TODO(ngeoffray): locals/parameters are being generated at use site, 633 // TODO(ngeoffray): locals/parameters are being generated at use site,
619 // but we need a name for them. We should probably not make 634 // but we need a name for them. We should probably not make
620 // them generate at use site to make things simpler. 635 // them generate at use site to make things simpler.
621 if (instruction is HLocalValue && instruction is !HThis) return true; 636 if (instruction is HLocalValue) return true;
622 if (instruction.usedBy.isEmpty) return false; 637 if (instruction.usedBy.isEmpty) return false;
623 if (generateAtUseSite.contains(instruction)) return false; 638 if (generateAtUseSite.contains(instruction)) return false;
624 // A [HCheck] instruction that has control flow needs a name only if its 639 // A [HCheck] instruction that has control flow needs a name only if its
625 // checked input needs a name (e.g. a check [HConstant] does not 640 // checked input needs a name (e.g. a check [HConstant] does not
626 // need a name). 641 // need a name).
627 if (instruction is HCheck && instruction.isControlFlow()) { 642 if (instruction is HCheck && instruction.isControlFlow()) {
628 HCheck check = instruction; 643 HCheck check = instruction;
629 return needsName(instruction.checkedInput); 644 return needsName(instruction.checkedInput);
630 } 645 }
631 return true; 646 return true;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 if (!needsName(input)) { 690 if (!needsName(input)) {
676 names.addAssignment(predecessor, input, phi); 691 names.addAssignment(predecessor, input, phi);
677 } else { 692 } else {
678 names.addCopy(predecessor, input, phi); 693 names.addCopy(predecessor, input, phi);
679 } 694 }
680 } 695 }
681 696
682 namer.allocateName(phi); 697 namer.allocateName(phi);
683 } 698 }
684 } 699 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/nodes.dart ('k') | tests/compiler/dart2js/dart_backend_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698