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

Side by Side Diff: src/liveedit-debugger.js

Issue 23783007: LiveEdit to mark more closure functions for re-instantiation when scope layout changes (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 7 years, 3 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
« no previous file with comments | « src/liveedit.cc ('k') | test/mjsunit/debug-liveedit-4.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 } 214 }
215 215
216 for (var i = 0; i < replace_code_list.length; i++) { 216 for (var i = 0; i < replace_code_list.length; i++) {
217 PatchFunctionCode(replace_code_list[i], change_log); 217 PatchFunctionCode(replace_code_list[i], change_log);
218 } 218 }
219 219
220 var position_patch_report = new Array(); 220 var position_patch_report = new Array();
221 change_log.push( {position_patched: position_patch_report} ); 221 change_log.push( {position_patched: position_patch_report} );
222 222
223 for (var i = 0; i < update_positions_list.length; i++) { 223 for (var i = 0; i < update_positions_list.length; i++) {
224 // TODO(LiveEdit): take into account wether it's source_changed or 224 // TODO(LiveEdit): take into account whether it's source_changed or
225 // unchanged and whether positions changed at all. 225 // unchanged and whether positions changed at all.
226 PatchPositions(update_positions_list[i], diff_array, 226 PatchPositions(update_positions_list[i], diff_array,
227 position_patch_report); 227 position_patch_report);
228 228
229 if (update_positions_list[i].live_shared_function_infos) { 229 if (update_positions_list[i].live_shared_function_infos) {
230 update_positions_list[i].live_shared_function_infos. 230 update_positions_list[i].live_shared_function_infos.
231 forEach(function (info) { 231 forEach(function (info) {
232 %LiveEditFunctionSourceUpdated(info.raw_array); 232 %LiveEditFunctionSourceUpdated(info.raw_array);
233 }); 233 });
234 } 234 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 if (k != i) { 281 if (k != i) {
282 var temp_info = compile_info[k]; 282 var temp_info = compile_info[k];
283 var temp_index = old_index_map[k]; 283 var temp_index = old_index_map[k];
284 compile_info[k] = compile_info[i]; 284 compile_info[k] = compile_info[i];
285 old_index_map[k] = old_index_map[i]; 285 old_index_map[k] = old_index_map[i];
286 compile_info[i] = temp_info; 286 compile_info[i] = temp_info;
287 old_index_map[i] = temp_index; 287 old_index_map[i] = temp_index;
288 } 288 }
289 } 289 }
290 290
291 // After sorting update outer_inder field using old_index_map. Also 291 // After sorting update outer_index field using old_index_map. Also
292 // set next_sibling_index field. 292 // set next_sibling_index field.
293 var current_index = 0; 293 var current_index = 0;
294 294
295 // The recursive function, that goes over all children of a particular 295 // The recursive function, that goes over all children of a particular
296 // node (i.e. function info). 296 // node (i.e. function info).
297 function ResetIndexes(new_parent_index, old_parent_index) { 297 function ResetIndexes(new_parent_index, old_parent_index) {
298 var previous_sibling = -1; 298 var previous_sibling = -1;
299 while (current_index < compile_info.length && 299 while (current_index < compile_info.length &&
300 compile_info[current_index].outer_index == old_parent_index) { 300 compile_info[current_index].outer_index == old_parent_index) {
301 var saved_index = current_index; 301 var saved_index = current_index;
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 } 685 }
686 686
687 function ProcessUnchangedChild(node) { 687 function ProcessUnchangedChild(node) {
688 node.new_start_pos = chunk_it.TranslatePos(node.info.start_position); 688 node.new_start_pos = chunk_it.TranslatePos(node.info.start_position);
689 node.new_end_pos = chunk_it.TranslatePos(node.info.end_position); 689 node.new_end_pos = chunk_it.TranslatePos(node.info.end_position);
690 } 690 }
691 691
692 ProcessInternals(code_info_tree); 692 ProcessInternals(code_info_tree);
693 } 693 }
694 694
695 // For ecah old function (if it is not damaged) tries to find a corresponding 695 // For each old function (if it is not damaged) tries to find a corresponding
696 // function in new script. Typically it should succeed (non-damaged functions 696 // function in new script. Typically it should succeed (non-damaged functions
697 // by definition may only have changes inside their bodies). However there are 697 // by definition may only have changes inside their bodies). However there are
698 // reasons for corresponence not to be found; function with unmodified text 698 // reasons for correspondence not to be found; function with unmodified text
699 // in new script may become enclosed into other function; the innocent change 699 // in new script may become enclosed into other function; the innocent change
700 // inside function body may in fact be something like "} function B() {" that 700 // inside function body may in fact be something like "} function B() {" that
701 // splits a function into 2 functions. 701 // splits a function into 2 functions.
702 function FindCorrespondingFunctions(old_code_tree, new_code_tree) { 702 function FindCorrespondingFunctions(old_code_tree, new_code_tree) {
703 703
704 // A recursive function that tries to find a correspondence for all 704 // A recursive function that tries to find a correspondence for all
705 // child functions and for their inner functions. 705 // child functions and for their inner functions.
706 function ProcessChildren(old_node, new_node) { 706 function ProcessNode(old_node, new_node) {
707 var scope_change_description =
708 IsFunctionContextLocalsChanged(old_node.info, new_node.info);
709 if (scope_change_description) {
710 old_node.status = FunctionStatus.CHANGED;
711 }
712
707 var old_children = old_node.children; 713 var old_children = old_node.children;
708 var new_children = new_node.children; 714 var new_children = new_node.children;
709 715
710 var unmatched_new_nodes_list = []; 716 var unmatched_new_nodes_list = [];
711 var textually_unmatched_new_nodes_list = []; 717 var textually_unmatched_new_nodes_list = [];
712 718
713 var old_index = 0; 719 var old_index = 0;
714 var new_index = 0; 720 var new_index = 0;
715 while (old_index < old_children.length) { 721 while (old_index < old_children.length) {
716 if (old_children[old_index].status == FunctionStatus.DAMAGED) { 722 if (old_children[old_index].status == FunctionStatus.DAMAGED) {
717 old_index++; 723 old_index++;
718 } else if (new_index < new_children.length) { 724 } else if (new_index < new_children.length) {
719 if (new_children[new_index].info.start_position < 725 if (new_children[new_index].info.start_position <
720 old_children[old_index].new_start_pos) { 726 old_children[old_index].new_start_pos) {
721 unmatched_new_nodes_list.push(new_children[new_index]); 727 unmatched_new_nodes_list.push(new_children[new_index]);
722 textually_unmatched_new_nodes_list.push(new_children[new_index]); 728 textually_unmatched_new_nodes_list.push(new_children[new_index]);
723 new_index++; 729 new_index++;
724 } else if (new_children[new_index].info.start_position == 730 } else if (new_children[new_index].info.start_position ==
725 old_children[old_index].new_start_pos) { 731 old_children[old_index].new_start_pos) {
726 if (new_children[new_index].info.end_position == 732 if (new_children[new_index].info.end_position ==
727 old_children[old_index].new_end_pos) { 733 old_children[old_index].new_end_pos) {
728 old_children[old_index].corresponding_node = 734 old_children[old_index].corresponding_node =
729 new_children[new_index]; 735 new_children[new_index];
730 old_children[old_index].textual_corresponding_node = 736 old_children[old_index].textual_corresponding_node =
731 new_children[new_index]; 737 new_children[new_index];
732 if (old_children[old_index].status != FunctionStatus.UNCHANGED) { 738 if (scope_change_description) {
733 ProcessChildren(old_children[old_index], 739 old_children[old_index].status = FunctionStatus.DAMAGED;
740 old_children[old_index].status_explanation =
741 "Enclosing function is now incompatible. " +
742 scope_change_description;
743 old_children[old_index].corresponding_node = void 0;
744 } else if (old_children[old_index].status !=
745 FunctionStatus.UNCHANGED) {
746 ProcessNode(old_children[old_index],
734 new_children[new_index]); 747 new_children[new_index]);
735 if (old_children[old_index].status == FunctionStatus.DAMAGED) { 748 if (old_children[old_index].status == FunctionStatus.DAMAGED) {
736 unmatched_new_nodes_list.push( 749 unmatched_new_nodes_list.push(
737 old_children[old_index].corresponding_node); 750 old_children[old_index].corresponding_node);
738 old_children[old_index].corresponding_node = void 0; 751 old_children[old_index].corresponding_node = void 0;
739 old_node.status = FunctionStatus.CHANGED; 752 old_node.status = FunctionStatus.CHANGED;
740 } 753 }
741 } 754 }
742 } else { 755 } else {
743 old_children[old_index].status = FunctionStatus.DAMAGED; 756 old_children[old_index].status = FunctionStatus.DAMAGED;
(...skipping 21 matching lines...) Expand all
765 } 778 }
766 } 779 }
767 780
768 while (new_index < new_children.length) { 781 while (new_index < new_children.length) {
769 unmatched_new_nodes_list.push(new_children[new_index]); 782 unmatched_new_nodes_list.push(new_children[new_index]);
770 textually_unmatched_new_nodes_list.push(new_children[new_index]); 783 textually_unmatched_new_nodes_list.push(new_children[new_index]);
771 new_index++; 784 new_index++;
772 } 785 }
773 786
774 if (old_node.status == FunctionStatus.CHANGED) { 787 if (old_node.status == FunctionStatus.CHANGED) {
775 var why_wrong_expectations = 788 if (old_node.info.param_num != new_node.info.param_num) {
776 WhyFunctionExpectationsDiffer(old_node.info, new_node.info);
777 if (why_wrong_expectations) {
778 old_node.status = FunctionStatus.DAMAGED; 789 old_node.status = FunctionStatus.DAMAGED;
779 old_node.status_explanation = why_wrong_expectations; 790 old_node.status_explanation = "Changed parameter number: " +
791 old_node.info.param_num + " and " + new_node.info.param_num;
780 } 792 }
781 } 793 }
782 old_node.unmatched_new_nodes = unmatched_new_nodes_list; 794 old_node.unmatched_new_nodes = unmatched_new_nodes_list;
783 old_node.textually_unmatched_new_nodes = 795 old_node.textually_unmatched_new_nodes =
784 textually_unmatched_new_nodes_list; 796 textually_unmatched_new_nodes_list;
785 } 797 }
786 798
787 ProcessChildren(old_code_tree, new_code_tree); 799 ProcessNode(old_code_tree, new_code_tree);
788 800
789 old_code_tree.corresponding_node = new_code_tree; 801 old_code_tree.corresponding_node = new_code_tree;
790 old_code_tree.textual_corresponding_node = new_code_tree; 802 old_code_tree.textual_corresponding_node = new_code_tree;
791 803
792 Assert(old_code_tree.status != FunctionStatus.DAMAGED, 804 Assert(old_code_tree.status != FunctionStatus.DAMAGED,
793 "Script became damaged"); 805 "Script became damaged");
794 } 806 }
795 807
796 function FindLiveSharedInfos(old_code_tree, script) { 808 function FindLiveSharedInfos(old_code_tree, script) {
797 var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script); 809 var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 } 861 }
850 862
851 function SharedInfoWrapper(raw_array) { 863 function SharedInfoWrapper(raw_array) {
852 this.function_name = raw_array[0]; 864 this.function_name = raw_array[0];
853 this.start_position = raw_array[1]; 865 this.start_position = raw_array[1];
854 this.end_position = raw_array[2]; 866 this.end_position = raw_array[2];
855 this.info = raw_array[3]; 867 this.info = raw_array[3];
856 this.raw_array = raw_array; 868 this.raw_array = raw_array;
857 } 869 }
858 870
859 // Changes positions (including all statments) in function. 871 // Changes positions (including all statements) in function.
860 function PatchPositions(old_info_node, diff_array, report_array) { 872 function PatchPositions(old_info_node, diff_array, report_array) {
861 if (old_info_node.live_shared_function_infos) { 873 if (old_info_node.live_shared_function_infos) {
862 old_info_node.live_shared_function_infos.forEach(function (info) { 874 old_info_node.live_shared_function_infos.forEach(function (info) {
863 %LiveEditPatchFunctionPositions(info.raw_array, 875 %LiveEditPatchFunctionPositions(info.raw_array,
864 diff_array); 876 diff_array);
865 }); 877 });
866 878
867 report_array.push( { name: old_info_node.info.function_name } ); 879 report_array.push( { name: old_info_node.info.function_name } );
868 } else { 880 } else {
869 // TODO(LiveEdit): function is not compiled yet or is already collected. 881 // TODO(LiveEdit): function is not compiled yet or is already collected.
870 report_array.push( 882 report_array.push(
871 { name: old_info_node.info.function_name, info_not_found: true } ); 883 { name: old_info_node.info.function_name, info_not_found: true } );
872 } 884 }
873 } 885 }
874 886
875 // Adds a suffix to script name to mark that it is old version. 887 // Adds a suffix to script name to mark that it is old version.
876 function CreateNameForOldScript(script) { 888 function CreateNameForOldScript(script) {
877 // TODO(635): try better than this; support several changes. 889 // TODO(635): try better than this; support several changes.
878 return script.name + " (old)"; 890 return script.name + " (old)";
879 } 891 }
880 892
881 // Compares a function interface old and new version, whether it 893 // Compares a function scope heap structure, old and new version, whether it
882 // changed or not. Returns explanation if they differ. 894 // changed or not. Returns explanation if they differ.
883 function WhyFunctionExpectationsDiffer(function_info1, function_info2) { 895 function IsFunctionContextLocalsChanged(function_info1, function_info2) {
884 // Check that function has the same number of parameters (there may exist
885 // an adapter, that won't survive function parameter number change).
886 if (function_info1.param_num != function_info2.param_num) {
887 return "Changed parameter number: " + function_info1.param_num +
888 " and " + function_info2.param_num;
889 }
890 var scope_info1 = function_info1.scope_info; 896 var scope_info1 = function_info1.scope_info;
891 var scope_info2 = function_info2.scope_info; 897 var scope_info2 = function_info2.scope_info;
892 898
893 var scope_info1_text; 899 var scope_info1_text;
894 var scope_info2_text; 900 var scope_info2_text;
895 901
896 if (scope_info1) { 902 if (scope_info1) {
897 scope_info1_text = scope_info1.toString(); 903 scope_info1_text = scope_info1.toString();
898 } else { 904 } else {
899 scope_info1_text = ""; 905 scope_info1_text = "";
900 } 906 }
901 if (scope_info2) { 907 if (scope_info2) {
902 scope_info2_text = scope_info2.toString(); 908 scope_info2_text = scope_info2.toString();
903 } else { 909 } else {
904 scope_info2_text = ""; 910 scope_info2_text = "";
905 } 911 }
906 912
907 if (scope_info1_text != scope_info2_text) { 913 if (scope_info1_text != scope_info2_text) {
908 return "Incompatible variable maps: [" + scope_info1_text + 914 return "Variable map changed: [" + scope_info1_text +
909 "] and [" + scope_info2_text + "]"; 915 "] => [" + scope_info2_text + "]";
910 } 916 }
911 // No differences. Return undefined. 917 // No differences. Return undefined.
912 return; 918 return;
913 } 919 }
914 920
915 // Minifier forward declaration. 921 // Minifier forward declaration.
916 var FunctionPatchabilityStatus; 922 var FunctionPatchabilityStatus;
917 923
918 // For array of wrapped shared function infos checks that none of them 924 // For array of wrapped shared function infos checks that none of them
919 // have activations on stack (of any thread). Throws a Failure exception 925 // have activations on stack (of any thread). Throws a Failure exception
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 // Function is public. 1134 // Function is public.
1129 this.RestartFrame = RestartFrame; 1135 this.RestartFrame = RestartFrame;
1130 1136
1131 // Functions are public for tests. 1137 // Functions are public for tests.
1132 this.TestApi = { 1138 this.TestApi = {
1133 PosTranslator: PosTranslator, 1139 PosTranslator: PosTranslator,
1134 CompareStrings: CompareStrings, 1140 CompareStrings: CompareStrings,
1135 ApplySingleChunkPatch: ApplySingleChunkPatch 1141 ApplySingleChunkPatch: ApplySingleChunkPatch
1136 }; 1142 };
1137 }; 1143 };
OLDNEW
« no previous file with comments | « src/liveedit.cc ('k') | test/mjsunit/debug-liveedit-4.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698