• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "src/v8.h"
6 
7 #include "src/api.h"
8 #include "src/arguments.h"
9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h"
11 #include "src/codegen.h"
12 #include "src/compilation-cache.h"
13 #include "src/compiler.h"
14 #include "src/debug.h"
15 #include "src/deoptimizer.h"
16 #include "src/execution.h"
17 #include "src/full-codegen.h"
18 #include "src/global-handles.h"
19 #include "src/ic.h"
20 #include "src/ic-inl.h"
21 #include "src/isolate-inl.h"
22 #include "src/list.h"
23 #include "src/messages.h"
24 #include "src/natives.h"
25 #include "src/stub-cache.h"
26 #include "src/log.h"
27 
28 #include "include/v8-debug.h"
29 
30 namespace v8 {
31 namespace internal {
32 
Debug(Isolate * isolate)33 Debug::Debug(Isolate* isolate)
34     : debug_context_(Handle<Context>()),
35       event_listener_(Handle<Object>()),
36       event_listener_data_(Handle<Object>()),
37       message_handler_(NULL),
38       command_received_(0),
39       command_queue_(isolate->logger(), kQueueInitialSize),
40       event_command_queue_(isolate->logger(), kQueueInitialSize),
41       is_active_(false),
42       is_suppressed_(false),
43       live_edit_enabled_(true),  // TODO(yangguo): set to false by default.
44       has_break_points_(false),
45       break_disabled_(false),
46       break_on_exception_(false),
47       break_on_uncaught_exception_(false),
48       script_cache_(NULL),
49       debug_info_list_(NULL),
50       isolate_(isolate) {
51   ThreadInit();
52 }
53 
54 
GetDebugEventContext(Isolate * isolate)55 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
56   Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
57   // Isolate::context() may have been NULL when "script collected" event
58   // occured.
59   if (context.is_null()) return v8::Local<v8::Context>();
60   Handle<Context> native_context(context->native_context());
61   return v8::Utils::ToLocal(native_context);
62 }
63 
64 
BreakLocationIterator(Handle<DebugInfo> debug_info,BreakLocatorType type)65 BreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info,
66                                              BreakLocatorType type) {
67   debug_info_ = debug_info;
68   type_ = type;
69   reloc_iterator_ = NULL;
70   reloc_iterator_original_ = NULL;
71   Reset();  // Initialize the rest of the member variables.
72 }
73 
74 
~BreakLocationIterator()75 BreakLocationIterator::~BreakLocationIterator() {
76   ASSERT(reloc_iterator_ != NULL);
77   ASSERT(reloc_iterator_original_ != NULL);
78   delete reloc_iterator_;
79   delete reloc_iterator_original_;
80 }
81 
82 
83 // Check whether a code stub with the specified major key is a possible break
84 // point location when looking for source break locations.
IsSourceBreakStub(Code * code)85 static bool IsSourceBreakStub(Code* code) {
86   CodeStub::Major major_key = CodeStub::GetMajorKey(code);
87   return major_key == CodeStub::CallFunction;
88 }
89 
90 
91 // Check whether a code stub with the specified major key is a possible break
92 // location.
IsBreakStub(Code * code)93 static bool IsBreakStub(Code* code) {
94   CodeStub::Major major_key = CodeStub::GetMajorKey(code);
95   return major_key == CodeStub::CallFunction;
96 }
97 
98 
Next()99 void BreakLocationIterator::Next() {
100   DisallowHeapAllocation no_gc;
101   ASSERT(!RinfoDone());
102 
103   // Iterate through reloc info for code and original code stopping at each
104   // breakable code target.
105   bool first = break_point_ == -1;
106   while (!RinfoDone()) {
107     if (!first) RinfoNext();
108     first = false;
109     if (RinfoDone()) return;
110 
111     // Whenever a statement position or (plain) position is passed update the
112     // current value of these.
113     if (RelocInfo::IsPosition(rmode())) {
114       if (RelocInfo::IsStatementPosition(rmode())) {
115         statement_position_ = static_cast<int>(
116             rinfo()->data() - debug_info_->shared()->start_position());
117       }
118       // Always update the position as we don't want that to be before the
119       // statement position.
120       position_ = static_cast<int>(
121           rinfo()->data() - debug_info_->shared()->start_position());
122       ASSERT(position_ >= 0);
123       ASSERT(statement_position_ >= 0);
124     }
125 
126     if (IsDebugBreakSlot()) {
127       // There is always a possible break point at a debug break slot.
128       break_point_++;
129       return;
130     } else if (RelocInfo::IsCodeTarget(rmode())) {
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
133       // to be of a different kind than in the original code.
134       Address target = original_rinfo()->target_address();
135       Code* code = Code::GetCodeFromTargetAddress(target);
136       if ((code->is_inline_cache_stub() &&
137            !code->is_binary_op_stub() &&
138            !code->is_compare_ic_stub() &&
139            !code->is_to_boolean_ic_stub()) ||
140           RelocInfo::IsConstructCall(rmode())) {
141         break_point_++;
142         return;
143       }
144       if (code->kind() == Code::STUB) {
145         if (IsDebuggerStatement()) {
146           break_point_++;
147           return;
148         } else if (type_ == ALL_BREAK_LOCATIONS) {
149           if (IsBreakStub(code)) {
150             break_point_++;
151             return;
152           }
153         } else {
154           ASSERT(type_ == SOURCE_BREAK_LOCATIONS);
155           if (IsSourceBreakStub(code)) {
156             break_point_++;
157             return;
158           }
159         }
160       }
161     }
162 
163     // Check for break at return.
164     if (RelocInfo::IsJSReturn(rmode())) {
165       // Set the positions to the end of the function.
166       if (debug_info_->shared()->HasSourceCode()) {
167         position_ = debug_info_->shared()->end_position() -
168                     debug_info_->shared()->start_position() - 1;
169       } else {
170         position_ = 0;
171       }
172       statement_position_ = position_;
173       break_point_++;
174       return;
175     }
176   }
177 }
178 
179 
Next(int count)180 void BreakLocationIterator::Next(int count) {
181   while (count > 0) {
182     Next();
183     count--;
184   }
185 }
186 
187 
188 // Find the break point at the supplied address, or the closest one before
189 // the address.
FindBreakLocationFromAddress(Address pc)190 void BreakLocationIterator::FindBreakLocationFromAddress(Address pc) {
191   // Run through all break points to locate the one closest to the address.
192   int closest_break_point = 0;
193   int distance = kMaxInt;
194   while (!Done()) {
195     // Check if this break point is closer that what was previously found.
196     if (this->pc() <= pc && pc - this->pc() < distance) {
197       closest_break_point = break_point();
198       distance = static_cast<int>(pc - this->pc());
199       // Check whether we can't get any closer.
200       if (distance == 0) break;
201     }
202     Next();
203   }
204 
205   // Move to the break point found.
206   Reset();
207   Next(closest_break_point);
208 }
209 
210 
211 // Find the break point closest to the supplied source position.
FindBreakLocationFromPosition(int position,BreakPositionAlignment alignment)212 void BreakLocationIterator::FindBreakLocationFromPosition(int position,
213     BreakPositionAlignment alignment) {
214   // Run through all break points to locate the one closest to the source
215   // position.
216   int closest_break_point = 0;
217   int distance = kMaxInt;
218 
219   while (!Done()) {
220     int next_position;
221     switch (alignment) {
222     case STATEMENT_ALIGNED:
223       next_position = this->statement_position();
224       break;
225     case BREAK_POSITION_ALIGNED:
226       next_position = this->position();
227       break;
228     default:
229       UNREACHABLE();
230       next_position = this->statement_position();
231     }
232     // Check if this break point is closer that what was previously found.
233     if (position <= next_position && next_position - position < distance) {
234       closest_break_point = break_point();
235       distance = next_position - position;
236       // Check whether we can't get any closer.
237       if (distance == 0) break;
238     }
239     Next();
240   }
241 
242   // Move to the break point found.
243   Reset();
244   Next(closest_break_point);
245 }
246 
247 
Reset()248 void BreakLocationIterator::Reset() {
249   // Create relocation iterators for the two code objects.
250   if (reloc_iterator_ != NULL) delete reloc_iterator_;
251   if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_;
252   reloc_iterator_ = new RelocIterator(
253       debug_info_->code(),
254       ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE));
255   reloc_iterator_original_ = new RelocIterator(
256       debug_info_->original_code(),
257       ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE));
258 
259   // Position at the first break point.
260   break_point_ = -1;
261   position_ = 1;
262   statement_position_ = 1;
263   Next();
264 }
265 
266 
Done() const267 bool BreakLocationIterator::Done() const {
268   return RinfoDone();
269 }
270 
271 
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
274   // break.
275   if (!HasBreakPoint()) SetDebugBreak();
276   ASSERT(IsDebugBreak() || IsDebuggerStatement());
277   // Set the break point information.
278   DebugInfo::SetBreakPoint(debug_info_, code_position(),
279                            position(), statement_position(),
280                            break_point_object);
281 }
282 
283 
ClearBreakPoint(Handle<Object> break_point_object)284 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
285   // Clear the break point information.
286   DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
287   // If there are no more break points here remove the debug break.
288   if (!HasBreakPoint()) {
289     ClearDebugBreak();
290     ASSERT(!IsDebugBreak());
291   }
292 }
293 
294 
SetOneShot()295 void BreakLocationIterator::SetOneShot() {
296   // Debugger statement always calls debugger. No need to modify it.
297   if (IsDebuggerStatement()) return;
298 
299   // If there is a real break point here no more to do.
300   if (HasBreakPoint()) {
301     ASSERT(IsDebugBreak());
302     return;
303   }
304 
305   // Patch code with debug break.
306   SetDebugBreak();
307 }
308 
309 
ClearOneShot()310 void BreakLocationIterator::ClearOneShot() {
311   // Debugger statement always calls debugger. No need to modify it.
312   if (IsDebuggerStatement()) return;
313 
314   // If there is a real break point here no more to do.
315   if (HasBreakPoint()) {
316     ASSERT(IsDebugBreak());
317     return;
318   }
319 
320   // Patch code removing debug break.
321   ClearDebugBreak();
322   ASSERT(!IsDebugBreak());
323 }
324 
325 
SetDebugBreak()326 void BreakLocationIterator::SetDebugBreak() {
327   // Debugger statement always calls debugger. No need to modify it.
328   if (IsDebuggerStatement()) return;
329 
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
332   // function twice might happen when stepping in a function with an exception
333   // handler as the handler and the function is the same.
334   if (IsDebugBreak()) return;
335 
336   if (RelocInfo::IsJSReturn(rmode())) {
337     // Patch the frame exit code with a break point.
338     SetDebugBreakAtReturn();
339   } else if (IsDebugBreakSlot()) {
340     // Patch the code in the break slot.
341     SetDebugBreakAtSlot();
342   } else {
343     // Patch the IC call.
344     SetDebugBreakAtIC();
345   }
346   ASSERT(IsDebugBreak());
347 }
348 
349 
ClearDebugBreak()350 void BreakLocationIterator::ClearDebugBreak() {
351   // Debugger statement always calls debugger. No need to modify it.
352   if (IsDebuggerStatement()) return;
353 
354   if (RelocInfo::IsJSReturn(rmode())) {
355     // Restore the frame exit code.
356     ClearDebugBreakAtReturn();
357   } else if (IsDebugBreakSlot()) {
358     // Restore the code in the break slot.
359     ClearDebugBreakAtSlot();
360   } else {
361     // Patch the IC call.
362     ClearDebugBreakAtIC();
363   }
364   ASSERT(!IsDebugBreak());
365 }
366 
367 
IsStepInLocation(Isolate * isolate)368 bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) {
369   if (RelocInfo::IsConstructCall(original_rmode())) {
370     return true;
371   } else if (RelocInfo::IsCodeTarget(rmode())) {
372     HandleScope scope(debug_info_->GetIsolate());
373     Address target = original_rinfo()->target_address();
374     Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
375     if (target_code->kind() == Code::STUB) {
376       return target_code->major_key() == CodeStub::CallFunction;
377     }
378     return target_code->is_call_stub();
379   }
380   return false;
381 }
382 
383 
PrepareStepIn(Isolate * isolate)384 void BreakLocationIterator::PrepareStepIn(Isolate* isolate) {
385 #ifdef DEBUG
386   HandleScope scope(isolate);
387   // Step in can only be prepared if currently positioned on an IC call,
388   // construct call or CallFunction stub call.
389   Address target = rinfo()->target_address();
390   Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
391   // All the following stuff is needed only for assertion checks so the code
392   // is wrapped in ifdef.
393   Handle<Code> maybe_call_function_stub = target_code;
394   if (IsDebugBreak()) {
395     Address original_target = original_rinfo()->target_address();
396     maybe_call_function_stub =
397         Handle<Code>(Code::GetCodeFromTargetAddress(original_target));
398   }
399   bool is_call_function_stub =
400       (maybe_call_function_stub->kind() == Code::STUB &&
401        maybe_call_function_stub->major_key() == CodeStub::CallFunction);
402 
403   // Step in through construct call requires no changes to the running code.
404   // Step in through getters/setters should already be prepared as well
405   // because caller of this function (Debug::PrepareStep) is expected to
406   // flood the top frame's function with one shot breakpoints.
407   // Step in through CallFunction stub should also be prepared by caller of
408   // this function (Debug::PrepareStep) which should flood target function
409   // with breakpoints.
410   ASSERT(RelocInfo::IsConstructCall(rmode()) ||
411          target_code->is_inline_cache_stub() ||
412          is_call_function_stub);
413 #endif
414 }
415 
416 
417 // Check whether the break point is at a position which will exit the function.
IsExit() const418 bool BreakLocationIterator::IsExit() const {
419   return (RelocInfo::IsJSReturn(rmode()));
420 }
421 
422 
HasBreakPoint()423 bool BreakLocationIterator::HasBreakPoint() {
424   return debug_info_->HasBreakPoint(code_position());
425 }
426 
427 
428 // Check whether there is a debug break at the current position.
IsDebugBreak()429 bool BreakLocationIterator::IsDebugBreak() {
430   if (RelocInfo::IsJSReturn(rmode())) {
431     return IsDebugBreakAtReturn();
432   } else if (IsDebugBreakSlot()) {
433     return IsDebugBreakAtSlot();
434   } else {
435     return Debug::IsDebugBreak(rinfo()->target_address());
436   }
437 }
438 
439 
440 // Find the builtin to use for invoking the debug break
DebugBreakForIC(Handle<Code> code,RelocInfo::Mode mode)441 static Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) {
442   Isolate* isolate = code->GetIsolate();
443 
444   // Find the builtin debug break function matching the calling convention
445   // used by the call site.
446   if (code->is_inline_cache_stub()) {
447     switch (code->kind()) {
448       case Code::CALL_IC:
449         return isolate->builtins()->CallICStub_DebugBreak();
450 
451       case Code::LOAD_IC:
452         return isolate->builtins()->LoadIC_DebugBreak();
453 
454       case Code::STORE_IC:
455         return isolate->builtins()->StoreIC_DebugBreak();
456 
457       case Code::KEYED_LOAD_IC:
458         return isolate->builtins()->KeyedLoadIC_DebugBreak();
459 
460       case Code::KEYED_STORE_IC:
461         return isolate->builtins()->KeyedStoreIC_DebugBreak();
462 
463       case Code::COMPARE_NIL_IC:
464         return isolate->builtins()->CompareNilIC_DebugBreak();
465 
466       default:
467         UNREACHABLE();
468     }
469   }
470   if (RelocInfo::IsConstructCall(mode)) {
471     if (code->has_function_cache()) {
472       return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
473     } else {
474       return isolate->builtins()->CallConstructStub_DebugBreak();
475     }
476   }
477   if (code->kind() == Code::STUB) {
478     ASSERT(code->major_key() == CodeStub::CallFunction);
479     return isolate->builtins()->CallFunctionStub_DebugBreak();
480   }
481 
482   UNREACHABLE();
483   return Handle<Code>::null();
484 }
485 
486 
SetDebugBreakAtIC()487 void BreakLocationIterator::SetDebugBreakAtIC() {
488   // Patch the original code with the current address as the current address
489   // might have changed by the inline caching since the code was copied.
490   original_rinfo()->set_target_address(rinfo()->target_address());
491 
492   RelocInfo::Mode mode = rmode();
493   if (RelocInfo::IsCodeTarget(mode)) {
494     Address target = rinfo()->target_address();
495     Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
496 
497     // Patch the code to invoke the builtin debug break function matching the
498     // calling convention used by the call site.
499     Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode);
500     rinfo()->set_target_address(dbgbrk_code->entry());
501   }
502 }
503 
504 
ClearDebugBreakAtIC()505 void BreakLocationIterator::ClearDebugBreakAtIC() {
506   // Patch the code to the original invoke.
507   rinfo()->set_target_address(original_rinfo()->target_address());
508 }
509 
510 
IsDebuggerStatement()511 bool BreakLocationIterator::IsDebuggerStatement() {
512   return RelocInfo::DEBUG_BREAK == rmode();
513 }
514 
515 
IsDebugBreakSlot()516 bool BreakLocationIterator::IsDebugBreakSlot() {
517   return RelocInfo::DEBUG_BREAK_SLOT == rmode();
518 }
519 
520 
BreakPointObjects()521 Object* BreakLocationIterator::BreakPointObjects() {
522   return debug_info_->GetBreakPointObjects(code_position());
523 }
524 
525 
526 // Clear out all the debug break code. This is ONLY supposed to be used when
527 // shutting down the debugger as it will leave the break point information in
528 // DebugInfo even though the code is patched back to the non break point state.
ClearAllDebugBreak()529 void BreakLocationIterator::ClearAllDebugBreak() {
530   while (!Done()) {
531     ClearDebugBreak();
532     Next();
533   }
534 }
535 
536 
RinfoDone() const537 bool BreakLocationIterator::RinfoDone() const {
538   ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
539   return reloc_iterator_->done();
540 }
541 
542 
RinfoNext()543 void BreakLocationIterator::RinfoNext() {
544   reloc_iterator_->next();
545   reloc_iterator_original_->next();
546 #ifdef DEBUG
547   ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
548   if (!reloc_iterator_->done()) {
549     ASSERT(rmode() == original_rmode());
550   }
551 #endif
552 }
553 
554 
555 // Threading support.
ThreadInit()556 void Debug::ThreadInit() {
557   thread_local_.break_count_ = 0;
558   thread_local_.break_id_ = 0;
559   thread_local_.break_frame_id_ = StackFrame::NO_ID;
560   thread_local_.last_step_action_ = StepNone;
561   thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
562   thread_local_.step_count_ = 0;
563   thread_local_.last_fp_ = 0;
564   thread_local_.queued_step_count_ = 0;
565   thread_local_.step_into_fp_ = 0;
566   thread_local_.step_out_fp_ = 0;
567   // TODO(isolates): frames_are_dropped_?
568   thread_local_.current_debug_scope_ = NULL;
569   thread_local_.restarter_frame_function_pointer_ = NULL;
570   thread_local_.promise_on_stack_ = NULL;
571 }
572 
573 
ArchiveDebug(char * storage)574 char* Debug::ArchiveDebug(char* storage) {
575   char* to = storage;
576   MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
577   ThreadInit();
578   return storage + ArchiveSpacePerThread();
579 }
580 
581 
RestoreDebug(char * storage)582 char* Debug::RestoreDebug(char* storage) {
583   char* from = storage;
584   MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
585   return storage + ArchiveSpacePerThread();
586 }
587 
588 
ArchiveSpacePerThread()589 int Debug::ArchiveSpacePerThread() {
590   return sizeof(ThreadLocal);
591 }
592 
593 
ScriptCache(Isolate * isolate)594 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch),
595                                              isolate_(isolate),
596                                              collected_scripts_(10) {
597   Heap* heap = isolate_->heap();
598   HandleScope scope(isolate_);
599 
600   // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
601   // rid of all the cached script wrappers and the second gets rid of the
602   // scripts which are no longer referenced.
603   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
604   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
605 
606   // Scan heap for Script objects.
607   HeapIterator iterator(heap);
608   DisallowHeapAllocation no_allocation;
609 
610   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
611     if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
612       Add(Handle<Script>(Script::cast(obj)));
613     }
614   }
615 }
616 
617 
Add(Handle<Script> script)618 void ScriptCache::Add(Handle<Script> script) {
619   GlobalHandles* global_handles = isolate_->global_handles();
620   // Create an entry in the hash map for the script.
621   int id = script->id()->value();
622   HashMap::Entry* entry =
623       HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
624   if (entry->value != NULL) {
625     ASSERT(*script == *reinterpret_cast<Script**>(entry->value));
626     return;
627   }
628   // Globalize the script object, make it weak and use the location of the
629   // global handle as the value in the hash map.
630   Handle<Script> script_ =
631       Handle<Script>::cast(global_handles->Create(*script));
632   GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
633                           this,
634                           ScriptCache::HandleWeakScript);
635   entry->value = script_.location();
636 }
637 
638 
GetScripts()639 Handle<FixedArray> ScriptCache::GetScripts() {
640   Factory* factory = isolate_->factory();
641   Handle<FixedArray> instances = factory->NewFixedArray(occupancy());
642   int count = 0;
643   for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
644     ASSERT(entry->value != NULL);
645     if (entry->value != NULL) {
646       instances->set(count, *reinterpret_cast<Script**>(entry->value));
647       count++;
648     }
649   }
650   return instances;
651 }
652 
653 
ProcessCollectedScripts()654 void ScriptCache::ProcessCollectedScripts() {
655   Debug* debug = isolate_->debug();
656   for (int i = 0; i < collected_scripts_.length(); i++) {
657     debug->OnScriptCollected(collected_scripts_[i]);
658   }
659   collected_scripts_.Clear();
660 }
661 
662 
Clear()663 void ScriptCache::Clear() {
664   // Iterate the script cache to get rid of all the weak handles.
665   for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
666     ASSERT(entry != NULL);
667     Object** location = reinterpret_cast<Object**>(entry->value);
668     ASSERT((*location)->IsScript());
669     GlobalHandles::ClearWeakness(location);
670     GlobalHandles::Destroy(location);
671   }
672   // Clear the content of the hash map.
673   HashMap::Clear();
674 }
675 
676 
HandleWeakScript(const v8::WeakCallbackData<v8::Value,void> & data)677 void ScriptCache::HandleWeakScript(
678     const v8::WeakCallbackData<v8::Value, void>& data) {
679   // Retrieve the script identifier.
680   Handle<Object> object = Utils::OpenHandle(*data.GetValue());
681   int id = Handle<Script>::cast(object)->id()->value();
682   void* key = reinterpret_cast<void*>(id);
683   uint32_t hash = Hash(id);
684 
685   // Remove the corresponding entry from the cache.
686   ScriptCache* script_cache =
687       reinterpret_cast<ScriptCache*>(data.GetParameter());
688   HashMap::Entry* entry = script_cache->Lookup(key, hash, false);
689   Object** location = reinterpret_cast<Object**>(entry->value);
690   script_cache->Remove(key, hash);
691   script_cache->collected_scripts_.Add(id);
692 
693   // Clear the weak handle.
694   GlobalHandles::Destroy(location);
695 }
696 
697 
HandleWeakDebugInfo(const v8::WeakCallbackData<v8::Value,void> & data)698 void Debug::HandleWeakDebugInfo(
699     const v8::WeakCallbackData<v8::Value, void>& data) {
700   Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
701   DebugInfoListNode* node =
702       reinterpret_cast<DebugInfoListNode*>(data.GetParameter());
703   // We need to clear all breakpoints associated with the function to restore
704   // original code and avoid patching the code twice later because
705   // the function will live in the heap until next gc, and can be found by
706   // Debug::FindSharedFunctionInfoInScript.
707   BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
708   it.ClearAllDebugBreak();
709   debug->RemoveDebugInfo(node->debug_info());
710 #ifdef DEBUG
711   for (DebugInfoListNode* n = debug->debug_info_list_;
712        n != NULL;
713        n = n->next()) {
714     ASSERT(n != node);
715   }
716 #endif
717 }
718 
719 
DebugInfoListNode(DebugInfo * debug_info)720 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
721   // Globalize the request debug info object and make it weak.
722   GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
723   debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info));
724   GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
725                           this,
726                           Debug::HandleWeakDebugInfo);
727 }
728 
729 
~DebugInfoListNode()730 DebugInfoListNode::~DebugInfoListNode() {
731   GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location()));
732 }
733 
734 
CompileDebuggerScript(Isolate * isolate,int index)735 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
736   Factory* factory = isolate->factory();
737   HandleScope scope(isolate);
738 
739   // Bail out if the index is invalid.
740   if (index == -1) return false;
741 
742   // Find source and name for the requested script.
743   Handle<String> source_code =
744       isolate->bootstrapper()->NativesSourceLookup(index);
745   Vector<const char> name = Natives::GetScriptName(index);
746   Handle<String> script_name =
747       factory->NewStringFromAscii(name).ToHandleChecked();
748   Handle<Context> context = isolate->native_context();
749 
750   // Compile the script.
751   Handle<SharedFunctionInfo> function_info;
752   function_info = Compiler::CompileScript(source_code,
753                                           script_name, 0, 0,
754                                           false,
755                                           context,
756                                           NULL, NULL, NO_CACHED_DATA,
757                                           NATIVES_CODE);
758 
759   // Silently ignore stack overflows during compilation.
760   if (function_info.is_null()) {
761     ASSERT(isolate->has_pending_exception());
762     isolate->clear_pending_exception();
763     return false;
764   }
765 
766   // Execute the shared function in the debugger context.
767   Handle<JSFunction> function =
768       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
769 
770   Handle<Object> exception;
771   MaybeHandle<Object> result =
772       Execution::TryCall(function,
773                          Handle<Object>(context->global_object(), isolate),
774                          0,
775                          NULL,
776                          &exception);
777 
778   // Check for caught exceptions.
779   if (result.is_null()) {
780     ASSERT(!isolate->has_pending_exception());
781     MessageLocation computed_location;
782     isolate->ComputeLocation(&computed_location);
783     Handle<Object> message = MessageHandler::MakeMessageObject(
784         isolate, "error_loading_debugger", &computed_location,
785         Vector<Handle<Object> >::empty(), Handle<JSArray>());
786     ASSERT(!isolate->has_pending_exception());
787     if (!exception.is_null()) {
788       isolate->set_pending_exception(*exception);
789       MessageHandler::ReportMessage(isolate, NULL, message);
790       isolate->clear_pending_exception();
791     }
792     return false;
793   }
794 
795   // Mark this script as native and return successfully.
796   Handle<Script> script(Script::cast(function->shared()->script()));
797   script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
798   return true;
799 }
800 
801 
Load()802 bool Debug::Load() {
803   // Return if debugger is already loaded.
804   if (is_loaded()) return true;
805 
806   // Bail out if we're already in the process of compiling the native
807   // JavaScript source code for the debugger.
808   if (is_suppressed_) return false;
809   SuppressDebug while_loading(this);
810 
811   // Disable breakpoints and interrupts while compiling and running the
812   // debugger scripts including the context creation code.
813   DisableBreak disable(this, true);
814   PostponeInterruptsScope postpone(isolate_);
815 
816   // Create the debugger context.
817   HandleScope scope(isolate_);
818   ExtensionConfiguration no_extensions;
819   Handle<Context> context =
820       isolate_->bootstrapper()->CreateEnvironment(
821           Handle<Object>::null(),
822           v8::Handle<ObjectTemplate>(),
823           &no_extensions);
824 
825   // Fail if no context could be created.
826   if (context.is_null()) return false;
827 
828   // Use the debugger context.
829   SaveContext save(isolate_);
830   isolate_->set_context(*context);
831 
832   // Expose the builtins object in the debugger context.
833   Handle<String> key = isolate_->factory()->InternalizeOneByteString(
834       STATIC_ASCII_VECTOR("builtins"));
835   Handle<GlobalObject> global =
836       Handle<GlobalObject>(context->global_object(), isolate_);
837   Handle<JSBuiltinsObject> builtin =
838       Handle<JSBuiltinsObject>(global->builtins(), isolate_);
839   RETURN_ON_EXCEPTION_VALUE(
840       isolate_,
841       JSReceiver::SetProperty(global, key, builtin, NONE, SLOPPY),
842       false);
843 
844   // Compile the JavaScript for the debugger in the debugger context.
845   bool caught_exception =
846       !CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) ||
847       !CompileDebuggerScript(isolate_, Natives::GetIndex("debug"));
848 
849   if (FLAG_enable_liveedit) {
850     caught_exception = caught_exception ||
851         !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
852   }
853   // Check for caught exceptions.
854   if (caught_exception) return false;
855 
856   debug_context_ = Handle<Context>::cast(
857       isolate_->global_handles()->Create(*context));
858   return true;
859 }
860 
861 
Unload()862 void Debug::Unload() {
863   ClearAllBreakPoints();
864   ClearStepping();
865 
866   // Match unmatched PromiseHandlePrologue calls.
867   while (thread_local_.promise_on_stack_) PromiseHandleEpilogue();
868 
869   // Return debugger is not loaded.
870   if (!is_loaded()) return;
871 
872   // Clear the script cache.
873   if (script_cache_ != NULL) {
874     delete script_cache_;
875     script_cache_ = NULL;
876   }
877 
878   // Clear debugger context global handle.
879   GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
880   debug_context_ = Handle<Context>();
881 }
882 
883 
Break(Arguments args,JavaScriptFrame * frame)884 void Debug::Break(Arguments args, JavaScriptFrame* frame) {
885   Heap* heap = isolate_->heap();
886   HandleScope scope(isolate_);
887   ASSERT(args.length() == 0);
888 
889   // Initialize LiveEdit.
890   LiveEdit::InitializeThreadLocal(this);
891 
892   // Just continue if breaks are disabled or debugger cannot be loaded.
893   if (break_disabled_) return;
894 
895   // Enter the debugger.
896   DebugScope debug_scope(this);
897   if (debug_scope.failed()) return;
898 
899   // Postpone interrupt during breakpoint processing.
900   PostponeInterruptsScope postpone(isolate_);
901 
902   // Get the debug info (create it if it does not exist).
903   Handle<SharedFunctionInfo> shared =
904       Handle<SharedFunctionInfo>(frame->function()->shared());
905   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
906 
907   // Find the break point where execution has stopped.
908   BreakLocationIterator break_location_iterator(debug_info,
909                                                 ALL_BREAK_LOCATIONS);
910   // pc points to the instruction after the current one, possibly a break
911   // location as well. So the "- 1" to exclude it from the search.
912   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
913 
914   // Check whether step next reached a new statement.
915   if (!StepNextContinue(&break_location_iterator, frame)) {
916     // Decrease steps left if performing multiple steps.
917     if (thread_local_.step_count_ > 0) {
918       thread_local_.step_count_--;
919     }
920   }
921 
922   // If there is one or more real break points check whether any of these are
923   // triggered.
924   Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
925   if (break_location_iterator.HasBreakPoint()) {
926     Handle<Object> break_point_objects =
927         Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_);
928     break_points_hit = CheckBreakPoints(break_point_objects);
929   }
930 
931   // If step out is active skip everything until the frame where we need to step
932   // out to is reached, unless real breakpoint is hit.
933   if (StepOutActive() &&
934       frame->fp() != thread_local_.step_out_fp_ &&
935       break_points_hit->IsUndefined() ) {
936       // Step count should always be 0 for StepOut.
937       ASSERT(thread_local_.step_count_ == 0);
938   } else if (!break_points_hit->IsUndefined() ||
939              (thread_local_.last_step_action_ != StepNone &&
940               thread_local_.step_count_ == 0)) {
941     // Notify debugger if a real break point is triggered or if performing
942     // single stepping with no more steps to perform. Otherwise do another step.
943 
944     // Clear all current stepping setup.
945     ClearStepping();
946 
947     if (thread_local_.queued_step_count_ > 0) {
948       // Perform queued steps
949       int step_count = thread_local_.queued_step_count_;
950 
951       // Clear queue
952       thread_local_.queued_step_count_ = 0;
953 
954       PrepareStep(StepNext, step_count, StackFrame::NO_ID);
955     } else {
956       // Notify the debug event listeners.
957       OnDebugBreak(break_points_hit, false);
958     }
959   } else if (thread_local_.last_step_action_ != StepNone) {
960     // Hold on to last step action as it is cleared by the call to
961     // ClearStepping.
962     StepAction step_action = thread_local_.last_step_action_;
963     int step_count = thread_local_.step_count_;
964 
965     // If StepNext goes deeper in code, StepOut until original frame
966     // and keep step count queued up in the meantime.
967     if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
968       // Count frames until target frame
969       int count = 0;
970       JavaScriptFrameIterator it(isolate_);
971       while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) {
972         count++;
973         it.Advance();
974       }
975 
976       // Check that we indeed found the frame we are looking for.
977       CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_));
978       if (step_count > 1) {
979         // Save old count and action to continue stepping after StepOut.
980         thread_local_.queued_step_count_ = step_count - 1;
981       }
982 
983       // Set up for StepOut to reach target frame.
984       step_action = StepOut;
985       step_count = count;
986     }
987 
988     // Clear all current stepping setup.
989     ClearStepping();
990 
991     // Set up for the remaining steps.
992     PrepareStep(step_action, step_count, StackFrame::NO_ID);
993   }
994 }
995 
996 
RUNTIME_FUNCTION(Debug_Break)997 RUNTIME_FUNCTION(Debug_Break) {
998   // Get the top-most JavaScript frame.
999   JavaScriptFrameIterator it(isolate);
1000   isolate->debug()->Break(args, it.frame());
1001   isolate->debug()->SetAfterBreakTarget(it.frame());
1002   return isolate->heap()->undefined_value();
1003 }
1004 
1005 
1006 // Check the break point objects for whether one or more are actually
1007 // triggered. This function returns a JSArray with the break point objects
1008 // which is triggered.
CheckBreakPoints(Handle<Object> break_point_objects)1009 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
1010   Factory* factory = isolate_->factory();
1011 
1012   // Count the number of break points hit. If there are multiple break points
1013   // they are in a FixedArray.
1014   Handle<FixedArray> break_points_hit;
1015   int break_points_hit_count = 0;
1016   ASSERT(!break_point_objects->IsUndefined());
1017   if (break_point_objects->IsFixedArray()) {
1018     Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
1019     break_points_hit = factory->NewFixedArray(array->length());
1020     for (int i = 0; i < array->length(); i++) {
1021       Handle<Object> o(array->get(i), isolate_);
1022       if (CheckBreakPoint(o)) {
1023         break_points_hit->set(break_points_hit_count++, *o);
1024       }
1025     }
1026   } else {
1027     break_points_hit = factory->NewFixedArray(1);
1028     if (CheckBreakPoint(break_point_objects)) {
1029       break_points_hit->set(break_points_hit_count++, *break_point_objects);
1030     }
1031   }
1032 
1033   // Return undefined if no break points were triggered.
1034   if (break_points_hit_count == 0) {
1035     return factory->undefined_value();
1036   }
1037   // Return break points hit as a JSArray.
1038   Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
1039   result->set_length(Smi::FromInt(break_points_hit_count));
1040   return result;
1041 }
1042 
1043 
1044 // Check whether a single break point object is triggered.
CheckBreakPoint(Handle<Object> break_point_object)1045 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
1046   Factory* factory = isolate_->factory();
1047   HandleScope scope(isolate_);
1048 
1049   // Ignore check if break point object is not a JSObject.
1050   if (!break_point_object->IsJSObject()) return true;
1051 
1052   // Get the function IsBreakPointTriggered (defined in debug-debugger.js).
1053   Handle<String> is_break_point_triggered_string =
1054       factory->InternalizeOneByteString(
1055           STATIC_ASCII_VECTOR("IsBreakPointTriggered"));
1056   Handle<GlobalObject> debug_global(debug_context()->global_object());
1057   Handle<JSFunction> check_break_point =
1058     Handle<JSFunction>::cast(Object::GetProperty(
1059         debug_global, is_break_point_triggered_string).ToHandleChecked());
1060 
1061   // Get the break id as an object.
1062   Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
1063 
1064   // Call HandleBreakPointx.
1065   Handle<Object> argv[] = { break_id, break_point_object };
1066   Handle<Object> result;
1067   if (!Execution::TryCall(check_break_point,
1068                           isolate_->js_builtins_object(),
1069                           ARRAY_SIZE(argv),
1070                           argv).ToHandle(&result)) {
1071     return false;
1072   }
1073 
1074   // Return whether the break point is triggered.
1075   return result->IsTrue();
1076 }
1077 
1078 
1079 // Check whether the function has debug information.
HasDebugInfo(Handle<SharedFunctionInfo> shared)1080 bool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) {
1081   return !shared->debug_info()->IsUndefined();
1082 }
1083 
1084 
1085 // Return the debug info for this function. EnsureDebugInfo must be called
1086 // prior to ensure the debug info has been generated for shared.
GetDebugInfo(Handle<SharedFunctionInfo> shared)1087 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) {
1088   ASSERT(HasDebugInfo(shared));
1089   return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info()));
1090 }
1091 
1092 
SetBreakPoint(Handle<JSFunction> function,Handle<Object> break_point_object,int * source_position)1093 bool Debug::SetBreakPoint(Handle<JSFunction> function,
1094                           Handle<Object> break_point_object,
1095                           int* source_position) {
1096   HandleScope scope(isolate_);
1097 
1098   PrepareForBreakPoints();
1099 
1100   // Make sure the function is compiled and has set up the debug info.
1101   Handle<SharedFunctionInfo> shared(function->shared());
1102   if (!EnsureDebugInfo(shared, function)) {
1103     // Return if retrieving debug info failed.
1104     return true;
1105   }
1106 
1107   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1108   // Source positions starts with zero.
1109   ASSERT(*source_position >= 0);
1110 
1111   // Find the break point and change it.
1112   BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
1113   it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED);
1114   it.SetBreakPoint(break_point_object);
1115 
1116   *source_position = it.position();
1117 
1118   // At least one active break point now.
1119   return debug_info->GetBreakPointCount() > 0;
1120 }
1121 
1122 
SetBreakPointForScript(Handle<Script> script,Handle<Object> break_point_object,int * source_position,BreakPositionAlignment alignment)1123 bool Debug::SetBreakPointForScript(Handle<Script> script,
1124                                    Handle<Object> break_point_object,
1125                                    int* source_position,
1126                                    BreakPositionAlignment alignment) {
1127   HandleScope scope(isolate_);
1128 
1129   PrepareForBreakPoints();
1130 
1131   // Obtain shared function info for the function.
1132   Object* result = FindSharedFunctionInfoInScript(script, *source_position);
1133   if (result->IsUndefined()) return false;
1134 
1135   // Make sure the function has set up the debug info.
1136   Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
1137   if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
1138     // Return if retrieving debug info failed.
1139     return false;
1140   }
1141 
1142   // Find position within function. The script position might be before the
1143   // source position of the first function.
1144   int position;
1145   if (shared->start_position() > *source_position) {
1146     position = 0;
1147   } else {
1148     position = *source_position - shared->start_position();
1149   }
1150 
1151   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1152   // Source positions starts with zero.
1153   ASSERT(position >= 0);
1154 
1155   // Find the break point and change it.
1156   BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
1157   it.FindBreakLocationFromPosition(position, alignment);
1158   it.SetBreakPoint(break_point_object);
1159 
1160   *source_position = it.position() + shared->start_position();
1161 
1162   // At least one active break point now.
1163   ASSERT(debug_info->GetBreakPointCount() > 0);
1164   return true;
1165 }
1166 
1167 
ClearBreakPoint(Handle<Object> break_point_object)1168 void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
1169   HandleScope scope(isolate_);
1170 
1171   DebugInfoListNode* node = debug_info_list_;
1172   while (node != NULL) {
1173     Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),
1174                                                    break_point_object);
1175     if (!result->IsUndefined()) {
1176       // Get information in the break point.
1177       BreakPointInfo* break_point_info = BreakPointInfo::cast(result);
1178       Handle<DebugInfo> debug_info = node->debug_info();
1179 
1180       // Find the break point and clear it.
1181       BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
1182       it.FindBreakLocationFromAddress(debug_info->code()->entry() +
1183           break_point_info->code_position()->value());
1184       it.ClearBreakPoint(break_point_object);
1185 
1186       // If there are no more break points left remove the debug info for this
1187       // function.
1188       if (debug_info->GetBreakPointCount() == 0) {
1189         RemoveDebugInfo(debug_info);
1190       }
1191 
1192       return;
1193     }
1194     node = node->next();
1195   }
1196 }
1197 
1198 
ClearAllBreakPoints()1199 void Debug::ClearAllBreakPoints() {
1200   DebugInfoListNode* node = debug_info_list_;
1201   while (node != NULL) {
1202     // Remove all debug break code.
1203     BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1204     it.ClearAllDebugBreak();
1205     node = node->next();
1206   }
1207 
1208   // Remove all debug info.
1209   while (debug_info_list_ != NULL) {
1210     RemoveDebugInfo(debug_info_list_->debug_info());
1211   }
1212 }
1213 
1214 
FloodWithOneShot(Handle<JSFunction> function)1215 void Debug::FloodWithOneShot(Handle<JSFunction> function) {
1216   PrepareForBreakPoints();
1217 
1218   // Make sure the function is compiled and has set up the debug info.
1219   Handle<SharedFunctionInfo> shared(function->shared());
1220   if (!EnsureDebugInfo(shared, function)) {
1221     // Return if we failed to retrieve the debug info.
1222     return;
1223   }
1224 
1225   // Flood the function with break points.
1226   BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS);
1227   while (!it.Done()) {
1228     it.SetOneShot();
1229     it.Next();
1230   }
1231 }
1232 
1233 
FloodBoundFunctionWithOneShot(Handle<JSFunction> function)1234 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) {
1235   Handle<FixedArray> new_bindings(function->function_bindings());
1236   Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex),
1237                         isolate_);
1238 
1239   if (!bindee.is_null() && bindee->IsJSFunction() &&
1240       !JSFunction::cast(*bindee)->IsNative()) {
1241     Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
1242     Debug::FloodWithOneShot(bindee_function);
1243   }
1244 }
1245 
1246 
FloodHandlerWithOneShot()1247 void Debug::FloodHandlerWithOneShot() {
1248   // Iterate through the JavaScript stack looking for handlers.
1249   StackFrame::Id id = break_frame_id();
1250   if (id == StackFrame::NO_ID) {
1251     // If there is no JavaScript stack don't do anything.
1252     return;
1253   }
1254   for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
1255     JavaScriptFrame* frame = it.frame();
1256     if (frame->HasHandler()) {
1257       // Flood the function with the catch block with break points
1258       FloodWithOneShot(Handle<JSFunction>(frame->function()));
1259       return;
1260     }
1261   }
1262 }
1263 
1264 
ChangeBreakOnException(ExceptionBreakType type,bool enable)1265 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
1266   if (type == BreakUncaughtException) {
1267     break_on_uncaught_exception_ = enable;
1268   } else {
1269     break_on_exception_ = enable;
1270   }
1271 }
1272 
1273 
IsBreakOnException(ExceptionBreakType type)1274 bool Debug::IsBreakOnException(ExceptionBreakType type) {
1275   if (type == BreakUncaughtException) {
1276     return break_on_uncaught_exception_;
1277   } else {
1278     return break_on_exception_;
1279   }
1280 }
1281 
1282 
PromiseOnStack(Isolate * isolate,PromiseOnStack * prev,Handle<JSFunction> getter)1283 PromiseOnStack::PromiseOnStack(Isolate* isolate,
1284                                       PromiseOnStack* prev,
1285                                       Handle<JSFunction> getter)
1286     : isolate_(isolate), prev_(prev) {
1287   handler_ = StackHandler::FromAddress(
1288       Isolate::handler(isolate->thread_local_top()));
1289   getter_ = Handle<JSFunction>::cast(
1290       isolate->global_handles()->Create(*getter));
1291 }
1292 
1293 
~PromiseOnStack()1294 PromiseOnStack::~PromiseOnStack() {
1295   isolate_->global_handles()->Destroy(Handle<Object>::cast(getter_).location());
1296 }
1297 
1298 
PromiseHandlePrologue(Handle<JSFunction> promise_getter)1299 void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) {
1300   PromiseOnStack* prev = thread_local_.promise_on_stack_;
1301   thread_local_.promise_on_stack_ =
1302       new PromiseOnStack(isolate_, prev, promise_getter);
1303 }
1304 
1305 
PromiseHandleEpilogue()1306 void Debug::PromiseHandleEpilogue() {
1307   if (thread_local_.promise_on_stack_ == NULL) return;
1308   PromiseOnStack* prev = thread_local_.promise_on_stack_->prev();
1309   delete thread_local_.promise_on_stack_;
1310   thread_local_.promise_on_stack_ = prev;
1311 }
1312 
1313 
GetPromiseForUncaughtException()1314 Handle<Object> Debug::GetPromiseForUncaughtException() {
1315   Handle<Object> undefined = isolate_->factory()->undefined_value();
1316   if (thread_local_.promise_on_stack_ == NULL) return undefined;
1317   Handle<JSFunction> promise_getter = thread_local_.promise_on_stack_->getter();
1318   StackHandler* promise_catch = thread_local_.promise_on_stack_->handler();
1319   // Find the top-most try-catch handler.
1320   StackHandler* handler = StackHandler::FromAddress(
1321       Isolate::handler(isolate_->thread_local_top()));
1322   while (handler != NULL && !handler->is_catch()) {
1323     handler = handler->next();
1324   }
1325 #ifdef DEBUG
1326   // Make sure that our promise catch handler is in the list of handlers,
1327   // even if it's not the top-most try-catch handler.
1328   StackHandler* temp = handler;
1329   while (temp != promise_catch && !temp->is_catch()) {
1330     temp = temp->next();
1331     CHECK(temp != NULL);
1332   }
1333 #endif  // DEBUG
1334 
1335   if (handler == promise_catch) {
1336     return Execution::Call(
1337         isolate_, promise_getter, undefined, 0, NULL).ToHandleChecked();
1338   }
1339   return undefined;
1340 }
1341 
1342 
PrepareStep(StepAction step_action,int step_count,StackFrame::Id frame_id)1343 void Debug::PrepareStep(StepAction step_action,
1344                         int step_count,
1345                         StackFrame::Id frame_id) {
1346   HandleScope scope(isolate_);
1347 
1348   PrepareForBreakPoints();
1349 
1350   ASSERT(in_debug_scope());
1351 
1352   // Remember this step action and count.
1353   thread_local_.last_step_action_ = step_action;
1354   if (step_action == StepOut) {
1355     // For step out target frame will be found on the stack so there is no need
1356     // to set step counter for it. It's expected to always be 0 for StepOut.
1357     thread_local_.step_count_ = 0;
1358   } else {
1359     thread_local_.step_count_ = step_count;
1360   }
1361 
1362   // Get the frame where the execution has stopped and skip the debug frame if
1363   // any. The debug frame will only be present if execution was stopped due to
1364   // hitting a break point. In other situations (e.g. unhandled exception) the
1365   // debug frame is not present.
1366   StackFrame::Id id = break_frame_id();
1367   if (id == StackFrame::NO_ID) {
1368     // If there is no JavaScript stack don't do anything.
1369     return;
1370   }
1371   if (frame_id != StackFrame::NO_ID) {
1372     id = frame_id;
1373   }
1374   JavaScriptFrameIterator frames_it(isolate_, id);
1375   JavaScriptFrame* frame = frames_it.frame();
1376 
1377   // First of all ensure there is one-shot break points in the top handler
1378   // if any.
1379   FloodHandlerWithOneShot();
1380 
1381   // If the function on the top frame is unresolved perform step out. This will
1382   // be the case when calling unknown functions and having the debugger stopped
1383   // in an unhandled exception.
1384   if (!frame->function()->IsJSFunction()) {
1385     // Step out: Find the calling JavaScript frame and flood it with
1386     // breakpoints.
1387     frames_it.Advance();
1388     // Fill the function to return to with one-shot break points.
1389     JSFunction* function = frames_it.frame()->function();
1390     FloodWithOneShot(Handle<JSFunction>(function));
1391     return;
1392   }
1393 
1394   // Get the debug info (create it if it does not exist).
1395   Handle<JSFunction> function(frame->function());
1396   Handle<SharedFunctionInfo> shared(function->shared());
1397   if (!EnsureDebugInfo(shared, function)) {
1398     // Return if ensuring debug info failed.
1399     return;
1400   }
1401   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1402 
1403   // Find the break location where execution has stopped.
1404   BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS);
1405   // pc points to the instruction after the current one, possibly a break
1406   // location as well. So the "- 1" to exclude it from the search.
1407   it.FindBreakLocationFromAddress(frame->pc() - 1);
1408 
1409   // Compute whether or not the target is a call target.
1410   bool is_load_or_store = false;
1411   bool is_inline_cache_stub = false;
1412   bool is_at_restarted_function = false;
1413   Handle<Code> call_function_stub;
1414 
1415   if (thread_local_.restarter_frame_function_pointer_ == NULL) {
1416     if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
1417       bool is_call_target = false;
1418       Address target = it.rinfo()->target_address();
1419       Code* code = Code::GetCodeFromTargetAddress(target);
1420       if (code->is_call_stub()) {
1421         is_call_target = true;
1422       }
1423       if (code->is_inline_cache_stub()) {
1424         is_inline_cache_stub = true;
1425         is_load_or_store = !is_call_target;
1426       }
1427 
1428       // Check if target code is CallFunction stub.
1429       Code* maybe_call_function_stub = code;
1430       // If there is a breakpoint at this line look at the original code to
1431       // check if it is a CallFunction stub.
1432       if (it.IsDebugBreak()) {
1433         Address original_target = it.original_rinfo()->target_address();
1434         maybe_call_function_stub =
1435             Code::GetCodeFromTargetAddress(original_target);
1436       }
1437       if ((maybe_call_function_stub->kind() == Code::STUB &&
1438            maybe_call_function_stub->major_key() == CodeStub::CallFunction) ||
1439           maybe_call_function_stub->kind() == Code::CALL_IC) {
1440         // Save reference to the code as we may need it to find out arguments
1441         // count for 'step in' later.
1442         call_function_stub = Handle<Code>(maybe_call_function_stub);
1443       }
1444     }
1445   } else {
1446     is_at_restarted_function = true;
1447   }
1448 
1449   // If this is the last break code target step out is the only possibility.
1450   if (it.IsExit() || step_action == StepOut) {
1451     if (step_action == StepOut) {
1452       // Skip step_count frames starting with the current one.
1453       while (step_count-- > 0 && !frames_it.done()) {
1454         frames_it.Advance();
1455       }
1456     } else {
1457       ASSERT(it.IsExit());
1458       frames_it.Advance();
1459     }
1460     // Skip builtin functions on the stack.
1461     while (!frames_it.done() && frames_it.frame()->function()->IsNative()) {
1462       frames_it.Advance();
1463     }
1464     // Step out: If there is a JavaScript caller frame, we need to
1465     // flood it with breakpoints.
1466     if (!frames_it.done()) {
1467       // Fill the function to return to with one-shot break points.
1468       JSFunction* function = frames_it.frame()->function();
1469       FloodWithOneShot(Handle<JSFunction>(function));
1470       // Set target frame pointer.
1471       ActivateStepOut(frames_it.frame());
1472     }
1473   } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
1474                !call_function_stub.is_null() || is_at_restarted_function)
1475              || step_action == StepNext || step_action == StepMin) {
1476     // Step next or step min.
1477 
1478     // Fill the current function with one-shot break points.
1479     FloodWithOneShot(function);
1480 
1481     // Remember source position and frame to handle step next.
1482     thread_local_.last_statement_position_ =
1483         debug_info->code()->SourceStatementPosition(frame->pc());
1484     thread_local_.last_fp_ = frame->UnpaddedFP();
1485   } else {
1486     // If there's restarter frame on top of the stack, just get the pointer
1487     // to function which is going to be restarted.
1488     if (is_at_restarted_function) {
1489       Handle<JSFunction> restarted_function(
1490           JSFunction::cast(*thread_local_.restarter_frame_function_pointer_));
1491       FloodWithOneShot(restarted_function);
1492     } else if (!call_function_stub.is_null()) {
1493       // If it's CallFunction stub ensure target function is compiled and flood
1494       // it with one shot breakpoints.
1495       bool is_call_ic = call_function_stub->kind() == Code::CALL_IC;
1496 
1497       // Find out number of arguments from the stub minor key.
1498       // Reverse lookup required as the minor key cannot be retrieved
1499       // from the code object.
1500       Handle<Object> obj(
1501           isolate_->heap()->code_stubs()->SlowReverseLookup(
1502               *call_function_stub),
1503           isolate_);
1504       ASSERT(!obj.is_null());
1505       ASSERT(!(*obj)->IsUndefined());
1506       ASSERT(obj->IsSmi());
1507       // Get the STUB key and extract major and minor key.
1508       uint32_t key = Smi::cast(*obj)->value();
1509       // Argc in the stub is the number of arguments passed - not the
1510       // expected arguments of the called function.
1511       int call_function_arg_count = is_call_ic
1512           ? CallICStub::ExtractArgcFromMinorKey(CodeStub::MinorKeyFromKey(key))
1513           : CallFunctionStub::ExtractArgcFromMinorKey(
1514               CodeStub::MinorKeyFromKey(key));
1515 
1516       ASSERT(is_call_ic ||
1517              call_function_stub->major_key() == CodeStub::MajorKeyFromKey(key));
1518 
1519       // Find target function on the expression stack.
1520       // Expression stack looks like this (top to bottom):
1521       // argN
1522       // ...
1523       // arg0
1524       // Receiver
1525       // Function to call
1526       int expressions_count = frame->ComputeExpressionsCount();
1527       ASSERT(expressions_count - 2 - call_function_arg_count >= 0);
1528       Object* fun = frame->GetExpression(
1529           expressions_count - 2 - call_function_arg_count);
1530 
1531       // Flood the actual target of call/apply.
1532       if (fun->IsJSFunction()) {
1533         Isolate* isolate = JSFunction::cast(fun)->GetIsolate();
1534         Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply);
1535         Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall);
1536         while (fun->IsJSFunction()) {
1537           Code* code = JSFunction::cast(fun)->shared()->code();
1538           if (code != apply && code != call) break;
1539           fun = frame->GetExpression(
1540               expressions_count - 1 - call_function_arg_count);
1541         }
1542       }
1543 
1544       if (fun->IsJSFunction()) {
1545         Handle<JSFunction> js_function(JSFunction::cast(fun));
1546         if (js_function->shared()->bound()) {
1547           Debug::FloodBoundFunctionWithOneShot(js_function);
1548         } else if (!js_function->IsNative()) {
1549           // Don't step into builtins.
1550           // It will also compile target function if it's not compiled yet.
1551           FloodWithOneShot(js_function);
1552         }
1553       }
1554     }
1555 
1556     // Fill the current function with one-shot break points even for step in on
1557     // a call target as the function called might be a native function for
1558     // which step in will not stop. It also prepares for stepping in
1559     // getters/setters.
1560     FloodWithOneShot(function);
1561 
1562     if (is_load_or_store) {
1563       // Remember source position and frame to handle step in getter/setter. If
1564       // there is a custom getter/setter it will be handled in
1565       // Object::Get/SetPropertyWithCallback, otherwise the step action will be
1566       // propagated on the next Debug::Break.
1567       thread_local_.last_statement_position_ =
1568           debug_info->code()->SourceStatementPosition(frame->pc());
1569       thread_local_.last_fp_ = frame->UnpaddedFP();
1570     }
1571 
1572     // Step in or Step in min
1573     it.PrepareStepIn(isolate_);
1574     ActivateStepIn(frame);
1575   }
1576 }
1577 
1578 
1579 // Check whether the current debug break should be reported to the debugger. It
1580 // is used to have step next and step in only report break back to the debugger
1581 // if on a different frame or in a different statement. In some situations
1582 // there will be several break points in the same statement when the code is
1583 // flooded with one-shot break points. This function helps to perform several
1584 // steps before reporting break back to the debugger.
StepNextContinue(BreakLocationIterator * break_location_iterator,JavaScriptFrame * frame)1585 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
1586                              JavaScriptFrame* frame) {
1587   // StepNext and StepOut shouldn't bring us deeper in code, so last frame
1588   // shouldn't be a parent of current frame.
1589   if (thread_local_.last_step_action_ == StepNext ||
1590       thread_local_.last_step_action_ == StepOut) {
1591     if (frame->fp() < thread_local_.last_fp_) return true;
1592   }
1593 
1594   // If the step last action was step next or step in make sure that a new
1595   // statement is hit.
1596   if (thread_local_.last_step_action_ == StepNext ||
1597       thread_local_.last_step_action_ == StepIn) {
1598     // Never continue if returning from function.
1599     if (break_location_iterator->IsExit()) return false;
1600 
1601     // Continue if we are still on the same frame and in the same statement.
1602     int current_statement_position =
1603         break_location_iterator->code()->SourceStatementPosition(frame->pc());
1604     return thread_local_.last_fp_ == frame->UnpaddedFP() &&
1605         thread_local_.last_statement_position_ == current_statement_position;
1606   }
1607 
1608   // No step next action - don't continue.
1609   return false;
1610 }
1611 
1612 
1613 // Check whether the code object at the specified address is a debug break code
1614 // object.
IsDebugBreak(Address addr)1615 bool Debug::IsDebugBreak(Address addr) {
1616   Code* code = Code::GetCodeFromTargetAddress(addr);
1617   return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK;
1618 }
1619 
1620 
1621 
1622 
1623 
1624 // Simple function for returning the source positions for active break points.
GetSourceBreakLocations(Handle<SharedFunctionInfo> shared,BreakPositionAlignment position_alignment)1625 Handle<Object> Debug::GetSourceBreakLocations(
1626     Handle<SharedFunctionInfo> shared,
1627     BreakPositionAlignment position_alignment) {
1628   Isolate* isolate = shared->GetIsolate();
1629   Heap* heap = isolate->heap();
1630   if (!HasDebugInfo(shared)) {
1631     return Handle<Object>(heap->undefined_value(), isolate);
1632   }
1633   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1634   if (debug_info->GetBreakPointCount() == 0) {
1635     return Handle<Object>(heap->undefined_value(), isolate);
1636   }
1637   Handle<FixedArray> locations =
1638       isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1639   int count = 0;
1640   for (int i = 0; i < debug_info->break_points()->length(); i++) {
1641     if (!debug_info->break_points()->get(i)->IsUndefined()) {
1642       BreakPointInfo* break_point_info =
1643           BreakPointInfo::cast(debug_info->break_points()->get(i));
1644       if (break_point_info->GetBreakPointCount() > 0) {
1645         Smi* position;
1646         switch (position_alignment) {
1647         case STATEMENT_ALIGNED:
1648           position = break_point_info->statement_position();
1649           break;
1650         case BREAK_POSITION_ALIGNED:
1651           position = break_point_info->source_position();
1652           break;
1653         default:
1654           UNREACHABLE();
1655           position = break_point_info->statement_position();
1656         }
1657 
1658         locations->set(count++, position);
1659       }
1660     }
1661   }
1662   return locations;
1663 }
1664 
1665 
1666 // Handle stepping into a function.
HandleStepIn(Handle<JSFunction> function,Handle<Object> holder,Address fp,bool is_constructor)1667 void Debug::HandleStepIn(Handle<JSFunction> function,
1668                          Handle<Object> holder,
1669                          Address fp,
1670                          bool is_constructor) {
1671   Isolate* isolate = function->GetIsolate();
1672   // If the frame pointer is not supplied by the caller find it.
1673   if (fp == 0) {
1674     StackFrameIterator it(isolate);
1675     it.Advance();
1676     // For constructor functions skip another frame.
1677     if (is_constructor) {
1678       ASSERT(it.frame()->is_construct());
1679       it.Advance();
1680     }
1681     fp = it.frame()->fp();
1682   }
1683 
1684   // Flood the function with one-shot break points if it is called from where
1685   // step into was requested.
1686   if (fp == thread_local_.step_into_fp_) {
1687     if (function->shared()->bound()) {
1688       // Handle Function.prototype.bind
1689       Debug::FloodBoundFunctionWithOneShot(function);
1690     } else if (!function->IsNative()) {
1691       // Don't allow step into functions in the native context.
1692       if (function->shared()->code() ==
1693           isolate->builtins()->builtin(Builtins::kFunctionApply) ||
1694           function->shared()->code() ==
1695           isolate->builtins()->builtin(Builtins::kFunctionCall)) {
1696         // Handle function.apply and function.call separately to flood the
1697         // function to be called and not the code for Builtins::FunctionApply or
1698         // Builtins::FunctionCall. The receiver of call/apply is the target
1699         // function.
1700         if (!holder.is_null() && holder->IsJSFunction()) {
1701           Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
1702           if (!js_function->IsNative()) {
1703             Debug::FloodWithOneShot(js_function);
1704           } else if (js_function->shared()->bound()) {
1705             // Handle Function.prototype.bind
1706             Debug::FloodBoundFunctionWithOneShot(js_function);
1707           }
1708         }
1709       } else {
1710         Debug::FloodWithOneShot(function);
1711       }
1712     }
1713   }
1714 }
1715 
1716 
ClearStepping()1717 void Debug::ClearStepping() {
1718   // Clear the various stepping setup.
1719   ClearOneShot();
1720   ClearStepIn();
1721   ClearStepOut();
1722   ClearStepNext();
1723 
1724   // Clear multiple step counter.
1725   thread_local_.step_count_ = 0;
1726 }
1727 
1728 
1729 // Clears all the one-shot break points that are currently set. Normally this
1730 // function is called each time a break point is hit as one shot break points
1731 // are used to support stepping.
ClearOneShot()1732 void Debug::ClearOneShot() {
1733   // The current implementation just runs through all the breakpoints. When the
1734   // last break point for a function is removed that function is automatically
1735   // removed from the list.
1736 
1737   DebugInfoListNode* node = debug_info_list_;
1738   while (node != NULL) {
1739     BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1740     while (!it.Done()) {
1741       it.ClearOneShot();
1742       it.Next();
1743     }
1744     node = node->next();
1745   }
1746 }
1747 
1748 
ActivateStepIn(StackFrame * frame)1749 void Debug::ActivateStepIn(StackFrame* frame) {
1750   ASSERT(!StepOutActive());
1751   thread_local_.step_into_fp_ = frame->UnpaddedFP();
1752 }
1753 
1754 
ClearStepIn()1755 void Debug::ClearStepIn() {
1756   thread_local_.step_into_fp_ = 0;
1757 }
1758 
1759 
ActivateStepOut(StackFrame * frame)1760 void Debug::ActivateStepOut(StackFrame* frame) {
1761   ASSERT(!StepInActive());
1762   thread_local_.step_out_fp_ = frame->UnpaddedFP();
1763 }
1764 
1765 
ClearStepOut()1766 void Debug::ClearStepOut() {
1767   thread_local_.step_out_fp_ = 0;
1768 }
1769 
1770 
ClearStepNext()1771 void Debug::ClearStepNext() {
1772   thread_local_.last_step_action_ = StepNone;
1773   thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
1774   thread_local_.last_fp_ = 0;
1775 }
1776 
1777 
CollectActiveFunctionsFromThread(Isolate * isolate,ThreadLocalTop * top,List<Handle<JSFunction>> * active_functions,Object * active_code_marker)1778 static void CollectActiveFunctionsFromThread(
1779     Isolate* isolate,
1780     ThreadLocalTop* top,
1781     List<Handle<JSFunction> >* active_functions,
1782     Object* active_code_marker) {
1783   // Find all non-optimized code functions with activation frames
1784   // on the stack. This includes functions which have optimized
1785   // activations (including inlined functions) on the stack as the
1786   // non-optimized code is needed for the lazy deoptimization.
1787   for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1788     JavaScriptFrame* frame = it.frame();
1789     if (frame->is_optimized()) {
1790       List<JSFunction*> functions(FLAG_max_inlining_levels + 1);
1791       frame->GetFunctions(&functions);
1792       for (int i = 0; i < functions.length(); i++) {
1793         JSFunction* function = functions[i];
1794         active_functions->Add(Handle<JSFunction>(function));
1795         function->shared()->code()->set_gc_metadata(active_code_marker);
1796       }
1797     } else if (frame->function()->IsJSFunction()) {
1798       JSFunction* function = frame->function();
1799       ASSERT(frame->LookupCode()->kind() == Code::FUNCTION);
1800       active_functions->Add(Handle<JSFunction>(function));
1801       function->shared()->code()->set_gc_metadata(active_code_marker);
1802     }
1803   }
1804 }
1805 
1806 
1807 // Figure out how many bytes of "pc_offset" correspond to actual code by
1808 // subtracting off the bytes that correspond to constant/veneer pools.  See
1809 // Assembler::CheckConstPool() and Assembler::CheckVeneerPool(). Note that this
1810 // is only useful for architectures using constant pools or veneer pools.
ComputeCodeOffsetFromPcOffset(Code * code,int pc_offset)1811 static int ComputeCodeOffsetFromPcOffset(Code *code, int pc_offset) {
1812   ASSERT_EQ(code->kind(), Code::FUNCTION);
1813   ASSERT(!code->has_debug_break_slots());
1814   ASSERT_LE(0, pc_offset);
1815   ASSERT_LT(pc_offset, code->instruction_end() - code->instruction_start());
1816 
1817   int mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
1818              RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
1819   byte *pc = code->instruction_start() + pc_offset;
1820   int code_offset = pc_offset;
1821   for (RelocIterator it(code, mask); !it.done(); it.next()) {
1822     RelocInfo* info = it.rinfo();
1823     if (info->pc() >= pc) break;
1824     ASSERT(RelocInfo::IsConstPool(info->rmode()));
1825     code_offset -= static_cast<int>(info->data());
1826     ASSERT_LE(0, code_offset);
1827   }
1828 
1829   return code_offset;
1830 }
1831 
1832 
1833 // The inverse of ComputeCodeOffsetFromPcOffset.
ComputePcOffsetFromCodeOffset(Code * code,int code_offset)1834 static int ComputePcOffsetFromCodeOffset(Code *code, int code_offset) {
1835   ASSERT_EQ(code->kind(), Code::FUNCTION);
1836 
1837   int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
1838              RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
1839              RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
1840   int reloc = 0;
1841   for (RelocIterator it(code, mask); !it.done(); it.next()) {
1842     RelocInfo* info = it.rinfo();
1843     if (info->pc() - code->instruction_start() - reloc >= code_offset) break;
1844     if (RelocInfo::IsDebugBreakSlot(info->rmode())) {
1845       reloc += Assembler::kDebugBreakSlotLength;
1846     } else {
1847       ASSERT(RelocInfo::IsConstPool(info->rmode()));
1848       reloc += static_cast<int>(info->data());
1849     }
1850   }
1851 
1852   int pc_offset = code_offset + reloc;
1853 
1854   ASSERT_LT(code->instruction_start() + pc_offset, code->instruction_end());
1855 
1856   return pc_offset;
1857 }
1858 
1859 
RedirectActivationsToRecompiledCodeOnThread(Isolate * isolate,ThreadLocalTop * top)1860 static void RedirectActivationsToRecompiledCodeOnThread(
1861     Isolate* isolate,
1862     ThreadLocalTop* top) {
1863   for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1864     JavaScriptFrame* frame = it.frame();
1865 
1866     if (frame->is_optimized() || !frame->function()->IsJSFunction()) continue;
1867 
1868     JSFunction* function = frame->function();
1869 
1870     ASSERT(frame->LookupCode()->kind() == Code::FUNCTION);
1871 
1872     Handle<Code> frame_code(frame->LookupCode());
1873     if (frame_code->has_debug_break_slots()) continue;
1874 
1875     Handle<Code> new_code(function->shared()->code());
1876     if (new_code->kind() != Code::FUNCTION ||
1877         !new_code->has_debug_break_slots()) {
1878       continue;
1879     }
1880 
1881     int old_pc_offset =
1882         static_cast<int>(frame->pc() - frame_code->instruction_start());
1883     int code_offset = ComputeCodeOffsetFromPcOffset(*frame_code, old_pc_offset);
1884     int new_pc_offset = ComputePcOffsetFromCodeOffset(*new_code, code_offset);
1885 
1886     // Compute the equivalent pc in the new code.
1887     byte* new_pc = new_code->instruction_start() + new_pc_offset;
1888 
1889     if (FLAG_trace_deopt) {
1890       PrintF("Replacing code %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
1891              "with %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
1892              "for debugging, "
1893              "changing pc from %08" V8PRIxPTR " to %08" V8PRIxPTR "\n",
1894              reinterpret_cast<intptr_t>(
1895                  frame_code->instruction_start()),
1896              reinterpret_cast<intptr_t>(
1897                  frame_code->instruction_start()) +
1898              frame_code->instruction_size(),
1899              frame_code->instruction_size(),
1900              reinterpret_cast<intptr_t>(new_code->instruction_start()),
1901              reinterpret_cast<intptr_t>(new_code->instruction_start()) +
1902              new_code->instruction_size(),
1903              new_code->instruction_size(),
1904              reinterpret_cast<intptr_t>(frame->pc()),
1905              reinterpret_cast<intptr_t>(new_pc));
1906     }
1907 
1908     // Patch the return address to return into the code with
1909     // debug break slots.
1910     frame->set_pc(new_pc);
1911   }
1912 }
1913 
1914 
1915 class ActiveFunctionsCollector : public ThreadVisitor {
1916  public:
ActiveFunctionsCollector(List<Handle<JSFunction>> * active_functions,Object * active_code_marker)1917   explicit ActiveFunctionsCollector(List<Handle<JSFunction> >* active_functions,
1918                                     Object* active_code_marker)
1919       : active_functions_(active_functions),
1920         active_code_marker_(active_code_marker) { }
1921 
VisitThread(Isolate * isolate,ThreadLocalTop * top)1922   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1923     CollectActiveFunctionsFromThread(isolate,
1924                                      top,
1925                                      active_functions_,
1926                                      active_code_marker_);
1927   }
1928 
1929  private:
1930   List<Handle<JSFunction> >* active_functions_;
1931   Object* active_code_marker_;
1932 };
1933 
1934 
1935 class ActiveFunctionsRedirector : public ThreadVisitor {
1936  public:
VisitThread(Isolate * isolate,ThreadLocalTop * top)1937   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1938     RedirectActivationsToRecompiledCodeOnThread(isolate, top);
1939   }
1940 };
1941 
1942 
EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function)1943 static void EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) {
1944   if (function->code()->kind() == Code::FUNCTION &&
1945       function->code()->has_debug_break_slots()) {
1946     // Nothing to do. Function code already had debug break slots.
1947     return;
1948   }
1949   // Make sure that the shared full code is compiled with debug
1950   // break slots.
1951   if (!function->shared()->code()->has_debug_break_slots()) {
1952     MaybeHandle<Code> code = Compiler::GetCodeForDebugging(function);
1953     // Recompilation can fail.  In that case leave the code as it was.
1954     if (!code.is_null()) function->ReplaceCode(*code.ToHandleChecked());
1955   } else {
1956     // Simply use shared code if it has debug break slots.
1957     function->ReplaceCode(function->shared()->code());
1958   }
1959 }
1960 
1961 
RecompileAndRelocateSuspendedGenerators(const List<Handle<JSGeneratorObject>> & generators)1962 static void RecompileAndRelocateSuspendedGenerators(
1963     const List<Handle<JSGeneratorObject> > &generators) {
1964   for (int i = 0; i < generators.length(); i++) {
1965     Handle<JSFunction> fun(generators[i]->function());
1966 
1967     EnsureFunctionHasDebugBreakSlots(fun);
1968 
1969     int code_offset = generators[i]->continuation();
1970     int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset);
1971     generators[i]->set_continuation(pc_offset);
1972   }
1973 }
1974 
1975 
PrepareForBreakPoints()1976 void Debug::PrepareForBreakPoints() {
1977   // If preparing for the first break point make sure to deoptimize all
1978   // functions as debugging does not work with optimized code.
1979   if (!has_break_points_) {
1980     if (isolate_->concurrent_recompilation_enabled()) {
1981       isolate_->optimizing_compiler_thread()->Flush();
1982     }
1983 
1984     Deoptimizer::DeoptimizeAll(isolate_);
1985 
1986     Handle<Code> lazy_compile = isolate_->builtins()->CompileUnoptimized();
1987 
1988     // There will be at least one break point when we are done.
1989     has_break_points_ = true;
1990 
1991     // Keep the list of activated functions in a handlified list as it
1992     // is used both in GC and non-GC code.
1993     List<Handle<JSFunction> > active_functions(100);
1994 
1995     // A list of all suspended generators.
1996     List<Handle<JSGeneratorObject> > suspended_generators;
1997 
1998     // A list of all generator functions.  We need to recompile all functions,
1999     // but we don't know until after visiting the whole heap which generator
2000     // functions have suspended activations and which do not.  As in the case of
2001     // functions with activations on the stack, we need to be careful with
2002     // generator functions with suspended activations because although they
2003     // should be recompiled, recompilation can fail, and we need to avoid
2004     // leaving the heap in an inconsistent state.
2005     //
2006     // We could perhaps avoid this list and instead re-use the GC metadata
2007     // links.
2008     List<Handle<JSFunction> > generator_functions;
2009 
2010     {
2011       // We are going to iterate heap to find all functions without
2012       // debug break slots.
2013       Heap* heap = isolate_->heap();
2014       heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
2015                               "preparing for breakpoints");
2016       HeapIterator iterator(heap);
2017 
2018       // Ensure no GC in this scope as we are going to use gc_metadata
2019       // field in the Code object to mark active functions.
2020       DisallowHeapAllocation no_allocation;
2021 
2022       Object* active_code_marker = heap->the_hole_value();
2023 
2024       CollectActiveFunctionsFromThread(isolate_,
2025                                        isolate_->thread_local_top(),
2026                                        &active_functions,
2027                                        active_code_marker);
2028       ActiveFunctionsCollector active_functions_collector(&active_functions,
2029                                                           active_code_marker);
2030       isolate_->thread_manager()->IterateArchivedThreads(
2031           &active_functions_collector);
2032 
2033       // Scan the heap for all non-optimized functions which have no
2034       // debug break slots and are not active or inlined into an active
2035       // function and mark them for lazy compilation.
2036       HeapObject* obj = NULL;
2037       while (((obj = iterator.next()) != NULL)) {
2038         if (obj->IsJSFunction()) {
2039           JSFunction* function = JSFunction::cast(obj);
2040           SharedFunctionInfo* shared = function->shared();
2041 
2042           if (!shared->allows_lazy_compilation()) continue;
2043           if (!shared->script()->IsScript()) continue;
2044           if (function->IsNative()) continue;
2045           if (shared->code()->gc_metadata() == active_code_marker) continue;
2046 
2047           if (shared->is_generator()) {
2048             generator_functions.Add(Handle<JSFunction>(function, isolate_));
2049             continue;
2050           }
2051 
2052           Code::Kind kind = function->code()->kind();
2053           if (kind == Code::FUNCTION &&
2054               !function->code()->has_debug_break_slots()) {
2055             function->ReplaceCode(*lazy_compile);
2056             function->shared()->ReplaceCode(*lazy_compile);
2057           } else if (kind == Code::BUILTIN &&
2058               (function->IsInOptimizationQueue() ||
2059                function->IsMarkedForOptimization() ||
2060                function->IsMarkedForConcurrentOptimization())) {
2061             // Abort in-flight compilation.
2062             Code* shared_code = function->shared()->code();
2063             if (shared_code->kind() == Code::FUNCTION &&
2064                 shared_code->has_debug_break_slots()) {
2065               function->ReplaceCode(shared_code);
2066             } else {
2067               function->ReplaceCode(*lazy_compile);
2068               function->shared()->ReplaceCode(*lazy_compile);
2069             }
2070           }
2071         } else if (obj->IsJSGeneratorObject()) {
2072           JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
2073           if (!gen->is_suspended()) continue;
2074 
2075           JSFunction* fun = gen->function();
2076           ASSERT_EQ(fun->code()->kind(), Code::FUNCTION);
2077           if (fun->code()->has_debug_break_slots()) continue;
2078 
2079           int pc_offset = gen->continuation();
2080           ASSERT_LT(0, pc_offset);
2081 
2082           int code_offset =
2083               ComputeCodeOffsetFromPcOffset(fun->code(), pc_offset);
2084 
2085           // This will be fixed after we recompile the functions.
2086           gen->set_continuation(code_offset);
2087 
2088           suspended_generators.Add(Handle<JSGeneratorObject>(gen, isolate_));
2089         }
2090       }
2091 
2092       // Clear gc_metadata field.
2093       for (int i = 0; i < active_functions.length(); i++) {
2094         Handle<JSFunction> function = active_functions[i];
2095         function->shared()->code()->set_gc_metadata(Smi::FromInt(0));
2096       }
2097     }
2098 
2099     // Recompile generator functions that have suspended activations, and
2100     // relocate those activations.
2101     RecompileAndRelocateSuspendedGenerators(suspended_generators);
2102 
2103     // Mark generator functions that didn't have suspended activations for lazy
2104     // recompilation.  Note that this set does not include any active functions.
2105     for (int i = 0; i < generator_functions.length(); i++) {
2106       Handle<JSFunction> &function = generator_functions[i];
2107       if (function->code()->kind() != Code::FUNCTION) continue;
2108       if (function->code()->has_debug_break_slots()) continue;
2109       function->ReplaceCode(*lazy_compile);
2110       function->shared()->ReplaceCode(*lazy_compile);
2111     }
2112 
2113     // Now recompile all functions with activation frames and and
2114     // patch the return address to run in the new compiled code.  It could be
2115     // that some active functions were recompiled already by the suspended
2116     // generator recompilation pass above; a generator with suspended
2117     // activations could also have active activations.  That's fine.
2118     for (int i = 0; i < active_functions.length(); i++) {
2119       Handle<JSFunction> function = active_functions[i];
2120       Handle<SharedFunctionInfo> shared(function->shared());
2121 
2122       // If recompilation is not possible just skip it.
2123       if (shared->is_toplevel()) continue;
2124       if (!shared->allows_lazy_compilation()) continue;
2125       if (shared->code()->kind() == Code::BUILTIN) continue;
2126 
2127       EnsureFunctionHasDebugBreakSlots(function);
2128     }
2129 
2130     RedirectActivationsToRecompiledCodeOnThread(isolate_,
2131                                                 isolate_->thread_local_top());
2132 
2133     ActiveFunctionsRedirector active_functions_redirector;
2134     isolate_->thread_manager()->IterateArchivedThreads(
2135           &active_functions_redirector);
2136   }
2137 }
2138 
2139 
FindSharedFunctionInfoInScript(Handle<Script> script,int position)2140 Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
2141                                               int position) {
2142   // Iterate the heap looking for SharedFunctionInfo generated from the
2143   // script. The inner most SharedFunctionInfo containing the source position
2144   // for the requested break point is found.
2145   // NOTE: This might require several heap iterations. If the SharedFunctionInfo
2146   // which is found is not compiled it is compiled and the heap is iterated
2147   // again as the compilation might create inner functions from the newly
2148   // compiled function and the actual requested break point might be in one of
2149   // these functions.
2150   // NOTE: The below fix-point iteration depends on all functions that cannot be
2151   // compiled lazily without a context to not be compiled at all. Compilation
2152   // will be triggered at points where we do not need a context.
2153   bool done = false;
2154   // The current candidate for the source position:
2155   int target_start_position = RelocInfo::kNoPosition;
2156   Handle<JSFunction> target_function;
2157   Handle<SharedFunctionInfo> target;
2158   Heap* heap = isolate_->heap();
2159   while (!done) {
2160     { // Extra scope for iterator.
2161       HeapIterator iterator(heap);
2162       for (HeapObject* obj = iterator.next();
2163            obj != NULL; obj = iterator.next()) {
2164         bool found_next_candidate = false;
2165         Handle<JSFunction> function;
2166         Handle<SharedFunctionInfo> shared;
2167         if (obj->IsJSFunction()) {
2168           function = Handle<JSFunction>(JSFunction::cast(obj));
2169           shared = Handle<SharedFunctionInfo>(function->shared());
2170           ASSERT(shared->allows_lazy_compilation() || shared->is_compiled());
2171           found_next_candidate = true;
2172         } else if (obj->IsSharedFunctionInfo()) {
2173           shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj));
2174           // Skip functions that we cannot compile lazily without a context,
2175           // which is not available here, because there is no closure.
2176           found_next_candidate = shared->is_compiled() ||
2177               shared->allows_lazy_compilation_without_context();
2178         }
2179         if (!found_next_candidate) continue;
2180         if (shared->script() == *script) {
2181           // If the SharedFunctionInfo found has the requested script data and
2182           // contains the source position it is a candidate.
2183           int start_position = shared->function_token_position();
2184           if (start_position == RelocInfo::kNoPosition) {
2185             start_position = shared->start_position();
2186           }
2187           if (start_position <= position &&
2188               position <= shared->end_position()) {
2189             // If there is no candidate or this function is within the current
2190             // candidate this is the new candidate.
2191             if (target.is_null()) {
2192               target_start_position = start_position;
2193               target_function = function;
2194               target = shared;
2195             } else {
2196               if (target_start_position == start_position &&
2197                   shared->end_position() == target->end_position()) {
2198                 // If a top-level function contains only one function
2199                 // declaration the source for the top-level and the function
2200                 // is the same. In that case prefer the non top-level function.
2201                 if (!shared->is_toplevel()) {
2202                   target_start_position = start_position;
2203                   target_function = function;
2204                   target = shared;
2205                 }
2206               } else if (target_start_position <= start_position &&
2207                          shared->end_position() <= target->end_position()) {
2208                 // This containment check includes equality as a function
2209                 // inside a top-level function can share either start or end
2210                 // position with the top-level function.
2211                 target_start_position = start_position;
2212                 target_function = function;
2213                 target = shared;
2214               }
2215             }
2216           }
2217         }
2218       }  // End for loop.
2219     }  // End no-allocation scope.
2220 
2221     if (target.is_null()) return heap->undefined_value();
2222 
2223     // There will be at least one break point when we are done.
2224     has_break_points_ = true;
2225 
2226     // If the candidate found is compiled we are done.
2227     done = target->is_compiled();
2228     if (!done) {
2229       // If the candidate is not compiled, compile it to reveal any inner
2230       // functions which might contain the requested source position. This
2231       // will compile all inner functions that cannot be compiled without a
2232       // context, because Compiler::BuildFunctionInfo checks whether the
2233       // debugger is active.
2234       MaybeHandle<Code> maybe_result = target_function.is_null()
2235           ? Compiler::GetUnoptimizedCode(target)
2236           : Compiler::GetUnoptimizedCode(target_function);
2237       if (maybe_result.is_null()) return isolate_->heap()->undefined_value();
2238     }
2239   }  // End while loop.
2240 
2241   return *target;
2242 }
2243 
2244 
2245 // Ensures the debug information is present for shared.
EnsureDebugInfo(Handle<SharedFunctionInfo> shared,Handle<JSFunction> function)2246 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
2247                             Handle<JSFunction> function) {
2248   Isolate* isolate = shared->GetIsolate();
2249 
2250   // Return if we already have the debug info for shared.
2251   if (HasDebugInfo(shared)) {
2252     ASSERT(shared->is_compiled());
2253     return true;
2254   }
2255 
2256   // There will be at least one break point when we are done.
2257   has_break_points_ = true;
2258 
2259   // Ensure function is compiled. Return false if this failed.
2260   if (!function.is_null() &&
2261       !Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) {
2262     return false;
2263   }
2264 
2265   // Create the debug info object.
2266   Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared);
2267 
2268   // Add debug info to the list.
2269   DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
2270   node->set_next(debug_info_list_);
2271   debug_info_list_ = node;
2272 
2273   return true;
2274 }
2275 
2276 
RemoveDebugInfo(Handle<DebugInfo> debug_info)2277 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
2278   ASSERT(debug_info_list_ != NULL);
2279   // Run through the debug info objects to find this one and remove it.
2280   DebugInfoListNode* prev = NULL;
2281   DebugInfoListNode* current = debug_info_list_;
2282   while (current != NULL) {
2283     if (*current->debug_info() == *debug_info) {
2284       // Unlink from list. If prev is NULL we are looking at the first element.
2285       if (prev == NULL) {
2286         debug_info_list_ = current->next();
2287       } else {
2288         prev->set_next(current->next());
2289       }
2290       current->debug_info()->shared()->set_debug_info(
2291               isolate_->heap()->undefined_value());
2292       delete current;
2293 
2294       // If there are no more debug info objects there are not more break
2295       // points.
2296       has_break_points_ = debug_info_list_ != NULL;
2297 
2298       return;
2299     }
2300     // Move to next in list.
2301     prev = current;
2302     current = current->next();
2303   }
2304   UNREACHABLE();
2305 }
2306 
2307 
SetAfterBreakTarget(JavaScriptFrame * frame)2308 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
2309   after_break_target_ = NULL;
2310 
2311   if (LiveEdit::SetAfterBreakTarget(this)) return;  // LiveEdit did the job.
2312 
2313   HandleScope scope(isolate_);
2314   PrepareForBreakPoints();
2315 
2316   // Get the executing function in which the debug break occurred.
2317   Handle<JSFunction> function(JSFunction::cast(frame->function()));
2318   Handle<SharedFunctionInfo> shared(function->shared());
2319   if (!EnsureDebugInfo(shared, function)) {
2320     // Return if we failed to retrieve the debug info.
2321     return;
2322   }
2323   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
2324   Handle<Code> code(debug_info->code());
2325   Handle<Code> original_code(debug_info->original_code());
2326 #ifdef DEBUG
2327   // Get the code which is actually executing.
2328   Handle<Code> frame_code(frame->LookupCode());
2329   ASSERT(frame_code.is_identical_to(code));
2330 #endif
2331 
2332   // Find the call address in the running code. This address holds the call to
2333   // either a DebugBreakXXX or to the debug break return entry code if the
2334   // break point is still active after processing the break point.
2335   Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset;
2336 
2337   // Check if the location is at JS exit or debug break slot.
2338   bool at_js_return = false;
2339   bool break_at_js_return_active = false;
2340   bool at_debug_break_slot = false;
2341   RelocIterator it(debug_info->code());
2342   while (!it.done() && !at_js_return && !at_debug_break_slot) {
2343     if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
2344       at_js_return = (it.rinfo()->pc() ==
2345           addr - Assembler::kPatchReturnSequenceAddressOffset);
2346       break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence();
2347     }
2348     if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) {
2349       at_debug_break_slot = (it.rinfo()->pc() ==
2350           addr - Assembler::kPatchDebugBreakSlotAddressOffset);
2351     }
2352     it.next();
2353   }
2354 
2355   // Handle the jump to continue execution after break point depending on the
2356   // break location.
2357   if (at_js_return) {
2358     // If the break point as return is still active jump to the corresponding
2359     // place in the original code. If not the break point was removed during
2360     // break point processing.
2361     if (break_at_js_return_active) {
2362       addr += original_code->instruction_start() - code->instruction_start();
2363     }
2364 
2365     // Move back to where the call instruction sequence started.
2366     after_break_target_ = addr - Assembler::kPatchReturnSequenceAddressOffset;
2367   } else if (at_debug_break_slot) {
2368     // Address of where the debug break slot starts.
2369     addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset;
2370 
2371     // Continue just after the slot.
2372     after_break_target_ = addr + Assembler::kDebugBreakSlotLength;
2373   } else if (IsDebugBreak(Assembler::target_address_at(addr, *code))) {
2374     // We now know that there is still a debug break call at the target address,
2375     // so the break point is still there and the original code will hold the
2376     // address to jump to in order to complete the call which is replaced by a
2377     // call to DebugBreakXXX.
2378 
2379     // Find the corresponding address in the original code.
2380     addr += original_code->instruction_start() - code->instruction_start();
2381 
2382     // Install jump to the call address in the original code. This will be the
2383     // call which was overwritten by the call to DebugBreakXXX.
2384     after_break_target_ = Assembler::target_address_at(addr, *original_code);
2385   } else {
2386     // There is no longer a break point present. Don't try to look in the
2387     // original code as the running code will have the right address. This takes
2388     // care of the case where the last break point is removed from the function
2389     // and therefore no "original code" is available.
2390     after_break_target_ = Assembler::target_address_at(addr, *code);
2391   }
2392 }
2393 
2394 
IsBreakAtReturn(JavaScriptFrame * frame)2395 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
2396   HandleScope scope(isolate_);
2397 
2398   // If there are no break points this cannot be break at return, as
2399   // the debugger statement and stack guard bebug break cannot be at
2400   // return.
2401   if (!has_break_points_) {
2402     return false;
2403   }
2404 
2405   PrepareForBreakPoints();
2406 
2407   // Get the executing function in which the debug break occurred.
2408   Handle<JSFunction> function(JSFunction::cast(frame->function()));
2409   Handle<SharedFunctionInfo> shared(function->shared());
2410   if (!EnsureDebugInfo(shared, function)) {
2411     // Return if we failed to retrieve the debug info.
2412     return false;
2413   }
2414   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
2415   Handle<Code> code(debug_info->code());
2416 #ifdef DEBUG
2417   // Get the code which is actually executing.
2418   Handle<Code> frame_code(frame->LookupCode());
2419   ASSERT(frame_code.is_identical_to(code));
2420 #endif
2421 
2422   // Find the call address in the running code.
2423   Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset;
2424 
2425   // Check if the location is at JS return.
2426   RelocIterator it(debug_info->code());
2427   while (!it.done()) {
2428     if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
2429       return (it.rinfo()->pc() ==
2430           addr - Assembler::kPatchReturnSequenceAddressOffset);
2431     }
2432     it.next();
2433   }
2434   return false;
2435 }
2436 
2437 
FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,LiveEdit::FrameDropMode mode,Object ** restarter_frame_function_pointer)2438 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
2439                                   LiveEdit::FrameDropMode mode,
2440                                   Object** restarter_frame_function_pointer) {
2441   if (mode != LiveEdit::CURRENTLY_SET_MODE) {
2442     thread_local_.frame_drop_mode_ = mode;
2443   }
2444   thread_local_.break_frame_id_ = new_break_frame_id;
2445   thread_local_.restarter_frame_function_pointer_ =
2446       restarter_frame_function_pointer;
2447 }
2448 
2449 
IsDebugGlobal(GlobalObject * global)2450 bool Debug::IsDebugGlobal(GlobalObject* global) {
2451   return is_loaded() && global == debug_context()->global_object();
2452 }
2453 
2454 
ClearMirrorCache()2455 void Debug::ClearMirrorCache() {
2456   PostponeInterruptsScope postpone(isolate_);
2457   HandleScope scope(isolate_);
2458   AssertDebugContext();
2459   Factory* factory = isolate_->factory();
2460   JSObject::SetProperty(isolate_->global_object(),
2461       factory->NewStringFromAsciiChecked("next_handle_"),
2462       handle(Smi::FromInt(0), isolate_),
2463       NONE,
2464       SLOPPY).Check();
2465   JSObject::SetProperty(isolate_->global_object(),
2466       factory->NewStringFromAsciiChecked("mirror_cache_"),
2467       factory->NewJSArray(0, FAST_ELEMENTS),
2468       NONE,
2469       SLOPPY).Check();
2470 }
2471 
2472 
GetLoadedScripts()2473 Handle<FixedArray> Debug::GetLoadedScripts() {
2474   // Create and fill the script cache when the loaded scripts is requested for
2475   // the first time.
2476   if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
2477 
2478   // Perform GC to get unreferenced scripts evicted from the cache before
2479   // returning the content.
2480   isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
2481                                       "Debug::GetLoadedScripts");
2482 
2483   // Get the scripts from the cache.
2484   return script_cache_->GetScripts();
2485 }
2486 
2487 
RecordEvalCaller(Handle<Script> script)2488 void Debug::RecordEvalCaller(Handle<Script> script) {
2489   script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
2490   // For eval scripts add information on the function from which eval was
2491   // called.
2492   StackTraceFrameIterator it(script->GetIsolate());
2493   if (!it.done()) {
2494     script->set_eval_from_shared(it.frame()->function()->shared());
2495     Code* code = it.frame()->LookupCode();
2496     int offset = static_cast<int>(
2497         it.frame()->pc() - code->instruction_start());
2498     script->set_eval_from_instructions_offset(Smi::FromInt(offset));
2499   }
2500 }
2501 
2502 
AfterGarbageCollection()2503 void Debug::AfterGarbageCollection() {
2504   // Generate events for collected scripts.
2505   if (script_cache_ != NULL) {
2506     script_cache_->ProcessCollectedScripts();
2507   }
2508 }
2509 
2510 
MakeJSObject(const char * constructor_name,int argc,Handle<Object> argv[])2511 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
2512                                         int argc,
2513                                         Handle<Object> argv[]) {
2514   AssertDebugContext();
2515   // Create the execution state object.
2516   Handle<Object> constructor = Object::GetProperty(
2517       isolate_, isolate_->global_object(), constructor_name).ToHandleChecked();
2518   ASSERT(constructor->IsJSFunction());
2519   if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
2520   // We do not handle interrupts here.  In particular, termination interrupts.
2521   PostponeInterruptsScope no_interrupts(isolate_);
2522   return Execution::TryCall(Handle<JSFunction>::cast(constructor),
2523                             Handle<JSObject>(debug_context()->global_object()),
2524                             argc,
2525                             argv);
2526 }
2527 
2528 
MakeExecutionState()2529 MaybeHandle<Object> Debug::MakeExecutionState() {
2530   // Create the execution state object.
2531   Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
2532   return MakeJSObject("MakeExecutionState", ARRAY_SIZE(argv), argv);
2533 }
2534 
2535 
MakeBreakEvent(Handle<Object> break_points_hit)2536 MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
2537   Handle<Object> exec_state;
2538   if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2539   // Create the new break event object.
2540   Handle<Object> argv[] = { exec_state, break_points_hit };
2541   return MakeJSObject("MakeBreakEvent", ARRAY_SIZE(argv), argv);
2542 }
2543 
2544 
MakeExceptionEvent(Handle<Object> exception,bool uncaught,Handle<Object> promise)2545 MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
2546                                               bool uncaught,
2547                                               Handle<Object> promise) {
2548   Handle<Object> exec_state;
2549   if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2550   // Create the new exception event object.
2551   Handle<Object> argv[] = { exec_state,
2552                             exception,
2553                             isolate_->factory()->ToBoolean(uncaught),
2554                             promise };
2555   return MakeJSObject("MakeExceptionEvent", ARRAY_SIZE(argv), argv);
2556 }
2557 
2558 
MakeCompileEvent(Handle<Script> script,bool before)2559 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
2560                                             bool before) {
2561   Handle<Object> exec_state;
2562   if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2563   // Create the compile event object.
2564   Handle<Object> script_wrapper = Script::GetWrapper(script);
2565   Handle<Object> argv[] = { exec_state,
2566                             script_wrapper,
2567                             isolate_->factory()->ToBoolean(before) };
2568   return MakeJSObject("MakeCompileEvent", ARRAY_SIZE(argv), argv);
2569 }
2570 
2571 
MakeScriptCollectedEvent(int id)2572 MaybeHandle<Object> Debug::MakeScriptCollectedEvent(int id) {
2573   Handle<Object> exec_state;
2574   if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2575   // Create the script collected event object.
2576   Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
2577   Handle<Object> argv[] = { exec_state, id_object };
2578   return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv);
2579 }
2580 
2581 
OnException(Handle<Object> exception,bool uncaught)2582 void Debug::OnException(Handle<Object> exception, bool uncaught) {
2583   if (in_debug_scope() || ignore_events()) return;
2584 
2585   HandleScope scope(isolate_);
2586   Handle<Object> promise = GetPromiseForUncaughtException();
2587   uncaught |= !promise->IsUndefined();
2588 
2589   // Bail out if exception breaks are not active
2590   if (uncaught) {
2591     // Uncaught exceptions are reported by either flags.
2592     if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
2593   } else {
2594     // Caught exceptions are reported is activated.
2595     if (!break_on_exception_) return;
2596   }
2597 
2598   DebugScope debug_scope(this);
2599   if (debug_scope.failed()) return;
2600 
2601   // Clear all current stepping setup.
2602   ClearStepping();
2603 
2604   // Create the event data object.
2605   Handle<Object> event_data;
2606   // Bail out and don't call debugger if exception.
2607   if (!MakeExceptionEvent(
2608           exception, uncaught, promise).ToHandle(&event_data)) {
2609     return;
2610   }
2611 
2612   // Process debug event.
2613   ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
2614   // Return to continue execution from where the exception was thrown.
2615 }
2616 
2617 
OnDebugBreak(Handle<Object> break_points_hit,bool auto_continue)2618 void Debug::OnDebugBreak(Handle<Object> break_points_hit,
2619                             bool auto_continue) {
2620   // The caller provided for DebugScope.
2621   AssertDebugContext();
2622   // Bail out if there is no listener for this event
2623   if (ignore_events()) return;
2624 
2625   HandleScope scope(isolate_);
2626   // Create the event data object.
2627   Handle<Object> event_data;
2628   // Bail out and don't call debugger if exception.
2629   if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
2630 
2631   // Process debug event.
2632   ProcessDebugEvent(v8::Break,
2633                     Handle<JSObject>::cast(event_data),
2634                     auto_continue);
2635 }
2636 
2637 
OnBeforeCompile(Handle<Script> script)2638 void Debug::OnBeforeCompile(Handle<Script> script) {
2639   if (in_debug_scope() || ignore_events()) return;
2640 
2641   HandleScope scope(isolate_);
2642   DebugScope debug_scope(this);
2643   if (debug_scope.failed()) return;
2644 
2645   // Create the event data object.
2646   Handle<Object> event_data;
2647   // Bail out and don't call debugger if exception.
2648   if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return;
2649 
2650   // Process debug event.
2651   ProcessDebugEvent(v8::BeforeCompile,
2652                     Handle<JSObject>::cast(event_data),
2653                     true);
2654 }
2655 
2656 
2657 // Handle debugger actions when a new script is compiled.
OnAfterCompile(Handle<Script> script,AfterCompileFlags after_compile_flags)2658 void Debug::OnAfterCompile(Handle<Script> script,
2659                            AfterCompileFlags after_compile_flags) {
2660   // Add the newly compiled script to the script cache.
2661   if (script_cache_ != NULL) script_cache_->Add(script);
2662 
2663   // No more to do if not debugging.
2664   if (in_debug_scope() || ignore_events()) return;
2665 
2666   HandleScope scope(isolate_);
2667   // Store whether in debugger before entering debugger.
2668   bool was_in_scope = in_debug_scope();
2669 
2670   DebugScope debug_scope(this);
2671   if (debug_scope.failed()) return;
2672 
2673   // If debugging there might be script break points registered for this
2674   // script. Make sure that these break points are set.
2675 
2676   // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
2677   Handle<String> update_script_break_points_string =
2678       isolate_->factory()->InternalizeOneByteString(
2679           STATIC_ASCII_VECTOR("UpdateScriptBreakPoints"));
2680   Handle<GlobalObject> debug_global(debug_context()->global_object());
2681   Handle<Object> update_script_break_points =
2682       Object::GetProperty(
2683           debug_global, update_script_break_points_string).ToHandleChecked();
2684   if (!update_script_break_points->IsJSFunction()) {
2685     return;
2686   }
2687   ASSERT(update_script_break_points->IsJSFunction());
2688 
2689   // Wrap the script object in a proper JS object before passing it
2690   // to JavaScript.
2691   Handle<Object> wrapper = Script::GetWrapper(script);
2692 
2693   // Call UpdateScriptBreakPoints expect no exceptions.
2694   Handle<Object> argv[] = { wrapper };
2695   if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
2696                          isolate_->js_builtins_object(),
2697                          ARRAY_SIZE(argv),
2698                          argv).is_null()) {
2699     return;
2700   }
2701   // Bail out based on state or if there is no listener for this event
2702   if (was_in_scope && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return;
2703 
2704   // Create the compile state object.
2705   Handle<Object> event_data;
2706   // Bail out and don't call debugger if exception.
2707   if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return;
2708 
2709   // Process debug event.
2710   ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
2711 }
2712 
2713 
OnScriptCollected(int id)2714 void Debug::OnScriptCollected(int id) {
2715   if (in_debug_scope() || ignore_events()) return;
2716 
2717   HandleScope scope(isolate_);
2718   DebugScope debug_scope(this);
2719   if (debug_scope.failed()) return;
2720 
2721   // Create the script collected state object.
2722   Handle<Object> event_data;
2723   // Bail out and don't call debugger if exception.
2724   if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return;
2725 
2726   // Process debug event.
2727   ProcessDebugEvent(v8::ScriptCollected,
2728                     Handle<JSObject>::cast(event_data),
2729                     true);
2730 }
2731 
2732 
ProcessDebugEvent(v8::DebugEvent event,Handle<JSObject> event_data,bool auto_continue)2733 void Debug::ProcessDebugEvent(v8::DebugEvent event,
2734                               Handle<JSObject> event_data,
2735                               bool auto_continue) {
2736   HandleScope scope(isolate_);
2737 
2738   // Create the execution state.
2739   Handle<Object> exec_state;
2740   // Bail out and don't call debugger if exception.
2741   if (!MakeExecutionState().ToHandle(&exec_state)) return;
2742 
2743   // First notify the message handler if any.
2744   if (message_handler_ != NULL) {
2745     NotifyMessageHandler(event,
2746                          Handle<JSObject>::cast(exec_state),
2747                          event_data,
2748                          auto_continue);
2749   }
2750   // Notify registered debug event listener. This can be either a C or
2751   // a JavaScript function. Don't call event listener for v8::Break
2752   // here, if it's only a debug command -- they will be processed later.
2753   if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
2754     CallEventCallback(event, exec_state, event_data, NULL);
2755   }
2756   // Process pending debug commands.
2757   if (event == v8::Break) {
2758     while (!event_command_queue_.IsEmpty()) {
2759       CommandMessage command = event_command_queue_.Get();
2760       if (!event_listener_.is_null()) {
2761         CallEventCallback(v8::BreakForCommand,
2762                           exec_state,
2763                           event_data,
2764                           command.client_data());
2765       }
2766       command.Dispose();
2767     }
2768   }
2769 }
2770 
2771 
CallEventCallback(v8::DebugEvent event,Handle<Object> exec_state,Handle<Object> event_data,v8::Debug::ClientData * client_data)2772 void Debug::CallEventCallback(v8::DebugEvent event,
2773                               Handle<Object> exec_state,
2774                               Handle<Object> event_data,
2775                               v8::Debug::ClientData* client_data) {
2776   if (event_listener_->IsForeign()) {
2777     // Invoke the C debug event listener.
2778     v8::Debug::EventCallback callback =
2779         FUNCTION_CAST<v8::Debug::EventCallback>(
2780             Handle<Foreign>::cast(event_listener_)->foreign_address());
2781     EventDetailsImpl event_details(event,
2782                                    Handle<JSObject>::cast(exec_state),
2783                                    Handle<JSObject>::cast(event_data),
2784                                    event_listener_data_,
2785                                    client_data);
2786     callback(event_details);
2787     ASSERT(!isolate_->has_scheduled_exception());
2788   } else {
2789     // Invoke the JavaScript debug event listener.
2790     ASSERT(event_listener_->IsJSFunction());
2791     Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
2792                               exec_state,
2793                               event_data,
2794                               event_listener_data_ };
2795     Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
2796                        isolate_->global_object(),
2797                        ARRAY_SIZE(argv),
2798                        argv);
2799   }
2800 }
2801 
2802 
GetDebugContext()2803 Handle<Context> Debug::GetDebugContext() {
2804   DebugScope debug_scope(this);
2805   // The global handle may be destroyed soon after.  Return it reboxed.
2806   return handle(*debug_context(), isolate_);
2807 }
2808 
2809 
NotifyMessageHandler(v8::DebugEvent event,Handle<JSObject> exec_state,Handle<JSObject> event_data,bool auto_continue)2810 void Debug::NotifyMessageHandler(v8::DebugEvent event,
2811                                  Handle<JSObject> exec_state,
2812                                  Handle<JSObject> event_data,
2813                                  bool auto_continue) {
2814   // Prevent other interrupts from triggering, for example API callbacks,
2815   // while dispatching message handler callbacks.
2816   PostponeInterruptsScope no_interrupts(isolate_);
2817   ASSERT(is_active_);
2818   HandleScope scope(isolate_);
2819   // Process the individual events.
2820   bool sendEventMessage = false;
2821   switch (event) {
2822     case v8::Break:
2823     case v8::BreakForCommand:
2824       sendEventMessage = !auto_continue;
2825       break;
2826     case v8::Exception:
2827       sendEventMessage = true;
2828       break;
2829     case v8::BeforeCompile:
2830       break;
2831     case v8::AfterCompile:
2832       sendEventMessage = true;
2833       break;
2834     case v8::ScriptCollected:
2835       sendEventMessage = true;
2836       break;
2837     case v8::NewFunction:
2838       break;
2839     default:
2840       UNREACHABLE();
2841   }
2842 
2843   // The debug command interrupt flag might have been set when the command was
2844   // added. It should be enough to clear the flag only once while we are in the
2845   // debugger.
2846   ASSERT(in_debug_scope());
2847   isolate_->stack_guard()->ClearDebugCommand();
2848 
2849   // Notify the debugger that a debug event has occurred unless auto continue is
2850   // active in which case no event is send.
2851   if (sendEventMessage) {
2852     MessageImpl message = MessageImpl::NewEvent(
2853         event,
2854         auto_continue,
2855         Handle<JSObject>::cast(exec_state),
2856         Handle<JSObject>::cast(event_data));
2857     InvokeMessageHandler(message);
2858   }
2859 
2860   // If auto continue don't make the event cause a break, but process messages
2861   // in the queue if any. For script collected events don't even process
2862   // messages in the queue as the execution state might not be what is expected
2863   // by the client.
2864   if ((auto_continue && !has_commands()) || event == v8::ScriptCollected) {
2865     return;
2866   }
2867 
2868   // DebugCommandProcessor goes here.
2869   bool running = auto_continue;
2870 
2871   Handle<Object> cmd_processor_ctor = Object::GetProperty(
2872       isolate_, exec_state, "debugCommandProcessor").ToHandleChecked();
2873   Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
2874   Handle<Object> cmd_processor = Execution::Call(
2875       isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked();
2876   Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
2877       Object::GetProperty(
2878           isolate_, cmd_processor, "processDebugRequest").ToHandleChecked());
2879   Handle<Object> is_running = Object::GetProperty(
2880       isolate_, cmd_processor, "isRunning").ToHandleChecked();
2881 
2882   // Process requests from the debugger.
2883   do {
2884     // Wait for new command in the queue.
2885     command_received_.Wait();
2886 
2887     // Get the command from the queue.
2888     CommandMessage command = command_queue_.Get();
2889     isolate_->logger()->DebugTag(
2890         "Got request from command queue, in interactive loop.");
2891     if (!is_active()) {
2892       // Delete command text and user data.
2893       command.Dispose();
2894       return;
2895     }
2896 
2897     Vector<const uc16> command_text(
2898         const_cast<const uc16*>(command.text().start()),
2899         command.text().length());
2900     Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
2901         command_text).ToHandleChecked();
2902     Handle<Object> request_args[] = { request_text };
2903     Handle<Object> exception;
2904     Handle<Object> answer_value;
2905     Handle<String> answer;
2906     MaybeHandle<Object> maybe_result = Execution::TryCall(
2907         process_debug_request, cmd_processor, 1, request_args, &exception);
2908 
2909     if (maybe_result.ToHandle(&answer_value)) {
2910       if (answer_value->IsUndefined()) {
2911         answer = isolate_->factory()->empty_string();
2912       } else {
2913         answer = Handle<String>::cast(answer_value);
2914       }
2915 
2916       // Log the JSON request/response.
2917       if (FLAG_trace_debug_json) {
2918         PrintF("%s\n", request_text->ToCString().get());
2919         PrintF("%s\n", answer->ToCString().get());
2920       }
2921 
2922       Handle<Object> is_running_args[] = { answer };
2923       maybe_result = Execution::Call(
2924           isolate_, is_running, cmd_processor, 1, is_running_args);
2925       running = maybe_result.ToHandleChecked()->IsTrue();
2926     } else {
2927       answer = Handle<String>::cast(
2928           Execution::ToString(isolate_, exception).ToHandleChecked());
2929     }
2930 
2931     // Return the result.
2932     MessageImpl message = MessageImpl::NewResponse(
2933         event, running, exec_state, event_data, answer, command.client_data());
2934     InvokeMessageHandler(message);
2935     command.Dispose();
2936 
2937     // Return from debug event processing if either the VM is put into the
2938     // running state (through a continue command) or auto continue is active
2939     // and there are no more commands queued.
2940   } while (!running || has_commands());
2941 }
2942 
2943 
SetEventListener(Handle<Object> callback,Handle<Object> data)2944 void Debug::SetEventListener(Handle<Object> callback,
2945                              Handle<Object> data) {
2946   GlobalHandles* global_handles = isolate_->global_handles();
2947 
2948   // Remove existing entry.
2949   GlobalHandles::Destroy(event_listener_.location());
2950   event_listener_ = Handle<Object>();
2951   GlobalHandles::Destroy(event_listener_data_.location());
2952   event_listener_data_ = Handle<Object>();
2953 
2954   // Set new entry.
2955   if (!callback->IsUndefined() && !callback->IsNull()) {
2956     event_listener_ = global_handles->Create(*callback);
2957     if (data.is_null()) data = isolate_->factory()->undefined_value();
2958     event_listener_data_ = global_handles->Create(*data);
2959   }
2960 
2961   UpdateState();
2962 }
2963 
2964 
SetMessageHandler(v8::Debug::MessageHandler handler)2965 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
2966   message_handler_ = handler;
2967   UpdateState();
2968   if (handler == NULL && in_debug_scope()) {
2969     // Send an empty command to the debugger if in a break to make JavaScript
2970     // run again if the debugger is closed.
2971     EnqueueCommandMessage(Vector<const uint16_t>::empty());
2972   }
2973 }
2974 
2975 
2976 
UpdateState()2977 void Debug::UpdateState() {
2978   is_active_ = message_handler_ != NULL || !event_listener_.is_null();
2979   if (is_active_ || in_debug_scope()) {
2980     // Note that the debug context could have already been loaded to
2981     // bootstrap test cases.
2982     isolate_->compilation_cache()->Disable();
2983     is_active_ = Load();
2984   } else if (is_loaded()) {
2985     isolate_->compilation_cache()->Enable();
2986     Unload();
2987   }
2988 }
2989 
2990 
2991 // Calls the registered debug message handler. This callback is part of the
2992 // public API.
InvokeMessageHandler(MessageImpl message)2993 void Debug::InvokeMessageHandler(MessageImpl message) {
2994   if (message_handler_ != NULL) message_handler_(message);
2995 }
2996 
2997 
2998 // Puts a command coming from the public API on the queue.  Creates
2999 // a copy of the command string managed by the debugger.  Up to this
3000 // point, the command data was managed by the API client.  Called
3001 // by the API client thread.
EnqueueCommandMessage(Vector<const uint16_t> command,v8::Debug::ClientData * client_data)3002 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
3003                                   v8::Debug::ClientData* client_data) {
3004   // Need to cast away const.
3005   CommandMessage message = CommandMessage::New(
3006       Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
3007                        command.length()),
3008       client_data);
3009   isolate_->logger()->DebugTag("Put command on command_queue.");
3010   command_queue_.Put(message);
3011   command_received_.Signal();
3012 
3013   // Set the debug command break flag to have the command processed.
3014   if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
3015 }
3016 
3017 
EnqueueDebugCommand(v8::Debug::ClientData * client_data)3018 void Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
3019   CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
3020   event_command_queue_.Put(message);
3021 
3022   // Set the debug command break flag to have the command processed.
3023   if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
3024 }
3025 
3026 
Call(Handle<JSFunction> fun,Handle<Object> data)3027 MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
3028   DebugScope debug_scope(this);
3029   if (debug_scope.failed()) return isolate_->factory()->undefined_value();
3030 
3031   // Create the execution state.
3032   Handle<Object> exec_state;
3033   if (!MakeExecutionState().ToHandle(&exec_state)) {
3034     return isolate_->factory()->undefined_value();
3035   }
3036 
3037   Handle<Object> argv[] = { exec_state, data };
3038   return Execution::Call(
3039       isolate_,
3040       fun,
3041       Handle<Object>(debug_context()->global_proxy(), isolate_),
3042       ARRAY_SIZE(argv),
3043       argv);
3044 }
3045 
3046 
HandleDebugBreak()3047 void Debug::HandleDebugBreak() {
3048   // Ignore debug break during bootstrapping.
3049   if (isolate_->bootstrapper()->IsActive()) return;
3050   // Just continue if breaks are disabled.
3051   if (break_disabled_) return;
3052   // Ignore debug break if debugger is not active.
3053   if (!is_active()) return;
3054 
3055   StackLimitCheck check(isolate_);
3056   if (check.HasOverflowed()) return;
3057 
3058   { JavaScriptFrameIterator it(isolate_);
3059     ASSERT(!it.done());
3060     Object* fun = it.frame()->function();
3061     if (fun && fun->IsJSFunction()) {
3062       // Don't stop in builtin functions.
3063       if (JSFunction::cast(fun)->IsBuiltin()) return;
3064       GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
3065       // Don't stop in debugger functions.
3066       if (IsDebugGlobal(global)) return;
3067     }
3068   }
3069 
3070   // Collect the break state before clearing the flags.
3071   bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
3072                             !isolate_->stack_guard()->CheckDebugBreak();
3073 
3074   isolate_->stack_guard()->ClearDebugBreak();
3075 
3076   ProcessDebugMessages(debug_command_only);
3077 }
3078 
3079 
ProcessDebugMessages(bool debug_command_only)3080 void Debug::ProcessDebugMessages(bool debug_command_only) {
3081   isolate_->stack_guard()->ClearDebugCommand();
3082 
3083   StackLimitCheck check(isolate_);
3084   if (check.HasOverflowed()) return;
3085 
3086   HandleScope scope(isolate_);
3087   DebugScope debug_scope(this);
3088   if (debug_scope.failed()) return;
3089 
3090   // Notify the debug event listeners. Indicate auto continue if the break was
3091   // a debug command break.
3092   OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
3093 }
3094 
3095 
DebugScope(Debug * debug)3096 DebugScope::DebugScope(Debug* debug) : debug_(debug),
3097                                        prev_(debug->debugger_entry()),
3098                                        save_(debug_->isolate_) {
3099   // Link recursive debugger entry.
3100   debug_->thread_local_.current_debug_scope_ = this;
3101 
3102   // Store the previous break id and frame id.
3103   break_id_ = debug_->break_id();
3104   break_frame_id_ = debug_->break_frame_id();
3105 
3106   // Create the new break info. If there is no JavaScript frames there is no
3107   // break frame id.
3108   JavaScriptFrameIterator it(isolate());
3109   bool has_js_frames = !it.done();
3110   debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
3111                                                         : StackFrame::NO_ID;
3112   debug_->SetNextBreakId();
3113 
3114   debug_->UpdateState();
3115   // Make sure that debugger is loaded and enter the debugger context.
3116   // The previous context is kept in save_.
3117   failed_ = !debug_->is_loaded();
3118   if (!failed_) isolate()->set_context(*debug->debug_context());
3119 }
3120 
3121 
3122 
~DebugScope()3123 DebugScope::~DebugScope() {
3124   if (!failed_ && prev_ == NULL) {
3125     // Clear mirror cache when leaving the debugger. Skip this if there is a
3126     // pending exception as clearing the mirror cache calls back into
3127     // JavaScript. This can happen if the v8::Debug::Call is used in which
3128     // case the exception should end up in the calling code.
3129     if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
3130 
3131     // If there are commands in the queue when leaving the debugger request
3132     // that these commands are processed.
3133     if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
3134   }
3135 
3136   // Leaving this debugger entry.
3137   debug_->thread_local_.current_debug_scope_ = prev_;
3138 
3139   // Restore to the previous break state.
3140   debug_->thread_local_.break_frame_id_ = break_frame_id_;
3141   debug_->thread_local_.break_id_ = break_id_;
3142 
3143   debug_->UpdateState();
3144 }
3145 
3146 
NewEvent(DebugEvent event,bool running,Handle<JSObject> exec_state,Handle<JSObject> event_data)3147 MessageImpl MessageImpl::NewEvent(DebugEvent event,
3148                                   bool running,
3149                                   Handle<JSObject> exec_state,
3150                                   Handle<JSObject> event_data) {
3151   MessageImpl message(true, event, running,
3152                       exec_state, event_data, Handle<String>(), NULL);
3153   return message;
3154 }
3155 
3156 
NewResponse(DebugEvent event,bool running,Handle<JSObject> exec_state,Handle<JSObject> event_data,Handle<String> response_json,v8::Debug::ClientData * client_data)3157 MessageImpl MessageImpl::NewResponse(DebugEvent event,
3158                                      bool running,
3159                                      Handle<JSObject> exec_state,
3160                                      Handle<JSObject> event_data,
3161                                      Handle<String> response_json,
3162                                      v8::Debug::ClientData* client_data) {
3163   MessageImpl message(false, event, running,
3164                       exec_state, event_data, response_json, client_data);
3165   return message;
3166 }
3167 
3168 
MessageImpl(bool is_event,DebugEvent event,bool running,Handle<JSObject> exec_state,Handle<JSObject> event_data,Handle<String> response_json,v8::Debug::ClientData * client_data)3169 MessageImpl::MessageImpl(bool is_event,
3170                          DebugEvent event,
3171                          bool running,
3172                          Handle<JSObject> exec_state,
3173                          Handle<JSObject> event_data,
3174                          Handle<String> response_json,
3175                          v8::Debug::ClientData* client_data)
3176     : is_event_(is_event),
3177       event_(event),
3178       running_(running),
3179       exec_state_(exec_state),
3180       event_data_(event_data),
3181       response_json_(response_json),
3182       client_data_(client_data) {}
3183 
3184 
IsEvent() const3185 bool MessageImpl::IsEvent() const {
3186   return is_event_;
3187 }
3188 
3189 
IsResponse() const3190 bool MessageImpl::IsResponse() const {
3191   return !is_event_;
3192 }
3193 
3194 
GetEvent() const3195 DebugEvent MessageImpl::GetEvent() const {
3196   return event_;
3197 }
3198 
3199 
WillStartRunning() const3200 bool MessageImpl::WillStartRunning() const {
3201   return running_;
3202 }
3203 
3204 
GetExecutionState() const3205 v8::Handle<v8::Object> MessageImpl::GetExecutionState() const {
3206   return v8::Utils::ToLocal(exec_state_);
3207 }
3208 
3209 
GetIsolate() const3210 v8::Isolate* MessageImpl::GetIsolate() const {
3211   return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
3212 }
3213 
3214 
GetEventData() const3215 v8::Handle<v8::Object> MessageImpl::GetEventData() const {
3216   return v8::Utils::ToLocal(event_data_);
3217 }
3218 
3219 
GetJSON() const3220 v8::Handle<v8::String> MessageImpl::GetJSON() const {
3221   Isolate* isolate = event_data_->GetIsolate();
3222   v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
3223 
3224   if (IsEvent()) {
3225     // Call toJSONProtocol on the debug event object.
3226     Handle<Object> fun = Object::GetProperty(
3227         isolate, event_data_, "toJSONProtocol").ToHandleChecked();
3228     if (!fun->IsJSFunction()) {
3229       return v8::Handle<v8::String>();
3230     }
3231 
3232     MaybeHandle<Object> maybe_json =
3233         Execution::TryCall(Handle<JSFunction>::cast(fun), event_data_, 0, NULL);
3234     Handle<Object> json;
3235     if (!maybe_json.ToHandle(&json) || !json->IsString()) {
3236       return v8::Handle<v8::String>();
3237     }
3238     return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
3239   } else {
3240     return v8::Utils::ToLocal(response_json_);
3241   }
3242 }
3243 
3244 
GetEventContext() const3245 v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
3246   Isolate* isolate = event_data_->GetIsolate();
3247   v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
3248   // Isolate::context() may be NULL when "script collected" event occures.
3249   ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected);
3250   return context;
3251 }
3252 
3253 
GetClientData() const3254 v8::Debug::ClientData* MessageImpl::GetClientData() const {
3255   return client_data_;
3256 }
3257 
3258 
EventDetailsImpl(DebugEvent event,Handle<JSObject> exec_state,Handle<JSObject> event_data,Handle<Object> callback_data,v8::Debug::ClientData * client_data)3259 EventDetailsImpl::EventDetailsImpl(DebugEvent event,
3260                                    Handle<JSObject> exec_state,
3261                                    Handle<JSObject> event_data,
3262                                    Handle<Object> callback_data,
3263                                    v8::Debug::ClientData* client_data)
3264     : event_(event),
3265       exec_state_(exec_state),
3266       event_data_(event_data),
3267       callback_data_(callback_data),
3268       client_data_(client_data) {}
3269 
3270 
GetEvent() const3271 DebugEvent EventDetailsImpl::GetEvent() const {
3272   return event_;
3273 }
3274 
3275 
GetExecutionState() const3276 v8::Handle<v8::Object> EventDetailsImpl::GetExecutionState() const {
3277   return v8::Utils::ToLocal(exec_state_);
3278 }
3279 
3280 
GetEventData() const3281 v8::Handle<v8::Object> EventDetailsImpl::GetEventData() const {
3282   return v8::Utils::ToLocal(event_data_);
3283 }
3284 
3285 
GetEventContext() const3286 v8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const {
3287   return GetDebugEventContext(exec_state_->GetIsolate());
3288 }
3289 
3290 
GetCallbackData() const3291 v8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const {
3292   return v8::Utils::ToLocal(callback_data_);
3293 }
3294 
3295 
GetClientData() const3296 v8::Debug::ClientData* EventDetailsImpl::GetClientData() const {
3297   return client_data_;
3298 }
3299 
3300 
CommandMessage()3301 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
3302                                    client_data_(NULL) {
3303 }
3304 
3305 
CommandMessage(const Vector<uint16_t> & text,v8::Debug::ClientData * data)3306 CommandMessage::CommandMessage(const Vector<uint16_t>& text,
3307                                v8::Debug::ClientData* data)
3308     : text_(text),
3309       client_data_(data) {
3310 }
3311 
3312 
Dispose()3313 void CommandMessage::Dispose() {
3314   text_.Dispose();
3315   delete client_data_;
3316   client_data_ = NULL;
3317 }
3318 
3319 
New(const Vector<uint16_t> & command,v8::Debug::ClientData * data)3320 CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
3321                                    v8::Debug::ClientData* data) {
3322   return CommandMessage(command.Clone(), data);
3323 }
3324 
3325 
CommandMessageQueue(int size)3326 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
3327                                                      size_(size) {
3328   messages_ = NewArray<CommandMessage>(size);
3329 }
3330 
3331 
~CommandMessageQueue()3332 CommandMessageQueue::~CommandMessageQueue() {
3333   while (!IsEmpty()) Get().Dispose();
3334   DeleteArray(messages_);
3335 }
3336 
3337 
Get()3338 CommandMessage CommandMessageQueue::Get() {
3339   ASSERT(!IsEmpty());
3340   int result = start_;
3341   start_ = (start_ + 1) % size_;
3342   return messages_[result];
3343 }
3344 
3345 
Put(const CommandMessage & message)3346 void CommandMessageQueue::Put(const CommandMessage& message) {
3347   if ((end_ + 1) % size_ == start_) {
3348     Expand();
3349   }
3350   messages_[end_] = message;
3351   end_ = (end_ + 1) % size_;
3352 }
3353 
3354 
Expand()3355 void CommandMessageQueue::Expand() {
3356   CommandMessageQueue new_queue(size_ * 2);
3357   while (!IsEmpty()) {
3358     new_queue.Put(Get());
3359   }
3360   CommandMessage* array_to_free = messages_;
3361   *this = new_queue;
3362   new_queue.messages_ = array_to_free;
3363   // Make the new_queue empty so that it doesn't call Dispose on any messages.
3364   new_queue.start_ = new_queue.end_;
3365   // Automatic destructor called on new_queue, freeing array_to_free.
3366 }
3367 
3368 
LockingCommandMessageQueue(Logger * logger,int size)3369 LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
3370     : logger_(logger), queue_(size) {}
3371 
3372 
IsEmpty() const3373 bool LockingCommandMessageQueue::IsEmpty() const {
3374   LockGuard<Mutex> lock_guard(&mutex_);
3375   return queue_.IsEmpty();
3376 }
3377 
3378 
Get()3379 CommandMessage LockingCommandMessageQueue::Get() {
3380   LockGuard<Mutex> lock_guard(&mutex_);
3381   CommandMessage result = queue_.Get();
3382   logger_->DebugEvent("Get", result.text());
3383   return result;
3384 }
3385 
3386 
Put(const CommandMessage & message)3387 void LockingCommandMessageQueue::Put(const CommandMessage& message) {
3388   LockGuard<Mutex> lock_guard(&mutex_);
3389   queue_.Put(message);
3390   logger_->DebugEvent("Put", message.text());
3391 }
3392 
3393 
Clear()3394 void LockingCommandMessageQueue::Clear() {
3395   LockGuard<Mutex> lock_guard(&mutex_);
3396   queue_.Clear();
3397 }
3398 
3399 } }  // namespace v8::internal
3400