Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/debugger.h" | 5 #include "vm/debugger.h" |
| 6 | 6 |
| 7 #include "vm/code_index_table.h" | 7 #include "vm/code_index_table.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 } | 63 } |
| 64 | 64 |
| 65 | 65 |
| 66 void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 66 void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 67 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); | 67 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); |
| 68 } | 68 } |
| 69 | 69 |
| 70 | 70 |
| 71 ActivationFrame::ActivationFrame(uword pc) | 71 ActivationFrame::ActivationFrame(uword pc) |
| 72 : pc_(pc), | 72 : pc_(pc), |
| 73 function_(Function::null()), | 73 function_(NULL), |
| 74 token_index_(-1), | 74 token_index_(-1), |
| 75 line_number_(-1) { | 75 line_number_(-1), |
| 76 locals_(NULL) { | |
| 76 } | 77 } |
| 77 | 78 |
| 78 | 79 |
| 79 RawFunction* ActivationFrame::DartFunction() { | 80 Function* ActivationFrame::DartFunction() { |
|
srdjan
2011/12/20 22:07:04
Maybe you could return const Function&, since you
hausner
2011/12/20 22:13:29
Will address in next checkin. Good idea.
| |
| 80 if (function_ == Function::null()) { | 81 if (function_ == NULL) { |
| 81 ASSERT(Isolate::Current() != NULL); | 82 ASSERT(Isolate::Current() != NULL); |
| 82 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); | 83 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); |
| 83 ASSERT(code_index_table != NULL); | 84 ASSERT(code_index_table != NULL); |
| 84 function_ = code_index_table->LookupFunction(pc_); | 85 function_ = &Function::ZoneHandle(code_index_table->LookupFunction(pc_)); |
| 85 } | 86 } |
| 86 return function_; | 87 return function_; |
| 87 } | 88 } |
| 88 | 89 |
| 89 | 90 |
| 90 const char* Debugger::QualifiedFunctionName(const Function& func) { | 91 const char* Debugger::QualifiedFunctionName(const Function& func) { |
| 91 String& func_name = String::Handle(func.name()); | 92 String& func_name = String::Handle(func.name()); |
| 92 Class& func_class = Class::Handle(func.owner()); | 93 Class& func_class = Class::Handle(func.owner()); |
| 93 String& class_name = String::Handle(func_class.Name()); | 94 String& class_name = String::Handle(func_class.Name()); |
| 94 | 95 |
| 95 const char* kFormat = "%s%s%s"; | 96 const char* kFormat = "%s%s%s"; |
| 96 intptr_t len = OS::SNPrint(NULL, 0, kFormat, | 97 intptr_t len = OS::SNPrint(NULL, 0, kFormat, |
| 97 func_class.IsTopLevel() ? "" : class_name.ToCString(), | 98 func_class.IsTopLevel() ? "" : class_name.ToCString(), |
| 98 func_class.IsTopLevel() ? "" : ".", | 99 func_class.IsTopLevel() ? "" : ".", |
| 99 func_name.ToCString()); | 100 func_name.ToCString()); |
| 100 len++; // String terminator. | 101 len++; // String terminator. |
| 101 char* chars = reinterpret_cast<char*>( | 102 char* chars = reinterpret_cast<char*>( |
| 102 Isolate::Current()->current_zone()->Allocate(len)); | 103 Isolate::Current()->current_zone()->Allocate(len)); |
| 103 OS::SNPrint(chars, len, kFormat, | 104 OS::SNPrint(chars, len, kFormat, |
| 104 func_class.IsTopLevel() ? "" : class_name.ToCString(), | 105 func_class.IsTopLevel() ? "" : class_name.ToCString(), |
| 105 func_class.IsTopLevel() ? "" : ".", | 106 func_class.IsTopLevel() ? "" : ".", |
| 106 func_name.ToCString()); | 107 func_name.ToCString()); |
| 107 return chars; | 108 return chars; |
| 108 } | 109 } |
| 109 | 110 |
| 110 | 111 |
| 111 RawString* ActivationFrame::QualifiedFunctionName() { | 112 RawString* ActivationFrame::QualifiedFunctionName() { |
| 112 Function& func = Function::Handle(DartFunction()); | 113 Function& func = *DartFunction(); |
| 113 return String::New(Debugger::QualifiedFunctionName(func)); | 114 return String::New(Debugger::QualifiedFunctionName(func)); |
| 114 } | 115 } |
| 115 | 116 |
| 116 | 117 |
| 117 RawString* ActivationFrame::SourceUrl() { | 118 RawString* ActivationFrame::SourceUrl() { |
| 118 const Script& script = Script::Handle(SourceScript()); | 119 const Script& script = Script::Handle(SourceScript()); |
| 119 return script.url(); | 120 return script.url(); |
| 120 } | 121 } |
| 121 | 122 |
| 122 | 123 |
| 123 RawScript* ActivationFrame::SourceScript() { | 124 RawScript* ActivationFrame::SourceScript() { |
| 124 const Function& func = Function::Handle(DartFunction()); | 125 const Function& func = *DartFunction(); |
| 125 const Class& cls = Class::Handle(func.owner()); | 126 const Class& cls = Class::Handle(func.owner()); |
| 126 return cls.script(); | 127 return cls.script(); |
| 127 } | 128 } |
| 128 | 129 |
| 129 | 130 |
| 130 intptr_t ActivationFrame::TokenIndex() { | 131 intptr_t ActivationFrame::TokenIndex() { |
| 131 if (token_index_ < 0) { | 132 if (token_index_ < 0) { |
| 132 const Function& func = Function::Handle(DartFunction()); | 133 const Function& func = *DartFunction(); |
| 133 Code& code = Code::Handle(func.code()); | 134 Code& code = Code::Handle(func.code()); |
| 134 ASSERT(!code.IsNull()); | 135 ASSERT(!code.IsNull()); |
| 135 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 136 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 136 for (int i = 0; i < desc.Length(); i++) { | 137 for (int i = 0; i < desc.Length(); i++) { |
| 137 if (desc.PC(i) == pc_) { | 138 if (desc.PC(i) == pc_) { |
| 138 token_index_ = desc.TokenIndex(i); | 139 token_index_ = desc.TokenIndex(i); |
| 139 break; | 140 break; |
| 140 } | 141 } |
| 141 } | 142 } |
| 142 ASSERT(token_index_ >= 0); | 143 ASSERT(token_index_ >= 0); |
| 143 } | 144 } |
| 144 return token_index_; | 145 return token_index_; |
| 145 } | 146 } |
| 146 | 147 |
| 147 | 148 |
| 148 intptr_t ActivationFrame::LineNumber() { | 149 intptr_t ActivationFrame::LineNumber() { |
| 149 // Compute line number lazily since it causes scanning of the script. | 150 // Compute line number lazily since it causes scanning of the script. |
| 150 if (line_number_ < 0) { | 151 if (line_number_ < 0) { |
| 151 const Script& script = Script::Handle(SourceScript()); | 152 const Script& script = Script::Handle(SourceScript()); |
| 152 intptr_t ignore_column; | 153 intptr_t ignore_column; |
| 153 script.GetTokenLocation(TokenIndex(), &line_number_, &ignore_column); | 154 script.GetTokenLocation(TokenIndex(), &line_number_, &ignore_column); |
| 154 } | 155 } |
| 155 return line_number_; | 156 return line_number_; |
| 156 } | 157 } |
| 157 | 158 |
| 158 | 159 |
| 159 RawArray* ActivationFrame::Variables() { | 160 ActiveVariables* ActivationFrame::LocalVariables() { |
|
srdjan
2011/12/20 22:07:04
Ditto const ActiveVariables&
hausner
2011/12/20 22:13:29
Ditto
| |
| 160 UNIMPLEMENTED(); | 161 if (locals_ == NULL) { |
| 161 return NULL; | 162 const Function& func = *DartFunction(); |
| 163 locals_ = new ActiveVariables(func, TokenIndex()); | |
| 164 } | |
| 165 return locals_; | |
| 162 } | 166 } |
| 163 | 167 |
| 164 | 168 |
| 165 RawInstance* ActivationFrame::Value(const String& variable_name) { | 169 RawInstance* ActivationFrame::Value(const String& variable_name) { |
| 166 UNIMPLEMENTED(); | 170 UNIMPLEMENTED(); |
| 167 return NULL; | 171 return NULL; |
| 168 } | 172 } |
| 169 | 173 |
| 170 | 174 |
| 171 const char* ActivationFrame::ToCString() { | 175 const char* ActivationFrame::ToCString() { |
| 172 const char* kFormat = "Function: '%s' url: '%s' line: %d"; | 176 const char* kFormat = "Function: '%s' url: '%s' line: %d"; |
| 173 | 177 |
| 174 Function& func = Function::Handle(DartFunction()); | 178 Function& func = *DartFunction(); |
| 175 String& url = String::Handle(SourceUrl()); | 179 String& url = String::Handle(SourceUrl()); |
| 176 intptr_t line = LineNumber(); | 180 intptr_t line = LineNumber(); |
| 177 const char* func_name = Debugger::QualifiedFunctionName(func); | 181 const char* func_name = Debugger::QualifiedFunctionName(func); |
| 178 | 182 |
| 179 intptr_t len = | 183 intptr_t len = |
| 180 OS::SNPrint(NULL, 0, kFormat, func_name, url.ToCString(), line); | 184 OS::SNPrint(NULL, 0, kFormat, func_name, url.ToCString(), line); |
| 181 len++; // String terminator. | 185 len++; // String terminator. |
| 182 char* chars = reinterpret_cast<char*>( | 186 char* chars = reinterpret_cast<char*>( |
| 183 Isolate::Current()->current_zone()->Allocate(len)); | 187 Isolate::Current()->current_zone()->Allocate(len)); |
| 184 OS::SNPrint(chars, len, kFormat, func_name, url.ToCString(), line); | 188 OS::SNPrint(chars, len, kFormat, func_name, url.ToCString(), line); |
| 185 return chars; | 189 return chars; |
| 186 } | 190 } |
| 187 | 191 |
| 188 | 192 |
| 189 void StackTrace::AddActivation(ActivationFrame* frame) { | 193 void StackTrace::AddActivation(ActivationFrame* frame) { |
| 190 this->trace_.Add(frame); | 194 this->trace_.Add(frame); |
| 191 } | 195 } |
| 192 | 196 |
| 193 | 197 |
| 198 ActiveVariables::ActiveVariables(const Function& function, intptr_t token_pos) | |
| 199 : descriptors_(NULL), | |
| 200 desc_indices_(8) { | |
| 201 const Code& code = Code::Handle(function.code()); | |
| 202 LocalVarDescriptors& var_descs = | |
| 203 LocalVarDescriptors::ZoneHandle(code.var_descriptors()); | |
| 204 descriptors_ = &var_descs; | |
| 205 intptr_t desc_len = var_descs.Length(); | |
| 206 for (int i = 0; i < desc_len; i++) { | |
| 207 intptr_t begin_pos, end_pos; | |
| 208 var_descs.GetRange(i, &begin_pos, &end_pos); | |
| 209 if ((begin_pos <= token_pos) && (token_pos <= end_pos)) { | |
| 210 desc_indices_.Add(i); | |
| 211 } | |
| 212 } | |
| 213 } | |
| 214 | |
| 215 | |
| 216 void ActiveVariables::VariableAt(intptr_t i, | |
| 217 String* name, | |
| 218 intptr_t* token_pos, | |
| 219 intptr_t* end_pos, | |
| 220 Instance* value) const { | |
| 221 ASSERT(i < Length()); | |
| 222 ASSERT(name != NULL); | |
| 223 intptr_t desc_index = desc_indices_[i]; | |
| 224 *name ^= descriptors_->GetName(desc_index); | |
| 225 descriptors_->GetRange(i, token_pos, end_pos); | |
| 226 ASSERT(value != NULL); | |
| 227 *value = Instance::null(); // TODO(hausner): get actual variable value. | |
| 228 } | |
| 229 | |
| 230 | |
| 194 Debugger::Debugger() | 231 Debugger::Debugger() |
| 195 : initialized_(false), | 232 : initialized_(false), |
| 196 bp_handler_(NULL), | 233 bp_handler_(NULL), |
| 197 breakpoints_(NULL) { | 234 breakpoints_(NULL) { |
| 198 } | 235 } |
| 199 | 236 |
| 200 | 237 |
| 201 bool Debugger::IsActive() { | 238 bool Debugger::IsActive() { |
| 202 // TODO(hausner): The code generator uses this function to prevent | 239 // TODO(hausner): The code generator uses this function to prevent |
| 203 // generation of optimized code when Dart code is being debugged. | 240 // generation of optimized code when Dart code is being debugged. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 ASSERT(!code.IsNull()); | 288 ASSERT(!code.IsNull()); |
| 252 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 289 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 253 for (int i = 0; i < desc.Length(); i++) { | 290 for (int i = 0; i < desc.Length(); i++) { |
| 254 PcDescriptors::Kind kind = desc.DescriptorKind(i); | 291 PcDescriptors::Kind kind = desc.DescriptorKind(i); |
| 255 Breakpoint* bpt = NULL; | 292 Breakpoint* bpt = NULL; |
| 256 if (kind == PcDescriptors::kIcCall) { | 293 if (kind == PcDescriptors::kIcCall) { |
| 257 CodePatcher::PatchInstanceCallAt( | 294 CodePatcher::PatchInstanceCallAt( |
| 258 desc.PC(i), StubCode::BreakpointDynamicEntryPoint()); | 295 desc.PC(i), StubCode::BreakpointDynamicEntryPoint()); |
| 259 bpt = new Breakpoint(target_function, i); | 296 bpt = new Breakpoint(target_function, i); |
| 260 } else if (kind == PcDescriptors::kOther) { | 297 } else if (kind == PcDescriptors::kOther) { |
| 261 if (CodePatcher::IsDartCall(desc.PC(i))) { | 298 if ((desc.TokenIndex(i) > 0) && CodePatcher::IsDartCall(desc.PC(i))) { |
| 262 CodePatcher::PatchStaticCallAt( | 299 CodePatcher::PatchStaticCallAt( |
| 263 desc.PC(i), StubCode::BreakpointStaticEntryPoint()); | 300 desc.PC(i), StubCode::BreakpointStaticEntryPoint()); |
| 264 bpt = new Breakpoint(target_function, i); | 301 bpt = new Breakpoint(target_function, i); |
| 265 } | 302 } |
| 266 } | 303 } |
| 267 if (bpt != NULL) { | 304 if (bpt != NULL) { |
| 268 if (verbose) { | 305 if (verbose) { |
| 269 OS::Print("Setting breakpoint at '%s' line %d (PC %p)\n", | 306 OS::Print("Setting breakpoint at '%s' line %d (PC %p)\n", |
| 270 String::Handle(bpt->SourceUrl()).ToCString(), | 307 String::Handle(bpt->SourceUrl()).ToCString(), |
| 271 bpt->LineNumber(), | 308 bpt->LineNumber(), |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 283 ASSERT(visitor != NULL); | 320 ASSERT(visitor != NULL); |
| 284 Breakpoint* bpt = this->breakpoints_; | 321 Breakpoint* bpt = this->breakpoints_; |
| 285 while (bpt != NULL) { | 322 while (bpt != NULL) { |
| 286 bpt->VisitObjectPointers(visitor); | 323 bpt->VisitObjectPointers(visitor); |
| 287 bpt = bpt->next(); | 324 bpt = bpt->next(); |
| 288 } | 325 } |
| 289 } | 326 } |
| 290 | 327 |
| 291 | 328 |
| 292 static void DefaultBreakpointHandler(Breakpoint* bpt, StackTrace* stack) { | 329 static void DefaultBreakpointHandler(Breakpoint* bpt, StackTrace* stack) { |
| 330 String& var_name = String::Handle(); | |
| 331 Instance& value = Instance::Handle(); | |
| 293 for (intptr_t i = 0; i < stack->Length(); i++) { | 332 for (intptr_t i = 0; i < stack->Length(); i++) { |
| 333 ActivationFrame* frame = stack->ActivationFrameAt(i); | |
| 294 OS::Print(" %d. %s\n", | 334 OS::Print(" %d. %s\n", |
| 295 i + 1, stack->ActivationFrameAt(i)->ToCString()); | 335 i + 1, frame->ToCString()); |
| 336 ActiveVariables* locals = frame->LocalVariables(); | |
| 337 intptr_t num_locals = locals->Length(); | |
| 338 for (intptr_t i = 0; i < num_locals; i++) { | |
| 339 intptr_t token_pos, end_pos; | |
| 340 locals->VariableAt(i, &var_name, &token_pos, &end_pos, &value); | |
| 341 OS::Print(" var %s (pos %d) = %s\n", | |
| 342 var_name.ToCString(), token_pos, value.ToCString()); | |
| 343 } | |
| 296 } | 344 } |
| 297 } | 345 } |
| 298 | 346 |
| 299 | 347 |
| 300 void Debugger::SetBreakpointHandler(BreakpointHandler* handler) { | 348 void Debugger::SetBreakpointHandler(BreakpointHandler* handler) { |
| 301 bp_handler_ = handler; | 349 bp_handler_ = handler; |
| 302 if (bp_handler_ == NULL) { | 350 if (bp_handler_ == NULL) { |
| 303 bp_handler_ = &DefaultBreakpointHandler; | 351 bp_handler_ = &DefaultBreakpointHandler; |
| 304 } | 352 } |
| 305 } | 353 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 | 403 |
| 356 | 404 |
| 357 void Debugger::AddBreakpoint(Breakpoint* bpt) { | 405 void Debugger::AddBreakpoint(Breakpoint* bpt) { |
| 358 ASSERT(bpt->next() == NULL); | 406 ASSERT(bpt->next() == NULL); |
| 359 bpt->set_next(this->breakpoints_); | 407 bpt->set_next(this->breakpoints_); |
| 360 this->breakpoints_ = bpt; | 408 this->breakpoints_ = bpt; |
| 361 } | 409 } |
| 362 | 410 |
| 363 | 411 |
| 364 } // namespace dart | 412 } // namespace dart |
| OLD | NEW |