[debugger] use source position to identify break points.

This makes break point info independent from the code kind being executed.

BUG=v8:5265

Review-Url: https://codereview.chromium.org/2230143002
Cr-Commit-Position: refs/heads/master@{#38528}
This commit is contained in:
yangguo 2016-08-10 02:57:00 -07:00 committed by Commit bot
parent 7e065bad8c
commit e2e676d51d
6 changed files with 71 additions and 93 deletions

View File

@ -321,14 +321,14 @@ void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
if (!HasBreakPoint()) SetDebugBreak();
DCHECK(IsDebugBreak() || IsDebuggerStatement());
// Set the break point information.
DebugInfo::SetBreakPoint(debug_info_, code_offset_, position_,
statement_position_, break_point_object);
DebugInfo::SetBreakPoint(debug_info_, position_, statement_position_,
break_point_object);
}
void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) {
// Clear the break point information.
DebugInfo::ClearBreakPoint(debug_info_, code_offset_, break_point_object);
DebugInfo::ClearBreakPoint(debug_info_, position_, break_point_object);
// If there are no more break points here remove the debug break.
if (!HasBreakPoint()) {
ClearDebugBreak();
@ -341,12 +341,6 @@ void BreakLocation::SetOneShot() {
// Debugger statement always calls debugger. No need to modify it.
if (IsDebuggerStatement()) return;
// If there is a real break point here no more to do.
if (HasBreakPoint()) {
DCHECK(IsDebugBreak());
return;
}
// Patch code with debug break.
SetDebugBreak();
}
@ -435,9 +429,19 @@ bool BreakLocation::IsDebugBreak() const {
}
}
Handle<Object> BreakLocation::BreakPointObjects() const {
return debug_info_->GetBreakPointObjects(code_offset_);
return debug_info_->GetBreakPointObjects(position_);
}
bool BreakLocation::HasBreakPoint() const {
// First check whether there is a break point with the same source position.
if (!debug_info_->HasBreakPoint(position_)) return false;
// Then check whether a break point at that source position would have
// the same code offset. Otherwise it's just a break location that we can
// step to, but not actually a location where we can put a break point.
BreakLocation break_point_location = BreakLocation::FromPosition(
debug_info_, position_, BREAK_POSITION_ALIGNED);
return break_point_location.code_offset() == code_offset_;
}
void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) {
@ -830,8 +834,9 @@ void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
Handle<BreakPointInfo>::cast(result);
Handle<DebugInfo> debug_info = node->debug_info();
BreakLocation location = BreakLocation::FromCodeOffset(
debug_info, break_point_info->code_offset());
BreakLocation location = BreakLocation::FromPosition(
debug_info, break_point_info->source_position(),
BREAK_POSITION_ALIGNED);
location.ClearBreakPoint(break_point_object);
// If there are no more break points left remove the debug info for this
@ -1094,13 +1099,14 @@ Handle<Object> Debug::GetSourceBreakLocations(
int break_points = break_point_info->GetBreakPointCount();
if (break_points == 0) continue;
Smi* position = NULL;
switch (position_alignment) {
case STATEMENT_ALIGNED:
position = Smi::FromInt(break_point_info->statement_position());
break;
case BREAK_POSITION_ALIGNED:
position = Smi::FromInt(break_point_info->source_position());
break;
if (position_alignment == STATEMENT_ALIGNED) {
BreakLocation break_point_location = BreakLocation::FromPosition(
debug_info, break_point_info->source_position(),
BREAK_POSITION_ALIGNED);
position = Smi::FromInt(break_point_location.statement_position());
} else {
DCHECK_EQ(BREAK_POSITION_ALIGNED, position_alignment);
position = Smi::FromInt(break_point_info->source_position());
}
for (int j = 0; j < break_points; ++j) locations->set(count++, position);
}

View File

@ -75,6 +75,7 @@ class BreakLocation {
int statement_position,
List<BreakLocation>* result_out);
// Find break location (for a break point) from source positon.
static BreakLocation FromPosition(Handle<DebugInfo> debug_info, int position,
BreakPositionAlignment alignment);
@ -89,9 +90,8 @@ class BreakLocation {
inline bool IsDebuggerStatement() const {
return type_ == DEBUGGER_STATEMENT;
}
inline bool HasBreakPoint() const {
return debug_info_->HasBreakPoint(code_offset_);
}
bool HasBreakPoint() const;
Handle<Object> BreakPointObjects() const;

View File

@ -5818,9 +5818,7 @@ BytecodeArray* DebugInfo::original_bytecode_array() {
return shared()->bytecode_array();
}
SMI_ACCESSORS(BreakPointInfo, code_offset, kCodeOffsetIndex)
SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex)
SMI_ACCESSORS(BreakPointInfo, statement_position, kStatementPositionIndex)
ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)

View File

@ -1286,9 +1286,7 @@ void DebugInfo::DebugInfoPrint(std::ostream& os) { // NOLINT
void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) { // NOLINT
HeapObject::PrintHeader(os, "BreakPointInfo");
os << "\n - code_offset: " << code_offset();
os << "\n - source_position: " << source_position();
os << "\n - statement_position: " << statement_position();
os << "\n - break_point_objects: " << Brief(break_point_objects());
os << "\n";
}

View File

@ -18462,10 +18462,10 @@ bool JSWeakCollection::Delete(Handle<JSWeakCollection> weak_collection,
return was_present;
}
// Check if there is a break point at this code offset.
bool DebugInfo::HasBreakPoint(int code_offset) {
// Check if there is a break point at this source position.
bool DebugInfo::HasBreakPoint(int source_position) {
// Get the break point info object for this code offset.
Object* break_point_info = GetBreakPointInfo(code_offset);
Object* break_point_info = GetBreakPointInfo(source_position);
// If there is no break point info object or no break points in the break
// point info object there is no break point at this code offset.
@ -18473,34 +18473,42 @@ bool DebugInfo::HasBreakPoint(int code_offset) {
return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
}
// Get the break point info object for this code offset.
Object* DebugInfo::GetBreakPointInfo(int code_offset) {
// Find the index of the break point info object for this code offset.
int index = GetBreakPointInfoIndex(code_offset);
// Return the break point info object if any.
if (index == kNoBreakPointInfo) return GetHeap()->undefined_value();
return BreakPointInfo::cast(break_points()->get(index));
// Get the break point info object for this source position.
Object* DebugInfo::GetBreakPointInfo(int source_position) {
Isolate* isolate = GetIsolate();
if (!break_points()->IsUndefined(isolate)) {
for (int i = 0; i < break_points()->length(); i++) {
if (!break_points()->get(i)->IsUndefined(isolate)) {
BreakPointInfo* break_point_info =
BreakPointInfo::cast(break_points()->get(i));
if (break_point_info->source_position() == source_position) {
return break_point_info;
}
}
}
}
return isolate->heap()->undefined_value();
}
// Clear a break point at the specified code offset.
void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
// Clear a break point at the specified source_position.
void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
int source_position,
Handle<Object> break_point_object) {
Isolate* isolate = debug_info->GetIsolate();
Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_offset),
isolate);
Handle<Object> break_point_info(
debug_info->GetBreakPointInfo(source_position), isolate);
if (break_point_info->IsUndefined(isolate)) return;
BreakPointInfo::ClearBreakPoint(
Handle<BreakPointInfo>::cast(break_point_info),
break_point_object);
}
void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
int source_position, int statement_position,
void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
int statement_position,
Handle<Object> break_point_object) {
Isolate* isolate = debug_info->GetIsolate();
Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_offset),
isolate);
Handle<Object> break_point_info(
debug_info->GetBreakPointInfo(source_position), isolate);
if (!break_point_info->IsUndefined(isolate)) {
BreakPointInfo::SetBreakPoint(
Handle<BreakPointInfo>::cast(break_point_info),
@ -18510,6 +18518,7 @@ void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
// Adding a new break point for a code offset which did not have any
// break points before. Try to find a free slot.
static const int kNoBreakPointInfo = -1;
int index = kNoBreakPointInfo;
for (int i = 0; i < debug_info->break_points()->length(); i++) {
if (debug_info->break_points()->get(i)->IsUndefined(isolate)) {
@ -18537,18 +18546,16 @@ void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
// Allocate new BreakPointInfo object and set the break point.
Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast(
isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE));
new_break_point_info->set_code_offset(code_offset);
new_break_point_info->set_source_position(source_position);
new_break_point_info->set_statement_position(statement_position);
new_break_point_info->set_break_point_objects(
isolate->heap()->undefined_value());
BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
debug_info->break_points()->set(index, *new_break_point_info);
}
// Get the break point objects for a code offset.
Handle<Object> DebugInfo::GetBreakPointObjects(int code_offset) {
Object* break_point_info = GetBreakPointInfo(code_offset);
// Get the break point objects for a source position.
Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) {
Object* break_point_info = GetBreakPointInfo(source_position);
Isolate* isolate = GetIsolate();
if (break_point_info->IsUndefined(isolate)) {
return isolate->factory()->undefined_value();
@ -18592,25 +18599,6 @@ Handle<Object> DebugInfo::FindBreakPointInfo(
return isolate->factory()->undefined_value();
}
// Find the index of the break point info object for the specified code
// position.
int DebugInfo::GetBreakPointInfoIndex(int code_offset) {
Isolate* isolate = GetIsolate();
if (break_points()->IsUndefined(isolate)) return kNoBreakPointInfo;
for (int i = 0; i < break_points()->length(); i++) {
if (!break_points()->get(i)->IsUndefined(isolate)) {
BreakPointInfo* break_point_info =
BreakPointInfo::cast(break_points()->get(i));
if (break_point_info->code_offset() == code_offset) {
return i;
}
}
}
return kNoBreakPointInfo;
}
// Remove the specified break point object.
void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
Handle<Object> break_point_object) {

View File

@ -10866,19 +10866,17 @@ class DebugInfo: public Struct {
// Fixed array holding status information for each active break point.
DECL_ACCESSORS(break_points, FixedArray)
// Check if there is a break point at a code offset.
bool HasBreakPoint(int code_offset);
// Get the break point info object for a code offset.
Object* GetBreakPointInfo(int code_offset);
// Check if there is a break point at a source position.
bool HasBreakPoint(int source_position);
// Clear a break point.
static void ClearBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
static void ClearBreakPoint(Handle<DebugInfo> debug_info, int source_position,
Handle<Object> break_point_object);
// Set a break point.
static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
int source_position, int statement_position,
static void SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
int statement_position,
Handle<Object> break_point_object);
// Get the break point objects for a code offset.
Handle<Object> GetBreakPointObjects(int code_offset);
// Get the break point objects for a source position.
Handle<Object> GetBreakPointObjects(int source_position);
// Find the break point info holding this break point object.
static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
Handle<Object> break_point_object);
@ -10903,10 +10901,8 @@ class DebugInfo: public Struct {
static const int kEstimatedNofBreakPointsInFunction = 16;
private:
static const int kNoBreakPointInfo = -1;
// Lookup the index in the break_points array for a code offset.
int GetBreakPointInfoIndex(int code_offset);
// Get the break point info object for a source position.
Object* GetBreakPointInfo(int source_position);
DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
};
@ -10917,13 +10913,8 @@ class DebugInfo: public Struct {
// position with one or more break points.
class BreakPointInfo: public Struct {
public:
// The code offset for the break point.
DECL_INT_ACCESSORS(code_offset)
// The position in the source for the break position.
DECL_INT_ACCESSORS(source_position)
// The position in the source for the last statement before this break
// position.
DECL_INT_ACCESSORS(statement_position)
// List of related JavaScript break points.
DECL_ACCESSORS(break_point_objects, Object)
@ -10945,12 +10936,9 @@ class BreakPointInfo: public Struct {
DECLARE_PRINTER(BreakPointInfo)
DECLARE_VERIFIER(BreakPointInfo)
static const int kCodeOffsetIndex = Struct::kHeaderSize;
static const int kSourcePositionIndex = kCodeOffsetIndex + kPointerSize;
static const int kStatementPositionIndex =
kSourcePositionIndex + kPointerSize;
static const int kSourcePositionIndex = Struct::kHeaderSize;
static const int kBreakPointObjectsIndex =
kStatementPositionIndex + kPointerSize;
kSourcePositionIndex + kPointerSize;
static const int kSize = kBreakPointObjectsIndex + kPointerSize;
private: