⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    return;  }  Handle<DebugInfo> debug_info = GetDebugInfo(shared);  // Source positions starts with zero.  ASSERT(source_position >= 0);  // Find the break point and change it.  BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);  it.FindBreakLocationFromPosition(source_position);  it.SetBreakPoint(break_point_object);  // At least one active break point now.  ASSERT(debug_info->GetBreakPointCount() > 0);}void Debug::ClearBreakPoint(Handle<Object> break_point_object) {  DebugInfoListNode* node = debug_info_list_;  while (node != NULL) {    Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),                                                   break_point_object);    if (!result->IsUndefined()) {      // Get information in the break point.      BreakPointInfo* break_point_info = BreakPointInfo::cast(result);      Handle<DebugInfo> debug_info = node->debug_info();      Handle<SharedFunctionInfo> shared(debug_info->shared());      int source_position =  break_point_info->statement_position()->value();      // Source positions starts with zero.      ASSERT(source_position >= 0);      // Find the break point and clear it.      BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);      it.FindBreakLocationFromPosition(source_position);      it.ClearBreakPoint(break_point_object);      // If there are no more break points left remove the debug info for this      // function.      if (debug_info->GetBreakPointCount() == 0) {        RemoveDebugInfo(debug_info);      }      return;    }    node = node->next();  }}void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {  // Make sure the function has setup the debug info.  if (!EnsureDebugInfo(shared)) {    // Return if we failed to retrieve the debug info.    return;  }  // Flood the function with break points.  BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS);  while (!it.Done()) {    it.SetOneShot();    it.Next();  }}void Debug::FloodHandlerWithOneShot() {  StackFrame::Id id = Top::break_frame_id();  for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) {    JavaScriptFrame* frame = it.frame();    if (frame->HasHandler()) {      Handle<SharedFunctionInfo> shared =          Handle<SharedFunctionInfo>(              JSFunction::cast(frame->function())->shared());      // Flood the function with the catch block with break points      FloodWithOneShot(shared);      return;    }  }}void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {  if (type == BreakUncaughtException) {    break_on_uncaught_exception_ = enable;  } else {    break_on_exception_ = enable;  }}void Debug::PrepareStep(StepAction step_action, int step_count) {  HandleScope scope;  ASSERT(Debug::InDebugger());  // Remember this step action and count.  thread_local_.last_step_action_ = step_action;  thread_local_.step_count_ = step_count;  // Get the frame where the execution has stopped and skip the debug frame if  // any. The debug frame will only be present if execution was stopped due to  // hitting a break point. In other situations (e.g. unhandled exception) the  // debug frame is not present.  StackFrame::Id id = Top::break_frame_id();  JavaScriptFrameIterator frames_it(id);  JavaScriptFrame* frame = frames_it.frame();  // First of all ensure there is one-shot break points in the top handler  // if any.  FloodHandlerWithOneShot();  // If the function on the top frame is unresolved perform step out. This will  // be the case when calling unknown functions and having the debugger stopped  // in an unhandled exception.  if (!frame->function()->IsJSFunction()) {    // Step out: Find the calling JavaScript frame and flood it with    // breakpoints.    frames_it.Advance();    // Fill the function to return to with one-shot break points.    JSFunction* function = JSFunction::cast(frames_it.frame()->function());    FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));    return;  }  // Get the debug info (create it if it does not exist).  Handle<SharedFunctionInfo> shared =      Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());  if (!EnsureDebugInfo(shared)) {    // Return if ensuring debug info failed.    return;  }  Handle<DebugInfo> debug_info = GetDebugInfo(shared);  // Find the break location where execution has stopped.  BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS);  it.FindBreakLocationFromAddress(frame->pc());  // Compute whether or not the target is a call target.  bool is_call_target = false;  if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {    Address target = it.rinfo()->target_address();    Code* code = Debug::GetCodeTarget(target);    if (code->is_call_stub()) is_call_target = true;  }  // If this is the last break code target step out is the only possibility.  if (it.IsExit() || step_action == StepOut) {    // Step out: If there is a JavaScript caller frame, we need to    // flood it with breakpoints.    frames_it.Advance();    if (!frames_it.done()) {      // Fill the function to return to with one-shot break points.      JSFunction* function = JSFunction::cast(frames_it.frame()->function());      FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));    }  } else if (!(is_call_target || RelocInfo::IsConstructCall(it.rmode())) ||             step_action == StepNext || step_action == StepMin) {    // Step next or step min.    // Fill the current function with one-shot break points.    FloodWithOneShot(shared);    // Remember source position and frame to handle step next.    thread_local_.last_statement_position_ =        debug_info->code()->SourceStatementPosition(frame->pc());    thread_local_.last_fp_ = frame->fp();  } else {    // Fill the current function with one-shot break points even for step in on    // a call target as the function called might be a native function for    // which step in will not stop.    FloodWithOneShot(shared);    // Step in or Step in min    it.PrepareStepIn();    ActivateStepIn(frame);  }}// Check whether the current debug break should be reported to the debugger. It// is used to have step next and step in only report break back to the debugger// if on a different frame or in a different statement. In some situations// there will be several break points in the same statement when the code is// flooded with one-shot break points. This function helps to perform several// steps before reporting break back to the debugger.bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,                             JavaScriptFrame* frame) {  // If the step last action was step next or step in make sure that a new  // statement is hit.  if (thread_local_.last_step_action_ == StepNext ||      thread_local_.last_step_action_ == StepIn) {    // Never continue if returning from function.    if (break_location_iterator->IsExit()) return false;    // Continue if we are still on the same frame and in the same statement.    int current_statement_position =        break_location_iterator->code()->SourceStatementPosition(frame->pc());    return thread_local_.last_fp_ == frame->fp() &&        thread_local_.last_statement_position_ == current_statement_position;  }  // No step next action - don't continue.  return false;}// Check whether the code object at the specified address is a debug break code// object.bool Debug::IsDebugBreak(Address addr) {  Code* code = GetCodeTarget(addr);  return code->ic_state() == DEBUG_BREAK;}// 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 = code->major_key();  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 = code->major_key();  return major_key == CodeStub::CallFunction ||         major_key == CodeStub::StackCheck;}// Find the builtin to use for invoking the debug breakHandle<Code> Debug::FindDebugBreak(RelocInfo* rinfo) {  // Find the builtin debug break function matching the calling convention  // used by the call site.  RelocInfo::Mode mode = rinfo->rmode();  if (RelocInfo::IsCodeTarget(mode)) {    Address target = rinfo->target_address();    Code* code = Debug::GetCodeTarget(target);    if (code->is_inline_cache_stub()) {      if (code->is_call_stub()) {        return ComputeCallDebugBreak(code->arguments_count());      }      if (code->is_load_stub()) {        return Handle<Code>(Builtins::builtin(Builtins::LoadIC_DebugBreak));      }      if (code->is_store_stub()) {        return Handle<Code>(Builtins::builtin(Builtins::StoreIC_DebugBreak));      }      if (code->is_keyed_load_stub()) {        Handle<Code> result =            Handle<Code>(Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak));        return result;      }      if (code->is_keyed_store_stub()) {        Handle<Code> result =            Handle<Code>(Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak));        return result;      }    }    if (RelocInfo::IsConstructCall(mode)) {      Handle<Code> result =          Handle<Code>(Builtins::builtin(Builtins::ConstructCall_DebugBreak));      return result;    }    if (code->kind() == Code::STUB) {      ASSERT(code->major_key() == CodeStub::CallFunction ||             code->major_key() == CodeStub::StackCheck);      Handle<Code> result =          Handle<Code>(Builtins::builtin(Builtins::StubNoRegisters_DebugBreak));      return result;    }  }  UNREACHABLE();  return Handle<Code>::null();}// Simple function for returning the source positions for active break points.Handle<Object> Debug::GetSourceBreakLocations(    Handle<SharedFunctionInfo> shared) {  if (!HasDebugInfo(shared)) return Handle<Object>(Heap::undefined_value());  Handle<DebugInfo> debug_info = GetDebugInfo(shared);  if (debug_info->GetBreakPointCount() == 0) {    return Handle<Object>(Heap::undefined_value());  }  Handle<FixedArray> locations =      Factory::NewFixedArray(debug_info->GetBreakPointCount());  int count = 0;  for (int i = 0; i < debug_info->break_points()->length(); i++) {    if (!debug_info->break_points()->get(i)->IsUndefined()) {      BreakPointInfo* break_point_info =          BreakPointInfo::cast(debug_info->break_points()->get(i));      if (break_point_info->GetBreakPointCount() > 0) {        locations->set(count++, break_point_info->statement_position());      }    }  }  return locations;}void Debug::ClearStepping() {  // Clear the various stepping setup.  ClearOneShot();  ClearStepIn();  ClearStepNext();  // Clear multiple step counter.  thread_local_.step_count_ = 0;}// Clears all the one-shot break points that are currently set. Normally this// function is called each time a break point is hit as one shot break points// are used to support stepping.void Debug::ClearOneShot() {  // The current implementation just runs through all the breakpoints. When the  // last break point for a function is removed that function is automatically  // removed from the list.  DebugInfoListNode* node = debug_info_list_;  while (node != NULL) {    BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);    while (!it.Done()) {      it.ClearOneShot();      it.Next();    }    node = node->next();  }}void Debug::ActivateStepIn(StackFrame* frame) {  thread_local_.step_into_fp_ = frame->fp();}void Debug::ClearStepIn() {  thread_local_.step_into_fp_ = 0;}void Debug::ClearStepNext() {  thread_local_.last_step_action_ = StepNone;  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;  thread_local_.last_fp_ = 0;}bool Debug::EnsureCompiled(Handle<SharedFunctionInfo> shared) {  if (shared->is_compiled()) return true;  return CompileLazyShared(shared, CLEAR_EXCEPTION);}// Ensures the debug information is present for shared.bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {  // Return if we already have the debug info for shared.  if (HasDebugInfo(shared)) return true;  // Ensure shared in compiled. Return false if this failed.  if (!EnsureCompiled(shared)) return false;  // Create the debug info object.  Handle<DebugInfo> debug_info = Factory::NewDebugInfo(shared);  // Add debug info to the list.  DebugInfoListNode* node = new DebugInfoListNode(*debug_info);  node->set_next(debug_info_list_);  debug_info_list_ = node;  // Now there is at least one break point.  has_break_points_ = true;  return true;}void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {  ASSERT(debug_info_list_ != NULL);  // Run through the debug info objects to find this one and remove it.  DebugInfoListNode* prev = NULL;  DebugInfoListNode* current = debug_info_list_;  while (current != NULL) {    if (*current->debug_info() == *debug_info) {      // Unlink from list. If prev is NULL we are looking at the first element.      if (prev == NULL) {        debug_info_list_ = current->next();      } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -