Clean up debugger flags.
R=ulan@chromium.org Review URL: https://codereview.chromium.org/261253005 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21270 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
df296a2be0
commit
3ccedf8952
@ -171,7 +171,8 @@ void FullCodeGenerator::Generate() {
|
||||
FrameScope frame_scope(masm_, StackFrame::MANUAL);
|
||||
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
__ Prologue(BUILD_FUNCTION_FRAME);
|
||||
ASSERT(!info->IsStub());
|
||||
__ Prologue(info);
|
||||
info->AddNoFrameRange(0, masm_->pc_offset());
|
||||
|
||||
{ Comment cmnt(masm_, "[ Allocate locals");
|
||||
@ -349,7 +350,7 @@ void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
|
||||
|
||||
void FullCodeGenerator::EmitProfilingCounterReset() {
|
||||
int reset_value = FLAG_interrupt_budget;
|
||||
if (isolate()->IsDebuggerActive()) {
|
||||
if (info_->is_debug()) {
|
||||
// Detect debug break requests as soon as possible.
|
||||
reset_value = FLAG_interrupt_budget >> 4;
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ bool LCodeGen::GeneratePrologue() {
|
||||
|
||||
info()->set_prologue_offset(masm_->pc_offset());
|
||||
if (NeedsEagerFrame()) {
|
||||
__ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
|
||||
__ Prologue(info());
|
||||
frame_is_built_ = true;
|
||||
info_->AddNoFrameRange(0, masm_->pc_offset());
|
||||
}
|
||||
|
@ -902,8 +902,8 @@ void MacroAssembler::LoadConstantPoolPointerRegister() {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
if (frame_mode == BUILD_STUB_FRAME) {
|
||||
void MacroAssembler::Prologue(CompilationInfo* info) {
|
||||
if (info->IsStub()) {
|
||||
PushFixedFrame();
|
||||
Push(Smi::FromInt(StackFrame::STUB));
|
||||
// Adjust FP to point to saved FP.
|
||||
@ -913,7 +913,7 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
this, kNoCodeAgeSequenceLength);
|
||||
// The following three instructions must remain together and unmodified
|
||||
// for code aging to work properly.
|
||||
if (isolate()->IsCodePreAgingActive()) {
|
||||
if (info->IsCodePreAgingActive()) {
|
||||
// Pre-age the code.
|
||||
Code* stub = Code::GetPreAgedCodeAgeStub(isolate());
|
||||
add(r0, pc, Operand(-8));
|
||||
|
@ -519,7 +519,7 @@ class MacroAssembler: public Assembler {
|
||||
Label* not_int32);
|
||||
|
||||
// Generates function and stub prologue code.
|
||||
void Prologue(PrologueFrameMode frame_mode);
|
||||
void Prologue(CompilationInfo* info);
|
||||
|
||||
// Enter exit frame.
|
||||
// stack_space - extra stack space, used for alignment before call to C.
|
||||
|
@ -170,7 +170,8 @@ void FullCodeGenerator::Generate() {
|
||||
// Push(lr, fp, cp, x1);
|
||||
// Add(fp, jssp, 2 * kPointerSize);
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
__ Prologue(BUILD_FUNCTION_FRAME);
|
||||
ASSERT(!info->IsStub());
|
||||
__ Prologue(info);
|
||||
info->AddNoFrameRange(0, masm_->pc_offset());
|
||||
|
||||
// Reserve space on the stack for locals.
|
||||
@ -347,7 +348,7 @@ void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
|
||||
|
||||
void FullCodeGenerator::EmitProfilingCounterReset() {
|
||||
int reset_value = FLAG_interrupt_budget;
|
||||
if (isolate()->IsDebuggerActive()) {
|
||||
if (info_->is_debug()) {
|
||||
// Detect debug break requests as soon as possible.
|
||||
reset_value = FLAG_interrupt_budget >> 4;
|
||||
}
|
||||
|
@ -671,7 +671,7 @@ bool LCodeGen::GeneratePrologue() {
|
||||
ASSERT(__ StackPointer().Is(jssp));
|
||||
info()->set_prologue_offset(masm_->pc_offset());
|
||||
if (NeedsEagerFrame()) {
|
||||
__ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
|
||||
__ Prologue(info());
|
||||
frame_is_built_ = true;
|
||||
info_->AddNoFrameRange(0, masm_->pc_offset());
|
||||
}
|
||||
|
@ -2982,8 +2982,8 @@ void MacroAssembler::TruncateHeapNumberToI(Register result,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
if (frame_mode == BUILD_STUB_FRAME) {
|
||||
void MacroAssembler::Prologue(CompilationInfo* info) {
|
||||
if (info->IsStub()) {
|
||||
ASSERT(StackPointer().Is(jssp));
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register temp = temps.AcquireX();
|
||||
@ -2993,7 +2993,7 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
__ Push(lr, fp, cp, temp);
|
||||
__ Add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp);
|
||||
} else {
|
||||
if (isolate()->IsCodePreAgingActive()) {
|
||||
if (info->IsCodePreAgingActive()) {
|
||||
Code* stub = Code::GetPreAgedCodeAgeStub(isolate());
|
||||
__ EmitCodeAgeSequence(stub);
|
||||
} else {
|
||||
|
@ -1648,7 +1648,7 @@ class MacroAssembler : public Assembler {
|
||||
void ExitFrameRestoreFPRegs();
|
||||
|
||||
// Generates function and stub prologue code.
|
||||
void Prologue(PrologueFrameMode frame_mode);
|
||||
void Prologue(CompilationInfo* info);
|
||||
|
||||
// Enter exit frame. Exit frames are used when calling C code from generated
|
||||
// (JavaScript) code.
|
||||
|
@ -1421,7 +1421,7 @@ bool Genesis::CompileNative(Isolate* isolate,
|
||||
Vector<const char> name,
|
||||
Handle<String> source) {
|
||||
HandleScope scope(isolate);
|
||||
isolate->debugger()->set_compiling_natives(true);
|
||||
Debugger::IgnoreScope compiling_natives(isolate->debugger());
|
||||
// During genesis, the boilerplate for stack overflow won't work until the
|
||||
// environment has been at least partially initialized. Add a stack check
|
||||
// before entering JS code to catch overflow early.
|
||||
@ -1437,7 +1437,6 @@ bool Genesis::CompileNative(Isolate* isolate,
|
||||
true);
|
||||
ASSERT(isolate->has_pending_exception() != result);
|
||||
if (!result) isolate->clear_pending_exception();
|
||||
isolate->debugger()->set_compiling_natives(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,8 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
|
||||
Handle<Code> code =
|
||||
isolate->factory()->NewCode(desc, flags, masm->CodeObject(),
|
||||
false, is_crankshafted,
|
||||
info->prologue_offset());
|
||||
info->prologue_offset(),
|
||||
info->is_debug());
|
||||
isolate->counters()->total_compiled_code_size()->Increment(
|
||||
code->instruction_size());
|
||||
isolate->heap()->IncrementCodeGeneratedBytes(is_crankshafted,
|
||||
|
@ -110,9 +110,9 @@ void CompilationInfo::Initialize(Isolate* isolate,
|
||||
}
|
||||
mode_ = mode;
|
||||
abort_due_to_dependency_ = false;
|
||||
if (script_->type()->value() == Script::TYPE_NATIVE) {
|
||||
MarkAsNative();
|
||||
}
|
||||
if (script_->type()->value() == Script::TYPE_NATIVE) MarkAsNative();
|
||||
if (isolate_->debugger()->is_active()) MarkAsDebug();
|
||||
|
||||
if (!shared_info_.is_null()) {
|
||||
ASSERT(strict_mode() == SLOPPY);
|
||||
SetStrictMode(shared_info_->strict_mode());
|
||||
@ -279,21 +279,6 @@ class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder {
|
||||
};
|
||||
|
||||
|
||||
// Determine whether to use the full compiler for all code. If the flag
|
||||
// --always-full-compiler is specified this is the case. For the virtual frame
|
||||
// based compiler the full compiler is also used if a debugger is connected, as
|
||||
// the code from the full compiler supports mode precise break points. For the
|
||||
// crankshaft adaptive compiler debugging the optimized code is not possible at
|
||||
// all. However crankshaft support recompilation of functions, so in this case
|
||||
// the full compiler need not be be used if a debugger is attached, but only if
|
||||
// break points has actually been set.
|
||||
static bool IsDebuggerActive(Isolate* isolate) {
|
||||
return isolate->use_crankshaft() ?
|
||||
isolate->debug()->has_break_points() :
|
||||
isolate->debugger()->IsDebuggerActive();
|
||||
}
|
||||
|
||||
|
||||
OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
|
||||
ASSERT(isolate()->use_crankshaft());
|
||||
ASSERT(info()->IsOptimizing());
|
||||
@ -311,7 +296,9 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
|
||||
// to use the Hydrogen-based optimizing compiler. We already have
|
||||
// generated code for this from the shared function object.
|
||||
if (FLAG_always_full_compiler) return AbortOptimization();
|
||||
if (IsDebuggerActive(isolate())) return AbortOptimization(kDebuggerIsActive);
|
||||
|
||||
// Do not use crankshaft if compiling for debugging.
|
||||
if (info()->is_debug()) return AbortOptimization(kDebuggerIsActive);
|
||||
|
||||
// Limit the number of times we re-compile a functions with
|
||||
// the optimizing compiler.
|
||||
@ -711,6 +698,8 @@ MaybeHandle<Code> Compiler::GetCodeForDebugging(Handle<JSFunction> function) {
|
||||
Isolate* isolate = info.isolate();
|
||||
VMState<COMPILER> state(isolate);
|
||||
|
||||
info.MarkAsDebug();
|
||||
|
||||
ASSERT(!isolate->has_pending_exception());
|
||||
Handle<Code> old_code(function->shared()->code());
|
||||
ASSERT(old_code->kind() == Code::FUNCTION);
|
||||
|
@ -50,7 +50,6 @@ class CompilationInfo {
|
||||
bool is_eval() const { return IsEval::decode(flags_); }
|
||||
bool is_global() const { return IsGlobal::decode(flags_); }
|
||||
StrictMode strict_mode() const { return StrictModeField::decode(flags_); }
|
||||
bool is_in_loop() const { return IsInLoop::decode(flags_); }
|
||||
FunctionLiteral* function() const { return function_; }
|
||||
Scope* scope() const { return scope_; }
|
||||
Scope* global_scope() const { return global_scope_; }
|
||||
@ -95,10 +94,6 @@ class CompilationInfo {
|
||||
ASSERT(this->strict_mode() == SLOPPY || this->strict_mode() == strict_mode);
|
||||
flags_ = StrictModeField::update(flags_, strict_mode);
|
||||
}
|
||||
void MarkAsInLoop() {
|
||||
ASSERT(is_lazy());
|
||||
flags_ |= IsInLoop::encode(true);
|
||||
}
|
||||
void MarkAsNative() {
|
||||
flags_ |= IsNative::encode(true);
|
||||
}
|
||||
@ -151,6 +146,18 @@ class CompilationInfo {
|
||||
return MustNotHaveEagerFrame::decode(flags_);
|
||||
}
|
||||
|
||||
void MarkAsDebug() {
|
||||
flags_ |= IsDebug::encode(true);
|
||||
}
|
||||
|
||||
bool is_debug() const {
|
||||
return IsDebug::decode(flags_);
|
||||
}
|
||||
|
||||
bool IsCodePreAgingActive() const {
|
||||
return FLAG_optimize_for_size && FLAG_age_code && !is_debug();
|
||||
}
|
||||
|
||||
void SetParseRestriction(ParseRestriction restriction) {
|
||||
flags_ = ParseRestricitonField::update(flags_, restriction);
|
||||
}
|
||||
@ -353,8 +360,8 @@ class CompilationInfo {
|
||||
// Flags that can be set for eager compilation.
|
||||
class IsEval: public BitField<bool, 1, 1> {};
|
||||
class IsGlobal: public BitField<bool, 2, 1> {};
|
||||
// Flags that can be set for lazy compilation.
|
||||
class IsInLoop: public BitField<bool, 3, 1> {};
|
||||
// If the function is being compiled for the debugger.
|
||||
class IsDebug: public BitField<bool, 3, 1> {};
|
||||
// Strict mode - used in eager compilation.
|
||||
class StrictModeField: public BitField<StrictMode, 4, 1> {};
|
||||
// Is this a function from our natives.
|
||||
|
78
src/debug.cc
78
src/debug.cc
@ -766,11 +766,9 @@ bool Debug::Load() {
|
||||
|
||||
// Bail out if we're already in the process of compiling the native
|
||||
// JavaScript source code for the debugger.
|
||||
if (debugger->compiling_natives() ||
|
||||
debugger->is_loading_debugger())
|
||||
return false;
|
||||
debugger->set_loading_debugger(true);
|
||||
if (debugger->ignore_debugger()) return false;
|
||||
|
||||
Debugger::IgnoreScope during_load(debugger);
|
||||
// Disable breakpoints and interrupts while compiling and running the
|
||||
// debugger scripts including the context creation code.
|
||||
DisableBreak disable(isolate_, true);
|
||||
@ -806,7 +804,6 @@ bool Debug::Load() {
|
||||
false);
|
||||
|
||||
// Compile the JavaScript for the debugger in the debugger context.
|
||||
debugger->set_compiling_natives(true);
|
||||
bool caught_exception =
|
||||
!CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) ||
|
||||
!CompileDebuggerScript(isolate_, Natives::GetIndex("debug"));
|
||||
@ -816,11 +813,8 @@ bool Debug::Load() {
|
||||
!CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
|
||||
}
|
||||
|
||||
debugger->set_compiling_natives(false);
|
||||
|
||||
// Make sure we mark the debugger as not loading before we might
|
||||
// return.
|
||||
debugger->set_loading_debugger(false);
|
||||
|
||||
// Check for caught exceptions.
|
||||
if (caught_exception) return false;
|
||||
@ -1998,37 +1992,15 @@ class ActiveFunctionsRedirector : public ThreadVisitor {
|
||||
};
|
||||
|
||||
|
||||
class ForceDebuggerActive {
|
||||
public:
|
||||
explicit ForceDebuggerActive(Isolate *isolate) {
|
||||
isolate_ = isolate;
|
||||
old_state_ = isolate->debugger()->force_debugger_active();
|
||||
isolate_->debugger()->set_force_debugger_active(true);
|
||||
}
|
||||
|
||||
~ForceDebuggerActive() {
|
||||
isolate_->debugger()->set_force_debugger_active(old_state_);
|
||||
}
|
||||
|
||||
private:
|
||||
Isolate *isolate_;
|
||||
bool old_state_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ForceDebuggerActive);
|
||||
};
|
||||
|
||||
|
||||
void Debug::EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) {
|
||||
if (function->code()->kind() == Code::FUNCTION &&
|
||||
function->code()->has_debug_break_slots()) {
|
||||
// Nothing to do. Function code already had debug break slots.
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure that the shared full code is compiled with debug
|
||||
// break slots.
|
||||
if (!function->shared()->code()->has_debug_break_slots()) {
|
||||
ForceDebuggerActive force_debugger_active(isolate_);
|
||||
MaybeHandle<Code> code = Compiler::GetCodeForDebugging(function);
|
||||
// Recompilation can fail. In that case leave the code as it was.
|
||||
if (!code.is_null()) function->ReplaceCode(*code.ToHandleChecked());
|
||||
@ -2652,14 +2624,12 @@ void Debug::AfterGarbageCollection() {
|
||||
|
||||
|
||||
Debugger::Debugger(Isolate* isolate)
|
||||
: debugger_access_(isolate->debugger_access()),
|
||||
event_listener_(Handle<Object>()),
|
||||
: event_listener_(Handle<Object>()),
|
||||
event_listener_data_(Handle<Object>()),
|
||||
compiling_natives_(false),
|
||||
is_loading_debugger_(false),
|
||||
is_active_(false),
|
||||
ignore_debugger_(false),
|
||||
live_edit_enabled_(true),
|
||||
never_unload_debugger_(false),
|
||||
force_debugger_active_(false),
|
||||
message_handler_(NULL),
|
||||
debugger_unload_pending_(false),
|
||||
debug_message_dispatch_handler_(NULL),
|
||||
@ -2760,7 +2730,7 @@ void Debugger::OnException(Handle<Object> exception, bool uncaught) {
|
||||
|
||||
// Bail out based on state or if there is no listener for this event
|
||||
if (debug->InDebugger()) return;
|
||||
if (!Debugger::EventActive(v8::Exception)) return;
|
||||
if (!Debugger::EventActive()) return;
|
||||
|
||||
Handle<Object> promise = debug->GetPromiseForUncaughtException();
|
||||
uncaught |= !promise->IsUndefined();
|
||||
@ -2804,7 +2774,7 @@ void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
|
||||
ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
|
||||
|
||||
// Bail out if there is no listener for this event
|
||||
if (!Debugger::EventActive(v8::Break)) return;
|
||||
if (!Debugger::EventActive()) return;
|
||||
|
||||
// Debugger must be entered in advance.
|
||||
ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
|
||||
@ -2826,8 +2796,7 @@ void Debugger::OnBeforeCompile(Handle<Script> script) {
|
||||
|
||||
// Bail out based on state or if there is no listener for this event
|
||||
if (isolate_->debug()->InDebugger()) return;
|
||||
if (compiling_natives()) return;
|
||||
if (!EventActive(v8::BeforeCompile)) return;
|
||||
if (!EventActive()) return;
|
||||
|
||||
// Enter the debugger.
|
||||
EnterDebugger debugger(isolate_);
|
||||
@ -2855,10 +2824,7 @@ void Debugger::OnAfterCompile(Handle<Script> script,
|
||||
debug->AddScriptToScriptCache(script);
|
||||
|
||||
// No more to do if not debugging.
|
||||
if (!IsDebuggerActive()) return;
|
||||
|
||||
// No compile events while compiling natives.
|
||||
if (compiling_natives()) return;
|
||||
if (!Debugger::EventActive()) return;
|
||||
|
||||
// Store whether in debugger before entering debugger.
|
||||
bool in_debugger = debug->InDebugger();
|
||||
@ -2897,7 +2863,6 @@ void Debugger::OnAfterCompile(Handle<Script> script,
|
||||
}
|
||||
// Bail out based on state or if there is no listener for this event
|
||||
if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return;
|
||||
if (!Debugger::EventActive(v8::AfterCompile)) return;
|
||||
|
||||
// Create the compile state object.
|
||||
Handle<Object> event_data;
|
||||
@ -2914,8 +2879,7 @@ void Debugger::OnScriptCollected(int id) {
|
||||
|
||||
// No more to do if not debugging.
|
||||
if (isolate_->debug()->InDebugger()) return;
|
||||
if (!IsDebuggerActive()) return;
|
||||
if (!Debugger::EventActive(v8::ScriptCollected)) return;
|
||||
if (!Debugger::EventActive()) return;
|
||||
|
||||
// Enter the debugger.
|
||||
EnterDebugger debugger(isolate_);
|
||||
@ -3129,7 +3093,7 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
|
||||
CommandMessage command = command_queue_.Get();
|
||||
isolate_->logger()->DebugTag(
|
||||
"Got request from command queue, in interactive loop.");
|
||||
if (!Debugger::IsDebuggerActive()) {
|
||||
if (!Debugger::is_active()) {
|
||||
// Delete command text and user data.
|
||||
command.Dispose();
|
||||
return;
|
||||
@ -3217,7 +3181,7 @@ void Debugger::SetEventListener(Handle<Object> callback,
|
||||
|
||||
|
||||
void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) {
|
||||
LockGuard<RecursiveMutex> with(debugger_access_);
|
||||
LockGuard<RecursiveMutex> with(&debugger_access_);
|
||||
|
||||
message_handler_ = handler;
|
||||
ListenersChanged();
|
||||
@ -3232,8 +3196,9 @@ void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) {
|
||||
|
||||
|
||||
void Debugger::ListenersChanged() {
|
||||
bool active = IsDebuggerActive();
|
||||
if (active) {
|
||||
LockGuard<RecursiveMutex> with(&debugger_access_);
|
||||
is_active_ = message_handler_ != NULL || !event_listener_.is_null();
|
||||
if (is_active_) {
|
||||
// Disable the compilation cache when the debugger is active.
|
||||
isolate_->compilation_cache()->Disable();
|
||||
debugger_unload_pending_ = false;
|
||||
@ -3261,7 +3226,7 @@ void Debugger::SetDebugMessageDispatchHandler(
|
||||
// Calls the registered debug message handler. This callback is part of the
|
||||
// public API.
|
||||
void Debugger::InvokeMessageHandler(MessageImpl message) {
|
||||
LockGuard<RecursiveMutex> with(debugger_access_);
|
||||
LockGuard<RecursiveMutex> with(&debugger_access_);
|
||||
|
||||
if (message_handler_ != NULL) {
|
||||
message_handler_(message);
|
||||
@ -3319,15 +3284,6 @@ void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
|
||||
}
|
||||
|
||||
|
||||
bool Debugger::IsDebuggerActive() {
|
||||
LockGuard<RecursiveMutex> with(debugger_access_);
|
||||
|
||||
return message_handler_ != NULL ||
|
||||
!event_listener_.is_null() ||
|
||||
force_debugger_active_;
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun,
|
||||
Handle<Object> data) {
|
||||
// When calling functions in the debugger prevent it from beeing unloaded.
|
||||
@ -3478,7 +3434,7 @@ EnterDebugger::~EnterDebugger() {
|
||||
}
|
||||
|
||||
// If leaving the debugger with the debugger no longer active unload it.
|
||||
if (!isolate_->debugger()->IsDebuggerActive()) {
|
||||
if (!isolate_->debugger()->is_active()) {
|
||||
isolate_->debugger()->UnloadDebugger();
|
||||
}
|
||||
}
|
||||
|
57
src/debug.h
57
src/debug.h
@ -822,45 +822,49 @@ class Debugger {
|
||||
void UnloadDebugger();
|
||||
friend void ForceUnloadDebugger(); // In test-debug.cc
|
||||
|
||||
inline bool EventActive(v8::DebugEvent event) {
|
||||
LockGuard<RecursiveMutex> lock_guard(debugger_access_);
|
||||
inline bool EventActive() {
|
||||
LockGuard<RecursiveMutex> lock_guard(&debugger_access_);
|
||||
|
||||
// Check whether the message handler was been cleared.
|
||||
// TODO(yangguo): handle loading and unloading of the debugger differently.
|
||||
if (debugger_unload_pending_) {
|
||||
if (isolate_->debug()->debugger_entry() == NULL) {
|
||||
UnloadDebugger();
|
||||
}
|
||||
}
|
||||
|
||||
if (((event == v8::BeforeCompile) || (event == v8::AfterCompile)) &&
|
||||
!FLAG_debug_compile_events) {
|
||||
return false;
|
||||
|
||||
} else if ((event == v8::ScriptCollected) &&
|
||||
!FLAG_debug_script_collected_events) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Currently argument event is not used.
|
||||
return !compiling_natives_ && Debugger::IsDebuggerActive();
|
||||
return !ignore_debugger_ && is_active_;
|
||||
}
|
||||
|
||||
void set_compiling_natives(bool compiling_natives) {
|
||||
compiling_natives_ = compiling_natives;
|
||||
}
|
||||
bool compiling_natives() const { return compiling_natives_; }
|
||||
void set_loading_debugger(bool v) { is_loading_debugger_ = v; }
|
||||
bool is_loading_debugger() const { return is_loading_debugger_; }
|
||||
bool ignore_debugger() const { return ignore_debugger_; }
|
||||
void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
|
||||
bool live_edit_enabled() const {
|
||||
return FLAG_enable_liveedit && live_edit_enabled_ ;
|
||||
}
|
||||
void set_force_debugger_active(bool force_debugger_active) {
|
||||
force_debugger_active_ = force_debugger_active;
|
||||
}
|
||||
bool force_debugger_active() const { return force_debugger_active_; }
|
||||
|
||||
bool IsDebuggerActive();
|
||||
bool is_active() {
|
||||
LockGuard<RecursiveMutex> lock_guard(&debugger_access_);
|
||||
return is_active_;
|
||||
}
|
||||
|
||||
class IgnoreScope {
|
||||
public:
|
||||
explicit IgnoreScope(Debugger* debugger)
|
||||
: debugger_(debugger),
|
||||
old_state_(debugger_->ignore_debugger_) {
|
||||
debugger_->ignore_debugger_ = true;
|
||||
}
|
||||
|
||||
~IgnoreScope() {
|
||||
debugger_->ignore_debugger_ = old_state_;
|
||||
}
|
||||
|
||||
private:
|
||||
Debugger* debugger_;
|
||||
bool old_state_;
|
||||
DISALLOW_COPY_AND_ASSIGN(IgnoreScope);
|
||||
};
|
||||
|
||||
private:
|
||||
explicit Debugger(Isolate* isolate);
|
||||
@ -878,14 +882,13 @@ class Debugger {
|
||||
Handle<Object> event_data);
|
||||
void ListenersChanged();
|
||||
|
||||
RecursiveMutex* debugger_access_; // Mutex guarding debugger variables.
|
||||
RecursiveMutex debugger_access_; // Mutex guarding debugger variables.
|
||||
Handle<Object> event_listener_; // Global handle to listener.
|
||||
Handle<Object> event_listener_data_;
|
||||
bool compiling_natives_; // Are we compiling natives?
|
||||
bool is_loading_debugger_; // Are we loading the debugger?
|
||||
bool is_active_;
|
||||
bool ignore_debugger_; // Are we temporarily ignoring the debugger?
|
||||
bool live_edit_enabled_; // Enable LiveEdit.
|
||||
bool never_unload_debugger_; // Can we unload the debugger?
|
||||
bool force_debugger_active_; // Activate debugger without event listeners.
|
||||
v8::Debug::MessageHandler2 message_handler_;
|
||||
bool debugger_unload_pending_; // Was message handler cleared?
|
||||
|
||||
|
@ -104,7 +104,7 @@ MUST_USE_RESULT static MaybeHandle<Object> Invoke(
|
||||
if (has_exception) {
|
||||
isolate->ReportPendingMessages();
|
||||
// Reset stepping state when script exits with uncaught exception.
|
||||
if (isolate->debugger()->IsDebuggerActive()) {
|
||||
if (isolate->debugger()->is_active()) {
|
||||
isolate->debug()->ClearStepping();
|
||||
}
|
||||
return MaybeHandle<Object>();
|
||||
@ -685,7 +685,7 @@ void Execution::DebugBreakHelper(Isolate* isolate) {
|
||||
if (isolate->bootstrapper()->IsActive()) return;
|
||||
|
||||
// Ignore debug break if debugger is not active.
|
||||
if (!isolate->debugger()->IsDebuggerActive()) return;
|
||||
if (!isolate->debugger()->is_active()) return;
|
||||
|
||||
StackLimitCheck check(isolate);
|
||||
if (check.HasOverflowed()) return;
|
||||
|
@ -1395,7 +1395,8 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc,
|
||||
Handle<Object> self_ref,
|
||||
bool immovable,
|
||||
bool crankshafted,
|
||||
int prologue_offset) {
|
||||
int prologue_offset,
|
||||
bool is_debug) {
|
||||
Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED);
|
||||
Handle<ConstantPoolArray> constant_pool =
|
||||
desc.origin->NewConstantPool(isolate());
|
||||
@ -1428,13 +1429,14 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc,
|
||||
code->set_marked_for_deoptimization(false);
|
||||
}
|
||||
|
||||
if (is_debug) {
|
||||
ASSERT(code->kind() == Code::FUNCTION);
|
||||
code->set_has_debug_break_slots(true);
|
||||
}
|
||||
|
||||
desc.origin->PopulateConstantPool(*constant_pool);
|
||||
code->set_constant_pool(*constant_pool);
|
||||
|
||||
if (code->kind() == Code::FUNCTION) {
|
||||
code->set_has_debug_break_slots(isolate()->debugger()->IsDebuggerActive());
|
||||
}
|
||||
|
||||
// Allow self references to created code object by patching the handle to
|
||||
// point to the newly allocated Code object.
|
||||
if (!self_ref.is_null()) *(self_ref.location()) = *code;
|
||||
|
@ -489,7 +489,8 @@ class Factory V8_FINAL {
|
||||
Handle<Object> self_reference,
|
||||
bool immovable = false,
|
||||
bool crankshafted = false,
|
||||
int prologue_offset = Code::kPrologueOffsetNotSet);
|
||||
int prologue_offset = Code::kPrologueOffsetNotSet,
|
||||
bool is_debug = false);
|
||||
|
||||
Handle<Code> CopyCode(Handle<Code> code);
|
||||
|
||||
|
@ -671,17 +671,6 @@ DEFINE_string(map_counters, "", "Map counters to a file")
|
||||
DEFINE_args(js_arguments,
|
||||
"Pass all remaining arguments to the script. Alias for \"--\".")
|
||||
|
||||
#if defined(WEBOS__)
|
||||
DEFINE_bool(debug_compile_events, false, "Enable debugger compile events")
|
||||
DEFINE_bool(debug_script_collected_events, false,
|
||||
"Enable debugger script collected events")
|
||||
#else
|
||||
DEFINE_bool(debug_compile_events, true, "Enable debugger compile events")
|
||||
DEFINE_bool(debug_script_collected_events, true,
|
||||
"Enable debugger script collected events")
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// GDB JIT integration flags.
|
||||
//
|
||||
|
@ -930,13 +930,6 @@ class StackFrameLocator BASE_EMBEDDED {
|
||||
};
|
||||
|
||||
|
||||
// Used specify the type of prologue to generate.
|
||||
enum PrologueFrameMode {
|
||||
BUILD_FUNCTION_FRAME,
|
||||
BUILD_STUB_FRAME
|
||||
};
|
||||
|
||||
|
||||
// Reads all frames on the current stack and copies them into the current
|
||||
// zone memory.
|
||||
Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
|
||||
|
@ -805,7 +805,7 @@ void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
|
||||
|
||||
|
||||
void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
|
||||
if (!isolate()->debugger()->IsDebuggerActive()) {
|
||||
if (!info_->is_debug()) {
|
||||
CodeGenerator::RecordPositions(masm_, stmt->position());
|
||||
} else {
|
||||
// Check if the statement will be breakable without adding a debug break
|
||||
@ -827,7 +827,7 @@ void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
|
||||
|
||||
|
||||
void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
|
||||
if (!isolate()->debugger()->IsDebuggerActive()) {
|
||||
if (!info_->is_debug()) {
|
||||
CodeGenerator::RecordPositions(masm_, expr->position());
|
||||
} else {
|
||||
// Check if the expression will be breakable without adding a debug break
|
||||
|
@ -157,7 +157,8 @@ void FullCodeGenerator::Generate() {
|
||||
FrameScope frame_scope(masm_, StackFrame::MANUAL);
|
||||
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
__ Prologue(BUILD_FUNCTION_FRAME);
|
||||
ASSERT(!info->IsStub());
|
||||
__ Prologue(info);
|
||||
info->AddNoFrameRange(0, masm_->pc_offset());
|
||||
|
||||
{ Comment cmnt(masm_, "[ Allocate locals");
|
||||
|
@ -188,7 +188,7 @@ bool LCodeGen::GeneratePrologue() {
|
||||
if (NeedsEagerFrame()) {
|
||||
ASSERT(!frame_is_built_);
|
||||
frame_is_built_ = true;
|
||||
__ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
|
||||
__ Prologue(info());
|
||||
info()->AddNoFrameRange(0, masm_->pc_offset());
|
||||
}
|
||||
|
||||
|
@ -908,8 +908,8 @@ void MacroAssembler::AssertNotSmi(Register object) {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
if (frame_mode == BUILD_STUB_FRAME) {
|
||||
void MacroAssembler::Prologue(CompilationInfo* info) {
|
||||
if (info->IsStub()) {
|
||||
push(ebp); // Caller's frame pointer.
|
||||
mov(ebp, esp);
|
||||
push(esi); // Callee's context.
|
||||
@ -917,7 +917,7 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
} else {
|
||||
PredictableCodeSizeScope predictible_code_size_scope(this,
|
||||
kNoCodeAgeSequenceLength);
|
||||
if (isolate()->IsCodePreAgingActive()) {
|
||||
if (info->IsCodePreAgingActive()) {
|
||||
// Pre-age the code.
|
||||
call(isolate()->builtins()->MarkCodeAsExecutedOnce(),
|
||||
RelocInfo::CODE_AGE_SEQUENCE);
|
||||
|
@ -204,7 +204,7 @@ class MacroAssembler: public Assembler {
|
||||
void DebugBreak();
|
||||
|
||||
// Generates function and stub prologue code.
|
||||
void Prologue(PrologueFrameMode frame_mode);
|
||||
void Prologue(CompilationInfo* info);
|
||||
|
||||
// Enter specific kind of exit frame. Expects the number of
|
||||
// arguments in register eax and sets up the number of arguments in
|
||||
|
@ -25,16 +25,6 @@ SaveContext::SaveContext(Isolate* isolate)
|
||||
}
|
||||
|
||||
|
||||
bool Isolate::IsCodePreAgingActive() {
|
||||
return FLAG_optimize_for_size && FLAG_age_code && !IsDebuggerActive();
|
||||
}
|
||||
|
||||
|
||||
bool Isolate::IsDebuggerActive() {
|
||||
return debugger()->IsDebuggerActive();
|
||||
}
|
||||
|
||||
|
||||
bool Isolate::DebuggerHasBreakPoints() {
|
||||
return debug()->has_break_points();
|
||||
}
|
||||
|
@ -512,9 +512,6 @@ class Isolate {
|
||||
// Mutex for serializing access to break control structures.
|
||||
RecursiveMutex* break_access() { return &break_access_; }
|
||||
|
||||
// Mutex for serializing access to debugger.
|
||||
RecursiveMutex* debugger_access() { return &debugger_access_; }
|
||||
|
||||
Address get_address_from_id(AddressId id);
|
||||
|
||||
// Access to top context (where the current function object was created).
|
||||
@ -930,12 +927,9 @@ class Isolate {
|
||||
return &interp_canonicalize_mapping_;
|
||||
}
|
||||
|
||||
inline bool IsCodePreAgingActive();
|
||||
|
||||
Debugger* debugger() { return debugger_; }
|
||||
Debug* debug() { return debug_; }
|
||||
|
||||
inline bool IsDebuggerActive();
|
||||
inline bool DebuggerHasBreakPoints();
|
||||
|
||||
CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
|
||||
@ -1194,7 +1188,6 @@ class Isolate {
|
||||
CodeRange* code_range_;
|
||||
RecursiveMutex break_access_;
|
||||
Atomic32 debugger_initialized_;
|
||||
RecursiveMutex debugger_access_;
|
||||
Logger* logger_;
|
||||
StackGuard stack_guard_;
|
||||
StatsTable* stats_table_;
|
||||
|
@ -176,7 +176,8 @@ void FullCodeGenerator::Generate() {
|
||||
FrameScope frame_scope(masm_, StackFrame::MANUAL);
|
||||
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
__ Prologue(BUILD_FUNCTION_FRAME);
|
||||
ASSERT(!info->IsStub());
|
||||
__ Prologue(info);
|
||||
info->AddNoFrameRange(0, masm_->pc_offset());
|
||||
|
||||
{ Comment cmnt(masm_, "[ Allocate locals");
|
||||
@ -353,7 +354,7 @@ void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
|
||||
|
||||
void FullCodeGenerator::EmitProfilingCounterReset() {
|
||||
int reset_value = FLAG_interrupt_budget;
|
||||
if (isolate()->IsDebuggerActive()) {
|
||||
if (info_->is_debug()) {
|
||||
// Detect debug break requests as soon as possible.
|
||||
reset_value = FLAG_interrupt_budget >> 4;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ bool LCodeGen::GeneratePrologue() {
|
||||
|
||||
info()->set_prologue_offset(masm_->pc_offset());
|
||||
if (NeedsEagerFrame()) {
|
||||
__ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
|
||||
__ Prologue(info());
|
||||
frame_is_built_ = true;
|
||||
info_->AddNoFrameRange(0, masm_->pc_offset());
|
||||
}
|
||||
|
@ -4452,8 +4452,8 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
if (frame_mode == BUILD_STUB_FRAME) {
|
||||
void MacroAssembler::Prologue(CompilationInfo* info) {
|
||||
if (info->IsStub()) {
|
||||
Push(ra, fp, cp);
|
||||
Push(Smi::FromInt(StackFrame::STUB));
|
||||
// Adjust FP to point to saved FP.
|
||||
@ -4463,7 +4463,7 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
this, kNoCodeAgeSequenceLength);
|
||||
// The following three instructions must remain together and unmodified
|
||||
// for code aging to work properly.
|
||||
if (isolate()->IsCodePreAgingActive()) {
|
||||
if (info->IsCodePreAgingActive()) {
|
||||
// Pre-age the code.
|
||||
Code* stub = Code::GetPreAgedCodeAgeStub(isolate());
|
||||
nop(Assembler::CODE_AGE_MARKER_NOP);
|
||||
|
@ -1492,7 +1492,7 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
}
|
||||
|
||||
// Generates function and stub prologue code.
|
||||
void Prologue(PrologueFrameMode frame_mode);
|
||||
void Prologue(CompilationInfo* info);
|
||||
|
||||
// Activation support.
|
||||
void EnterFrame(StackFrame::Type type);
|
||||
|
@ -5609,7 +5609,7 @@ RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
|
||||
// to a built-in function such as Array.forEach.
|
||||
RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
|
||||
ASSERT(args.length() == 1);
|
||||
if (!isolate->IsDebuggerActive() || !isolate->debug()->StepInActive()) {
|
||||
if (!isolate->debugger()->is_active() || !isolate->debug()->StepInActive()) {
|
||||
return isolate->heap()->false_value();
|
||||
}
|
||||
CONVERT_ARG_CHECKED(Object, callback, 0);
|
||||
|
@ -157,7 +157,8 @@ void FullCodeGenerator::Generate() {
|
||||
FrameScope frame_scope(masm_, StackFrame::MANUAL);
|
||||
|
||||
info->set_prologue_offset(masm_->pc_offset());
|
||||
__ Prologue(BUILD_FUNCTION_FRAME);
|
||||
ASSERT(!info->IsStub());
|
||||
__ Prologue(info);
|
||||
info->AddNoFrameRange(0, masm_->pc_offset());
|
||||
|
||||
{ Comment cmnt(masm_, "[ Allocate locals");
|
||||
|
@ -149,7 +149,7 @@ bool LCodeGen::GeneratePrologue() {
|
||||
if (NeedsEagerFrame()) {
|
||||
ASSERT(!frame_is_built_);
|
||||
frame_is_built_ = true;
|
||||
__ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
|
||||
__ Prologue(info());
|
||||
info()->AddNoFrameRange(0, masm_->pc_offset());
|
||||
}
|
||||
|
||||
|
@ -3889,8 +3889,8 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
if (frame_mode == BUILD_STUB_FRAME) {
|
||||
void MacroAssembler::Prologue(CompilationInfo* info) {
|
||||
if (info->IsStub()) {
|
||||
pushq(rbp); // Caller's frame pointer.
|
||||
movp(rbp, rsp);
|
||||
Push(rsi); // Callee's context.
|
||||
@ -3898,7 +3898,7 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
|
||||
} else {
|
||||
PredictableCodeSizeScope predictible_code_size_scope(this,
|
||||
kNoCodeAgeSequenceLength);
|
||||
if (isolate()->IsCodePreAgingActive()) {
|
||||
if (info->IsCodePreAgingActive()) {
|
||||
// Pre-age the code.
|
||||
Call(isolate()->builtins()->MarkCodeAsExecutedOnce(),
|
||||
RelocInfo::CODE_AGE_SEQUENCE);
|
||||
|
@ -274,7 +274,7 @@ class MacroAssembler: public Assembler {
|
||||
void DebugBreak();
|
||||
|
||||
// Generates function and stub prologue code.
|
||||
void Prologue(PrologueFrameMode frame_mode);
|
||||
void Prologue(CompilationInfo* info);
|
||||
|
||||
// Enter specific kind of exit frame; either in normal or
|
||||
// debug mode. Expects the number of arguments in register rax and
|
||||
|
@ -3947,7 +3947,8 @@ static Handle<Code> DummyOptimizedCode(Isolate* isolate) {
|
||||
i::byte buffer[i::Assembler::kMinimalBufferSize];
|
||||
MacroAssembler masm(isolate, buffer, sizeof(buffer));
|
||||
CodeDesc desc;
|
||||
masm.Prologue(BUILD_FUNCTION_FRAME);
|
||||
masm.Push(isolate->factory()->undefined_value());
|
||||
masm.Drop(1);
|
||||
masm.GetCode(&desc);
|
||||
Handle<Object> undefined(isolate->heap()->undefined_value(), isolate);
|
||||
Handle<Code> code = isolate->factory()->NewCode(
|
||||
|
Loading…
Reference in New Issue
Block a user