| Index: src/liveedit.cc
|
| diff --git a/src/liveedit.cc b/src/liveedit.cc
|
| index e670b442b6d5033c4734d307a3cc74c9d094d537..47208f660c54f93e4aff452ff118d0a492e66f8f 100644
|
| --- a/src/liveedit.cc
|
| +++ b/src/liveedit.cc
|
| @@ -1595,17 +1595,36 @@ static bool IsDropableFrame(StackFrame* frame) {
|
| return !frame->is_exit();
|
| }
|
|
|
| -// Fills result array with statuses of functions. Modifies the stack
|
| -// removing all listed function if possible and if do_drop is true.
|
| -static const char* DropActivationsInActiveThread(
|
| - Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop,
|
| - Zone* zone) {
|
| +
|
| +// Describes a set of call frames that execute any of listed functions.
|
| +// Finding no such frames does not mean error.
|
| +class MultipleFunctionTarget {
|
| + public:
|
| + MultipleFunctionTarget(Handle<JSArray> shared_info_array,
|
| + Handle<JSArray> result)
|
| + : m_shared_info_array(shared_info_array),
|
| + m_result(result) {}
|
| + bool MatchActivation(StackFrame* frame,
|
| + LiveEdit::FunctionPatchabilityStatus status) {
|
| + return CheckActivation(m_shared_info_array, m_result, frame, status);
|
| + }
|
| + const char* GetNotFoundMessage() {
|
| + return NULL;
|
| + }
|
| + private:
|
| + Handle<JSArray> m_shared_info_array;
|
| + Handle<JSArray> m_result;
|
| +};
|
| +
|
| +// Drops all call frame matched by target and all frames above them.
|
| +template<typename TARGET>
|
| +static const char* DropActivationsInActiveThreadImpl(
|
| + TARGET& target, bool do_drop, Zone* zone) {
|
| Isolate* isolate = Isolate::Current();
|
| Debug* debug = isolate->debug();
|
| ZoneScope scope(isolate, DELETE_ON_EXIT);
|
| Vector<StackFrame*> frames = CreateStackMap(zone);
|
|
|
| - int array_len = Smi::cast(shared_info_array->length())->value();
|
|
|
| int top_frame_index = -1;
|
| int frame_index = 0;
|
| @@ -1615,8 +1634,8 @@ static const char* DropActivationsInActiveThread(
|
| top_frame_index = frame_index;
|
| break;
|
| }
|
| - if (CheckActivation(shared_info_array, result, frame,
|
| - LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
|
| + if (target.MatchActivation(
|
| + frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
|
| // We are still above break_frame. It is not a target frame,
|
| // it is a problem.
|
| return "Debugger mark-up on stack is not found";
|
| @@ -1625,7 +1644,7 @@ static const char* DropActivationsInActiveThread(
|
|
|
| if (top_frame_index == -1) {
|
| // We haven't found break frame, but no function is blocking us anyway.
|
| - return NULL;
|
| + return target.GetNotFoundMessage();
|
| }
|
|
|
| bool target_frame_found = false;
|
| @@ -1638,8 +1657,8 @@ static const char* DropActivationsInActiveThread(
|
| c_code_found = true;
|
| break;
|
| }
|
| - if (CheckActivation(shared_info_array, result, frame,
|
| - LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
|
| + if (target.MatchActivation(
|
| + frame, LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
|
| target_frame_found = true;
|
| bottom_js_frame_index = frame_index;
|
| }
|
| @@ -1651,8 +1670,8 @@ static const char* DropActivationsInActiveThread(
|
| for (; frame_index < frames.length(); frame_index++) {
|
| StackFrame* frame = frames[frame_index];
|
| if (frame->is_java_script()) {
|
| - if (CheckActivation(shared_info_array, result, frame,
|
| - LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
|
| + if (target.MatchActivation(
|
| + frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
|
| // Cannot drop frame under C frames.
|
| return NULL;
|
| }
|
| @@ -1667,7 +1686,7 @@ static const char* DropActivationsInActiveThread(
|
|
|
| if (!target_frame_found) {
|
| // Nothing to drop.
|
| - return NULL;
|
| + return target.GetNotFoundMessage();
|
| }
|
|
|
| Debug::FrameDropMode drop_mode = Debug::FRAMES_UNTOUCHED;
|
| @@ -1690,6 +1709,23 @@ static const char* DropActivationsInActiveThread(
|
| }
|
| debug->FramesHaveBeenDropped(new_id, drop_mode,
|
| restarter_frame_function_pointer);
|
| + return NULL;
|
| +}
|
| +
|
| +// Fills result array with statuses of functions. Modifies the stack
|
| +// removing all listed function if possible and if do_drop is true.
|
| +static const char* DropActivationsInActiveThread(
|
| + Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop,
|
| + Zone* zone) {
|
| + MultipleFunctionTarget target(shared_info_array, result);
|
| +
|
| + const char* message =
|
| + DropActivationsInActiveThreadImpl(target, do_drop, zone);
|
| + if (message) {
|
| + return message;
|
| + }
|
| +
|
| + int array_len = Smi::cast(shared_info_array->length())->value();
|
|
|
| // Replace "blocked on active" with "replaced on active" status.
|
| for (int i = 0; i < array_len; i++) {
|
| @@ -1766,6 +1802,41 @@ Handle<JSArray> LiveEdit::CheckAndDropActivations(
|
| }
|
|
|
|
|
| +// Describes a single callframe a target. Not finding this frame
|
| +// means an error.
|
| +class SingleFrameTarget {
|
| + public:
|
| + explicit SingleFrameTarget(JavaScriptFrame* frame) : m_frame(frame) {}
|
| +
|
| + bool MatchActivation(StackFrame* frame,
|
| + LiveEdit::FunctionPatchabilityStatus status) {
|
| + if (frame->fp() == m_frame->fp()) {
|
| + m_saved_status = status;
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| + const char* GetNotFoundMessage() {
|
| + return "Failed to found requested frame";
|
| + }
|
| + LiveEdit::FunctionPatchabilityStatus saved_status() {
|
| + return m_saved_status;
|
| + }
|
| + private:
|
| + JavaScriptFrame* m_frame;
|
| + LiveEdit::FunctionPatchabilityStatus m_saved_status;
|
| +};
|
| +
|
| +
|
| +// Finds a drops required frame and all frames above.
|
| +// Returns error message or NULL.
|
| +const char* LiveEdit::RestartFrame(JavaScriptFrame* frame, Zone* zone) {
|
| + SingleFrameTarget target(frame);
|
| +
|
| + return DropActivationsInActiveThreadImpl(target, true, zone);
|
| +}
|
| +
|
| +
|
| LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate,
|
| FunctionLiteral* fun)
|
| : isolate_(isolate) {
|
|
|