OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 BreakLocatorType type) { | 66 BreakLocatorType type) { |
67 debug_info_ = debug_info; | 67 debug_info_ = debug_info; |
68 type_ = type; | 68 type_ = type; |
69 reloc_iterator_ = NULL; | 69 reloc_iterator_ = NULL; |
70 reloc_iterator_original_ = NULL; | 70 reloc_iterator_original_ = NULL; |
71 Reset(); // Initialize the rest of the member variables. | 71 Reset(); // Initialize the rest of the member variables. |
72 } | 72 } |
73 | 73 |
74 | 74 |
75 BreakLocationIterator::~BreakLocationIterator() { | 75 BreakLocationIterator::~BreakLocationIterator() { |
76 ASSERT(reloc_iterator_ != NULL); | 76 DCHECK(reloc_iterator_ != NULL); |
77 ASSERT(reloc_iterator_original_ != NULL); | 77 DCHECK(reloc_iterator_original_ != NULL); |
78 delete reloc_iterator_; | 78 delete reloc_iterator_; |
79 delete reloc_iterator_original_; | 79 delete reloc_iterator_original_; |
80 } | 80 } |
81 | 81 |
82 | 82 |
83 // Check whether a code stub with the specified major key is a possible break | 83 // Check whether a code stub with the specified major key is a possible break |
84 // point location when looking for source break locations. | 84 // point location when looking for source break locations. |
85 static bool IsSourceBreakStub(Code* code) { | 85 static bool IsSourceBreakStub(Code* code) { |
86 CodeStub::Major major_key = CodeStub::GetMajorKey(code); | 86 CodeStub::Major major_key = CodeStub::GetMajorKey(code); |
87 return major_key == CodeStub::CallFunction; | 87 return major_key == CodeStub::CallFunction; |
88 } | 88 } |
89 | 89 |
90 | 90 |
91 // Check whether a code stub with the specified major key is a possible break | 91 // Check whether a code stub with the specified major key is a possible break |
92 // location. | 92 // location. |
93 static bool IsBreakStub(Code* code) { | 93 static bool IsBreakStub(Code* code) { |
94 CodeStub::Major major_key = CodeStub::GetMajorKey(code); | 94 CodeStub::Major major_key = CodeStub::GetMajorKey(code); |
95 return major_key == CodeStub::CallFunction; | 95 return major_key == CodeStub::CallFunction; |
96 } | 96 } |
97 | 97 |
98 | 98 |
99 void BreakLocationIterator::Next() { | 99 void BreakLocationIterator::Next() { |
100 DisallowHeapAllocation no_gc; | 100 DisallowHeapAllocation no_gc; |
101 ASSERT(!RinfoDone()); | 101 DCHECK(!RinfoDone()); |
102 | 102 |
103 // Iterate through reloc info for code and original code stopping at each | 103 // Iterate through reloc info for code and original code stopping at each |
104 // breakable code target. | 104 // breakable code target. |
105 bool first = break_point_ == -1; | 105 bool first = break_point_ == -1; |
106 while (!RinfoDone()) { | 106 while (!RinfoDone()) { |
107 if (!first) RinfoNext(); | 107 if (!first) RinfoNext(); |
108 first = false; | 108 first = false; |
109 if (RinfoDone()) return; | 109 if (RinfoDone()) return; |
110 | 110 |
111 // Whenever a statement position or (plain) position is passed update the | 111 // Whenever a statement position or (plain) position is passed update the |
112 // current value of these. | 112 // current value of these. |
113 if (RelocInfo::IsPosition(rmode())) { | 113 if (RelocInfo::IsPosition(rmode())) { |
114 if (RelocInfo::IsStatementPosition(rmode())) { | 114 if (RelocInfo::IsStatementPosition(rmode())) { |
115 statement_position_ = static_cast<int>( | 115 statement_position_ = static_cast<int>( |
116 rinfo()->data() - debug_info_->shared()->start_position()); | 116 rinfo()->data() - debug_info_->shared()->start_position()); |
117 } | 117 } |
118 // Always update the position as we don't want that to be before the | 118 // Always update the position as we don't want that to be before the |
119 // statement position. | 119 // statement position. |
120 position_ = static_cast<int>( | 120 position_ = static_cast<int>( |
121 rinfo()->data() - debug_info_->shared()->start_position()); | 121 rinfo()->data() - debug_info_->shared()->start_position()); |
122 ASSERT(position_ >= 0); | 122 DCHECK(position_ >= 0); |
123 ASSERT(statement_position_ >= 0); | 123 DCHECK(statement_position_ >= 0); |
124 } | 124 } |
125 | 125 |
126 if (IsDebugBreakSlot()) { | 126 if (IsDebugBreakSlot()) { |
127 // There is always a possible break point at a debug break slot. | 127 // There is always a possible break point at a debug break slot. |
128 break_point_++; | 128 break_point_++; |
129 return; | 129 return; |
130 } else if (RelocInfo::IsCodeTarget(rmode())) { | 130 } else if (RelocInfo::IsCodeTarget(rmode())) { |
131 // Check for breakable code target. Look in the original code as setting | 131 // Check for breakable code target. Look in the original code as setting |
132 // break points can cause the code targets in the running (debugged) code | 132 // break points can cause the code targets in the running (debugged) code |
133 // to be of a different kind than in the original code. | 133 // to be of a different kind than in the original code. |
(...skipping 10 matching lines...) Expand all Loading... |
144 if (code->kind() == Code::STUB) { | 144 if (code->kind() == Code::STUB) { |
145 if (IsDebuggerStatement()) { | 145 if (IsDebuggerStatement()) { |
146 break_point_++; | 146 break_point_++; |
147 return; | 147 return; |
148 } else if (type_ == ALL_BREAK_LOCATIONS) { | 148 } else if (type_ == ALL_BREAK_LOCATIONS) { |
149 if (IsBreakStub(code)) { | 149 if (IsBreakStub(code)) { |
150 break_point_++; | 150 break_point_++; |
151 return; | 151 return; |
152 } | 152 } |
153 } else { | 153 } else { |
154 ASSERT(type_ == SOURCE_BREAK_LOCATIONS); | 154 DCHECK(type_ == SOURCE_BREAK_LOCATIONS); |
155 if (IsSourceBreakStub(code)) { | 155 if (IsSourceBreakStub(code)) { |
156 break_point_++; | 156 break_point_++; |
157 return; | 157 return; |
158 } | 158 } |
159 } | 159 } |
160 } | 160 } |
161 } | 161 } |
162 | 162 |
163 // Check for break at return. | 163 // Check for break at return. |
164 if (RelocInfo::IsJSReturn(rmode())) { | 164 if (RelocInfo::IsJSReturn(rmode())) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 | 266 |
267 bool BreakLocationIterator::Done() const { | 267 bool BreakLocationIterator::Done() const { |
268 return RinfoDone(); | 268 return RinfoDone(); |
269 } | 269 } |
270 | 270 |
271 | 271 |
272 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) { | 272 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) { |
273 // If there is not already a real break point here patch code with debug | 273 // If there is not already a real break point here patch code with debug |
274 // break. | 274 // break. |
275 if (!HasBreakPoint()) SetDebugBreak(); | 275 if (!HasBreakPoint()) SetDebugBreak(); |
276 ASSERT(IsDebugBreak() || IsDebuggerStatement()); | 276 DCHECK(IsDebugBreak() || IsDebuggerStatement()); |
277 // Set the break point information. | 277 // Set the break point information. |
278 DebugInfo::SetBreakPoint(debug_info_, code_position(), | 278 DebugInfo::SetBreakPoint(debug_info_, code_position(), |
279 position(), statement_position(), | 279 position(), statement_position(), |
280 break_point_object); | 280 break_point_object); |
281 } | 281 } |
282 | 282 |
283 | 283 |
284 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) { | 284 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) { |
285 // Clear the break point information. | 285 // Clear the break point information. |
286 DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object); | 286 DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object); |
287 // If there are no more break points here remove the debug break. | 287 // If there are no more break points here remove the debug break. |
288 if (!HasBreakPoint()) { | 288 if (!HasBreakPoint()) { |
289 ClearDebugBreak(); | 289 ClearDebugBreak(); |
290 ASSERT(!IsDebugBreak()); | 290 DCHECK(!IsDebugBreak()); |
291 } | 291 } |
292 } | 292 } |
293 | 293 |
294 | 294 |
295 void BreakLocationIterator::SetOneShot() { | 295 void BreakLocationIterator::SetOneShot() { |
296 // Debugger statement always calls debugger. No need to modify it. | 296 // Debugger statement always calls debugger. No need to modify it. |
297 if (IsDebuggerStatement()) return; | 297 if (IsDebuggerStatement()) return; |
298 | 298 |
299 // If there is a real break point here no more to do. | 299 // If there is a real break point here no more to do. |
300 if (HasBreakPoint()) { | 300 if (HasBreakPoint()) { |
301 ASSERT(IsDebugBreak()); | 301 DCHECK(IsDebugBreak()); |
302 return; | 302 return; |
303 } | 303 } |
304 | 304 |
305 // Patch code with debug break. | 305 // Patch code with debug break. |
306 SetDebugBreak(); | 306 SetDebugBreak(); |
307 } | 307 } |
308 | 308 |
309 | 309 |
310 void BreakLocationIterator::ClearOneShot() { | 310 void BreakLocationIterator::ClearOneShot() { |
311 // Debugger statement always calls debugger. No need to modify it. | 311 // Debugger statement always calls debugger. No need to modify it. |
312 if (IsDebuggerStatement()) return; | 312 if (IsDebuggerStatement()) return; |
313 | 313 |
314 // If there is a real break point here no more to do. | 314 // If there is a real break point here no more to do. |
315 if (HasBreakPoint()) { | 315 if (HasBreakPoint()) { |
316 ASSERT(IsDebugBreak()); | 316 DCHECK(IsDebugBreak()); |
317 return; | 317 return; |
318 } | 318 } |
319 | 319 |
320 // Patch code removing debug break. | 320 // Patch code removing debug break. |
321 ClearDebugBreak(); | 321 ClearDebugBreak(); |
322 ASSERT(!IsDebugBreak()); | 322 DCHECK(!IsDebugBreak()); |
323 } | 323 } |
324 | 324 |
325 | 325 |
326 void BreakLocationIterator::SetDebugBreak() { | 326 void BreakLocationIterator::SetDebugBreak() { |
327 // Debugger statement always calls debugger. No need to modify it. | 327 // Debugger statement always calls debugger. No need to modify it. |
328 if (IsDebuggerStatement()) return; | 328 if (IsDebuggerStatement()) return; |
329 | 329 |
330 // If there is already a break point here just return. This might happen if | 330 // If there is already a break point here just return. This might happen if |
331 // the same code is flooded with break points twice. Flooding the same | 331 // the same code is flooded with break points twice. Flooding the same |
332 // function twice might happen when stepping in a function with an exception | 332 // function twice might happen when stepping in a function with an exception |
333 // handler as the handler and the function is the same. | 333 // handler as the handler and the function is the same. |
334 if (IsDebugBreak()) return; | 334 if (IsDebugBreak()) return; |
335 | 335 |
336 if (RelocInfo::IsJSReturn(rmode())) { | 336 if (RelocInfo::IsJSReturn(rmode())) { |
337 // Patch the frame exit code with a break point. | 337 // Patch the frame exit code with a break point. |
338 SetDebugBreakAtReturn(); | 338 SetDebugBreakAtReturn(); |
339 } else if (IsDebugBreakSlot()) { | 339 } else if (IsDebugBreakSlot()) { |
340 // Patch the code in the break slot. | 340 // Patch the code in the break slot. |
341 SetDebugBreakAtSlot(); | 341 SetDebugBreakAtSlot(); |
342 } else { | 342 } else { |
343 // Patch the IC call. | 343 // Patch the IC call. |
344 SetDebugBreakAtIC(); | 344 SetDebugBreakAtIC(); |
345 } | 345 } |
346 ASSERT(IsDebugBreak()); | 346 DCHECK(IsDebugBreak()); |
347 } | 347 } |
348 | 348 |
349 | 349 |
350 void BreakLocationIterator::ClearDebugBreak() { | 350 void BreakLocationIterator::ClearDebugBreak() { |
351 // Debugger statement always calls debugger. No need to modify it. | 351 // Debugger statement always calls debugger. No need to modify it. |
352 if (IsDebuggerStatement()) return; | 352 if (IsDebuggerStatement()) return; |
353 | 353 |
354 if (RelocInfo::IsJSReturn(rmode())) { | 354 if (RelocInfo::IsJSReturn(rmode())) { |
355 // Restore the frame exit code. | 355 // Restore the frame exit code. |
356 ClearDebugBreakAtReturn(); | 356 ClearDebugBreakAtReturn(); |
357 } else if (IsDebugBreakSlot()) { | 357 } else if (IsDebugBreakSlot()) { |
358 // Restore the code in the break slot. | 358 // Restore the code in the break slot. |
359 ClearDebugBreakAtSlot(); | 359 ClearDebugBreakAtSlot(); |
360 } else { | 360 } else { |
361 // Patch the IC call. | 361 // Patch the IC call. |
362 ClearDebugBreakAtIC(); | 362 ClearDebugBreakAtIC(); |
363 } | 363 } |
364 ASSERT(!IsDebugBreak()); | 364 DCHECK(!IsDebugBreak()); |
365 } | 365 } |
366 | 366 |
367 | 367 |
368 bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) { | 368 bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) { |
369 if (RelocInfo::IsConstructCall(original_rmode())) { | 369 if (RelocInfo::IsConstructCall(original_rmode())) { |
370 return true; | 370 return true; |
371 } else if (RelocInfo::IsCodeTarget(rmode())) { | 371 } else if (RelocInfo::IsCodeTarget(rmode())) { |
372 HandleScope scope(debug_info_->GetIsolate()); | 372 HandleScope scope(debug_info_->GetIsolate()); |
373 Address target = original_rinfo()->target_address(); | 373 Address target = original_rinfo()->target_address(); |
374 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); | 374 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); |
(...skipping 26 matching lines...) Expand all Loading... |
401 CodeStub::GetMajorKey(*maybe_call_function_stub) == | 401 CodeStub::GetMajorKey(*maybe_call_function_stub) == |
402 CodeStub::CallFunction); | 402 CodeStub::CallFunction); |
403 | 403 |
404 // Step in through construct call requires no changes to the running code. | 404 // Step in through construct call requires no changes to the running code. |
405 // Step in through getters/setters should already be prepared as well | 405 // Step in through getters/setters should already be prepared as well |
406 // because caller of this function (Debug::PrepareStep) is expected to | 406 // because caller of this function (Debug::PrepareStep) is expected to |
407 // flood the top frame's function with one shot breakpoints. | 407 // flood the top frame's function with one shot breakpoints. |
408 // Step in through CallFunction stub should also be prepared by caller of | 408 // Step in through CallFunction stub should also be prepared by caller of |
409 // this function (Debug::PrepareStep) which should flood target function | 409 // this function (Debug::PrepareStep) which should flood target function |
410 // with breakpoints. | 410 // with breakpoints. |
411 ASSERT(RelocInfo::IsConstructCall(rmode()) || | 411 DCHECK(RelocInfo::IsConstructCall(rmode()) || |
412 target_code->is_inline_cache_stub() || | 412 target_code->is_inline_cache_stub() || |
413 is_call_function_stub); | 413 is_call_function_stub); |
414 #endif | 414 #endif |
415 } | 415 } |
416 | 416 |
417 | 417 |
418 // Check whether the break point is at a position which will exit the function. | 418 // Check whether the break point is at a position which will exit the function. |
419 bool BreakLocationIterator::IsExit() const { | 419 bool BreakLocationIterator::IsExit() const { |
420 return (RelocInfo::IsJSReturn(rmode())); | 420 return (RelocInfo::IsJSReturn(rmode())); |
421 } | 421 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 } | 469 } |
470 } | 470 } |
471 if (RelocInfo::IsConstructCall(mode)) { | 471 if (RelocInfo::IsConstructCall(mode)) { |
472 if (code->has_function_cache()) { | 472 if (code->has_function_cache()) { |
473 return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); | 473 return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); |
474 } else { | 474 } else { |
475 return isolate->builtins()->CallConstructStub_DebugBreak(); | 475 return isolate->builtins()->CallConstructStub_DebugBreak(); |
476 } | 476 } |
477 } | 477 } |
478 if (code->kind() == Code::STUB) { | 478 if (code->kind() == Code::STUB) { |
479 ASSERT(CodeStub::GetMajorKey(*code) == CodeStub::CallFunction); | 479 DCHECK(CodeStub::GetMajorKey(*code) == CodeStub::CallFunction); |
480 return isolate->builtins()->CallFunctionStub_DebugBreak(); | 480 return isolate->builtins()->CallFunctionStub_DebugBreak(); |
481 } | 481 } |
482 | 482 |
483 UNREACHABLE(); | 483 UNREACHABLE(); |
484 return Handle<Code>::null(); | 484 return Handle<Code>::null(); |
485 } | 485 } |
486 | 486 |
487 | 487 |
488 void BreakLocationIterator::SetDebugBreakAtIC() { | 488 void BreakLocationIterator::SetDebugBreakAtIC() { |
489 // Patch the original code with the current address as the current address | 489 // Patch the original code with the current address as the current address |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 // DebugInfo even though the code is patched back to the non break point state. | 529 // DebugInfo even though the code is patched back to the non break point state. |
530 void BreakLocationIterator::ClearAllDebugBreak() { | 530 void BreakLocationIterator::ClearAllDebugBreak() { |
531 while (!Done()) { | 531 while (!Done()) { |
532 ClearDebugBreak(); | 532 ClearDebugBreak(); |
533 Next(); | 533 Next(); |
534 } | 534 } |
535 } | 535 } |
536 | 536 |
537 | 537 |
538 bool BreakLocationIterator::RinfoDone() const { | 538 bool BreakLocationIterator::RinfoDone() const { |
539 ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); | 539 DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done()); |
540 return reloc_iterator_->done(); | 540 return reloc_iterator_->done(); |
541 } | 541 } |
542 | 542 |
543 | 543 |
544 void BreakLocationIterator::RinfoNext() { | 544 void BreakLocationIterator::RinfoNext() { |
545 reloc_iterator_->next(); | 545 reloc_iterator_->next(); |
546 reloc_iterator_original_->next(); | 546 reloc_iterator_original_->next(); |
547 #ifdef DEBUG | 547 #ifdef DEBUG |
548 ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); | 548 DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done()); |
549 if (!reloc_iterator_->done()) { | 549 if (!reloc_iterator_->done()) { |
550 ASSERT(rmode() == original_rmode()); | 550 DCHECK(rmode() == original_rmode()); |
551 } | 551 } |
552 #endif | 552 #endif |
553 } | 553 } |
554 | 554 |
555 | 555 |
556 // Threading support. | 556 // Threading support. |
557 void Debug::ThreadInit() { | 557 void Debug::ThreadInit() { |
558 thread_local_.break_count_ = 0; | 558 thread_local_.break_count_ = 0; |
559 thread_local_.break_id_ = 0; | 559 thread_local_.break_id_ = 0; |
560 thread_local_.break_frame_id_ = StackFrame::NO_ID; | 560 thread_local_.break_frame_id_ = StackFrame::NO_ID; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 GlobalHandles* global_handles = isolate_->global_handles(); | 619 GlobalHandles* global_handles = isolate_->global_handles(); |
620 // Create an entry in the hash map for the script. | 620 // Create an entry in the hash map for the script. |
621 int id = script->id()->value(); | 621 int id = script->id()->value(); |
622 HashMap::Entry* entry = | 622 HashMap::Entry* entry = |
623 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); | 623 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); |
624 if (entry->value != NULL) { | 624 if (entry->value != NULL) { |
625 #ifdef DEBUG | 625 #ifdef DEBUG |
626 // The code deserializer may introduce duplicate Script objects. | 626 // The code deserializer may introduce duplicate Script objects. |
627 // Assert that the Script objects with the same id have the same name. | 627 // Assert that the Script objects with the same id have the same name. |
628 Handle<Script> found(reinterpret_cast<Script**>(entry->value)); | 628 Handle<Script> found(reinterpret_cast<Script**>(entry->value)); |
629 ASSERT(script->id() == found->id()); | 629 DCHECK(script->id() == found->id()); |
630 ASSERT(!script->name()->IsString() || | 630 DCHECK(!script->name()->IsString() || |
631 String::cast(script->name())->Equals(String::cast(found->name()))); | 631 String::cast(script->name())->Equals(String::cast(found->name()))); |
632 #endif | 632 #endif |
633 return; | 633 return; |
634 } | 634 } |
635 // Globalize the script object, make it weak and use the location of the | 635 // Globalize the script object, make it weak and use the location of the |
636 // global handle as the value in the hash map. | 636 // global handle as the value in the hash map. |
637 Handle<Script> script_ = | 637 Handle<Script> script_ = |
638 Handle<Script>::cast(global_handles->Create(*script)); | 638 Handle<Script>::cast(global_handles->Create(*script)); |
639 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()), | 639 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()), |
640 this, | 640 this, |
641 ScriptCache::HandleWeakScript); | 641 ScriptCache::HandleWeakScript); |
642 entry->value = script_.location(); | 642 entry->value = script_.location(); |
643 } | 643 } |
644 | 644 |
645 | 645 |
646 Handle<FixedArray> ScriptCache::GetScripts() { | 646 Handle<FixedArray> ScriptCache::GetScripts() { |
647 Factory* factory = isolate_->factory(); | 647 Factory* factory = isolate_->factory(); |
648 Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); | 648 Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); |
649 int count = 0; | 649 int count = 0; |
650 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { | 650 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
651 ASSERT(entry->value != NULL); | 651 DCHECK(entry->value != NULL); |
652 if (entry->value != NULL) { | 652 if (entry->value != NULL) { |
653 instances->set(count, *reinterpret_cast<Script**>(entry->value)); | 653 instances->set(count, *reinterpret_cast<Script**>(entry->value)); |
654 count++; | 654 count++; |
655 } | 655 } |
656 } | 656 } |
657 return instances; | 657 return instances; |
658 } | 658 } |
659 | 659 |
660 | 660 |
661 void ScriptCache::Clear() { | 661 void ScriptCache::Clear() { |
662 // Iterate the script cache to get rid of all the weak handles. | 662 // Iterate the script cache to get rid of all the weak handles. |
663 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { | 663 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
664 ASSERT(entry != NULL); | 664 DCHECK(entry != NULL); |
665 Object** location = reinterpret_cast<Object**>(entry->value); | 665 Object** location = reinterpret_cast<Object**>(entry->value); |
666 ASSERT((*location)->IsScript()); | 666 DCHECK((*location)->IsScript()); |
667 GlobalHandles::ClearWeakness(location); | 667 GlobalHandles::ClearWeakness(location); |
668 GlobalHandles::Destroy(location); | 668 GlobalHandles::Destroy(location); |
669 } | 669 } |
670 // Clear the content of the hash map. | 670 // Clear the content of the hash map. |
671 HashMap::Clear(); | 671 HashMap::Clear(); |
672 } | 672 } |
673 | 673 |
674 | 674 |
675 void ScriptCache::HandleWeakScript( | 675 void ScriptCache::HandleWeakScript( |
676 const v8::WeakCallbackData<v8::Value, void>& data) { | 676 const v8::WeakCallbackData<v8::Value, void>& data) { |
(...skipping 24 matching lines...) Expand all Loading... |
701 // original code and avoid patching the code twice later because | 701 // original code and avoid patching the code twice later because |
702 // the function will live in the heap until next gc, and can be found by | 702 // the function will live in the heap until next gc, and can be found by |
703 // Debug::FindSharedFunctionInfoInScript. | 703 // Debug::FindSharedFunctionInfoInScript. |
704 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); | 704 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); |
705 it.ClearAllDebugBreak(); | 705 it.ClearAllDebugBreak(); |
706 debug->RemoveDebugInfo(node->debug_info()); | 706 debug->RemoveDebugInfo(node->debug_info()); |
707 #ifdef DEBUG | 707 #ifdef DEBUG |
708 for (DebugInfoListNode* n = debug->debug_info_list_; | 708 for (DebugInfoListNode* n = debug->debug_info_list_; |
709 n != NULL; | 709 n != NULL; |
710 n = n->next()) { | 710 n = n->next()) { |
711 ASSERT(n != node); | 711 DCHECK(n != node); |
712 } | 712 } |
713 #endif | 713 #endif |
714 } | 714 } |
715 | 715 |
716 | 716 |
717 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { | 717 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { |
718 // Globalize the request debug info object and make it weak. | 718 // Globalize the request debug info object and make it weak. |
719 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); | 719 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); |
720 debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info)); | 720 debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info)); |
721 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()), | 721 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()), |
(...skipping 23 matching lines...) Expand all Loading... |
745 Handle<Context> context = isolate->native_context(); | 745 Handle<Context> context = isolate->native_context(); |
746 | 746 |
747 // Compile the script. | 747 // Compile the script. |
748 Handle<SharedFunctionInfo> function_info; | 748 Handle<SharedFunctionInfo> function_info; |
749 function_info = Compiler::CompileScript( | 749 function_info = Compiler::CompileScript( |
750 source_code, script_name, 0, 0, false, context, NULL, NULL, | 750 source_code, script_name, 0, 0, false, context, NULL, NULL, |
751 ScriptCompiler::kNoCompileOptions, NATIVES_CODE); | 751 ScriptCompiler::kNoCompileOptions, NATIVES_CODE); |
752 | 752 |
753 // Silently ignore stack overflows during compilation. | 753 // Silently ignore stack overflows during compilation. |
754 if (function_info.is_null()) { | 754 if (function_info.is_null()) { |
755 ASSERT(isolate->has_pending_exception()); | 755 DCHECK(isolate->has_pending_exception()); |
756 isolate->clear_pending_exception(); | 756 isolate->clear_pending_exception(); |
757 return false; | 757 return false; |
758 } | 758 } |
759 | 759 |
760 // Execute the shared function in the debugger context. | 760 // Execute the shared function in the debugger context. |
761 Handle<JSFunction> function = | 761 Handle<JSFunction> function = |
762 factory->NewFunctionFromSharedFunctionInfo(function_info, context); | 762 factory->NewFunctionFromSharedFunctionInfo(function_info, context); |
763 | 763 |
764 Handle<Object> exception; | 764 Handle<Object> exception; |
765 MaybeHandle<Object> result = | 765 MaybeHandle<Object> result = |
766 Execution::TryCall(function, | 766 Execution::TryCall(function, |
767 handle(context->global_proxy()), | 767 handle(context->global_proxy()), |
768 0, | 768 0, |
769 NULL, | 769 NULL, |
770 &exception); | 770 &exception); |
771 | 771 |
772 // Check for caught exceptions. | 772 // Check for caught exceptions. |
773 if (result.is_null()) { | 773 if (result.is_null()) { |
774 ASSERT(!isolate->has_pending_exception()); | 774 DCHECK(!isolate->has_pending_exception()); |
775 MessageLocation computed_location; | 775 MessageLocation computed_location; |
776 isolate->ComputeLocation(&computed_location); | 776 isolate->ComputeLocation(&computed_location); |
777 Handle<Object> message = MessageHandler::MakeMessageObject( | 777 Handle<Object> message = MessageHandler::MakeMessageObject( |
778 isolate, "error_loading_debugger", &computed_location, | 778 isolate, "error_loading_debugger", &computed_location, |
779 Vector<Handle<Object> >::empty(), Handle<JSArray>()); | 779 Vector<Handle<Object> >::empty(), Handle<JSArray>()); |
780 ASSERT(!isolate->has_pending_exception()); | 780 DCHECK(!isolate->has_pending_exception()); |
781 if (!exception.is_null()) { | 781 if (!exception.is_null()) { |
782 isolate->set_pending_exception(*exception); | 782 isolate->set_pending_exception(*exception); |
783 MessageHandler::ReportMessage(isolate, NULL, message); | 783 MessageHandler::ReportMessage(isolate, NULL, message); |
784 isolate->clear_pending_exception(); | 784 isolate->clear_pending_exception(); |
785 } | 785 } |
786 return false; | 786 return false; |
787 } | 787 } |
788 | 788 |
789 // Mark this script as native and return successfully. | 789 // Mark this script as native and return successfully. |
790 Handle<Script> script(Script::cast(function->shared()->script())); | 790 Handle<Script> script(Script::cast(function->shared()->script())); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 | 869 |
870 // Clear debugger context global handle. | 870 // Clear debugger context global handle. |
871 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); | 871 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); |
872 debug_context_ = Handle<Context>(); | 872 debug_context_ = Handle<Context>(); |
873 } | 873 } |
874 | 874 |
875 | 875 |
876 void Debug::Break(Arguments args, JavaScriptFrame* frame) { | 876 void Debug::Break(Arguments args, JavaScriptFrame* frame) { |
877 Heap* heap = isolate_->heap(); | 877 Heap* heap = isolate_->heap(); |
878 HandleScope scope(isolate_); | 878 HandleScope scope(isolate_); |
879 ASSERT(args.length() == 0); | 879 DCHECK(args.length() == 0); |
880 | 880 |
881 // Initialize LiveEdit. | 881 // Initialize LiveEdit. |
882 LiveEdit::InitializeThreadLocal(this); | 882 LiveEdit::InitializeThreadLocal(this); |
883 | 883 |
884 // Just continue if breaks are disabled or debugger cannot be loaded. | 884 // Just continue if breaks are disabled or debugger cannot be loaded. |
885 if (break_disabled_) return; | 885 if (break_disabled_) return; |
886 | 886 |
887 // Enter the debugger. | 887 // Enter the debugger. |
888 DebugScope debug_scope(this); | 888 DebugScope debug_scope(this); |
889 if (debug_scope.failed()) return; | 889 if (debug_scope.failed()) return; |
(...skipping 29 matching lines...) Expand all Loading... |
919 Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_); | 919 Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_); |
920 break_points_hit = CheckBreakPoints(break_point_objects); | 920 break_points_hit = CheckBreakPoints(break_point_objects); |
921 } | 921 } |
922 | 922 |
923 // If step out is active skip everything until the frame where we need to step | 923 // If step out is active skip everything until the frame where we need to step |
924 // out to is reached, unless real breakpoint is hit. | 924 // out to is reached, unless real breakpoint is hit. |
925 if (StepOutActive() && | 925 if (StepOutActive() && |
926 frame->fp() != thread_local_.step_out_fp_ && | 926 frame->fp() != thread_local_.step_out_fp_ && |
927 break_points_hit->IsUndefined() ) { | 927 break_points_hit->IsUndefined() ) { |
928 // Step count should always be 0 for StepOut. | 928 // Step count should always be 0 for StepOut. |
929 ASSERT(thread_local_.step_count_ == 0); | 929 DCHECK(thread_local_.step_count_ == 0); |
930 } else if (!break_points_hit->IsUndefined() || | 930 } else if (!break_points_hit->IsUndefined() || |
931 (thread_local_.last_step_action_ != StepNone && | 931 (thread_local_.last_step_action_ != StepNone && |
932 thread_local_.step_count_ == 0)) { | 932 thread_local_.step_count_ == 0)) { |
933 // Notify debugger if a real break point is triggered or if performing | 933 // Notify debugger if a real break point is triggered or if performing |
934 // single stepping with no more steps to perform. Otherwise do another step. | 934 // single stepping with no more steps to perform. Otherwise do another step. |
935 | 935 |
936 // Clear all current stepping setup. | 936 // Clear all current stepping setup. |
937 ClearStepping(); | 937 ClearStepping(); |
938 | 938 |
939 if (thread_local_.queued_step_count_ > 0) { | 939 if (thread_local_.queued_step_count_ > 0) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 // Check the break point objects for whether one or more are actually | 998 // Check the break point objects for whether one or more are actually |
999 // triggered. This function returns a JSArray with the break point objects | 999 // triggered. This function returns a JSArray with the break point objects |
1000 // which is triggered. | 1000 // which is triggered. |
1001 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { | 1001 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { |
1002 Factory* factory = isolate_->factory(); | 1002 Factory* factory = isolate_->factory(); |
1003 | 1003 |
1004 // Count the number of break points hit. If there are multiple break points | 1004 // Count the number of break points hit. If there are multiple break points |
1005 // they are in a FixedArray. | 1005 // they are in a FixedArray. |
1006 Handle<FixedArray> break_points_hit; | 1006 Handle<FixedArray> break_points_hit; |
1007 int break_points_hit_count = 0; | 1007 int break_points_hit_count = 0; |
1008 ASSERT(!break_point_objects->IsUndefined()); | 1008 DCHECK(!break_point_objects->IsUndefined()); |
1009 if (break_point_objects->IsFixedArray()) { | 1009 if (break_point_objects->IsFixedArray()) { |
1010 Handle<FixedArray> array(FixedArray::cast(*break_point_objects)); | 1010 Handle<FixedArray> array(FixedArray::cast(*break_point_objects)); |
1011 break_points_hit = factory->NewFixedArray(array->length()); | 1011 break_points_hit = factory->NewFixedArray(array->length()); |
1012 for (int i = 0; i < array->length(); i++) { | 1012 for (int i = 0; i < array->length(); i++) { |
1013 Handle<Object> o(array->get(i), isolate_); | 1013 Handle<Object> o(array->get(i), isolate_); |
1014 if (CheckBreakPoint(o)) { | 1014 if (CheckBreakPoint(o)) { |
1015 break_points_hit->set(break_points_hit_count++, *o); | 1015 break_points_hit->set(break_points_hit_count++, *o); |
1016 } | 1016 } |
1017 } | 1017 } |
1018 } else { | 1018 } else { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 | 1070 |
1071 // Check whether the function has debug information. | 1071 // Check whether the function has debug information. |
1072 bool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) { | 1072 bool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) { |
1073 return !shared->debug_info()->IsUndefined(); | 1073 return !shared->debug_info()->IsUndefined(); |
1074 } | 1074 } |
1075 | 1075 |
1076 | 1076 |
1077 // Return the debug info for this function. EnsureDebugInfo must be called | 1077 // Return the debug info for this function. EnsureDebugInfo must be called |
1078 // prior to ensure the debug info has been generated for shared. | 1078 // prior to ensure the debug info has been generated for shared. |
1079 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { | 1079 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { |
1080 ASSERT(HasDebugInfo(shared)); | 1080 DCHECK(HasDebugInfo(shared)); |
1081 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); | 1081 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); |
1082 } | 1082 } |
1083 | 1083 |
1084 | 1084 |
1085 bool Debug::SetBreakPoint(Handle<JSFunction> function, | 1085 bool Debug::SetBreakPoint(Handle<JSFunction> function, |
1086 Handle<Object> break_point_object, | 1086 Handle<Object> break_point_object, |
1087 int* source_position) { | 1087 int* source_position) { |
1088 HandleScope scope(isolate_); | 1088 HandleScope scope(isolate_); |
1089 | 1089 |
1090 PrepareForBreakPoints(); | 1090 PrepareForBreakPoints(); |
1091 | 1091 |
1092 // Make sure the function is compiled and has set up the debug info. | 1092 // Make sure the function is compiled and has set up the debug info. |
1093 Handle<SharedFunctionInfo> shared(function->shared()); | 1093 Handle<SharedFunctionInfo> shared(function->shared()); |
1094 if (!EnsureDebugInfo(shared, function)) { | 1094 if (!EnsureDebugInfo(shared, function)) { |
1095 // Return if retrieving debug info failed. | 1095 // Return if retrieving debug info failed. |
1096 return true; | 1096 return true; |
1097 } | 1097 } |
1098 | 1098 |
1099 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1099 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1100 // Source positions starts with zero. | 1100 // Source positions starts with zero. |
1101 ASSERT(*source_position >= 0); | 1101 DCHECK(*source_position >= 0); |
1102 | 1102 |
1103 // Find the break point and change it. | 1103 // Find the break point and change it. |
1104 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); | 1104 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); |
1105 it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED); | 1105 it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED); |
1106 it.SetBreakPoint(break_point_object); | 1106 it.SetBreakPoint(break_point_object); |
1107 | 1107 |
1108 *source_position = it.position(); | 1108 *source_position = it.position(); |
1109 | 1109 |
1110 // At least one active break point now. | 1110 // At least one active break point now. |
1111 return debug_info->GetBreakPointCount() > 0; | 1111 return debug_info->GetBreakPointCount() > 0; |
(...skipping 23 matching lines...) Expand all Loading... |
1135 // source position of the first function. | 1135 // source position of the first function. |
1136 int position; | 1136 int position; |
1137 if (shared->start_position() > *source_position) { | 1137 if (shared->start_position() > *source_position) { |
1138 position = 0; | 1138 position = 0; |
1139 } else { | 1139 } else { |
1140 position = *source_position - shared->start_position(); | 1140 position = *source_position - shared->start_position(); |
1141 } | 1141 } |
1142 | 1142 |
1143 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1143 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
1144 // Source positions starts with zero. | 1144 // Source positions starts with zero. |
1145 ASSERT(position >= 0); | 1145 DCHECK(position >= 0); |
1146 | 1146 |
1147 // Find the break point and change it. | 1147 // Find the break point and change it. |
1148 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); | 1148 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); |
1149 it.FindBreakLocationFromPosition(position, alignment); | 1149 it.FindBreakLocationFromPosition(position, alignment); |
1150 it.SetBreakPoint(break_point_object); | 1150 it.SetBreakPoint(break_point_object); |
1151 | 1151 |
1152 *source_position = it.position() + shared->start_position(); | 1152 *source_position = it.position() + shared->start_position(); |
1153 | 1153 |
1154 // At least one active break point now. | 1154 // At least one active break point now. |
1155 ASSERT(debug_info->GetBreakPointCount() > 0); | 1155 DCHECK(debug_info->GetBreakPointCount() > 0); |
1156 return true; | 1156 return true; |
1157 } | 1157 } |
1158 | 1158 |
1159 | 1159 |
1160 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { | 1160 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { |
1161 HandleScope scope(isolate_); | 1161 HandleScope scope(isolate_); |
1162 | 1162 |
1163 DebugInfoListNode* node = debug_info_list_; | 1163 DebugInfoListNode* node = debug_info_list_; |
1164 while (node != NULL) { | 1164 while (node != NULL) { |
1165 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), | 1165 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 } | 1332 } |
1333 | 1333 |
1334 | 1334 |
1335 void Debug::PrepareStep(StepAction step_action, | 1335 void Debug::PrepareStep(StepAction step_action, |
1336 int step_count, | 1336 int step_count, |
1337 StackFrame::Id frame_id) { | 1337 StackFrame::Id frame_id) { |
1338 HandleScope scope(isolate_); | 1338 HandleScope scope(isolate_); |
1339 | 1339 |
1340 PrepareForBreakPoints(); | 1340 PrepareForBreakPoints(); |
1341 | 1341 |
1342 ASSERT(in_debug_scope()); | 1342 DCHECK(in_debug_scope()); |
1343 | 1343 |
1344 // Remember this step action and count. | 1344 // Remember this step action and count. |
1345 thread_local_.last_step_action_ = step_action; | 1345 thread_local_.last_step_action_ = step_action; |
1346 if (step_action == StepOut) { | 1346 if (step_action == StepOut) { |
1347 // For step out target frame will be found on the stack so there is no need | 1347 // For step out target frame will be found on the stack so there is no need |
1348 // to set step counter for it. It's expected to always be 0 for StepOut. | 1348 // to set step counter for it. It's expected to always be 0 for StepOut. |
1349 thread_local_.step_count_ = 0; | 1349 thread_local_.step_count_ = 0; |
1350 } else { | 1350 } else { |
1351 thread_local_.step_count_ = step_count; | 1351 thread_local_.step_count_ = step_count; |
1352 } | 1352 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 } | 1440 } |
1441 | 1441 |
1442 // If this is the last break code target step out is the only possibility. | 1442 // If this is the last break code target step out is the only possibility. |
1443 if (it.IsExit() || step_action == StepOut) { | 1443 if (it.IsExit() || step_action == StepOut) { |
1444 if (step_action == StepOut) { | 1444 if (step_action == StepOut) { |
1445 // Skip step_count frames starting with the current one. | 1445 // Skip step_count frames starting with the current one. |
1446 while (step_count-- > 0 && !frames_it.done()) { | 1446 while (step_count-- > 0 && !frames_it.done()) { |
1447 frames_it.Advance(); | 1447 frames_it.Advance(); |
1448 } | 1448 } |
1449 } else { | 1449 } else { |
1450 ASSERT(it.IsExit()); | 1450 DCHECK(it.IsExit()); |
1451 frames_it.Advance(); | 1451 frames_it.Advance(); |
1452 } | 1452 } |
1453 // Skip builtin functions on the stack. | 1453 // Skip builtin functions on the stack. |
1454 while (!frames_it.done() && | 1454 while (!frames_it.done() && |
1455 frames_it.frame()->function()->IsFromNativeScript()) { | 1455 frames_it.frame()->function()->IsFromNativeScript()) { |
1456 frames_it.Advance(); | 1456 frames_it.Advance(); |
1457 } | 1457 } |
1458 // Step out: If there is a JavaScript caller frame, we need to | 1458 // Step out: If there is a JavaScript caller frame, we need to |
1459 // flood it with breakpoints. | 1459 // flood it with breakpoints. |
1460 if (!frames_it.done()) { | 1460 if (!frames_it.done()) { |
(...skipping 29 matching lines...) Expand all Loading... |
1490 | 1490 |
1491 // Find out number of arguments from the stub minor key. | 1491 // Find out number of arguments from the stub minor key. |
1492 uint32_t key = call_function_stub->stub_key(); | 1492 uint32_t key = call_function_stub->stub_key(); |
1493 // Argc in the stub is the number of arguments passed - not the | 1493 // Argc in the stub is the number of arguments passed - not the |
1494 // expected arguments of the called function. | 1494 // expected arguments of the called function. |
1495 int call_function_arg_count = is_call_ic | 1495 int call_function_arg_count = is_call_ic |
1496 ? CallICStub::ExtractArgcFromMinorKey(CodeStub::MinorKeyFromKey(key)) | 1496 ? CallICStub::ExtractArgcFromMinorKey(CodeStub::MinorKeyFromKey(key)) |
1497 : CallFunctionStub::ExtractArgcFromMinorKey( | 1497 : CallFunctionStub::ExtractArgcFromMinorKey( |
1498 CodeStub::MinorKeyFromKey(key)); | 1498 CodeStub::MinorKeyFromKey(key)); |
1499 | 1499 |
1500 ASSERT(is_call_ic || | 1500 DCHECK(is_call_ic || |
1501 CodeStub::GetMajorKey(*call_function_stub) == | 1501 CodeStub::GetMajorKey(*call_function_stub) == |
1502 CodeStub::MajorKeyFromKey(key)); | 1502 CodeStub::MajorKeyFromKey(key)); |
1503 | 1503 |
1504 // Find target function on the expression stack. | 1504 // Find target function on the expression stack. |
1505 // Expression stack looks like this (top to bottom): | 1505 // Expression stack looks like this (top to bottom): |
1506 // argN | 1506 // argN |
1507 // ... | 1507 // ... |
1508 // arg0 | 1508 // arg0 |
1509 // Receiver | 1509 // Receiver |
1510 // Function to call | 1510 // Function to call |
1511 int expressions_count = frame->ComputeExpressionsCount(); | 1511 int expressions_count = frame->ComputeExpressionsCount(); |
1512 ASSERT(expressions_count - 2 - call_function_arg_count >= 0); | 1512 DCHECK(expressions_count - 2 - call_function_arg_count >= 0); |
1513 Object* fun = frame->GetExpression( | 1513 Object* fun = frame->GetExpression( |
1514 expressions_count - 2 - call_function_arg_count); | 1514 expressions_count - 2 - call_function_arg_count); |
1515 | 1515 |
1516 // Flood the actual target of call/apply. | 1516 // Flood the actual target of call/apply. |
1517 if (fun->IsJSFunction()) { | 1517 if (fun->IsJSFunction()) { |
1518 Isolate* isolate = JSFunction::cast(fun)->GetIsolate(); | 1518 Isolate* isolate = JSFunction::cast(fun)->GetIsolate(); |
1519 Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply); | 1519 Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply); |
1520 Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall); | 1520 Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall); |
1521 while (fun->IsJSFunction()) { | 1521 while (fun->IsJSFunction()) { |
1522 Code* code = JSFunction::cast(fun)->shared()->code(); | 1522 Code* code = JSFunction::cast(fun)->shared()->code(); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1653 Handle<Object> holder, | 1653 Handle<Object> holder, |
1654 Address fp, | 1654 Address fp, |
1655 bool is_constructor) { | 1655 bool is_constructor) { |
1656 Isolate* isolate = function->GetIsolate(); | 1656 Isolate* isolate = function->GetIsolate(); |
1657 // If the frame pointer is not supplied by the caller find it. | 1657 // If the frame pointer is not supplied by the caller find it. |
1658 if (fp == 0) { | 1658 if (fp == 0) { |
1659 StackFrameIterator it(isolate); | 1659 StackFrameIterator it(isolate); |
1660 it.Advance(); | 1660 it.Advance(); |
1661 // For constructor functions skip another frame. | 1661 // For constructor functions skip another frame. |
1662 if (is_constructor) { | 1662 if (is_constructor) { |
1663 ASSERT(it.frame()->is_construct()); | 1663 DCHECK(it.frame()->is_construct()); |
1664 it.Advance(); | 1664 it.Advance(); |
1665 } | 1665 } |
1666 fp = it.frame()->fp(); | 1666 fp = it.frame()->fp(); |
1667 } | 1667 } |
1668 | 1668 |
1669 // Flood the function with one-shot break points if it is called from where | 1669 // Flood the function with one-shot break points if it is called from where |
1670 // step into was requested. | 1670 // step into was requested. |
1671 if (fp == thread_local_.step_into_fp_) { | 1671 if (fp == thread_local_.step_into_fp_) { |
1672 if (function->shared()->bound()) { | 1672 if (function->shared()->bound()) { |
1673 // Handle Function.prototype.bind | 1673 // Handle Function.prototype.bind |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1725 while (!it.Done()) { | 1725 while (!it.Done()) { |
1726 it.ClearOneShot(); | 1726 it.ClearOneShot(); |
1727 it.Next(); | 1727 it.Next(); |
1728 } | 1728 } |
1729 node = node->next(); | 1729 node = node->next(); |
1730 } | 1730 } |
1731 } | 1731 } |
1732 | 1732 |
1733 | 1733 |
1734 void Debug::ActivateStepIn(StackFrame* frame) { | 1734 void Debug::ActivateStepIn(StackFrame* frame) { |
1735 ASSERT(!StepOutActive()); | 1735 DCHECK(!StepOutActive()); |
1736 thread_local_.step_into_fp_ = frame->UnpaddedFP(); | 1736 thread_local_.step_into_fp_ = frame->UnpaddedFP(); |
1737 } | 1737 } |
1738 | 1738 |
1739 | 1739 |
1740 void Debug::ClearStepIn() { | 1740 void Debug::ClearStepIn() { |
1741 thread_local_.step_into_fp_ = 0; | 1741 thread_local_.step_into_fp_ = 0; |
1742 } | 1742 } |
1743 | 1743 |
1744 | 1744 |
1745 void Debug::ActivateStepOut(StackFrame* frame) { | 1745 void Debug::ActivateStepOut(StackFrame* frame) { |
1746 ASSERT(!StepInActive()); | 1746 DCHECK(!StepInActive()); |
1747 thread_local_.step_out_fp_ = frame->UnpaddedFP(); | 1747 thread_local_.step_out_fp_ = frame->UnpaddedFP(); |
1748 } | 1748 } |
1749 | 1749 |
1750 | 1750 |
1751 void Debug::ClearStepOut() { | 1751 void Debug::ClearStepOut() { |
1752 thread_local_.step_out_fp_ = 0; | 1752 thread_local_.step_out_fp_ = 0; |
1753 } | 1753 } |
1754 | 1754 |
1755 | 1755 |
1756 void Debug::ClearStepNext() { | 1756 void Debug::ClearStepNext() { |
(...skipping 17 matching lines...) Expand all Loading... |
1774 if (frame->is_optimized()) { | 1774 if (frame->is_optimized()) { |
1775 List<JSFunction*> functions(FLAG_max_inlining_levels + 1); | 1775 List<JSFunction*> functions(FLAG_max_inlining_levels + 1); |
1776 frame->GetFunctions(&functions); | 1776 frame->GetFunctions(&functions); |
1777 for (int i = 0; i < functions.length(); i++) { | 1777 for (int i = 0; i < functions.length(); i++) { |
1778 JSFunction* function = functions[i]; | 1778 JSFunction* function = functions[i]; |
1779 active_functions->Add(Handle<JSFunction>(function)); | 1779 active_functions->Add(Handle<JSFunction>(function)); |
1780 function->shared()->code()->set_gc_metadata(active_code_marker); | 1780 function->shared()->code()->set_gc_metadata(active_code_marker); |
1781 } | 1781 } |
1782 } else if (frame->function()->IsJSFunction()) { | 1782 } else if (frame->function()->IsJSFunction()) { |
1783 JSFunction* function = frame->function(); | 1783 JSFunction* function = frame->function(); |
1784 ASSERT(frame->LookupCode()->kind() == Code::FUNCTION); | 1784 DCHECK(frame->LookupCode()->kind() == Code::FUNCTION); |
1785 active_functions->Add(Handle<JSFunction>(function)); | 1785 active_functions->Add(Handle<JSFunction>(function)); |
1786 function->shared()->code()->set_gc_metadata(active_code_marker); | 1786 function->shared()->code()->set_gc_metadata(active_code_marker); |
1787 } | 1787 } |
1788 } | 1788 } |
1789 } | 1789 } |
1790 | 1790 |
1791 | 1791 |
1792 // Figure out how many bytes of "pc_offset" correspond to actual code by | 1792 // Figure out how many bytes of "pc_offset" correspond to actual code by |
1793 // subtracting off the bytes that correspond to constant/veneer pools. See | 1793 // subtracting off the bytes that correspond to constant/veneer pools. See |
1794 // Assembler::CheckConstPool() and Assembler::CheckVeneerPool(). Note that this | 1794 // Assembler::CheckConstPool() and Assembler::CheckVeneerPool(). Note that this |
1795 // is only useful for architectures using constant pools or veneer pools. | 1795 // is only useful for architectures using constant pools or veneer pools. |
1796 static int ComputeCodeOffsetFromPcOffset(Code *code, int pc_offset) { | 1796 static int ComputeCodeOffsetFromPcOffset(Code *code, int pc_offset) { |
1797 ASSERT_EQ(code->kind(), Code::FUNCTION); | 1797 DCHECK_EQ(code->kind(), Code::FUNCTION); |
1798 ASSERT(!code->has_debug_break_slots()); | 1798 DCHECK(!code->has_debug_break_slots()); |
1799 ASSERT_LE(0, pc_offset); | 1799 DCHECK_LE(0, pc_offset); |
1800 ASSERT_LT(pc_offset, code->instruction_end() - code->instruction_start()); | 1800 DCHECK_LT(pc_offset, code->instruction_end() - code->instruction_start()); |
1801 | 1801 |
1802 int mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL) | | 1802 int mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL) | |
1803 RelocInfo::ModeMask(RelocInfo::VENEER_POOL); | 1803 RelocInfo::ModeMask(RelocInfo::VENEER_POOL); |
1804 byte *pc = code->instruction_start() + pc_offset; | 1804 byte *pc = code->instruction_start() + pc_offset; |
1805 int code_offset = pc_offset; | 1805 int code_offset = pc_offset; |
1806 for (RelocIterator it(code, mask); !it.done(); it.next()) { | 1806 for (RelocIterator it(code, mask); !it.done(); it.next()) { |
1807 RelocInfo* info = it.rinfo(); | 1807 RelocInfo* info = it.rinfo(); |
1808 if (info->pc() >= pc) break; | 1808 if (info->pc() >= pc) break; |
1809 ASSERT(RelocInfo::IsConstPool(info->rmode())); | 1809 DCHECK(RelocInfo::IsConstPool(info->rmode())); |
1810 code_offset -= static_cast<int>(info->data()); | 1810 code_offset -= static_cast<int>(info->data()); |
1811 ASSERT_LE(0, code_offset); | 1811 DCHECK_LE(0, code_offset); |
1812 } | 1812 } |
1813 | 1813 |
1814 return code_offset; | 1814 return code_offset; |
1815 } | 1815 } |
1816 | 1816 |
1817 | 1817 |
1818 // The inverse of ComputeCodeOffsetFromPcOffset. | 1818 // The inverse of ComputeCodeOffsetFromPcOffset. |
1819 static int ComputePcOffsetFromCodeOffset(Code *code, int code_offset) { | 1819 static int ComputePcOffsetFromCodeOffset(Code *code, int code_offset) { |
1820 ASSERT_EQ(code->kind(), Code::FUNCTION); | 1820 DCHECK_EQ(code->kind(), Code::FUNCTION); |
1821 | 1821 |
1822 int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) | | 1822 int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) | |
1823 RelocInfo::ModeMask(RelocInfo::CONST_POOL) | | 1823 RelocInfo::ModeMask(RelocInfo::CONST_POOL) | |
1824 RelocInfo::ModeMask(RelocInfo::VENEER_POOL); | 1824 RelocInfo::ModeMask(RelocInfo::VENEER_POOL); |
1825 int reloc = 0; | 1825 int reloc = 0; |
1826 for (RelocIterator it(code, mask); !it.done(); it.next()) { | 1826 for (RelocIterator it(code, mask); !it.done(); it.next()) { |
1827 RelocInfo* info = it.rinfo(); | 1827 RelocInfo* info = it.rinfo(); |
1828 if (info->pc() - code->instruction_start() - reloc >= code_offset) break; | 1828 if (info->pc() - code->instruction_start() - reloc >= code_offset) break; |
1829 if (RelocInfo::IsDebugBreakSlot(info->rmode())) { | 1829 if (RelocInfo::IsDebugBreakSlot(info->rmode())) { |
1830 reloc += Assembler::kDebugBreakSlotLength; | 1830 reloc += Assembler::kDebugBreakSlotLength; |
1831 } else { | 1831 } else { |
1832 ASSERT(RelocInfo::IsConstPool(info->rmode())); | 1832 DCHECK(RelocInfo::IsConstPool(info->rmode())); |
1833 reloc += static_cast<int>(info->data()); | 1833 reloc += static_cast<int>(info->data()); |
1834 } | 1834 } |
1835 } | 1835 } |
1836 | 1836 |
1837 int pc_offset = code_offset + reloc; | 1837 int pc_offset = code_offset + reloc; |
1838 | 1838 |
1839 ASSERT_LT(code->instruction_start() + pc_offset, code->instruction_end()); | 1839 DCHECK_LT(code->instruction_start() + pc_offset, code->instruction_end()); |
1840 | 1840 |
1841 return pc_offset; | 1841 return pc_offset; |
1842 } | 1842 } |
1843 | 1843 |
1844 | 1844 |
1845 static void RedirectActivationsToRecompiledCodeOnThread( | 1845 static void RedirectActivationsToRecompiledCodeOnThread( |
1846 Isolate* isolate, | 1846 Isolate* isolate, |
1847 ThreadLocalTop* top) { | 1847 ThreadLocalTop* top) { |
1848 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 1848 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { |
1849 JavaScriptFrame* frame = it.frame(); | 1849 JavaScriptFrame* frame = it.frame(); |
1850 | 1850 |
1851 if (frame->is_optimized() || !frame->function()->IsJSFunction()) continue; | 1851 if (frame->is_optimized() || !frame->function()->IsJSFunction()) continue; |
1852 | 1852 |
1853 JSFunction* function = frame->function(); | 1853 JSFunction* function = frame->function(); |
1854 | 1854 |
1855 ASSERT(frame->LookupCode()->kind() == Code::FUNCTION); | 1855 DCHECK(frame->LookupCode()->kind() == Code::FUNCTION); |
1856 | 1856 |
1857 Handle<Code> frame_code(frame->LookupCode()); | 1857 Handle<Code> frame_code(frame->LookupCode()); |
1858 if (frame_code->has_debug_break_slots()) continue; | 1858 if (frame_code->has_debug_break_slots()) continue; |
1859 | 1859 |
1860 Handle<Code> new_code(function->shared()->code()); | 1860 Handle<Code> new_code(function->shared()->code()); |
1861 if (new_code->kind() != Code::FUNCTION || | 1861 if (new_code->kind() != Code::FUNCTION || |
1862 !new_code->has_debug_break_slots()) { | 1862 !new_code->has_debug_break_slots()) { |
1863 continue; | 1863 continue; |
1864 } | 1864 } |
1865 | 1865 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2056 } else { | 2056 } else { |
2057 function->ReplaceCode(*lazy_compile); | 2057 function->ReplaceCode(*lazy_compile); |
2058 function->shared()->ReplaceCode(*lazy_compile); | 2058 function->shared()->ReplaceCode(*lazy_compile); |
2059 } | 2059 } |
2060 } | 2060 } |
2061 } else if (obj->IsJSGeneratorObject()) { | 2061 } else if (obj->IsJSGeneratorObject()) { |
2062 JSGeneratorObject* gen = JSGeneratorObject::cast(obj); | 2062 JSGeneratorObject* gen = JSGeneratorObject::cast(obj); |
2063 if (!gen->is_suspended()) continue; | 2063 if (!gen->is_suspended()) continue; |
2064 | 2064 |
2065 JSFunction* fun = gen->function(); | 2065 JSFunction* fun = gen->function(); |
2066 ASSERT_EQ(fun->code()->kind(), Code::FUNCTION); | 2066 DCHECK_EQ(fun->code()->kind(), Code::FUNCTION); |
2067 if (fun->code()->has_debug_break_slots()) continue; | 2067 if (fun->code()->has_debug_break_slots()) continue; |
2068 | 2068 |
2069 int pc_offset = gen->continuation(); | 2069 int pc_offset = gen->continuation(); |
2070 ASSERT_LT(0, pc_offset); | 2070 DCHECK_LT(0, pc_offset); |
2071 | 2071 |
2072 int code_offset = | 2072 int code_offset = |
2073 ComputeCodeOffsetFromPcOffset(fun->code(), pc_offset); | 2073 ComputeCodeOffsetFromPcOffset(fun->code(), pc_offset); |
2074 | 2074 |
2075 // This will be fixed after we recompile the functions. | 2075 // This will be fixed after we recompile the functions. |
2076 gen->set_continuation(code_offset); | 2076 gen->set_continuation(code_offset); |
2077 | 2077 |
2078 suspended_generators.Add(Handle<JSGeneratorObject>(gen, isolate_)); | 2078 suspended_generators.Add(Handle<JSGeneratorObject>(gen, isolate_)); |
2079 } | 2079 } |
2080 } | 2080 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2150 { // Extra scope for iterator. | 2150 { // Extra scope for iterator. |
2151 HeapIterator iterator(heap); | 2151 HeapIterator iterator(heap); |
2152 for (HeapObject* obj = iterator.next(); | 2152 for (HeapObject* obj = iterator.next(); |
2153 obj != NULL; obj = iterator.next()) { | 2153 obj != NULL; obj = iterator.next()) { |
2154 bool found_next_candidate = false; | 2154 bool found_next_candidate = false; |
2155 Handle<JSFunction> function; | 2155 Handle<JSFunction> function; |
2156 Handle<SharedFunctionInfo> shared; | 2156 Handle<SharedFunctionInfo> shared; |
2157 if (obj->IsJSFunction()) { | 2157 if (obj->IsJSFunction()) { |
2158 function = Handle<JSFunction>(JSFunction::cast(obj)); | 2158 function = Handle<JSFunction>(JSFunction::cast(obj)); |
2159 shared = Handle<SharedFunctionInfo>(function->shared()); | 2159 shared = Handle<SharedFunctionInfo>(function->shared()); |
2160 ASSERT(shared->allows_lazy_compilation() || shared->is_compiled()); | 2160 DCHECK(shared->allows_lazy_compilation() || shared->is_compiled()); |
2161 found_next_candidate = true; | 2161 found_next_candidate = true; |
2162 } else if (obj->IsSharedFunctionInfo()) { | 2162 } else if (obj->IsSharedFunctionInfo()) { |
2163 shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj)); | 2163 shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj)); |
2164 // Skip functions that we cannot compile lazily without a context, | 2164 // Skip functions that we cannot compile lazily without a context, |
2165 // which is not available here, because there is no closure. | 2165 // which is not available here, because there is no closure. |
2166 found_next_candidate = shared->is_compiled() || | 2166 found_next_candidate = shared->is_compiled() || |
2167 shared->allows_lazy_compilation_without_context(); | 2167 shared->allows_lazy_compilation_without_context(); |
2168 } | 2168 } |
2169 if (!found_next_candidate) continue; | 2169 if (!found_next_candidate) continue; |
2170 if (shared->script() == *script) { | 2170 if (shared->script() == *script) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 } | 2232 } |
2233 | 2233 |
2234 | 2234 |
2235 // Ensures the debug information is present for shared. | 2235 // Ensures the debug information is present for shared. |
2236 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, | 2236 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, |
2237 Handle<JSFunction> function) { | 2237 Handle<JSFunction> function) { |
2238 Isolate* isolate = shared->GetIsolate(); | 2238 Isolate* isolate = shared->GetIsolate(); |
2239 | 2239 |
2240 // Return if we already have the debug info for shared. | 2240 // Return if we already have the debug info for shared. |
2241 if (HasDebugInfo(shared)) { | 2241 if (HasDebugInfo(shared)) { |
2242 ASSERT(shared->is_compiled()); | 2242 DCHECK(shared->is_compiled()); |
2243 return true; | 2243 return true; |
2244 } | 2244 } |
2245 | 2245 |
2246 // There will be at least one break point when we are done. | 2246 // There will be at least one break point when we are done. |
2247 has_break_points_ = true; | 2247 has_break_points_ = true; |
2248 | 2248 |
2249 // Ensure function is compiled. Return false if this failed. | 2249 // Ensure function is compiled. Return false if this failed. |
2250 if (!function.is_null() && | 2250 if (!function.is_null() && |
2251 !Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) { | 2251 !Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) { |
2252 return false; | 2252 return false; |
2253 } | 2253 } |
2254 | 2254 |
2255 // Create the debug info object. | 2255 // Create the debug info object. |
2256 Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared); | 2256 Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared); |
2257 | 2257 |
2258 // Add debug info to the list. | 2258 // Add debug info to the list. |
2259 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); | 2259 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); |
2260 node->set_next(debug_info_list_); | 2260 node->set_next(debug_info_list_); |
2261 debug_info_list_ = node; | 2261 debug_info_list_ = node; |
2262 | 2262 |
2263 return true; | 2263 return true; |
2264 } | 2264 } |
2265 | 2265 |
2266 | 2266 |
2267 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { | 2267 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { |
2268 ASSERT(debug_info_list_ != NULL); | 2268 DCHECK(debug_info_list_ != NULL); |
2269 // Run through the debug info objects to find this one and remove it. | 2269 // Run through the debug info objects to find this one and remove it. |
2270 DebugInfoListNode* prev = NULL; | 2270 DebugInfoListNode* prev = NULL; |
2271 DebugInfoListNode* current = debug_info_list_; | 2271 DebugInfoListNode* current = debug_info_list_; |
2272 while (current != NULL) { | 2272 while (current != NULL) { |
2273 if (*current->debug_info() == *debug_info) { | 2273 if (*current->debug_info() == *debug_info) { |
2274 // Unlink from list. If prev is NULL we are looking at the first element. | 2274 // Unlink from list. If prev is NULL we are looking at the first element. |
2275 if (prev == NULL) { | 2275 if (prev == NULL) { |
2276 debug_info_list_ = current->next(); | 2276 debug_info_list_ = current->next(); |
2277 } else { | 2277 } else { |
2278 prev->set_next(current->next()); | 2278 prev->set_next(current->next()); |
(...skipping 30 matching lines...) Expand all Loading... |
2309 if (!EnsureDebugInfo(shared, function)) { | 2309 if (!EnsureDebugInfo(shared, function)) { |
2310 // Return if we failed to retrieve the debug info. | 2310 // Return if we failed to retrieve the debug info. |
2311 return; | 2311 return; |
2312 } | 2312 } |
2313 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 2313 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
2314 Handle<Code> code(debug_info->code()); | 2314 Handle<Code> code(debug_info->code()); |
2315 Handle<Code> original_code(debug_info->original_code()); | 2315 Handle<Code> original_code(debug_info->original_code()); |
2316 #ifdef DEBUG | 2316 #ifdef DEBUG |
2317 // Get the code which is actually executing. | 2317 // Get the code which is actually executing. |
2318 Handle<Code> frame_code(frame->LookupCode()); | 2318 Handle<Code> frame_code(frame->LookupCode()); |
2319 ASSERT(frame_code.is_identical_to(code)); | 2319 DCHECK(frame_code.is_identical_to(code)); |
2320 #endif | 2320 #endif |
2321 | 2321 |
2322 // Find the call address in the running code. This address holds the call to | 2322 // Find the call address in the running code. This address holds the call to |
2323 // either a DebugBreakXXX or to the debug break return entry code if the | 2323 // either a DebugBreakXXX or to the debug break return entry code if the |
2324 // break point is still active after processing the break point. | 2324 // break point is still active after processing the break point. |
2325 Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset; | 2325 Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset; |
2326 | 2326 |
2327 // Check if the location is at JS exit or debug break slot. | 2327 // Check if the location is at JS exit or debug break slot. |
2328 bool at_js_return = false; | 2328 bool at_js_return = false; |
2329 bool break_at_js_return_active = false; | 2329 bool break_at_js_return_active = false; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2402 Handle<SharedFunctionInfo> shared(function->shared()); | 2402 Handle<SharedFunctionInfo> shared(function->shared()); |
2403 if (!EnsureDebugInfo(shared, function)) { | 2403 if (!EnsureDebugInfo(shared, function)) { |
2404 // Return if we failed to retrieve the debug info. | 2404 // Return if we failed to retrieve the debug info. |
2405 return false; | 2405 return false; |
2406 } | 2406 } |
2407 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 2407 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
2408 Handle<Code> code(debug_info->code()); | 2408 Handle<Code> code(debug_info->code()); |
2409 #ifdef DEBUG | 2409 #ifdef DEBUG |
2410 // Get the code which is actually executing. | 2410 // Get the code which is actually executing. |
2411 Handle<Code> frame_code(frame->LookupCode()); | 2411 Handle<Code> frame_code(frame->LookupCode()); |
2412 ASSERT(frame_code.is_identical_to(code)); | 2412 DCHECK(frame_code.is_identical_to(code)); |
2413 #endif | 2413 #endif |
2414 | 2414 |
2415 // Find the call address in the running code. | 2415 // Find the call address in the running code. |
2416 Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset; | 2416 Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset; |
2417 | 2417 |
2418 // Check if the location is at JS return. | 2418 // Check if the location is at JS return. |
2419 RelocIterator it(debug_info->code()); | 2419 RelocIterator it(debug_info->code()); |
2420 while (!it.done()) { | 2420 while (!it.done()) { |
2421 if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { | 2421 if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { |
2422 return (it.rinfo()->pc() == | 2422 return (it.rinfo()->pc() == |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2493 | 2493 |
2494 | 2494 |
2495 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name, | 2495 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name, |
2496 int argc, | 2496 int argc, |
2497 Handle<Object> argv[]) { | 2497 Handle<Object> argv[]) { |
2498 AssertDebugContext(); | 2498 AssertDebugContext(); |
2499 // Create the execution state object. | 2499 // Create the execution state object. |
2500 Handle<GlobalObject> global(isolate_->global_object()); | 2500 Handle<GlobalObject> global(isolate_->global_object()); |
2501 Handle<Object> constructor = Object::GetProperty( | 2501 Handle<Object> constructor = Object::GetProperty( |
2502 isolate_, global, constructor_name).ToHandleChecked(); | 2502 isolate_, global, constructor_name).ToHandleChecked(); |
2503 ASSERT(constructor->IsJSFunction()); | 2503 DCHECK(constructor->IsJSFunction()); |
2504 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); | 2504 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); |
2505 // We do not handle interrupts here. In particular, termination interrupts. | 2505 // We do not handle interrupts here. In particular, termination interrupts. |
2506 PostponeInterruptsScope no_interrupts(isolate_); | 2506 PostponeInterruptsScope no_interrupts(isolate_); |
2507 return Execution::TryCall(Handle<JSFunction>::cast(constructor), | 2507 return Execution::TryCall(Handle<JSFunction>::cast(constructor), |
2508 handle(debug_context()->global_proxy()), | 2508 handle(debug_context()->global_proxy()), |
2509 argc, | 2509 argc, |
2510 argv); | 2510 argv); |
2511 } | 2511 } |
2512 | 2512 |
2513 | 2513 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2675 Handle<String> update_script_break_points_string = | 2675 Handle<String> update_script_break_points_string = |
2676 isolate_->factory()->InternalizeOneByteString( | 2676 isolate_->factory()->InternalizeOneByteString( |
2677 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); | 2677 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); |
2678 Handle<GlobalObject> debug_global(debug_context()->global_object()); | 2678 Handle<GlobalObject> debug_global(debug_context()->global_object()); |
2679 Handle<Object> update_script_break_points = | 2679 Handle<Object> update_script_break_points = |
2680 Object::GetProperty( | 2680 Object::GetProperty( |
2681 debug_global, update_script_break_points_string).ToHandleChecked(); | 2681 debug_global, update_script_break_points_string).ToHandleChecked(); |
2682 if (!update_script_break_points->IsJSFunction()) { | 2682 if (!update_script_break_points->IsJSFunction()) { |
2683 return; | 2683 return; |
2684 } | 2684 } |
2685 ASSERT(update_script_break_points->IsJSFunction()); | 2685 DCHECK(update_script_break_points->IsJSFunction()); |
2686 | 2686 |
2687 // Wrap the script object in a proper JS object before passing it | 2687 // Wrap the script object in a proper JS object before passing it |
2688 // to JavaScript. | 2688 // to JavaScript. |
2689 Handle<Object> wrapper = Script::GetWrapper(script); | 2689 Handle<Object> wrapper = Script::GetWrapper(script); |
2690 | 2690 |
2691 // Call UpdateScriptBreakPoints expect no exceptions. | 2691 // Call UpdateScriptBreakPoints expect no exceptions. |
2692 Handle<Object> argv[] = { wrapper }; | 2692 Handle<Object> argv[] = { wrapper }; |
2693 if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), | 2693 if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), |
2694 isolate_->js_builtins_object(), | 2694 isolate_->js_builtins_object(), |
2695 ARRAY_SIZE(argv), | 2695 ARRAY_SIZE(argv), |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2792 // Invoke the C debug event listener. | 2792 // Invoke the C debug event listener. |
2793 v8::Debug::EventCallback callback = | 2793 v8::Debug::EventCallback callback = |
2794 FUNCTION_CAST<v8::Debug::EventCallback>( | 2794 FUNCTION_CAST<v8::Debug::EventCallback>( |
2795 Handle<Foreign>::cast(event_listener_)->foreign_address()); | 2795 Handle<Foreign>::cast(event_listener_)->foreign_address()); |
2796 EventDetailsImpl event_details(event, | 2796 EventDetailsImpl event_details(event, |
2797 Handle<JSObject>::cast(exec_state), | 2797 Handle<JSObject>::cast(exec_state), |
2798 Handle<JSObject>::cast(event_data), | 2798 Handle<JSObject>::cast(event_data), |
2799 event_listener_data_, | 2799 event_listener_data_, |
2800 client_data); | 2800 client_data); |
2801 callback(event_details); | 2801 callback(event_details); |
2802 ASSERT(!isolate_->has_scheduled_exception()); | 2802 DCHECK(!isolate_->has_scheduled_exception()); |
2803 } else { | 2803 } else { |
2804 // Invoke the JavaScript debug event listener. | 2804 // Invoke the JavaScript debug event listener. |
2805 ASSERT(event_listener_->IsJSFunction()); | 2805 DCHECK(event_listener_->IsJSFunction()); |
2806 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_), | 2806 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_), |
2807 exec_state, | 2807 exec_state, |
2808 event_data, | 2808 event_data, |
2809 event_listener_data_ }; | 2809 event_listener_data_ }; |
2810 Handle<JSReceiver> global(isolate_->global_proxy()); | 2810 Handle<JSReceiver> global(isolate_->global_proxy()); |
2811 Execution::TryCall(Handle<JSFunction>::cast(event_listener_), | 2811 Execution::TryCall(Handle<JSFunction>::cast(event_listener_), |
2812 global, ARRAY_SIZE(argv), argv); | 2812 global, ARRAY_SIZE(argv), argv); |
2813 } | 2813 } |
2814 } | 2814 } |
2815 | 2815 |
2816 | 2816 |
2817 Handle<Context> Debug::GetDebugContext() { | 2817 Handle<Context> Debug::GetDebugContext() { |
2818 DebugScope debug_scope(this); | 2818 DebugScope debug_scope(this); |
2819 // The global handle may be destroyed soon after. Return it reboxed. | 2819 // The global handle may be destroyed soon after. Return it reboxed. |
2820 return handle(*debug_context(), isolate_); | 2820 return handle(*debug_context(), isolate_); |
2821 } | 2821 } |
2822 | 2822 |
2823 | 2823 |
2824 void Debug::NotifyMessageHandler(v8::DebugEvent event, | 2824 void Debug::NotifyMessageHandler(v8::DebugEvent event, |
2825 Handle<JSObject> exec_state, | 2825 Handle<JSObject> exec_state, |
2826 Handle<JSObject> event_data, | 2826 Handle<JSObject> event_data, |
2827 bool auto_continue) { | 2827 bool auto_continue) { |
2828 // Prevent other interrupts from triggering, for example API callbacks, | 2828 // Prevent other interrupts from triggering, for example API callbacks, |
2829 // while dispatching message handler callbacks. | 2829 // while dispatching message handler callbacks. |
2830 PostponeInterruptsScope no_interrupts(isolate_); | 2830 PostponeInterruptsScope no_interrupts(isolate_); |
2831 ASSERT(is_active_); | 2831 DCHECK(is_active_); |
2832 HandleScope scope(isolate_); | 2832 HandleScope scope(isolate_); |
2833 // Process the individual events. | 2833 // Process the individual events. |
2834 bool sendEventMessage = false; | 2834 bool sendEventMessage = false; |
2835 switch (event) { | 2835 switch (event) { |
2836 case v8::Break: | 2836 case v8::Break: |
2837 case v8::BreakForCommand: | 2837 case v8::BreakForCommand: |
2838 sendEventMessage = !auto_continue; | 2838 sendEventMessage = !auto_continue; |
2839 break; | 2839 break; |
2840 case v8::Exception: | 2840 case v8::Exception: |
2841 sendEventMessage = true; | 2841 sendEventMessage = true; |
2842 break; | 2842 break; |
2843 case v8::BeforeCompile: | 2843 case v8::BeforeCompile: |
2844 break; | 2844 break; |
2845 case v8::AfterCompile: | 2845 case v8::AfterCompile: |
2846 sendEventMessage = true; | 2846 sendEventMessage = true; |
2847 break; | 2847 break; |
2848 case v8::NewFunction: | 2848 case v8::NewFunction: |
2849 break; | 2849 break; |
2850 default: | 2850 default: |
2851 UNREACHABLE(); | 2851 UNREACHABLE(); |
2852 } | 2852 } |
2853 | 2853 |
2854 // The debug command interrupt flag might have been set when the command was | 2854 // The debug command interrupt flag might have been set when the command was |
2855 // added. It should be enough to clear the flag only once while we are in the | 2855 // added. It should be enough to clear the flag only once while we are in the |
2856 // debugger. | 2856 // debugger. |
2857 ASSERT(in_debug_scope()); | 2857 DCHECK(in_debug_scope()); |
2858 isolate_->stack_guard()->ClearDebugCommand(); | 2858 isolate_->stack_guard()->ClearDebugCommand(); |
2859 | 2859 |
2860 // Notify the debugger that a debug event has occurred unless auto continue is | 2860 // Notify the debugger that a debug event has occurred unless auto continue is |
2861 // active in which case no event is send. | 2861 // active in which case no event is send. |
2862 if (sendEventMessage) { | 2862 if (sendEventMessage) { |
2863 MessageImpl message = MessageImpl::NewEvent( | 2863 MessageImpl message = MessageImpl::NewEvent( |
2864 event, | 2864 event, |
2865 auto_continue, | 2865 auto_continue, |
2866 Handle<JSObject>::cast(exec_state), | 2866 Handle<JSObject>::cast(exec_state), |
2867 Handle<JSObject>::cast(event_data)); | 2867 Handle<JSObject>::cast(event_data)); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3058 if (isolate_->bootstrapper()->IsActive()) return; | 3058 if (isolate_->bootstrapper()->IsActive()) return; |
3059 // Just continue if breaks are disabled. | 3059 // Just continue if breaks are disabled. |
3060 if (break_disabled_) return; | 3060 if (break_disabled_) return; |
3061 // Ignore debug break if debugger is not active. | 3061 // Ignore debug break if debugger is not active. |
3062 if (!is_active()) return; | 3062 if (!is_active()) return; |
3063 | 3063 |
3064 StackLimitCheck check(isolate_); | 3064 StackLimitCheck check(isolate_); |
3065 if (check.HasOverflowed()) return; | 3065 if (check.HasOverflowed()) return; |
3066 | 3066 |
3067 { JavaScriptFrameIterator it(isolate_); | 3067 { JavaScriptFrameIterator it(isolate_); |
3068 ASSERT(!it.done()); | 3068 DCHECK(!it.done()); |
3069 Object* fun = it.frame()->function(); | 3069 Object* fun = it.frame()->function(); |
3070 if (fun && fun->IsJSFunction()) { | 3070 if (fun && fun->IsJSFunction()) { |
3071 // Don't stop in builtin functions. | 3071 // Don't stop in builtin functions. |
3072 if (JSFunction::cast(fun)->IsBuiltin()) return; | 3072 if (JSFunction::cast(fun)->IsBuiltin()) return; |
3073 GlobalObject* global = JSFunction::cast(fun)->context()->global_object(); | 3073 GlobalObject* global = JSFunction::cast(fun)->context()->global_object(); |
3074 // Don't stop in debugger functions. | 3074 // Don't stop in debugger functions. |
3075 if (IsDebugGlobal(global)) return; | 3075 if (IsDebugGlobal(global)) return; |
3076 } | 3076 } |
3077 } | 3077 } |
3078 | 3078 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3251 } else { | 3251 } else { |
3252 return v8::Utils::ToLocal(response_json_); | 3252 return v8::Utils::ToLocal(response_json_); |
3253 } | 3253 } |
3254 } | 3254 } |
3255 | 3255 |
3256 | 3256 |
3257 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { | 3257 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { |
3258 Isolate* isolate = event_data_->GetIsolate(); | 3258 Isolate* isolate = event_data_->GetIsolate(); |
3259 v8::Handle<v8::Context> context = GetDebugEventContext(isolate); | 3259 v8::Handle<v8::Context> context = GetDebugEventContext(isolate); |
3260 // Isolate::context() may be NULL when "script collected" event occures. | 3260 // Isolate::context() may be NULL when "script collected" event occures. |
3261 ASSERT(!context.IsEmpty()); | 3261 DCHECK(!context.IsEmpty()); |
3262 return context; | 3262 return context; |
3263 } | 3263 } |
3264 | 3264 |
3265 | 3265 |
3266 v8::Debug::ClientData* MessageImpl::GetClientData() const { | 3266 v8::Debug::ClientData* MessageImpl::GetClientData() const { |
3267 return client_data_; | 3267 return client_data_; |
3268 } | 3268 } |
3269 | 3269 |
3270 | 3270 |
3271 EventDetailsImpl::EventDetailsImpl(DebugEvent event, | 3271 EventDetailsImpl::EventDetailsImpl(DebugEvent event, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3341 } | 3341 } |
3342 | 3342 |
3343 | 3343 |
3344 CommandMessageQueue::~CommandMessageQueue() { | 3344 CommandMessageQueue::~CommandMessageQueue() { |
3345 while (!IsEmpty()) Get().Dispose(); | 3345 while (!IsEmpty()) Get().Dispose(); |
3346 DeleteArray(messages_); | 3346 DeleteArray(messages_); |
3347 } | 3347 } |
3348 | 3348 |
3349 | 3349 |
3350 CommandMessage CommandMessageQueue::Get() { | 3350 CommandMessage CommandMessageQueue::Get() { |
3351 ASSERT(!IsEmpty()); | 3351 DCHECK(!IsEmpty()); |
3352 int result = start_; | 3352 int result = start_; |
3353 start_ = (start_ + 1) % size_; | 3353 start_ = (start_ + 1) % size_; |
3354 return messages_[result]; | 3354 return messages_[result]; |
3355 } | 3355 } |
3356 | 3356 |
3357 | 3357 |
3358 void CommandMessageQueue::Put(const CommandMessage& message) { | 3358 void CommandMessageQueue::Put(const CommandMessage& message) { |
3359 if ((end_ + 1) % size_ == start_) { | 3359 if ((end_ + 1) % size_ == start_) { |
3360 Expand(); | 3360 Expand(); |
3361 } | 3361 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3402 logger_->DebugEvent("Put", message.text()); | 3402 logger_->DebugEvent("Put", message.text()); |
3403 } | 3403 } |
3404 | 3404 |
3405 | 3405 |
3406 void LockingCommandMessageQueue::Clear() { | 3406 void LockingCommandMessageQueue::Clear() { |
3407 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 3407 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
3408 queue_.Clear(); | 3408 queue_.Clear(); |
3409 } | 3409 } |
3410 | 3410 |
3411 } } // namespace v8::internal | 3411 } } // namespace v8::internal |
OLD | NEW |