OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 14045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14056 Handle<Object> p = it.rinfo()->code_age_stub_handle(origin); | 14056 Handle<Object> p = it.rinfo()->code_age_stub_handle(origin); |
14057 Code* code = Code::cast(*p); | 14057 Code* code = Code::cast(*p); |
14058 it.rinfo()->set_code_age_stub(code, SKIP_ICACHE_FLUSH); | 14058 it.rinfo()->set_code_age_stub(code, SKIP_ICACHE_FLUSH); |
14059 } else { | 14059 } else { |
14060 it.rinfo()->apply(delta); | 14060 it.rinfo()->apply(delta); |
14061 } | 14061 } |
14062 } | 14062 } |
14063 Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size()); | 14063 Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size()); |
14064 } | 14064 } |
14065 | 14065 |
14066 | 14066 // Locate the source position which is closest to the code offset. This is |
14067 // Locate the source position which is closest to the address in the code. This | 14067 // using the source position information embedded in the relocation info. |
14068 // is using the source position information embedded in the relocation info. | |
14069 // The position returned is relative to the beginning of the script where the | 14068 // The position returned is relative to the beginning of the script where the |
14070 // source for this function is found. | 14069 // source for this function is found. |
14071 int Code::SourcePosition(Address pc) { | 14070 int Code::SourcePosition(int code_offset) { |
| 14071 Address pc = instruction_start() + code_offset; |
14072 int distance = kMaxInt; | 14072 int distance = kMaxInt; |
14073 int position = RelocInfo::kNoPosition; // Initially no position found. | 14073 int position = RelocInfo::kNoPosition; // Initially no position found. |
14074 // Run through all the relocation info to find the best matching source | 14074 // Run through all the relocation info to find the best matching source |
14075 // position. All the code needs to be considered as the sequence of the | 14075 // position. All the code needs to be considered as the sequence of the |
14076 // instructions in the code does not necessarily follow the same order as the | 14076 // instructions in the code does not necessarily follow the same order as the |
14077 // source. | 14077 // source. |
14078 RelocIterator it(this, RelocInfo::kPositionMask); | 14078 RelocIterator it(this, RelocInfo::kPositionMask); |
14079 while (!it.done()) { | 14079 while (!it.done()) { |
14080 // Only look at positions after the current pc. | 14080 // Only look at positions after the current pc. |
14081 if (it.rinfo()->pc() < pc) { | 14081 if (it.rinfo()->pc() < pc) { |
(...skipping 11 matching lines...) Expand all Loading... |
14093 } | 14093 } |
14094 } | 14094 } |
14095 it.next(); | 14095 it.next(); |
14096 } | 14096 } |
14097 return position; | 14097 return position; |
14098 } | 14098 } |
14099 | 14099 |
14100 | 14100 |
14101 // Same as Code::SourcePosition above except it only looks for statement | 14101 // Same as Code::SourcePosition above except it only looks for statement |
14102 // positions. | 14102 // positions. |
14103 int Code::SourceStatementPosition(Address pc) { | 14103 int Code::SourceStatementPosition(int code_offset) { |
14104 // First find the position as close as possible using all position | 14104 // First find the position as close as possible using all position |
14105 // information. | 14105 // information. |
14106 int position = SourcePosition(pc); | 14106 int position = SourcePosition(code_offset); |
14107 // Now find the closest statement position before the position. | 14107 // Now find the closest statement position before the position. |
14108 int statement_position = 0; | 14108 int statement_position = 0; |
14109 RelocIterator it(this, RelocInfo::kPositionMask); | 14109 RelocIterator it(this, RelocInfo::kPositionMask); |
14110 while (!it.done()) { | 14110 while (!it.done()) { |
14111 if (RelocInfo::IsStatementPosition(it.rinfo()->rmode())) { | 14111 if (RelocInfo::IsStatementPosition(it.rinfo()->rmode())) { |
14112 int p = static_cast<int>(it.rinfo()->data()); | 14112 int p = static_cast<int>(it.rinfo()->data()); |
14113 if (statement_position < p && p <= position) { | 14113 if (statement_position < p && p <= position) { |
14114 statement_position = p; | 14114 statement_position = p; |
14115 } | 14115 } |
14116 } | 14116 } |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14297 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); | 14297 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); |
14298 if (target->is_inline_cache_stub()) { | 14298 if (target->is_inline_cache_stub()) { |
14299 if (kind == NULL || *kind == target->kind()) { | 14299 if (kind == NULL || *kind == target->kind()) { |
14300 IC::Clear(this->GetIsolate(), info->pc(), | 14300 IC::Clear(this->GetIsolate(), info->pc(), |
14301 info->host()->constant_pool()); | 14301 info->host()->constant_pool()); |
14302 } | 14302 } |
14303 } | 14303 } |
14304 } | 14304 } |
14305 } | 14305 } |
14306 | 14306 |
| 14307 int AbstractCode::SourcePosition(int offset) { |
| 14308 if (IsBytecodeArray()) return GetBytecodeArray()->SourcePosition(offset); |
| 14309 return GetCode()->SourcePosition(offset); |
| 14310 } |
14307 | 14311 |
14308 void SharedFunctionInfo::ClearTypeFeedbackInfo() { | 14312 void SharedFunctionInfo::ClearTypeFeedbackInfo() { |
14309 feedback_vector()->ClearSlots(this); | 14313 feedback_vector()->ClearSlots(this); |
14310 } | 14314 } |
14311 | 14315 |
14312 | 14316 |
14313 void SharedFunctionInfo::ClearTypeFeedbackInfoAtGCTime() { | 14317 void SharedFunctionInfo::ClearTypeFeedbackInfoAtGCTime() { |
14314 feedback_vector()->ClearSlotsAtGCTime(this); | 14318 feedback_vector()->ClearSlotsAtGCTime(this); |
14315 } | 14319 } |
14316 | 14320 |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14989 } | 14993 } |
14990 | 14994 |
14991 os << "RelocInfo (size = " << relocation_size() << ")\n"; | 14995 os << "RelocInfo (size = " << relocation_size() << ")\n"; |
14992 for (RelocIterator it(this); !it.done(); it.next()) { | 14996 for (RelocIterator it(this); !it.done(); it.next()) { |
14993 it.rinfo()->Print(GetIsolate(), os); | 14997 it.rinfo()->Print(GetIsolate(), os); |
14994 } | 14998 } |
14995 os << "\n"; | 14999 os << "\n"; |
14996 } | 15000 } |
14997 #endif // ENABLE_DISASSEMBLER | 15001 #endif // ENABLE_DISASSEMBLER |
14998 | 15002 |
| 15003 int BytecodeArray::SourcePosition(int offset) { |
| 15004 // TODO(yangguo): implement this. |
| 15005 return 0; |
| 15006 } |
14999 | 15007 |
15000 void BytecodeArray::Disassemble(std::ostream& os) { | 15008 void BytecodeArray::Disassemble(std::ostream& os) { |
15001 os << "Parameter count " << parameter_count() << "\n"; | 15009 os << "Parameter count " << parameter_count() << "\n"; |
15002 os << "Frame size " << frame_size() << "\n"; | 15010 os << "Frame size " << frame_size() << "\n"; |
15003 Vector<char> buf = Vector<char>::New(50); | 15011 Vector<char> buf = Vector<char>::New(50); |
15004 | 15012 |
15005 const uint8_t* first_bytecode_address = GetFirstBytecodeAddress(); | 15013 const uint8_t* first_bytecode_address = GetFirstBytecodeAddress(); |
15006 int bytecode_size = 0; | 15014 int bytecode_size = 0; |
15007 for (int i = 0; i < this->length(); i += bytecode_size) { | 15015 for (int i = 0; i < this->length(); i += bytecode_size) { |
15008 const uint8_t* bytecode_start = &first_bytecode_address[i]; | 15016 const uint8_t* bytecode_start = &first_bytecode_address[i]; |
(...skipping 4034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19043 Handle<ObjectHashTable> new_table = | 19051 Handle<ObjectHashTable> new_table = |
19044 ObjectHashTable::Remove(table, key, &was_present, hash); | 19052 ObjectHashTable::Remove(table, key, &was_present, hash); |
19045 weak_collection->set_table(*new_table); | 19053 weak_collection->set_table(*new_table); |
19046 if (*table != *new_table) { | 19054 if (*table != *new_table) { |
19047 // Zap the old table since we didn't record slots for its elements. | 19055 // Zap the old table since we didn't record slots for its elements. |
19048 table->FillWithHoles(0, table->length()); | 19056 table->FillWithHoles(0, table->length()); |
19049 } | 19057 } |
19050 return was_present; | 19058 return was_present; |
19051 } | 19059 } |
19052 | 19060 |
19053 | 19061 // Check if there is a break point at this code offset. |
19054 // Check if there is a break point at this code position. | 19062 bool DebugInfo::HasBreakPoint(int code_offset) { |
19055 bool DebugInfo::HasBreakPoint(int code_position) { | 19063 // Get the break point info object for this code offset. |
19056 // Get the break point info object for this code position. | 19064 Object* break_point_info = GetBreakPointInfo(code_offset); |
19057 Object* break_point_info = GetBreakPointInfo(code_position); | |
19058 | 19065 |
19059 // If there is no break point info object or no break points in the break | 19066 // If there is no break point info object or no break points in the break |
19060 // point info object there is no break point at this code position. | 19067 // point info object there is no break point at this code offset. |
19061 if (break_point_info->IsUndefined()) return false; | 19068 if (break_point_info->IsUndefined()) return false; |
19062 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | 19069 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
19063 } | 19070 } |
19064 | 19071 |
19065 | 19072 // Get the break point info object for this code offset. |
19066 // Get the break point info object for this code position. | 19073 Object* DebugInfo::GetBreakPointInfo(int code_offset) { |
19067 Object* DebugInfo::GetBreakPointInfo(int code_position) { | 19074 // Find the index of the break point info object for this code offset. |
19068 // Find the index of the break point info object for this code position. | 19075 int index = GetBreakPointInfoIndex(code_offset); |
19069 int index = GetBreakPointInfoIndex(code_position); | |
19070 | 19076 |
19071 // Return the break point info object if any. | 19077 // Return the break point info object if any. |
19072 if (index == kNoBreakPointInfo) return GetHeap()->undefined_value(); | 19078 if (index == kNoBreakPointInfo) return GetHeap()->undefined_value(); |
19073 return BreakPointInfo::cast(break_points()->get(index)); | 19079 return BreakPointInfo::cast(break_points()->get(index)); |
19074 } | 19080 } |
19075 | 19081 |
19076 | 19082 // Clear a break point at the specified code offset. |
19077 // Clear a break point at the specified code position. | 19083 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, int code_offset, |
19078 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, | |
19079 int code_position, | |
19080 Handle<Object> break_point_object) { | 19084 Handle<Object> break_point_object) { |
19081 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position), | 19085 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_offset), |
19082 debug_info->GetIsolate()); | 19086 debug_info->GetIsolate()); |
19083 if (break_point_info->IsUndefined()) return; | 19087 if (break_point_info->IsUndefined()) return; |
19084 BreakPointInfo::ClearBreakPoint( | 19088 BreakPointInfo::ClearBreakPoint( |
19085 Handle<BreakPointInfo>::cast(break_point_info), | 19089 Handle<BreakPointInfo>::cast(break_point_info), |
19086 break_point_object); | 19090 break_point_object); |
19087 } | 19091 } |
19088 | 19092 |
19089 | 19093 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int code_offset, |
19090 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, | 19094 int source_position, int statement_position, |
19091 int code_position, | |
19092 int source_position, | |
19093 int statement_position, | |
19094 Handle<Object> break_point_object) { | 19095 Handle<Object> break_point_object) { |
19095 Isolate* isolate = debug_info->GetIsolate(); | 19096 Isolate* isolate = debug_info->GetIsolate(); |
19096 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position), | 19097 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_offset), |
19097 isolate); | 19098 isolate); |
19098 if (!break_point_info->IsUndefined()) { | 19099 if (!break_point_info->IsUndefined()) { |
19099 BreakPointInfo::SetBreakPoint( | 19100 BreakPointInfo::SetBreakPoint( |
19100 Handle<BreakPointInfo>::cast(break_point_info), | 19101 Handle<BreakPointInfo>::cast(break_point_info), |
19101 break_point_object); | 19102 break_point_object); |
19102 return; | 19103 return; |
19103 } | 19104 } |
19104 | 19105 |
19105 // Adding a new break point for a code position which did not have any | 19106 // Adding a new break point for a code offset which did not have any |
19106 // break points before. Try to find a free slot. | 19107 // break points before. Try to find a free slot. |
19107 int index = kNoBreakPointInfo; | 19108 int index = kNoBreakPointInfo; |
19108 for (int i = 0; i < debug_info->break_points()->length(); i++) { | 19109 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
19109 if (debug_info->break_points()->get(i)->IsUndefined()) { | 19110 if (debug_info->break_points()->get(i)->IsUndefined()) { |
19110 index = i; | 19111 index = i; |
19111 break; | 19112 break; |
19112 } | 19113 } |
19113 } | 19114 } |
19114 if (index == kNoBreakPointInfo) { | 19115 if (index == kNoBreakPointInfo) { |
19115 // No free slot - extend break point info array. | 19116 // No free slot - extend break point info array. |
19116 Handle<FixedArray> old_break_points = | 19117 Handle<FixedArray> old_break_points = |
19117 Handle<FixedArray>(FixedArray::cast(debug_info->break_points())); | 19118 Handle<FixedArray>(FixedArray::cast(debug_info->break_points())); |
19118 Handle<FixedArray> new_break_points = | 19119 Handle<FixedArray> new_break_points = |
19119 isolate->factory()->NewFixedArray( | 19120 isolate->factory()->NewFixedArray( |
19120 old_break_points->length() + | 19121 old_break_points->length() + |
19121 DebugInfo::kEstimatedNofBreakPointsInFunction); | 19122 DebugInfo::kEstimatedNofBreakPointsInFunction); |
19122 | 19123 |
19123 debug_info->set_break_points(*new_break_points); | 19124 debug_info->set_break_points(*new_break_points); |
19124 for (int i = 0; i < old_break_points->length(); i++) { | 19125 for (int i = 0; i < old_break_points->length(); i++) { |
19125 new_break_points->set(i, old_break_points->get(i)); | 19126 new_break_points->set(i, old_break_points->get(i)); |
19126 } | 19127 } |
19127 index = old_break_points->length(); | 19128 index = old_break_points->length(); |
19128 } | 19129 } |
19129 DCHECK(index != kNoBreakPointInfo); | 19130 DCHECK(index != kNoBreakPointInfo); |
19130 | 19131 |
19131 // Allocate new BreakPointInfo object and set the break point. | 19132 // Allocate new BreakPointInfo object and set the break point. |
19132 Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast( | 19133 Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast( |
19133 isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE)); | 19134 isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE)); |
19134 new_break_point_info->set_code_position(code_position); | 19135 new_break_point_info->set_code_offset(code_offset); |
19135 new_break_point_info->set_source_position(source_position); | 19136 new_break_point_info->set_source_position(source_position); |
19136 new_break_point_info->set_statement_position(statement_position); | 19137 new_break_point_info->set_statement_position(statement_position); |
19137 new_break_point_info->set_break_point_objects( | 19138 new_break_point_info->set_break_point_objects( |
19138 isolate->heap()->undefined_value()); | 19139 isolate->heap()->undefined_value()); |
19139 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); | 19140 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); |
19140 debug_info->break_points()->set(index, *new_break_point_info); | 19141 debug_info->break_points()->set(index, *new_break_point_info); |
19141 } | 19142 } |
19142 | 19143 |
19143 | 19144 // Get the break point objects for a code offset. |
19144 // Get the break point objects for a code position. | 19145 Handle<Object> DebugInfo::GetBreakPointObjects(int code_offset) { |
19145 Handle<Object> DebugInfo::GetBreakPointObjects(int code_position) { | 19146 Object* break_point_info = GetBreakPointInfo(code_offset); |
19146 Object* break_point_info = GetBreakPointInfo(code_position); | |
19147 if (break_point_info->IsUndefined()) { | 19147 if (break_point_info->IsUndefined()) { |
19148 return GetIsolate()->factory()->undefined_value(); | 19148 return GetIsolate()->factory()->undefined_value(); |
19149 } | 19149 } |
19150 return Handle<Object>( | 19150 return Handle<Object>( |
19151 BreakPointInfo::cast(break_point_info)->break_point_objects(), | 19151 BreakPointInfo::cast(break_point_info)->break_point_objects(), |
19152 GetIsolate()); | 19152 GetIsolate()); |
19153 } | 19153 } |
19154 | 19154 |
19155 | 19155 |
19156 // Get the total number of break points. | 19156 // Get the total number of break points. |
(...skipping 25 matching lines...) Expand all Loading... |
19182 } | 19182 } |
19183 } | 19183 } |
19184 } | 19184 } |
19185 } | 19185 } |
19186 return isolate->factory()->undefined_value(); | 19186 return isolate->factory()->undefined_value(); |
19187 } | 19187 } |
19188 | 19188 |
19189 | 19189 |
19190 // Find the index of the break point info object for the specified code | 19190 // Find the index of the break point info object for the specified code |
19191 // position. | 19191 // position. |
19192 int DebugInfo::GetBreakPointInfoIndex(int code_position) { | 19192 int DebugInfo::GetBreakPointInfoIndex(int code_offset) { |
19193 if (break_points()->IsUndefined()) return kNoBreakPointInfo; | 19193 if (break_points()->IsUndefined()) return kNoBreakPointInfo; |
19194 for (int i = 0; i < break_points()->length(); i++) { | 19194 for (int i = 0; i < break_points()->length(); i++) { |
19195 if (!break_points()->get(i)->IsUndefined()) { | 19195 if (!break_points()->get(i)->IsUndefined()) { |
19196 BreakPointInfo* break_point_info = | 19196 BreakPointInfo* break_point_info = |
19197 BreakPointInfo::cast(break_points()->get(i)); | 19197 BreakPointInfo::cast(break_points()->get(i)); |
19198 if (break_point_info->code_position() == code_position) { | 19198 if (break_point_info->code_offset() == code_offset) { |
19199 return i; | 19199 return i; |
19200 } | 19200 } |
19201 } | 19201 } |
19202 } | 19202 } |
19203 return kNoBreakPointInfo; | 19203 return kNoBreakPointInfo; |
19204 } | 19204 } |
19205 | 19205 |
19206 | 19206 |
19207 // Remove the specified break point object. | 19207 // Remove the specified break point object. |
19208 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, | 19208 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19749 if (cell->value() != *new_value) { | 19749 if (cell->value() != *new_value) { |
19750 cell->set_value(*new_value); | 19750 cell->set_value(*new_value); |
19751 Isolate* isolate = cell->GetIsolate(); | 19751 Isolate* isolate = cell->GetIsolate(); |
19752 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19752 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19753 isolate, DependentCode::kPropertyCellChangedGroup); | 19753 isolate, DependentCode::kPropertyCellChangedGroup); |
19754 } | 19754 } |
19755 } | 19755 } |
19756 | 19756 |
19757 } // namespace internal | 19757 } // namespace internal |
19758 } // namespace v8 | 19758 } // namespace v8 |
OLD | NEW |