blob: 4ee44661267ecb246aedb036c6f78e64eba6f4c4 [file] [log] [blame]
ager@chromium.org5c838252010-02-19 08:53:10 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_LIVEEDIT_H_
29#define V8_LIVEEDIT_H_
30
31
32
33// Live Edit feature implementation.
34// User should be able to change script on already running VM. This feature
35// matches hot swap features in other frameworks.
36//
37// The basic use-case is when user spots some mistake in function body
38// from debugger and wishes to change the algorithm without restart.
39//
40// A single change always has a form of a simple replacement (in pseudo-code):
41// script.source[positions, positions+length] = new_string;
42// Implementation first determines, which function's body includes this
43// change area. Then both old and new versions of script are fully compiled
44// in order to analyze, whether the function changed its outer scope
45// expectations (or number of parameters). If it didn't, function's code is
46// patched with a newly compiled code. If it did change, enclosing function
47// gets patched. All inner functions are left untouched, whatever happened
48// to them in a new script version. However, new version of code will
49// instantiate newly compiled functions.
50
51
lrn@chromium.org1c092762011-05-09 09:42:16 +000052#include "allocation.h"
ager@chromium.org5c838252010-02-19 08:53:10 +000053#include "compiler.h"
54
55namespace v8 {
56namespace internal {
57
58// This class collects some specific information on structure of functions
59// in a particular script. It gets called from compiler all the time, but
60// actually records any data only when liveedit operation is in process;
61// in any other time this class is very cheap.
62//
63// The primary interest of the Tracker is to record function scope structures
64// in order to analyze whether function code maybe safely patched (with new
65// code successfully reading existing data from function scopes). The Tracker
66// also collects compiled function codes.
67class LiveEditFunctionTracker {
68 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000069 explicit LiveEditFunctionTracker(Isolate* isolate, FunctionLiteral* fun);
ager@chromium.org5c838252010-02-19 08:53:10 +000070 ~LiveEditFunctionTracker();
kmillikin@chromium.org4111b802010-05-03 10:34:42 +000071 void RecordFunctionInfo(Handle<SharedFunctionInfo> info,
72 FunctionLiteral* lit);
73 void RecordRootFunctionInfo(Handle<Code> code);
ager@chromium.org5c838252010-02-19 08:53:10 +000074
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000075 static bool IsActive(Isolate* isolate);
76
77 private:
78#ifdef ENABLE_DEBUGGER_SUPPORT
79 Isolate* isolate_;
80#endif
ager@chromium.org5c838252010-02-19 08:53:10 +000081};
82
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000083#ifdef ENABLE_DEBUGGER_SUPPORT
84
85class LiveEdit : AllStatic {
86 public:
87 static JSArray* GatherCompileInfo(Handle<Script> script,
88 Handle<String> source);
89
90 static void WrapSharedFunctionInfos(Handle<JSArray> array);
91
lrn@chromium.org303ada72010-10-27 09:33:13 +000092 MUST_USE_RESULT static MaybeObject* ReplaceFunctionCode(
93 Handle<JSArray> new_compile_info_array,
94 Handle<JSArray> shared_info_array);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000095
kasperl@chromium.orga5551262010-12-07 12:49:48 +000096 static MaybeObject* FunctionSourceUpdated(Handle<JSArray> shared_info_array);
97
kmillikin@chromium.org4111b802010-05-03 10:34:42 +000098 // Updates script field in FunctionSharedInfo.
99 static void SetFunctionScript(Handle<JSValue> function_wrapper,
100 Handle<Object> script_handle);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000101
lrn@chromium.org303ada72010-10-27 09:33:13 +0000102 MUST_USE_RESULT static MaybeObject* PatchFunctionPositions(
ager@chromium.org357bf652010-04-12 11:30:10 +0000103 Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array);
104
kmillikin@chromium.org4111b802010-05-03 10:34:42 +0000105 // For a script updates its source field. If old_script_name is provided
106 // (i.e. is a String), also creates a copy of the script with its original
107 // source and sends notification to debugger.
108 static Object* ChangeScriptSource(Handle<Script> original_script,
109 Handle<String> new_source,
110 Handle<Object> old_script_name);
111
112 // In a code of a parent function replaces original function as embedded
113 // object with a substitution one.
114 static void ReplaceRefToNestedFunction(Handle<JSValue> parent_function_shared,
115 Handle<JSValue> orig_function_shared,
116 Handle<JSValue> subst_function_shared);
117
ager@chromium.org357bf652010-04-12 11:30:10 +0000118 // Checks listed functions on stack and return array with corresponding
119 // FunctionPatchabilityStatus statuses; extra array element may
120 // contain general error message. Modifies the current stack and
121 // has restart the lowest found frames and drops all other frames above
122 // if possible and if do_drop is true.
123 static Handle<JSArray> CheckAndDropActivations(
124 Handle<JSArray> shared_info_array, bool do_drop);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000125
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000126 // A copy of this is in liveedit-debugger.js.
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000127 enum FunctionPatchabilityStatus {
ager@chromium.org357bf652010-04-12 11:30:10 +0000128 FUNCTION_AVAILABLE_FOR_PATCH = 1,
129 FUNCTION_BLOCKED_ON_ACTIVE_STACK = 2,
130 FUNCTION_BLOCKED_ON_OTHER_STACK = 3,
131 FUNCTION_BLOCKED_UNDER_NATIVE_CODE = 4,
132 FUNCTION_REPLACED_ON_ACTIVE_STACK = 5
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000133 };
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000134
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000135 // Compares 2 strings line-by-line, then token-wise and returns diff in form
136 // of array of triplets (pos1, pos1_end, pos2_end) describing list
137 // of diff chunks.
138 static Handle<JSArray> CompareStrings(Handle<String> s1,
139 Handle<String> s2);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000140};
141
142
143// A general-purpose comparator between 2 arrays.
lrn@chromium.orgc34f5802010-04-28 12:53:43 +0000144class Comparator {
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000145 public:
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000146 // Holds 2 arrays of some elements allowing to compare any pair of
147 // element from the first array and element from the second array.
148 class Input {
149 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000150 virtual int GetLength1() = 0;
151 virtual int GetLength2() = 0;
152 virtual bool Equals(int index1, int index2) = 0;
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000153
154 protected:
155 virtual ~Input() {}
156 };
157
158 // Receives compare result as a series of chunks.
159 class Output {
160 public:
161 // Puts another chunk in result list. Note that technically speaking
162 // only 3 arguments actually needed with 4th being derivable.
163 virtual void AddChunk(int pos1, int pos2, int len1, int len2) = 0;
164
165 protected:
166 virtual ~Output() {}
167 };
168
169 // Finds the difference between 2 arrays of elements.
170 static void CalculateDifference(Input* input,
171 Output* result_writer);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000172};
173
174#endif // ENABLE_DEBUGGER_SUPPORT
175
176
ager@chromium.org5c838252010-02-19 08:53:10 +0000177} } // namespace v8::internal
178
179#endif /* V*_LIVEEDIT_H_ */