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

Unified Diff: src/liveedit-debugger.js

Issue 2943002: Reimplement stack manipulations for LiveEdit (Closed)
Patch Set: follow codereview Created 10 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/liveedit.cc ('k') | src/mips/debug-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/liveedit-debugger.js
diff --git a/src/liveedit-debugger.js b/src/liveedit-debugger.js
index c8c6f082c03297d28ca895c8b70cd73345db1197..506fb5b665319af775ed343f080735a724fe5d76 100644
--- a/src/liveedit-debugger.js
+++ b/src/liveedit-debugger.js
@@ -138,77 +138,92 @@ Debug.LiveEdit = new function() {
HarvestTodo(root_old_node);
- // Collect shared infos for functions whose code need to be patched.
- var replaced_function_infos = new Array();
- for (var i = 0; i < replace_code_list.length; i++) {
- var info_wrapper = replace_code_list[i].live_shared_info_wrapper;
- if (info_wrapper) {
- replaced_function_infos.push(info_wrapper);
- }
- }
-
+ // Check whether the functions being patched are currently on stack.
+ var stack_info_wrapper =
+ CheckStackActivations(replace_code_list, change_log);
+ preview_description.stack_modified = !!stack_info_wrapper;
+
// We haven't changed anything before this line yet.
// Committing all changes.
-
- // Check that function being patched is not currently on stack or drop them.
- var dropped_functions_number =
- CheckStackActivations(replaced_function_infos, change_log);
-
- preview_description.stack_modified = dropped_functions_number != 0;
-
+
// Start with breakpoints. Convert their line/column positions and
// temporary remove.
var break_points_restorer = TemporaryRemoveBreakPoints(script, change_log);
-
- var old_script;
-
- // Create an old script only if there are function that should be linked
- // to old version.
- if (link_to_old_script_list.length == 0) {
- %LiveEditReplaceScript(script, new_source, null);
- old_script = void 0;
- } else {
- var old_script_name = CreateNameForOldScript(script);
-
- // Update the script text and create a new script representing an old
- // version of the script.
- old_script = %LiveEditReplaceScript(script, new_source,
- old_script_name);
-
- var link_to_old_script_report = new Array();
- change_log.push( { linked_to_old_script: link_to_old_script_report } );
- // We need to link to old script all former nested functions.
- for (var i = 0; i < link_to_old_script_list.length; i++) {
- LinkToOldScript(link_to_old_script_list[i], old_script,
- link_to_old_script_report);
+ try {
+ var old_script;
+
+ // Create an old script only if there are function that should be linked
+ // to old version.
+ if (link_to_old_script_list.length == 0) {
+ %LiveEditReplaceScript(script, new_source, null);
+ old_script = void 0;
+ } else {
+ var old_script_name = CreateNameForOldScript(script);
+
+ // Update the script text and create a new script representing an old
+ // version of the script.
+ old_script = %LiveEditReplaceScript(script, new_source,
+ old_script_name);
+
+ var link_to_old_script_report = new Array();
+ change_log.push( { linked_to_old_script: link_to_old_script_report } );
+
+ // We need to link to old script all former nested functions.
+ for (var i = 0; i < link_to_old_script_list.length; i++) {
+ LinkToOldScript(link_to_old_script_list[i], old_script,
+ link_to_old_script_report);
+ }
+
+ preview_description.created_script_name = old_script_name;
}
- preview_description.created_script_name = old_script_name;
- }
-
- // Link to an actual script all the functions that we are going to use.
- for (var i = 0; i < link_to_original_script_list.length; i++) {
- %LiveEditFunctionSetScript(
- link_to_original_script_list[i].info.shared_function_info, script);
- }
+ // Link to an actual script all the functions that we are going to use.
+ for (var i = 0; i < link_to_original_script_list.length; i++) {
+ %LiveEditFunctionSetScript(
+ link_to_original_script_list[i].info.shared_function_info, script);
+ }
- for (var i = 0; i < replace_code_list.length; i++) {
- PatchFunctionCode(replace_code_list[i], change_log);
- }
-
- var position_patch_report = new Array();
- change_log.push( {position_patched: position_patch_report} );
+ // In the general case there are several functions to be patched
+ // and some of them are activated on the stack.
+ // We drop n topmost frames from the stack, while restaring the
+ // bottom frame. The bottom frame function always is in the patch
+ // list (otherwise there was no reason to touch it). We have to
+ // reset the stack and patch the function in one transaction.
+ // All other functions are patched later.
+ var bottom_function_index;
+ if (stack_info_wrapper) {
+ bottom_function_index = stack_info_wrapper.bottom_function_index;
+ // First we must patch the function that is being reset
+ // to start on stack.
+ PatchFunctionCode(replace_code_list[bottom_function_index],
+ stack_info_wrapper.drop_data, change_log);
+ } else {
+ bottom_function_index = -1;
+ }
+
+
+ for (var i = 0; i < replace_code_list.length; i++) {
+ if (i == bottom_function_index) {
+ // Skip the function that has already been patched.
+ continue;
+ }
+ PatchFunctionCode(replace_code_list[i], void 0, change_log);
+ }
- for (var i = 0; i < update_positions_list.length; i++) {
- // TODO(LiveEdit): take into account wether it's source_changed or
- // unchanged and whether positions changed at all.
- PatchPositions(update_positions_list[i], diff_array,
- position_patch_report);
+ var position_patch_report = new Array();
+ change_log.push( {position_patched: position_patch_report} );
+
+ for (var i = 0; i < update_positions_list.length; i++) {
+ // TODO(LiveEdit): take into account wether it's source_changed or
+ // unchanged and whether positions changed at all.
+ PatchPositions(update_positions_list[i], diff_array,
+ position_patch_report);
+ }
+ } finally {
+ break_points_restorer(pos_translator, old_script);
}
- break_points_restorer(pos_translator, old_script);
-
preview_description.updated = true;
return preview_description;
}
@@ -292,13 +307,13 @@ Debug.LiveEdit = new function() {
}
- // Replaces function's Code.
- function PatchFunctionCode(old_node, change_log) {
+ // Replaces function's Code and optionally resets the stack.
+ function PatchFunctionCode(old_node, stack_drop_data, change_log) {
var new_info = old_node.corresponding_node.info;
var shared_info_wrapper = old_node.live_shared_info_wrapper;
if (shared_info_wrapper) {
%LiveEditReplaceFunctionCode(new_info.raw_array,
- shared_info_wrapper.raw_array);
+ shared_info_wrapper.raw_array, stack_drop_data);
// The function got a new code. However, this new code brings all new
// instances of SharedFunctionInfo for nested functions. However,
@@ -814,6 +829,15 @@ Debug.LiveEdit = new function() {
this.info = raw_array[3];
this.raw_array = raw_array;
}
+
+ // Information about possible stack manipulations. Either
+ // success (drop_data is defined), failure (error_message is defined)
+ // or empty otherwise.
+ function StackInfoWrapper(raw_array) {
+ this.error_message = raw_array[0];
+ this.bottom_function_index = raw_array[1];
+ this.drop_data = raw_array[2];
+ }
// Changes positions (including all statments) in function.
function PatchPositions(old_info_node, diff_array, report_array) {
@@ -869,67 +893,35 @@ Debug.LiveEdit = new function() {
return;
}
- // Minifier forward declaration.
- var FunctionPatchabilityStatus;
-
- // For array of wrapped shared function infos checks that none of them
+ // For an array of function nodes checks that none of them
// have activations on stack (of any thread). Throws a Failure exception
// if this proves to be false.
- function CheckStackActivations(shared_wrapper_list, change_log) {
+ // Returns StackInfoWrapper for future stack manipulations or
+ // nothing if there is nothing to do with stack.
+ function CheckStackActivations(function_node_list, change_log) {
var shared_list = new Array();
- for (var i = 0; i < shared_wrapper_list.length; i++) {
- shared_list[i] = shared_wrapper_list[i].info;
- }
- var result = %LiveEditCheckAndDropActivations(shared_list, true);
- if (result[shared_list.length]) {
- // Extra array element may contain error message.
- throw new Failure(result[shared_list.length]);
- }
-
- var problems = new Array();
- var dropped = new Array();
- for (var i = 0; i < shared_list.length; i++) {
- var shared = shared_wrapper_list[i];
- if (result[i] == FunctionPatchabilityStatus.REPLACED_ON_ACTIVE_STACK) {
- dropped.push({ name: shared.function_name } );
- } else if (result[i] != FunctionPatchabilityStatus.AVAILABLE_FOR_PATCH) {
- var description = {
- name: shared.function_name,
- start_pos: shared.start_position,
- end_pos: shared.end_position,
- replace_problem:
- FunctionPatchabilityStatus.SymbolName(result[i])
- };
- problems.push(description);
+ for (var i = 0; i < function_node_list.length; i++) {
+ var info_wrapper = function_node_list[i].live_shared_info_wrapper;
+ if (info_wrapper) {
+ shared_list[i] = info_wrapper.info;
}
}
- if (dropped.length > 0) {
- change_log.push({ dropped_from_stack: dropped });
+ var raw_data_array = %LiveEditCheckActivations(shared_list);
+ var stack_info_wrapper = new StackInfoWrapper(raw_data_array);
+ var bottom_function_index = stack_info_wrapper.bottom_function_index;
+ if (stack_info_wrapper.error_message) {
+ if (IS_NUMBER(bottom_function_index)) {
+ throw new Failure(stack_info_wrapper.error_message +
+ "; function=" + shared_list[bottom_function_index].function_name);
+ } else {
+ throw new Failure(stack_info_wrapper.error_message + ".");
+ }
}
- if (problems.length > 0) {
- change_log.push( { functions_on_stack: problems } );
- throw new Failure("Blocked by functions on stack");
+ if (IS_NUMBER(bottom_function_index)) {
+ return stack_info_wrapper;
+ } else {
+ return;
}
-
- return dropped.length;
- }
-
- // A copy of the FunctionPatchabilityStatus enum from liveedit.h
- var FunctionPatchabilityStatus = {
- AVAILABLE_FOR_PATCH: 1,
- BLOCKED_ON_ACTIVE_STACK: 2,
- BLOCKED_ON_OTHER_STACK: 3,
- BLOCKED_UNDER_NATIVE_CODE: 4,
- REPLACED_ON_ACTIVE_STACK: 5
- }
-
- FunctionPatchabilityStatus.SymbolName = function(code) {
- var enum = FunctionPatchabilityStatus;
- for (name in enum) {
- if (enum[name] == code) {
- return name;
- }
- }
}
« no previous file with comments | « src/liveedit.cc ('k') | src/mips/debug-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698