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
This commit is contained in:
peter.rybin@gmail.com 2010-02-17 20:37:08 +00:00
parent 68246ec4a9
commit 3849f08ade
10 changed files with 207 additions and 3 deletions

View File

@ -72,6 +72,7 @@ SOURCES = {
interpreter-irregexp.cc
jsregexp.cc
jump-target.cc
liveedit.cc
log-utils.cc
log.cc
mark-compact.cc

View File

@ -31,6 +31,7 @@
#include "codegen-inl.h"
#include "compiler.h"
#include "debug.h"
#include "liveedit.h"
#include "oprofile-agent.h"
#include "prettyprinter.h"
#include "register-allocator-inl.h"
@ -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
// the compiler.cc code.
Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) {
LiveEditFunctionTracker live_edit_tracker(info->function());
Handle<Script> script = info->script();
if (!script->IsUndefined() && !script->source()->IsUndefined()) {
int len = String::cast(script->source())->length();
@ -245,6 +247,7 @@ Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) {
MacroAssembler masm(NULL, kInitialBufferSize);
CodeGenerator cgen(&masm);
CodeGeneratorScope scope(&cgen);
live_edit_tracker.RecordFunctionScope(info->function()->scope());
cgen.Generate(info, PRIMARY);
if (cgen.HasStackOverflow()) {
ASSERT(!Top::has_pending_exception());
@ -253,7 +256,9 @@ Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) {
InLoopFlag in_loop = (cgen.loop_nesting() != 0) ? IN_LOOP : NOT_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;
}

View File

@ -38,6 +38,7 @@
#include "rewriter.h"
#include "scopes.h"
#include "usage-analyzer.h"
#include "liveedit.h"
namespace v8 {
namespace internal {
@ -429,7 +430,8 @@ Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal,
// compiled. These builtins cannot be handled lazily by the parser,
// since we have to know if a function uses the special natives
// syntax, which is something the parser records.
bool allow_lazy = literal->AllowsLazyCompilation();
bool allow_lazy = literal->AllowsLazyCompilation() &&
!LiveEditFunctionTracker::IsActive();
// Generate code
Handle<Code> code;

View File

@ -32,6 +32,7 @@
#include "full-codegen.h"
#include "stub-cache.h"
#include "debug.h"
#include "liveedit.h"
namespace v8 {
namespace internal {
@ -448,6 +449,8 @@ Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) {
CodeGenerator::MakeCodePrologue(info);
const int kInitialBufferSize = 4 * KB;
MacroAssembler masm(NULL, kInitialBufferSize);
LiveEditFunctionTracker live_edit_tracker(info->function());
FullCodeGenerator cgen(&masm);
cgen.Generate(info, PRIMARY);
if (cgen.HasStackOverflow()) {
@ -455,7 +458,9 @@ Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) {
return Handle<Code>::null();
}
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;
}

87
src/liveedit.cc Normal file
View File

@ -0,0 +1,87 @@
// 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

78
src/liveedit.h Normal file
View File

@ -0,0 +1,78 @@
// 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_ */

View File

@ -308,6 +308,8 @@
'../../src/jsregexp.h',
'../../src/list-inl.h',
'../../src/list.h',
'../../src/liveedit.cc',
'../../src/liveedit.h',
'../../src/log-inl.h',
'../../src/log-utils.cc',
'../../src/log-utils.h',

View File

@ -576,6 +576,14 @@
RelativePath="..\..\src\list.h"
>
</File>
<File
RelativePath="..\..\src\liveedit.cc"
>
</File>
<File
RelativePath="..\..\src\liveedit.h"
>
</File>
<File
RelativePath="..\..\src\log.cc"
>

View File

@ -580,6 +580,14 @@
RelativePath="..\..\src\list.h"
>
</File>
<File
RelativePath="..\..\src\liveedit.cc"
>
</File>
<File
RelativePath="..\..\src\liveedit.h"
>
</File>
<File
RelativePath="..\..\src\log.cc"
>

View File

@ -577,6 +577,14 @@
RelativePath="..\..\src\list.h"
>
</File>
<File
RelativePath="..\..\src\liveedit.cc"
>
</File>
<File
RelativePath="..\..\src\liveedit.h"
>
</File>
<File
RelativePath="..\..\src\log.cc"
>