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