| Index: src/debug.cc
 | 
| diff --git a/src/debug.cc b/src/debug.cc
 | 
| index ea402ffa3d8c44865b509c7a2b60dbcf1c887593..0cd20ad5b134c9a3c2db796efebeb45d9fd23e7d 100644
 | 
| --- a/src/debug.cc
 | 
| +++ b/src/debug.cc
 | 
| @@ -60,47 +60,29 @@ static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -BreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info,
 | 
| -                                             BreakLocatorType type) {
 | 
| -  debug_info_ = debug_info;
 | 
| -  type_ = type;
 | 
| -  reloc_iterator_ = NULL;
 | 
| -  reloc_iterator_original_ = NULL;
 | 
| -  Reset();  // Initialize the rest of the member variables.
 | 
| -}
 | 
| -
 | 
| -
 | 
| -BreakLocationIterator::~BreakLocationIterator() {
 | 
| -  DCHECK(reloc_iterator_ != NULL);
 | 
| -  DCHECK(reloc_iterator_original_ != NULL);
 | 
| -  delete reloc_iterator_;
 | 
| -  delete reloc_iterator_original_;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// 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;
 | 
| +BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
 | 
| +                                  BreakLocatorType type)
 | 
| +    : debug_info_(debug_info),
 | 
| +      type_(type),
 | 
| +      reloc_iterator_(debug_info->code(),
 | 
| +                      ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)),
 | 
| +      reloc_iterator_original_(
 | 
| +          debug_info->original_code(),
 | 
| +          ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)),
 | 
| +      break_index_(-1),
 | 
| +      position_(1),
 | 
| +      statement_position_(1) {
 | 
| +  Next();
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::Next() {
 | 
| +void BreakLocation::Iterator::Next() {
 | 
|    DisallowHeapAllocation no_gc;
 | 
|    DCHECK(!RinfoDone());
 | 
|  
 | 
|    // Iterate through reloc info for code and original code stopping at each
 | 
|    // breakable code target.
 | 
| -  bool first = break_point_ == -1;
 | 
| +  bool first = break_index_ == -1;
 | 
|    while (!RinfoDone()) {
 | 
|      if (!first) RinfoNext();
 | 
|      first = false;
 | 
| @@ -115,8 +97,8 @@ void BreakLocationIterator::Next() {
 | 
|        }
 | 
|        // Always update the position as we don't want that to be before the
 | 
|        // statement position.
 | 
| -      position_ = static_cast<int>(
 | 
| -          rinfo()->data() - debug_info_->shared()->start_position());
 | 
| +      position_ = static_cast<int>(rinfo()->data() -
 | 
| +                                   debug_info_->shared()->start_position());
 | 
|        DCHECK(position_ >= 0);
 | 
|        DCHECK(statement_position_ >= 0);
 | 
|      }
 | 
| @@ -131,7 +113,7 @@ void BreakLocationIterator::Next() {
 | 
|          position_ = 0;
 | 
|        }
 | 
|        statement_position_ = position_;
 | 
| -      break_point_++;
 | 
| +      break_index_++;
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| @@ -143,7 +125,7 @@ void BreakLocationIterator::Next() {
 | 
|        Code* code = Code::GetCodeFromTargetAddress(target);
 | 
|  
 | 
|        if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) {
 | 
| -        break_point_++;
 | 
| +        break_index_++;
 | 
|          return;
 | 
|        }
 | 
|  
 | 
| @@ -152,144 +134,117 @@ void BreakLocationIterator::Next() {
 | 
|  
 | 
|        if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() &&
 | 
|             !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) {
 | 
| -        break_point_++;
 | 
| +        break_index_++;
 | 
|          return;
 | 
|        }
 | 
|        if (code->kind() == Code::STUB) {
 | 
| -        if (IsDebuggerStatement()) {
 | 
| -          break_point_++;
 | 
| +        if (RelocInfo::IsDebuggerStatement(rmode())) {
 | 
| +          break_index_++;
 | 
| +          return;
 | 
| +        } else if (CodeStub::GetMajorKey(code) == CodeStub::CallFunction) {
 | 
| +          break_index_++;
 | 
|            return;
 | 
| -        } else if (type_ == ALL_BREAK_LOCATIONS) {
 | 
| -          if (IsBreakStub(code)) {
 | 
| -            break_point_++;
 | 
| -            return;
 | 
| -          }
 | 
| -        } else {
 | 
| -          DCHECK(type_ == SOURCE_BREAK_LOCATIONS);
 | 
| -          if (IsSourceBreakStub(code)) {
 | 
| -            break_point_++;
 | 
| -            return;
 | 
| -          }
 | 
|          }
 | 
|        }
 | 
|      }
 | 
|  
 | 
| -    if (IsDebugBreakSlot() && type_ != CALLS_AND_RETURNS) {
 | 
| +    if (RelocInfo::IsDebugBreakSlot(rmode()) && type_ != CALLS_AND_RETURNS) {
 | 
|        // There is always a possible break point at a debug break slot.
 | 
| -      break_point_++;
 | 
| +      break_index_++;
 | 
|        return;
 | 
|      }
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::Next(int count) {
 | 
| -  while (count > 0) {
 | 
| -    Next();
 | 
| -    count--;
 | 
| -  }
 | 
| +// Find the break point at the supplied address, or the closest one before
 | 
| +// the address.
 | 
| +BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info,
 | 
| +                                         BreakLocatorType type, Address pc) {
 | 
| +  Iterator it(debug_info, type);
 | 
| +  it.SkipTo(BreakIndexFromAddress(debug_info, type, pc));
 | 
| +  return it.GetBreakLocation();
 | 
|  }
 | 
|  
 | 
|  
 | 
|  // Find the break point at the supplied address, or the closest one before
 | 
|  // the address.
 | 
| -void BreakLocationIterator::FindBreakLocationFromAddress(Address pc) {
 | 
| +void BreakLocation::FromAddressSameStatement(Handle<DebugInfo> debug_info,
 | 
| +                                             BreakLocatorType type, Address pc,
 | 
| +                                             List<BreakLocation>* result_out) {
 | 
| +  int break_index = BreakIndexFromAddress(debug_info, type, pc);
 | 
| +  Iterator it(debug_info, type);
 | 
| +  it.SkipTo(break_index);
 | 
| +  int statement_position = it.statement_position();
 | 
| +  while (!it.Done() && it.statement_position() == statement_position) {
 | 
| +    result_out->Add(it.GetBreakLocation());
 | 
| +    it.Next();
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
| +int BreakLocation::BreakIndexFromAddress(Handle<DebugInfo> debug_info,
 | 
| +                                         BreakLocatorType type, Address pc) {
 | 
|    // Run through all break points to locate the one closest to the address.
 | 
| -  int closest_break_point = 0;
 | 
| +  int closest_break = 0;
 | 
|    int distance = kMaxInt;
 | 
| -  while (!Done()) {
 | 
| +  for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
 | 
|      // Check if this break point is closer that what was previously found.
 | 
| -    if (this->pc() <= pc && pc - this->pc() < distance) {
 | 
| -      closest_break_point = break_point();
 | 
| -      distance = static_cast<int>(pc - this->pc());
 | 
| +    if (it.pc() <= pc && pc - it.pc() < distance) {
 | 
| +      closest_break = it.break_index();
 | 
| +      distance = static_cast<int>(pc - it.pc());
 | 
|        // Check whether we can't get any closer.
 | 
|        if (distance == 0) break;
 | 
|      }
 | 
| -    Next();
 | 
|    }
 | 
| -
 | 
| -  // Move to the break point found.
 | 
| -  Reset();
 | 
| -  Next(closest_break_point);
 | 
| +  return closest_break;
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// Find the break point closest to the supplied source position.
 | 
| -void BreakLocationIterator::FindBreakLocationFromPosition(int position,
 | 
| -    BreakPositionAlignment alignment) {
 | 
| +BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info,
 | 
| +                                          BreakLocatorType type, int position,
 | 
| +                                          BreakPositionAlignment alignment) {
 | 
|    // Run through all break points to locate the one closest to the source
 | 
|    // position.
 | 
| -  int closest_break_point = 0;
 | 
| +  int closest_break = 0;
 | 
|    int distance = kMaxInt;
 | 
|  
 | 
| -  while (!Done()) {
 | 
| +  for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
 | 
|      int next_position;
 | 
| -    switch (alignment) {
 | 
| -    case STATEMENT_ALIGNED:
 | 
| -      next_position = this->statement_position();
 | 
| -      break;
 | 
| -    case BREAK_POSITION_ALIGNED:
 | 
| -      next_position = this->position();
 | 
| -      break;
 | 
| -    default:
 | 
| -      UNREACHABLE();
 | 
| -      next_position = this->statement_position();
 | 
| +    if (alignment == STATEMENT_ALIGNED) {
 | 
| +      next_position = it.statement_position();
 | 
| +    } else {
 | 
| +      DCHECK(alignment == BREAK_POSITION_ALIGNED);
 | 
| +      next_position = it.position();
 | 
|      }
 | 
| -    // Check if this break point is closer that what was previously found.
 | 
|      if (position <= next_position && next_position - position < distance) {
 | 
| -      closest_break_point = break_point();
 | 
| +      closest_break = it.break_index();
 | 
|        distance = next_position - position;
 | 
|        // Check whether we can't get any closer.
 | 
|        if (distance == 0) break;
 | 
|      }
 | 
| -    Next();
 | 
|    }
 | 
|  
 | 
| -  // Move to the break point found.
 | 
| -  Reset();
 | 
| -  Next(closest_break_point);
 | 
| +  Iterator it(debug_info, type);
 | 
| +  it.SkipTo(closest_break);
 | 
| +  return it.GetBreakLocation();
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::Reset() {
 | 
| -  // Create relocation iterators for the two code objects.
 | 
| -  if (reloc_iterator_ != NULL) delete reloc_iterator_;
 | 
| -  if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_;
 | 
| -  reloc_iterator_ = new RelocIterator(
 | 
| -      debug_info_->code(),
 | 
| -      ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE));
 | 
| -  reloc_iterator_original_ = new RelocIterator(
 | 
| -      debug_info_->original_code(),
 | 
| -      ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE));
 | 
| -
 | 
| -  // Position at the first break point.
 | 
| -  break_point_ = -1;
 | 
| -  position_ = 1;
 | 
| -  statement_position_ = 1;
 | 
| -  Next();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -bool BreakLocationIterator::Done() const {
 | 
| -  return RinfoDone();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
 | 
| +void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
 | 
|    // If there is not already a real break point here patch code with debug
 | 
|    // break.
 | 
|    if (!HasBreakPoint()) SetDebugBreak();
 | 
|    DCHECK(IsDebugBreak() || IsDebuggerStatement());
 | 
|    // Set the break point information.
 | 
| -  DebugInfo::SetBreakPoint(debug_info_, code_position(),
 | 
| -                           position(), statement_position(),
 | 
| -                           break_point_object);
 | 
| +  DebugInfo::SetBreakPoint(debug_info_, pc_offset_, position_,
 | 
| +                           statement_position_, break_point_object);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
 | 
| +void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) {
 | 
|    // Clear the break point information.
 | 
| -  DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
 | 
| +  DebugInfo::ClearBreakPoint(debug_info_, pc_offset_, break_point_object);
 | 
|    // If there are no more break points here remove the debug break.
 | 
|    if (!HasBreakPoint()) {
 | 
|      ClearDebugBreak();
 | 
| @@ -298,7 +253,7 @@ void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::SetOneShot() {
 | 
| +void BreakLocation::SetOneShot() {
 | 
|    // Debugger statement always calls debugger. No need to modify it.
 | 
|    if (IsDebuggerStatement()) return;
 | 
|  
 | 
| @@ -313,7 +268,7 @@ void BreakLocationIterator::SetOneShot() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::ClearOneShot() {
 | 
| +void BreakLocation::ClearOneShot() {
 | 
|    // Debugger statement always calls debugger. No need to modify it.
 | 
|    if (IsDebuggerStatement()) return;
 | 
|  
 | 
| @@ -329,7 +284,7 @@ void BreakLocationIterator::ClearOneShot() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::SetDebugBreak() {
 | 
| +void BreakLocation::SetDebugBreak() {
 | 
|    // Debugger statement always calls debugger. No need to modify it.
 | 
|    if (IsDebuggerStatement()) return;
 | 
|  
 | 
| @@ -339,7 +294,7 @@ void BreakLocationIterator::SetDebugBreak() {
 | 
|    // handler as the handler and the function is the same.
 | 
|    if (IsDebugBreak()) return;
 | 
|  
 | 
| -  if (RelocInfo::IsJSReturn(rmode())) {
 | 
| +  if (IsExit()) {
 | 
|      // Patch the frame exit code with a break point.
 | 
|      SetDebugBreakAtReturn();
 | 
|    } else if (IsDebugBreakSlot()) {
 | 
| @@ -353,59 +308,48 @@ void BreakLocationIterator::SetDebugBreak() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::ClearDebugBreak() {
 | 
| +void BreakLocation::ClearDebugBreak() {
 | 
|    // Debugger statement always calls debugger. No need to modify it.
 | 
|    if (IsDebuggerStatement()) return;
 | 
|  
 | 
| -  if (RelocInfo::IsJSReturn(rmode())) {
 | 
| -    // Restore the frame exit code.
 | 
| -    ClearDebugBreakAtReturn();
 | 
| +  if (IsExit()) {
 | 
| +    // Restore the frame exit code with a break point.
 | 
| +    RestoreFromOriginal(Assembler::kJSReturnSequenceLength);
 | 
|    } else if (IsDebugBreakSlot()) {
 | 
|      // Restore the code in the break slot.
 | 
| -    ClearDebugBreakAtSlot();
 | 
| +    RestoreFromOriginal(Assembler::kDebugBreakSlotLength);
 | 
|    } else {
 | 
| -    // Patch the IC call.
 | 
| -    ClearDebugBreakAtIC();
 | 
| +    // Restore the IC call.
 | 
| +    rinfo().set_target_address(original_rinfo().target_address());
 | 
|    }
 | 
|    DCHECK(!IsDebugBreak());
 | 
|  }
 | 
|  
 | 
|  
 | 
| -bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) {
 | 
| -  if (RelocInfo::IsConstructCall(original_rmode())) {
 | 
| -    return true;
 | 
| -  } else if (RelocInfo::IsCodeTarget(rmode())) {
 | 
| +void BreakLocation::RestoreFromOriginal(int length_in_bytes) {
 | 
| +  memcpy(pc(), original_pc(), length_in_bytes);
 | 
| +  CpuFeatures::FlushICache(pc(), length_in_bytes);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +bool BreakLocation::IsStepInLocation() const {
 | 
| +  if (IsConstructCall()) return true;
 | 
| +  if (RelocInfo::IsCodeTarget(rmode())) {
 | 
|      HandleScope scope(debug_info_->GetIsolate());
 | 
| -    Address target = original_rinfo()->target_address();
 | 
| -    Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
 | 
| -    if (target_code->kind() == Code::STUB) {
 | 
| -      return CodeStub::GetMajorKey(*target_code) == CodeStub::CallFunction;
 | 
| -    }
 | 
| +    Handle<Code> target_code = CodeTarget();
 | 
|      return target_code->is_call_stub();
 | 
|    }
 | 
|    return false;
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// Check whether the break point is at a position which will exit the function.
 | 
| -bool BreakLocationIterator::IsExit() const {
 | 
| -  return (RelocInfo::IsJSReturn(rmode()));
 | 
| -}
 | 
| -
 | 
| -
 | 
| -bool BreakLocationIterator::HasBreakPoint() {
 | 
| -  return debug_info_->HasBreakPoint(code_position());
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// Check whether there is a debug break at the current position.
 | 
| -bool BreakLocationIterator::IsDebugBreak() {
 | 
| -  if (RelocInfo::IsJSReturn(rmode())) {
 | 
| -    return IsDebugBreakAtReturn();
 | 
| +bool BreakLocation::IsDebugBreak() const {
 | 
| +  if (IsExit()) {
 | 
| +    return rinfo().IsPatchedReturnSequence();
 | 
|    } else if (IsDebugBreakSlot()) {
 | 
| -    return IsDebugBreakAtSlot();
 | 
| +    return rinfo().IsPatchedDebugBreakSlotSequence();
 | 
|    } else {
 | 
| -    return Debug::IsDebugBreak(rinfo()->target_address());
 | 
| +    return Debug::IsDebugBreak(rinfo().target_address());
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -457,70 +401,53 @@ static Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::SetDebugBreakAtIC() {
 | 
| +void BreakLocation::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.
 | 
| -  original_rinfo()->set_target_address(rinfo()->target_address());
 | 
| +  original_rinfo().set_target_address(rinfo().target_address());
 | 
|  
 | 
| -  RelocInfo::Mode mode = rmode();
 | 
| -  if (RelocInfo::IsCodeTarget(mode)) {
 | 
| -    Address target = rinfo()->target_address();
 | 
| -    Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
 | 
| +  if (RelocInfo::IsCodeTarget(rmode_)) {
 | 
| +    Handle<Code> target_code = CodeTarget();
 | 
|  
 | 
|      // Patch the code to invoke the builtin debug break function matching the
 | 
|      // calling convention used by the call site.
 | 
| -    Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode);
 | 
| -    rinfo()->set_target_address(dbgbrk_code->entry());
 | 
| +    Handle<Code> debug_break_code = DebugBreakForIC(target_code, rmode_);
 | 
| +    rinfo().set_target_address(debug_break_code->entry());
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void BreakLocationIterator::ClearDebugBreakAtIC() {
 | 
| -  // Patch the code to the original invoke.
 | 
| -  rinfo()->set_target_address(original_rinfo()->target_address());
 | 
| +Handle<Object> BreakLocation::BreakPointObjects() const {
 | 
| +  return debug_info_->GetBreakPointObjects(pc_offset_);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -bool BreakLocationIterator::IsDebuggerStatement() {
 | 
| -  return RelocInfo::DEBUG_BREAK == rmode();
 | 
| +Handle<Code> BreakLocation::CodeTarget() const {
 | 
| +  DCHECK(IsCodeTarget());
 | 
| +  Address target = rinfo().target_address();
 | 
| +  return Handle<Code>(Code::GetCodeFromTargetAddress(target));
 | 
|  }
 | 
|  
 | 
|  
 | 
| -bool BreakLocationIterator::IsDebugBreakSlot() {
 | 
| -  return RelocInfo::DEBUG_BREAK_SLOT == rmode();
 | 
| +Handle<Code> BreakLocation::OriginalCodeTarget() const {
 | 
| +  DCHECK(IsCodeTarget());
 | 
| +  Address target = original_rinfo().target_address();
 | 
| +  return Handle<Code>(Code::GetCodeFromTargetAddress(target));
 | 
|  }
 | 
|  
 | 
|  
 | 
| -Object* BreakLocationIterator::BreakPointObjects() {
 | 
| -  return debug_info_->GetBreakPointObjects(code_position());
 | 
| +bool BreakLocation::Iterator::RinfoDone() const {
 | 
| +  DCHECK(reloc_iterator_.done() == reloc_iterator_original_.done());
 | 
| +  return reloc_iterator_.done();
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// Clear out all the debug break code. This is ONLY supposed to be used when
 | 
| -// shutting down the debugger as it will leave the break point information in
 | 
| -// DebugInfo even though the code is patched back to the non break point state.
 | 
| -void BreakLocationIterator::ClearAllDebugBreak() {
 | 
| -  while (!Done()) {
 | 
| -    ClearDebugBreak();
 | 
| -    Next();
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -bool BreakLocationIterator::RinfoDone() const {
 | 
| -  DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done());
 | 
| -  return reloc_iterator_->done();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void BreakLocationIterator::RinfoNext() {
 | 
| -  reloc_iterator_->next();
 | 
| -  reloc_iterator_original_->next();
 | 
| +void BreakLocation::Iterator::RinfoNext() {
 | 
| +  reloc_iterator_.next();
 | 
| +  reloc_iterator_original_.next();
 | 
|  #ifdef DEBUG
 | 
| -  DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done());
 | 
| -  if (!reloc_iterator_->done()) {
 | 
| -    DCHECK(rmode() == original_rmode());
 | 
| -  }
 | 
| +  DCHECK(reloc_iterator_.done() == reloc_iterator_original_.done());
 | 
| +  DCHECK(reloc_iterator_.done() || rmode() == original_rmode());
 | 
|  #endif
 | 
|  }
 | 
|  
 | 
| @@ -854,14 +781,14 @@ void Debug::Break(Arguments args, JavaScriptFrame* frame) {
 | 
|    Handle<DebugInfo> debug_info = GetDebugInfo(shared);
 | 
|  
 | 
|    // Find the break point where execution has stopped.
 | 
| -  BreakLocationIterator break_location_iterator(debug_info,
 | 
| -                                                ALL_BREAK_LOCATIONS);
 | 
| -  // pc points to the instruction after the current one, possibly a break
 | 
| +  // PC points to the instruction after the current one, possibly a break
 | 
|    // location as well. So the "- 1" to exclude it from the search.
 | 
| -  break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
 | 
| +  Address call_pc = frame->pc() - 1;
 | 
| +  BreakLocation break_location =
 | 
| +      BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
 | 
|  
 | 
|    // Check whether step next reached a new statement.
 | 
| -  if (!StepNextContinue(&break_location_iterator, frame)) {
 | 
| +  if (!StepNextContinue(&break_location, frame)) {
 | 
|      // Decrease steps left if performing multiple steps.
 | 
|      if (thread_local_.step_count_ > 0) {
 | 
|        thread_local_.step_count_--;
 | 
| @@ -871,9 +798,8 @@ void Debug::Break(Arguments args, JavaScriptFrame* frame) {
 | 
|    // If there is one or more real break points check whether any of these are
 | 
|    // triggered.
 | 
|    Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
 | 
| -  if (break_location_iterator.HasBreakPoint()) {
 | 
| -    Handle<Object> break_point_objects =
 | 
| -        Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_);
 | 
| +  if (break_location.HasBreakPoint()) {
 | 
| +    Handle<Object> break_point_objects = break_location.BreakPointObjects();
 | 
|      break_points_hit = CheckBreakPoints(break_point_objects);
 | 
|    }
 | 
|  
 | 
| @@ -1058,11 +984,10 @@ bool Debug::SetBreakPoint(Handle<JSFunction> function,
 | 
|    DCHECK(*source_position >= 0);
 | 
|  
 | 
|    // Find the break point and change it.
 | 
| -  BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
 | 
| -  it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED);
 | 
| -  it.SetBreakPoint(break_point_object);
 | 
| -
 | 
| -  *source_position = it.statement_position();
 | 
| +  BreakLocation location = BreakLocation::FromPosition(
 | 
| +      debug_info, SOURCE_BREAK_LOCATIONS, *source_position, STATEMENT_ALIGNED);
 | 
| +  *source_position = location.statement_position();
 | 
| +  location.SetBreakPoint(break_point_object);
 | 
|  
 | 
|    // At least one active break point now.
 | 
|    return debug_info->GetBreakPointCount() > 0;
 | 
| @@ -1078,11 +1003,12 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
 | 
|    PrepareForBreakPoints();
 | 
|  
 | 
|    // Obtain shared function info for the function.
 | 
| -  Object* result = FindSharedFunctionInfoInScript(script, *source_position);
 | 
| +  Handle<Object> result =
 | 
| +      FindSharedFunctionInfoInScript(script, *source_position);
 | 
|    if (result->IsUndefined()) return false;
 | 
|  
 | 
|    // Make sure the function has set up the debug info.
 | 
| -  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
 | 
| +  Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
 | 
|    if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
 | 
|      // Return if retrieving debug info failed.
 | 
|      return false;
 | 
| @@ -1102,12 +1028,12 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
 | 
|    DCHECK(position >= 0);
 | 
|  
 | 
|    // Find the break point and change it.
 | 
| -  BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
 | 
| -  it.FindBreakLocationFromPosition(position, alignment);
 | 
| -  it.SetBreakPoint(break_point_object);
 | 
| +  BreakLocation location = BreakLocation::FromPosition(
 | 
| +      debug_info, SOURCE_BREAK_LOCATIONS, position, alignment);
 | 
| +  location.SetBreakPoint(break_point_object);
 | 
|  
 | 
| -  position = (alignment == STATEMENT_ALIGNED) ? it.statement_position()
 | 
| -                                              : it.position();
 | 
| +  position = (alignment == STATEMENT_ALIGNED) ? location.statement_position()
 | 
| +                                              : location.position();
 | 
|  
 | 
|    *source_position = position + shared->start_position();
 | 
|  
 | 
| @@ -1122,18 +1048,21 @@ 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);
 | 
| +    Handle<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<BreakPointInfo> break_point_info =
 | 
| +          Handle<BreakPointInfo>::cast(result);
 | 
|        Handle<DebugInfo> debug_info = node->debug_info();
 | 
|  
 | 
|        // Find the break point and clear it.
 | 
| -      BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
 | 
| -      it.FindBreakLocationFromAddress(debug_info->code()->entry() +
 | 
| -          break_point_info->code_position()->value());
 | 
| -      it.ClearBreakPoint(break_point_object);
 | 
| +      Address pc = debug_info->code()->entry() +
 | 
| +                   break_point_info->code_position()->value();
 | 
| +
 | 
| +      BreakLocation location =
 | 
| +          BreakLocation::FromAddress(debug_info, SOURCE_BREAK_LOCATIONS, pc);
 | 
| +      location.ClearBreakPoint(break_point_object);
 | 
|  
 | 
|        // If there are no more break points left remove the debug info for this
 | 
|        // function.
 | 
| @@ -1148,15 +1077,17 @@ void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +// Clear out all the debug break code. This is ONLY supposed to be used when
 | 
| +// shutting down the debugger as it will leave the break point information in
 | 
| +// DebugInfo even though the code is patched back to the non break point state.
 | 
|  void Debug::ClearAllBreakPoints() {
 | 
| -  DebugInfoListNode* node = debug_info_list_;
 | 
| -  while (node != NULL) {
 | 
| -    // Remove all debug break code.
 | 
| -    BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
 | 
| -    it.ClearAllDebugBreak();
 | 
| -    node = node->next();
 | 
| +  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
 | 
| +       node = node->next()) {
 | 
| +    for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
 | 
| +         !it.Done(); it.Next()) {
 | 
| +      it.GetBreakLocation().ClearDebugBreak();
 | 
| +    }
 | 
|    }
 | 
| -
 | 
|    // Remove all debug info.
 | 
|    while (debug_info_list_ != NULL) {
 | 
|      RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
 | 
| @@ -1179,10 +1110,9 @@ void Debug::FloodWithOneShot(Handle<JSFunction> function,
 | 
|    }
 | 
|  
 | 
|    // Flood the function with break points.
 | 
| -  BreakLocationIterator it(GetDebugInfo(shared), type);
 | 
| -  while (!it.Done()) {
 | 
| -    it.SetOneShot();
 | 
| -    it.Next();
 | 
| +  for (BreakLocation::Iterator it(GetDebugInfo(shared), type); !it.Done();
 | 
| +       it.Next()) {
 | 
| +    it.GetBreakLocation().SetOneShot();
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -1341,64 +1271,49 @@ void Debug::PrepareStep(StepAction step_action,
 | 
|    bool is_load_or_store = false;
 | 
|    bool is_inline_cache_stub = false;
 | 
|    bool is_at_restarted_function = false;
 | 
| -  bool is_exit = false;
 | 
| -  bool is_construct_call = false;
 | 
|    Handle<Code> call_function_stub;
 | 
|  
 | 
| -  {
 | 
| -    // Find the break location where execution has stopped.
 | 
| -    DisallowHeapAllocation no_gc;
 | 
| -    BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS);
 | 
| -
 | 
| -    // pc points to the instruction after the current one, possibly a break
 | 
| -    // location as well. So the "- 1" to exclude it from the search.
 | 
| -    it.FindBreakLocationFromAddress(frame->pc() - 1);
 | 
| -
 | 
| -    is_exit = it.IsExit();
 | 
| -    is_construct_call = RelocInfo::IsConstructCall(it.rmode());
 | 
| -
 | 
| -    if (thread_local_.restarter_frame_function_pointer_ == NULL) {
 | 
| -      if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
 | 
| -        bool is_call_target = false;
 | 
| -        Address target = it.rinfo()->target_address();
 | 
| -        Code* code = Code::GetCodeFromTargetAddress(target);
 | 
| -
 | 
| -        is_call_target = code->is_call_stub();
 | 
| -        is_inline_cache_stub = code->is_inline_cache_stub();
 | 
| -        is_load_or_store = is_inline_cache_stub && !is_call_target;
 | 
| -
 | 
| -        // Check if target code is CallFunction stub.
 | 
| -        Code* maybe_call_function_stub = code;
 | 
| -        // If there is a breakpoint at this line look at the original code to
 | 
| -        // check if it is a CallFunction stub.
 | 
| -        if (it.IsDebugBreak()) {
 | 
| -          Address original_target = it.original_rinfo()->target_address();
 | 
| -          maybe_call_function_stub =
 | 
| -              Code::GetCodeFromTargetAddress(original_target);
 | 
| -        }
 | 
| -        if ((maybe_call_function_stub->kind() == Code::STUB &&
 | 
| -             CodeStub::GetMajorKey(maybe_call_function_stub) ==
 | 
| -                 CodeStub::CallFunction) ||
 | 
| -            maybe_call_function_stub->is_call_stub()) {
 | 
| -          // Save reference to the code as we may need it to find out arguments
 | 
| -          // count for 'step in' later.
 | 
| -          call_function_stub = Handle<Code>(maybe_call_function_stub);
 | 
| -        }
 | 
| +  // PC points to the instruction after the current one, possibly a break
 | 
| +  // location as well. So the "- 1" to exclude it from the search.
 | 
| +  Address call_pc = frame->pc() - 1;
 | 
| +  BreakLocation location =
 | 
| +      BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
 | 
| +
 | 
| +  if (thread_local_.restarter_frame_function_pointer_ == NULL) {
 | 
| +    if (location.IsCodeTarget()) {
 | 
| +      Handle<Code> target_code = location.CodeTarget();
 | 
| +      is_inline_cache_stub = target_code->is_inline_cache_stub();
 | 
| +      is_load_or_store = is_inline_cache_stub && !target_code->is_call_stub();
 | 
| +
 | 
| +      // Check if target code is CallFunction stub.
 | 
| +      Handle<Code> maybe_call_function_stub = target_code;
 | 
| +      // If there is a breakpoint at this line look at the original code to
 | 
| +      // check if it is a CallFunction stub.
 | 
| +      if (location.IsDebugBreak()) {
 | 
| +        maybe_call_function_stub = location.OriginalCodeTarget();
 | 
| +      }
 | 
| +      if ((maybe_call_function_stub->kind() == Code::STUB &&
 | 
| +           CodeStub::GetMajorKey(*maybe_call_function_stub) ==
 | 
| +               CodeStub::CallFunction) ||
 | 
| +          maybe_call_function_stub->is_call_stub()) {
 | 
| +        // Save reference to the code as we may need it to find out arguments
 | 
| +        // count for 'step in' later.
 | 
| +        call_function_stub = maybe_call_function_stub;
 | 
|        }
 | 
| -    } else {
 | 
| -      is_at_restarted_function = true;
 | 
|      }
 | 
| +  } else {
 | 
| +    is_at_restarted_function = true;
 | 
|    }
 | 
|  
 | 
|    // If this is the last break code target step out is the only possibility.
 | 
| -  if (is_exit || step_action == StepOut) {
 | 
| +  if (location.IsExit() || step_action == StepOut) {
 | 
|      if (step_action == StepOut) {
 | 
|        // Skip step_count frames starting with the current one.
 | 
|        while (step_count-- > 0 && !frames_it.done()) {
 | 
|          frames_it.Advance();
 | 
|        }
 | 
|      } else {
 | 
| -      DCHECK(is_exit);
 | 
| +      DCHECK(location.IsExit());
 | 
|        frames_it.Advance();
 | 
|      }
 | 
|      // Skip builtin functions on the stack.
 | 
| @@ -1415,7 +1330,7 @@ void Debug::PrepareStep(StepAction step_action,
 | 
|        // Set target frame pointer.
 | 
|        ActivateStepOut(frames_it.frame());
 | 
|      }
 | 
| -  } else if (!(is_inline_cache_stub || is_construct_call ||
 | 
| +  } else if (!(is_inline_cache_stub || location.IsConstructCall() ||
 | 
|                 !call_function_stub.is_null() || is_at_restarted_function) ||
 | 
|               step_action == StepNext || step_action == StepMin) {
 | 
|      // Step next or step min.
 | 
| @@ -1511,7 +1426,7 @@ void Debug::PrepareStep(StepAction step_action,
 | 
|      // Step in through CallFunction stub should also be prepared by caller of
 | 
|      // this function (Debug::PrepareStep) which should flood target function
 | 
|      // with breakpoints.
 | 
| -    DCHECK(is_construct_call || is_inline_cache_stub ||
 | 
| +    DCHECK(location.IsConstructCall() || is_inline_cache_stub ||
 | 
|             !call_function_stub.is_null() || is_at_restarted_function);
 | 
|      ActivateStepIn(frame);
 | 
|    }
 | 
| @@ -1524,7 +1439,7 @@ void Debug::PrepareStep(StepAction step_action,
 | 
|  // 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,
 | 
| +bool Debug::StepNextContinue(BreakLocation* break_location,
 | 
|                               JavaScriptFrame* frame) {
 | 
|    // StepNext and StepOut shouldn't bring us deeper in code, so last frame
 | 
|    // shouldn't be a parent of current frame.
 | 
| @@ -1543,11 +1458,11 @@ bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
 | 
|    // statement is hit.
 | 
|    if (step_action == StepNext || step_action == StepIn) {
 | 
|      // Never continue if returning from function.
 | 
| -    if (break_location_iterator->IsExit()) return false;
 | 
| +    if (break_location->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());
 | 
| +        break_location->code()->SourceStatementPosition(frame->pc());
 | 
|      return thread_local_.last_fp_ == frame->UnpaddedFP() &&
 | 
|          thread_local_.last_statement_position_ == current_statement_position;
 | 
|    }
 | 
| @@ -1565,9 +1480,6 @@ bool Debug::IsDebugBreak(Address addr) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -
 | 
| -
 | 
| -
 | 
|  // Simple function for returning the source positions for active break points.
 | 
|  Handle<Object> Debug::GetSourceBreakLocations(
 | 
|      Handle<SharedFunctionInfo> shared,
 | 
| @@ -1655,15 +1567,12 @@ 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();
 | 
| +  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
 | 
| +       node = node->next()) {
 | 
| +    for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
 | 
| +         !it.Done(); it.Next()) {
 | 
| +      it.GetBreakLocation().ClearOneShot();
 | 
|      }
 | 
| -    node = node->next();
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -2080,8 +1989,8 @@ void Debug::PrepareForBreakPoints() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
 | 
| -                                              int position) {
 | 
| +Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
 | 
| +                                                     int position) {
 | 
|    // Iterate the heap looking for SharedFunctionInfo generated from the
 | 
|    // script. The inner most SharedFunctionInfo containing the source position
 | 
|    // for the requested break point is found.
 | 
| @@ -2164,7 +2073,7 @@ Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
 | 
|        }  // End for loop.
 | 
|      }  // End no-allocation scope.
 | 
|  
 | 
| -    if (target.is_null()) return heap->undefined_value();
 | 
| +    if (target.is_null()) return isolate_->factory()->undefined_value();
 | 
|  
 | 
|      // There will be at least one break point when we are done.
 | 
|      has_break_points_ = true;
 | 
| @@ -2180,11 +2089,11 @@ Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
 | 
|        MaybeHandle<Code> maybe_result = target_function.is_null()
 | 
|            ? Compiler::GetUnoptimizedCode(target)
 | 
|            : Compiler::GetUnoptimizedCode(target_function);
 | 
| -      if (maybe_result.is_null()) return isolate_->heap()->undefined_value();
 | 
| +      if (maybe_result.is_null()) return isolate_->factory()->undefined_value();
 | 
|      }
 | 
|    }  // End while loop.
 | 
|  
 | 
| -  return *target;
 | 
| +  return target;
 | 
|  }
 | 
|  
 | 
|  
 | 
| 
 |