Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Unified Diff: src/debug.cc

Issue 297303006: Some more debugger-related refactorings. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/debug.cc
diff --git a/src/debug.cc b/src/debug.cc
index a4cce055db78a0cf86c8ec452e97ed5794480883..f6086abf84f9f17de41b2a7b8162209b2a4f6d70 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -80,6 +80,22 @@ BreakLocationIterator::~BreakLocationIterator() {
}
+// Check whether a code stub with the specified major key is a possible break
+// point location when looking for source break locations.
+static bool IsSourceBreakStub(Code* code) {
+ CodeStub::Major major_key = CodeStub::GetMajorKey(code);
+ return major_key == CodeStub::CallFunction;
+}
+
+
+// Check whether a code stub with the specified major key is a possible break
+// location.
+static bool IsBreakStub(Code* code) {
+ CodeStub::Major major_key = CodeStub::GetMajorKey(code);
+ return major_key == CodeStub::CallFunction;
+}
+
+
void BreakLocationIterator::Next() {
DisallowHeapAllocation no_gc;
ASSERT(!RinfoDone());
@@ -129,15 +145,14 @@ void BreakLocationIterator::Next() {
if (IsDebuggerStatement()) {
break_point_++;
return;
- }
- if (type_ == ALL_BREAK_LOCATIONS) {
- if (Debug::IsBreakStub(code)) {
+ } else if (type_ == ALL_BREAK_LOCATIONS) {
+ if (IsBreakStub(code)) {
break_point_++;
return;
}
} else {
ASSERT(type_ == SOURCE_BREAK_LOCATIONS);
- if (Debug::IsSourceBreakStub(code)) {
+ if (IsSourceBreakStub(code)) {
break_point_++;
return;
}
@@ -422,6 +437,53 @@ bool BreakLocationIterator::IsDebugBreak() {
}
+// Find the builtin to use for invoking the debug break
+static Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) {
+ Isolate* isolate = code->GetIsolate();
+
+ // Find the builtin debug break function matching the calling convention
+ // used by the call site.
+ if (code->is_inline_cache_stub()) {
+ switch (code->kind()) {
+ case Code::CALL_IC:
+ return isolate->builtins()->CallICStub_DebugBreak();
+
+ case Code::LOAD_IC:
+ return isolate->builtins()->LoadIC_DebugBreak();
+
+ case Code::STORE_IC:
+ return isolate->builtins()->StoreIC_DebugBreak();
+
+ case Code::KEYED_LOAD_IC:
+ return isolate->builtins()->KeyedLoadIC_DebugBreak();
+
+ case Code::KEYED_STORE_IC:
+ return isolate->builtins()->KeyedStoreIC_DebugBreak();
+
+ case Code::COMPARE_NIL_IC:
+ return isolate->builtins()->CompareNilIC_DebugBreak();
+
+ default:
+ UNREACHABLE();
+ }
+ }
+ if (RelocInfo::IsConstructCall(mode)) {
+ if (code->has_function_cache()) {
+ return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
+ } else {
+ return isolate->builtins()->CallConstructStub_DebugBreak();
+ }
+ }
+ if (code->kind() == Code::STUB) {
+ ASSERT(code->major_key() == CodeStub::CallFunction);
+ return isolate->builtins()->CallFunctionStub_DebugBreak();
+ }
+
+ UNREACHABLE();
+ return Handle<Code>::null();
+}
+
+
void BreakLocationIterator::SetDebugBreakAtIC() {
// Patch the original code with the current address as the current address
// might have changed by the inline caching since the code was copied.
@@ -434,7 +496,7 @@ void BreakLocationIterator::SetDebugBreakAtIC() {
// Patch the code to invoke the builtin debug break function matching the
// calling convention used by the call site.
- Handle<Code> dbgbrk_code(Debug::FindDebugBreak(target_code, mode));
+ Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode);
rinfo()->set_target_address(dbgbrk_code->entry());
}
}
@@ -504,7 +566,6 @@ void Debug::ThreadInit() {
thread_local_.step_out_fp_ = 0;
// TODO(isolates): frames_are_dropped_?
thread_local_.debugger_entry_ = NULL;
- thread_local_.has_pending_interrupt_ = false;
thread_local_.restarter_frame_function_pointer_ = NULL;
thread_local_.promise_on_stack_ = NULL;
}
@@ -530,6 +591,30 @@ int Debug::ArchiveSpacePerThread() {
}
+ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch),
+ isolate_(isolate),
+ collected_scripts_(10) {
+ Heap* heap = isolate_->heap();
+ HandleScope scope(isolate_);
+
+ // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
+ // rid of all the cached script wrappers and the second gets rid of the
+ // scripts which are no longer referenced.
+ heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
+ heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
+
+ // Scan heap for Script objects.
+ HeapIterator iterator(heap);
+ DisallowHeapAllocation no_allocation;
+
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
+ if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
+ Add(Handle<Script>(Script::cast(obj)));
+ }
+ }
+}
+
+
void ScriptCache::Add(Handle<Script> script) {
GlobalHandles* global_handles = isolate_->global_handles();
// Create an entry in the hash map for the script.
@@ -785,7 +870,10 @@ void Debug::Unload() {
if (!is_loaded()) return;
// Clear the script cache.
- DestroyScriptCache();
+ if (script_cache_ != NULL) {
+ delete script_cache_;
+ script_cache_ = NULL;
+ }
// Clear debugger context global handle.
GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
@@ -843,7 +931,8 @@ void Debug::Break(Arguments args, JavaScriptFrame* frame) {
// If step out is active skip everything until the frame where we need to step
// out to is reached, unless real breakpoint is hit.
- if (StepOutActive() && frame->fp() != step_out_fp() &&
+ if (StepOutActive() &&
+ frame->fp() != thread_local_.step_out_fp_ &&
break_points_hit->IsUndefined() ) {
// Step count should always be 0 for StepOut.
ASSERT(thread_local_.step_count_ == 0);
@@ -1192,7 +1281,7 @@ bool Debug::IsBreakOnException(ExceptionBreakType type) {
}
-Debug::PromiseOnStack::PromiseOnStack(Isolate* isolate,
+PromiseOnStack::PromiseOnStack(Isolate* isolate,
PromiseOnStack* prev,
Handle<JSFunction> getter)
: isolate_(isolate), prev_(prev) {
@@ -1203,7 +1292,7 @@ Debug::PromiseOnStack::PromiseOnStack(Isolate* isolate,
}
-Debug::PromiseOnStack::~PromiseOnStack() {
+PromiseOnStack::~PromiseOnStack() {
isolate_->global_handles()->Destroy(Handle<Object>::cast(getter_).location());
}
@@ -1530,67 +1619,7 @@ bool Debug::IsDebugBreak(Address addr) {
}
-// Check whether a code stub with the specified major key is a possible break
-// point location when looking for source break locations.
-bool Debug::IsSourceBreakStub(Code* code) {
- CodeStub::Major major_key = CodeStub::GetMajorKey(code);
- return major_key == CodeStub::CallFunction;
-}
-
-
-// Check whether a code stub with the specified major key is a possible break
-// location.
-bool Debug::IsBreakStub(Code* code) {
- CodeStub::Major major_key = CodeStub::GetMajorKey(code);
- return major_key == CodeStub::CallFunction;
-}
-
-
-// Find the builtin to use for invoking the debug break
-Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
- Isolate* isolate = code->GetIsolate();
-
- // Find the builtin debug break function matching the calling convention
- // used by the call site.
- if (code->is_inline_cache_stub()) {
- switch (code->kind()) {
- case Code::CALL_IC:
- return isolate->builtins()->CallICStub_DebugBreak();
-
- case Code::LOAD_IC:
- return isolate->builtins()->LoadIC_DebugBreak();
-
- case Code::STORE_IC:
- return isolate->builtins()->StoreIC_DebugBreak();
-
- case Code::KEYED_LOAD_IC:
- return isolate->builtins()->KeyedLoadIC_DebugBreak();
-
- case Code::KEYED_STORE_IC:
- return isolate->builtins()->KeyedStoreIC_DebugBreak();
-
- case Code::COMPARE_NIL_IC:
- return isolate->builtins()->CompareNilIC_DebugBreak();
-
- default:
- UNREACHABLE();
- }
- }
- if (RelocInfo::IsConstructCall(mode)) {
- if (code->has_function_cache()) {
- return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
- } else {
- return isolate->builtins()->CallConstructStub_DebugBreak();
- }
- }
- if (code->kind() == Code::STUB) {
- ASSERT(code->major_key() == CodeStub::CallFunction);
- return isolate->builtins()->CallFunctionStub_DebugBreak();
- }
- UNREACHABLE();
- return Handle<Code>::null();
-}
// Simple function for returning the source positions for active break points.
@@ -1655,7 +1684,7 @@ void Debug::HandleStepIn(Handle<JSFunction> function,
// Flood the function with one-shot break points if it is called from where
// step into was requested.
- if (fp == step_in_fp()) {
+ if (fp == thread_local_.step_into_fp_) {
if (function->shared()->bound()) {
// Handle Function.prototype.bind
Debug::FloodBoundFunctionWithOneShot(function);
@@ -1912,7 +1941,7 @@ class ActiveFunctionsRedirector : public ThreadVisitor {
};
-void Debug::EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) {
+static void 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.
@@ -1931,7 +1960,7 @@ void Debug::EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) {
}
-void Debug::RecompileAndRelocateSuspendedGenerators(
+static void RecompileAndRelocateSuspendedGenerators(
const List<Handle<JSGeneratorObject> > &generators) {
for (int i = 0; i < generators.length(); i++) {
Handle<JSFunction> fun(generators[i]->function());
@@ -2444,60 +2473,10 @@ void Debug::ClearMirrorCache() {
}
-void Debug::CreateScriptCache() {
- Heap* heap = isolate_->heap();
- HandleScope scope(isolate_);
-
- // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
- // rid of all the cached script wrappers and the second gets rid of the
- // scripts which are no longer referenced. The second also sweeps precisely,
- // which saves us doing yet another GC to make the heap iterable.
- heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache");
-
- ASSERT(script_cache_ == NULL);
- script_cache_ = new ScriptCache(isolate_);
-
- // Scan heap for Script objects.
- int count = 0;
- HeapIterator iterator(heap);
-
- for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
- if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
- script_cache_->Add(Handle<Script>(Script::cast(obj)));
- count++;
- }
- }
-}
-
-
-void Debug::DestroyScriptCache() {
- // Get rid of the script cache if it was created.
- if (script_cache_ != NULL) {
- delete script_cache_;
- script_cache_ = NULL;
- }
-}
-
-
-void Debug::AddScriptToScriptCache(Handle<Script> script) {
- if (script_cache_ != NULL) {
- script_cache_->Add(script);
- }
-}
-
-
Handle<FixedArray> Debug::GetLoadedScripts() {
// Create and fill the script cache when the loaded scripts is requested for
// the first time.
- if (script_cache_ == NULL) {
- CreateScriptCache();
- }
-
- // If the script cache is not active just return an empty array.
- ASSERT(script_cache_ != NULL);
- if (script_cache_ == NULL) {
- isolate_->factory()->NewFixedArray(0);
- }
+ if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
// Perform GC to get unreferenced scripts evicted from the cache before
// returning the content.
@@ -2604,22 +2583,19 @@ MaybeHandle<Object> Debug::MakeScriptCollectedEvent(int id) {
void Debug::OnException(Handle<Object> exception, bool uncaught) {
- HandleScope scope(isolate_);
-
- // Bail out based on state or if there is no listener for this event
- if (is_entered()) return;
- if (!EventActive()) return;
+ if (is_entered() || ignore_events()) return;
+ HandleScope scope(isolate_);
Handle<Object> promise = GetPromiseForUncaughtException();
uncaught |= !promise->IsUndefined();
// Bail out if exception breaks are not active
if (uncaught) {
// Uncaught exceptions are reported by either flags.
- if (!(break_on_uncaught_exception() || break_on_exception())) return;
+ if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
} else {
// Caught exceptions are reported is activated.
- if (!break_on_exception()) return;
+ if (!break_on_exception_) return;
}
// Enter the debugger.
@@ -2645,14 +2621,12 @@ void Debug::OnException(Handle<Object> exception, bool uncaught) {
void Debug::OnDebugBreak(Handle<Object> break_points_hit,
bool auto_continue) {
- HandleScope scope(isolate_);
-
// Debugger has already been entered by caller.
ASSERT(isolate_->context() == *debug_context());
-
// Bail out if there is no listener for this event
- if (!EventActive()) return;
+ if (ignore_events()) return;
+ HandleScope scope(isolate_);
// Create the event data object.
Handle<Object> event_data;
// Bail out and don't call debugger if exception.
@@ -2666,12 +2640,9 @@ void Debug::OnDebugBreak(Handle<Object> break_points_hit,
void Debug::OnBeforeCompile(Handle<Script> script) {
- HandleScope scope(isolate_);
-
- // Bail out based on state or if there is no listener for this event
- if (is_entered()) return;
- if (!EventActive()) return;
+ if (is_entered() || ignore_events()) return;
+ HandleScope scope(isolate_);
// Enter the debugger.
EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) return;
@@ -2690,15 +2661,14 @@ void Debug::OnBeforeCompile(Handle<Script> script) {
// Handle debugger actions when a new script is compiled.
void Debug::OnAfterCompile(Handle<Script> script,
- AfterCompileFlags after_compile_flags) {
- HandleScope scope(isolate_);
-
+ AfterCompileFlags after_compile_flags) {
// Add the newly compiled script to the script cache.
- AddScriptToScriptCache(script);
+ if (script_cache_ != NULL) script_cache_->Add(script);
// No more to do if not debugging.
- if (!EventActive()) return;
+ if (is_entered() || ignore_events()) return;
+ HandleScope scope(isolate_);
// Store whether in debugger before entering debugger.
bool in_debugger = is_entered();
@@ -2748,12 +2718,9 @@ void Debug::OnAfterCompile(Handle<Script> script,
void Debug::OnScriptCollected(int id) {
- HandleScope scope(isolate_);
-
- // No more to do if not debugging.
- if (is_entered()) return;
- if (!EventActive()) return;
+ if (is_entered() || ignore_events()) return;
+ HandleScope scope(isolate_);
// Enter the debugger.
EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) return;
@@ -2775,9 +2742,6 @@ void Debug::ProcessDebugEvent(v8::DebugEvent event,
bool auto_continue) {
HandleScope scope(isolate_);
- // Clear any pending debug break if this is a real break.
- if (!auto_continue) thread_local_.has_pending_interrupt_ = false;
-
// Create the execution state.
Handle<Object> exec_state;
// Bail out and don't call debugger if exception.
@@ -3095,7 +3059,7 @@ MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
}
-void Debug::DebugBreakHelper() {
+void Debug::HandleDebugBreak() {
// Ignore debug break during bootstrapping.
if (isolate_->bootstrapper()->IsActive()) return;
// Just continue if breaks are disabled.
@@ -3161,9 +3125,9 @@ EnterDebugger::EnterDebugger(Isolate* isolate)
// Create the new break info. If there is no JavaScript frames there is no
// break frame id.
JavaScriptFrameIterator it(isolate_);
- has_js_frames_ = !it.done();
- debug->thread_local_.break_frame_id_ = has_js_frames_ ? it.frame()->id()
- : StackFrame::NO_ID;
+ bool has_js_frames = !it.done();
+ debug->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
+ : StackFrame::NO_ID;
debug->SetNextBreakId();
debug->UpdateState();
@@ -3187,9 +3151,7 @@ EnterDebugger::~EnterDebugger() {
// pending exception as clearing the mirror cache calls back into
// JavaScript. This can happen if the v8::Debug::Call is used in which
// case the exception should end up in the calling code.
- if (!isolate_->has_pending_exception()) {
- debug->ClearMirrorCache();
- }
+ if (!isolate_->has_pending_exception()) debug->ClearMirrorCache();
// If there are commands in the queue when leaving the debugger request
// that these commands are processed.
@@ -3369,10 +3331,6 @@ CommandMessage::CommandMessage(const Vector<uint16_t>& text,
}
-CommandMessage::~CommandMessage() {
-}
-
-
void CommandMessage::Dispose() {
text_.Dispose();
delete client_data_;
@@ -3393,10 +3351,7 @@ CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
CommandMessageQueue::~CommandMessageQueue() {
- while (!IsEmpty()) {
- CommandMessage m = Get();
- m.Dispose();
- }
+ while (!IsEmpty()) Get().Dispose();
DeleteArray(messages_);
}
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698