Commit 3849f08a authored by peter.rybin@gmail.com's avatar peter.rybin@gmail.com

Add central bridge for liveedit support

Review URL: http://codereview.chromium.org/607004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3891 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 68246ec4
...@@ -72,6 +72,7 @@ SOURCES = { ...@@ -72,6 +72,7 @@ SOURCES = {
interpreter-irregexp.cc interpreter-irregexp.cc
jsregexp.cc jsregexp.cc
jump-target.cc jump-target.cc
liveedit.cc
log-utils.cc log-utils.cc
log.cc log.cc
mark-compact.cc mark-compact.cc
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "codegen-inl.h" #include "codegen-inl.h"
#include "compiler.h" #include "compiler.h"
#include "debug.h" #include "debug.h"
#include "liveedit.h"
#include "oprofile-agent.h" #include "oprofile-agent.h"
#include "prettyprinter.h" #include "prettyprinter.h"
#include "register-allocator-inl.h" #include "register-allocator-inl.h"
...@@ -234,6 +235,7 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm, ...@@ -234,6 +235,7 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
// all the pieces into a Code object. This function is only to be called by // all the pieces into a Code object. This function is only to be called by
// the compiler.cc code. // the compiler.cc code.
Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) { Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) {
LiveEditFunctionTracker live_edit_tracker(info->function());
Handle<Script> script = info->script(); Handle<Script> script = info->script();
if (!script->IsUndefined() && !script->source()->IsUndefined()) { if (!script->IsUndefined() && !script->source()->IsUndefined()) {
int len = String::cast(script->source())->length(); int len = String::cast(script->source())->length();
...@@ -245,6 +247,7 @@ Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) { ...@@ -245,6 +247,7 @@ Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) {
MacroAssembler masm(NULL, kInitialBufferSize); MacroAssembler masm(NULL, kInitialBufferSize);
CodeGenerator cgen(&masm); CodeGenerator cgen(&masm);
CodeGeneratorScope scope(&cgen); CodeGeneratorScope scope(&cgen);
live_edit_tracker.RecordFunctionScope(info->function()->scope());
cgen.Generate(info, PRIMARY); cgen.Generate(info, PRIMARY);
if (cgen.HasStackOverflow()) { if (cgen.HasStackOverflow()) {
ASSERT(!Top::has_pending_exception()); ASSERT(!Top::has_pending_exception());
...@@ -253,7 +256,9 @@ Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) { ...@@ -253,7 +256,9 @@ Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) {
InLoopFlag in_loop = (cgen.loop_nesting() != 0) ? IN_LOOP : NOT_IN_LOOP; InLoopFlag in_loop = (cgen.loop_nesting() != 0) ? IN_LOOP : NOT_IN_LOOP;
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop); Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop);
return MakeCodeEpilogue(cgen.masm(), flags, info); Handle<Code> result = MakeCodeEpilogue(cgen.masm(), flags, info);
live_edit_tracker.RecordFunctionCode(result);
return result;
} }
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "rewriter.h" #include "rewriter.h"
#include "scopes.h" #include "scopes.h"
#include "usage-analyzer.h" #include "usage-analyzer.h"
#include "liveedit.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -429,7 +430,8 @@ Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal, ...@@ -429,7 +430,8 @@ Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal,
// compiled. These builtins cannot be handled lazily by the parser, // compiled. These builtins cannot be handled lazily by the parser,
// since we have to know if a function uses the special natives // since we have to know if a function uses the special natives
// syntax, which is something the parser records. // syntax, which is something the parser records.
bool allow_lazy = literal->AllowsLazyCompilation(); bool allow_lazy = literal->AllowsLazyCompilation() &&
!LiveEditFunctionTracker::IsActive();
// Generate code // Generate code
Handle<Code> code; Handle<Code> code;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "full-codegen.h" #include "full-codegen.h"
#include "stub-cache.h" #include "stub-cache.h"
#include "debug.h" #include "debug.h"
#include "liveedit.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -448,6 +449,8 @@ Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) { ...@@ -448,6 +449,8 @@ Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) {
CodeGenerator::MakeCodePrologue(info); CodeGenerator::MakeCodePrologue(info);
const int kInitialBufferSize = 4 * KB; const int kInitialBufferSize = 4 * KB;
MacroAssembler masm(NULL, kInitialBufferSize); MacroAssembler masm(NULL, kInitialBufferSize);
LiveEditFunctionTracker live_edit_tracker(info->function());
FullCodeGenerator cgen(&masm); FullCodeGenerator cgen(&masm);
cgen.Generate(info, PRIMARY); cgen.Generate(info, PRIMARY);
if (cgen.HasStackOverflow()) { if (cgen.HasStackOverflow()) {
...@@ -455,7 +458,9 @@ Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) { ...@@ -455,7 +458,9 @@ Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) {
return Handle<Code>::null(); return Handle<Code>::null();
} }
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
return CodeGenerator::MakeCodeEpilogue(&masm, flags, info); Handle<Code> result = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
live_edit_tracker.RecordFunctionCode(result);
return result;
} }
......
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "v8.h"
#include "liveedit.h"
#include "compiler.h"
#include "oprofile-agent.h"
#include "scopes.h"
#include "global-handles.h"
#include "debug.h"
namespace v8 {
namespace internal {
class FunctionInfoListener {
public:
void FunctionStarted(FunctionLiteral* fun) {
// Implementation follows.
}
void FunctionDone() {
// Implementation follows.
}
void FunctionScope(Scope* scope){
// Implementation follows.
}
void FunctionCode(Handle<Code> function_code) {
// Implementation follows.
}
};
static FunctionInfoListener* active_function_info_listener = NULL;
LiveEditFunctionTracker::LiveEditFunctionTracker(FunctionLiteral* fun) {
if (active_function_info_listener != NULL) {
active_function_info_listener->FunctionStarted(fun);
}
}
LiveEditFunctionTracker::~LiveEditFunctionTracker() {
if (active_function_info_listener != NULL) {
active_function_info_listener->FunctionDone();
}
}
void LiveEditFunctionTracker::RecordFunctionCode(Handle<Code> code) {
if (active_function_info_listener != NULL) {
active_function_info_listener->FunctionCode(code);
}
}
void LiveEditFunctionTracker::RecordFunctionScope(Scope* scope) {
if (active_function_info_listener != NULL) {
active_function_info_listener->FunctionScope(scope);
}
}
bool LiveEditFunctionTracker::IsActive() {
return active_function_info_listener != NULL;
}
} } // namespace v8::internal
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_LIVEEDIT_H_
#define V8_LIVEEDIT_H_
// Live Edit feature implementation.
// User should be able to change script on already running VM. This feature
// matches hot swap features in other frameworks.
//
// The basic use-case is when user spots some mistake in function body
// from debugger and wishes to change the algorithm without restart.
//
// A single change always has a form of a simple replacement (in pseudo-code):
// script.source[positions, positions+length] = new_string;
// Implementation first determines, which function's body includes this
// change area. Then both old and new versions of script are fully compiled
// in order to analyze, whether the function changed its outer scope
// expectations (or number of parameters). If it didn't, function's code is
// patched with a newly compiled code. If it did change, enclosing function
// gets patched. All inner functions are left untouched, whatever happened
// to them in a new script version. However, new version of code will
// instantiate newly compiled functions.
#include "compiler.h"
namespace v8 {
namespace internal {
// This class collects some specific information on structure of functions
// in a particular script. It gets called from compiler all the time, but
// actually records any data only when liveedit operation is in process;
// in any other time this class is very cheap.
//
// The primary interest of the Tracker is to record function scope structures
// in order to analyze whether function code maybe safely patched (with new
// code successfully reading existing data from function scopes). The Tracker
// also collects compiled function codes.
class LiveEditFunctionTracker {
public:
LiveEditFunctionTracker(FunctionLiteral* fun);
~LiveEditFunctionTracker();
void RecordFunctionCode(Handle<Code> code);
void RecordFunctionScope(Scope* scope);
static bool IsActive();
};
} } // namespace v8::internal
#endif /* V*_LIVEEDIT_H_ */
...@@ -308,6 +308,8 @@ ...@@ -308,6 +308,8 @@
'../../src/jsregexp.h', '../../src/jsregexp.h',
'../../src/list-inl.h', '../../src/list-inl.h',
'../../src/list.h', '../../src/list.h',
'../../src/liveedit.cc',
'../../src/liveedit.h',
'../../src/log-inl.h', '../../src/log-inl.h',
'../../src/log-utils.cc', '../../src/log-utils.cc',
'../../src/log-utils.h', '../../src/log-utils.h',
......
...@@ -576,6 +576,14 @@ ...@@ -576,6 +576,14 @@
RelativePath="..\..\src\list.h" RelativePath="..\..\src\list.h"
> >
</File> </File>
<File
RelativePath="..\..\src\liveedit.cc"
>
</File>
<File
RelativePath="..\..\src\liveedit.h"
>
</File>
<File <File
RelativePath="..\..\src\log.cc" RelativePath="..\..\src\log.cc"
> >
......
...@@ -580,6 +580,14 @@ ...@@ -580,6 +580,14 @@
RelativePath="..\..\src\list.h" RelativePath="..\..\src\list.h"
> >
</File> </File>
<File
RelativePath="..\..\src\liveedit.cc"
>
</File>
<File
RelativePath="..\..\src\liveedit.h"
>
</File>
<File <File
RelativePath="..\..\src\log.cc" RelativePath="..\..\src\log.cc"
> >
......
...@@ -577,6 +577,14 @@ ...@@ -577,6 +577,14 @@
RelativePath="..\..\src\list.h" RelativePath="..\..\src\list.h"
> >
</File> </File>
<File
RelativePath="..\..\src\liveedit.cc"
>
</File>
<File
RelativePath="..\..\src\liveedit.h"
>
</File>
<File <File
RelativePath="..\..\src\log.cc" RelativePath="..\..\src\log.cc"
> >
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment