debug.cc revision 3100271588b61cbc1dc472a3f2f105d2eed8497f
1// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "api.h"
31#include "arguments.h"
32#include "bootstrapper.h"
33#include "code-stubs.h"
34#include "compilation-cache.h"
35#include "compiler.h"
36#include "debug.h"
37#include "execution.h"
38#include "global-handles.h"
39#include "ic.h"
40#include "ic-inl.h"
41#include "natives.h"
42#include "stub-cache.h"
43#include "log.h"
44
45#include "../include/v8-debug.h"
46
47namespace v8 {
48namespace internal {
49
50#ifdef ENABLE_DEBUGGER_SUPPORT
51static void PrintLn(v8::Local<v8::Value> value) {
52  v8::Local<v8::String> s = value->ToString();
53  char* data = NewArray<char>(s->Length() + 1);
54  if (data == NULL) {
55    V8::FatalProcessOutOfMemory("PrintLn");
56    return;
57  }
58  s->WriteAscii(data);
59  PrintF("%s\n", data);
60  DeleteArray(data);
61}
62
63
64static Handle<Code> ComputeCallDebugBreak(int argc) {
65  CALL_HEAP_FUNCTION(StubCache::ComputeCallDebugBreak(argc), Code);
66}
67
68
69static Handle<Code> ComputeCallDebugPrepareStepIn(int argc) {
70  CALL_HEAP_FUNCTION(StubCache::ComputeCallDebugPrepareStepIn(argc), Code);
71}
72
73
74BreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info,
75                                             BreakLocatorType type) {
76  debug_info_ = debug_info;
77  type_ = type;
78  reloc_iterator_ = NULL;
79  reloc_iterator_original_ = NULL;
80  Reset();  // Initialize the rest of the member variables.
81}
82
83
84BreakLocationIterator::~BreakLocationIterator() {
85  ASSERT(reloc_iterator_ != NULL);
86  ASSERT(reloc_iterator_original_ != NULL);
87  delete reloc_iterator_;
88  delete reloc_iterator_original_;
89}
90
91
92void BreakLocationIterator::Next() {
93  AssertNoAllocation nogc;
94  ASSERT(!RinfoDone());
95
96  // Iterate through reloc info for code and original code stopping at each
97  // breakable code target.
98  bool first = break_point_ == -1;
99  while (!RinfoDone()) {
100    if (!first) RinfoNext();
101    first = false;
102    if (RinfoDone()) return;
103
104    // Whenever a statement position or (plain) position is passed update the
105    // current value of these.
106    if (RelocInfo::IsPosition(rmode())) {
107      if (RelocInfo::IsStatementPosition(rmode())) {
108        statement_position_ = static_cast<int>(
109            rinfo()->data() - debug_info_->shared()->start_position());
110      }
111      // Always update the position as we don't want that to be before the
112      // statement position.
113      position_ = static_cast<int>(
114          rinfo()->data() - debug_info_->shared()->start_position());
115      ASSERT(position_ >= 0);
116      ASSERT(statement_position_ >= 0);
117    }
118
119    // Check for breakable code target. Look in the original code as setting
120    // break points can cause the code targets in the running (debugged) code to
121    // be of a different kind than in the original code.
122    if (RelocInfo::IsCodeTarget(rmode())) {
123      Address target = original_rinfo()->target_address();
124      Code* code = Code::GetCodeFromTargetAddress(target);
125      if (code->is_inline_cache_stub() || RelocInfo::IsConstructCall(rmode())) {
126        break_point_++;
127        return;
128      }
129      if (code->kind() == Code::STUB) {
130        if (IsDebuggerStatement()) {
131          break_point_++;
132          return;
133        }
134        if (type_ == ALL_BREAK_LOCATIONS) {
135          if (Debug::IsBreakStub(code)) {
136            break_point_++;
137            return;
138          }
139        } else {
140          ASSERT(type_ == SOURCE_BREAK_LOCATIONS);
141          if (Debug::IsSourceBreakStub(code)) {
142            break_point_++;
143            return;
144          }
145        }
146      }
147    }
148
149    // Check for break at return.
150    if (RelocInfo::IsJSReturn(rmode())) {
151      // Set the positions to the end of the function.
152      if (debug_info_->shared()->HasSourceCode()) {
153        position_ = debug_info_->shared()->end_position() -
154                    debug_info_->shared()->start_position();
155      } else {
156        position_ = 0;
157      }
158      statement_position_ = position_;
159      break_point_++;
160      return;
161    }
162  }
163}
164
165
166void BreakLocationIterator::Next(int count) {
167  while (count > 0) {
168    Next();
169    count--;
170  }
171}
172
173
174// Find the break point closest to the supplied address.
175void BreakLocationIterator::FindBreakLocationFromAddress(Address pc) {
176  // Run through all break points to locate the one closest to the address.
177  int closest_break_point = 0;
178  int distance = kMaxInt;
179  while (!Done()) {
180    // Check if this break point is closer that what was previously found.
181    if (this->pc() < pc && pc - this->pc() < distance) {
182      closest_break_point = break_point();
183      distance = static_cast<int>(pc - this->pc());
184      // Check whether we can't get any closer.
185      if (distance == 0) break;
186    }
187    Next();
188  }
189
190  // Move to the break point found.
191  Reset();
192  Next(closest_break_point);
193}
194
195
196// Find the break point closest to the supplied source position.
197void BreakLocationIterator::FindBreakLocationFromPosition(int position) {
198  // Run through all break points to locate the one closest to the source
199  // position.
200  int closest_break_point = 0;
201  int distance = kMaxInt;
202  while (!Done()) {
203    // Check if this break point is closer that what was previously found.
204    if (position <= statement_position() &&
205        statement_position() - position < distance) {
206      closest_break_point = break_point();
207      distance = statement_position() - position;
208      // Check whether we can't get any closer.
209      if (distance == 0) break;
210    }
211    Next();
212  }
213
214  // Move to the break point found.
215  Reset();
216  Next(closest_break_point);
217}
218
219
220void BreakLocationIterator::Reset() {
221  // Create relocation iterators for the two code objects.
222  if (reloc_iterator_ != NULL) delete reloc_iterator_;
223  if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_;
224  reloc_iterator_ = new RelocIterator(debug_info_->code());
225  reloc_iterator_original_ = new RelocIterator(debug_info_->original_code());
226
227  // Position at the first break point.
228  break_point_ = -1;
229  position_ = 1;
230  statement_position_ = 1;
231  Next();
232}
233
234
235bool BreakLocationIterator::Done() const {
236  return RinfoDone();
237}
238
239
240void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
241  // If there is not already a real break point here patch code with debug
242  // break.
243  if (!HasBreakPoint()) {
244    SetDebugBreak();
245  }
246  ASSERT(IsDebugBreak() || IsDebuggerStatement());
247  // Set the break point information.
248  DebugInfo::SetBreakPoint(debug_info_, code_position(),
249                           position(), statement_position(),
250                           break_point_object);
251}
252
253
254void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
255  // Clear the break point information.
256  DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
257  // If there are no more break points here remove the debug break.
258  if (!HasBreakPoint()) {
259    ClearDebugBreak();
260    ASSERT(!IsDebugBreak());
261  }
262}
263
264
265void BreakLocationIterator::SetOneShot() {
266  // Debugger statement always calls debugger. No need to modify it.
267  if (IsDebuggerStatement()) {
268    return;
269  }
270
271  // If there is a real break point here no more to do.
272  if (HasBreakPoint()) {
273    ASSERT(IsDebugBreak());
274    return;
275  }
276
277  // Patch code with debug break.
278  SetDebugBreak();
279}
280
281
282void BreakLocationIterator::ClearOneShot() {
283  // Debugger statement always calls debugger. No need to modify it.
284  if (IsDebuggerStatement()) {
285    return;
286  }
287
288  // If there is a real break point here no more to do.
289  if (HasBreakPoint()) {
290    ASSERT(IsDebugBreak());
291    return;
292  }
293
294  // Patch code removing debug break.
295  ClearDebugBreak();
296  ASSERT(!IsDebugBreak());
297}
298
299
300void BreakLocationIterator::SetDebugBreak() {
301  // Debugger statement always calls debugger. No need to modify it.
302  if (IsDebuggerStatement()) {
303    return;
304  }
305
306  // If there is already a break point here just return. This might happen if
307  // the same code is flooded with break points twice. Flooding the same
308  // function twice might happen when stepping in a function with an exception
309  // handler as the handler and the function is the same.
310  if (IsDebugBreak()) {
311    return;
312  }
313
314  if (RelocInfo::IsJSReturn(rmode())) {
315    // Patch the frame exit code with a break point.
316    SetDebugBreakAtReturn();
317  } else {
318    // Patch the IC call.
319    SetDebugBreakAtIC();
320  }
321  ASSERT(IsDebugBreak());
322}
323
324
325void BreakLocationIterator::ClearDebugBreak() {
326  // Debugger statement always calls debugger. No need to modify it.
327  if (IsDebuggerStatement()) {
328    return;
329  }
330
331  if (RelocInfo::IsJSReturn(rmode())) {
332    // Restore the frame exit code.
333    ClearDebugBreakAtReturn();
334  } else {
335    // Patch the IC call.
336    ClearDebugBreakAtIC();
337  }
338  ASSERT(!IsDebugBreak());
339}
340
341
342void BreakLocationIterator::PrepareStepIn() {
343  HandleScope scope;
344
345  // Step in can only be prepared if currently positioned on an IC call,
346  // construct call or CallFunction stub call.
347  Address target = rinfo()->target_address();
348  Handle<Code> code(Code::GetCodeFromTargetAddress(target));
349  if (code->is_call_stub()) {
350    // Step in through IC call is handled by the runtime system. Therefore make
351    // sure that the any current IC is cleared and the runtime system is
352    // called. If the executing code has a debug break at the location change
353    // the call in the original code as it is the code there that will be
354    // executed in place of the debug break call.
355    Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count());
356    if (IsDebugBreak()) {
357      original_rinfo()->set_target_address(stub->entry());
358    } else {
359      rinfo()->set_target_address(stub->entry());
360    }
361  } else {
362#ifdef DEBUG
363    // All the following stuff is needed only for assertion checks so the code
364    // is wrapped in ifdef.
365    Handle<Code> maybe_call_function_stub = code;
366    if (IsDebugBreak()) {
367      Address original_target = original_rinfo()->target_address();
368      maybe_call_function_stub =
369          Handle<Code>(Code::GetCodeFromTargetAddress(original_target));
370    }
371    bool is_call_function_stub =
372        (maybe_call_function_stub->kind() == Code::STUB &&
373         maybe_call_function_stub->major_key() == CodeStub::CallFunction);
374
375    // Step in through construct call requires no changes to the running code.
376    // Step in through getters/setters should already be prepared as well
377    // because caller of this function (Debug::PrepareStep) is expected to
378    // flood the top frame's function with one shot breakpoints.
379    // Step in through CallFunction stub should also be prepared by caller of
380    // this function (Debug::PrepareStep) which should flood target function
381    // with breakpoints.
382    ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub()
383           || is_call_function_stub);
384#endif
385  }
386}
387
388
389// Check whether the break point is at a position which will exit the function.
390bool BreakLocationIterator::IsExit() const {
391  return (RelocInfo::IsJSReturn(rmode()));
392}
393
394
395bool BreakLocationIterator::HasBreakPoint() {
396  return debug_info_->HasBreakPoint(code_position());
397}
398
399
400// Check whether there is a debug break at the current position.
401bool BreakLocationIterator::IsDebugBreak() {
402  if (RelocInfo::IsJSReturn(rmode())) {
403    return IsDebugBreakAtReturn();
404  } else {
405    return Debug::IsDebugBreak(rinfo()->target_address());
406  }
407}
408
409
410void BreakLocationIterator::SetDebugBreakAtIC() {
411  // Patch the original code with the current address as the current address
412  // might have changed by the inline caching since the code was copied.
413  original_rinfo()->set_target_address(rinfo()->target_address());
414
415  RelocInfo::Mode mode = rmode();
416  if (RelocInfo::IsCodeTarget(mode)) {
417    Address target = rinfo()->target_address();
418    Handle<Code> code(Code::GetCodeFromTargetAddress(target));
419
420    // Patch the code to invoke the builtin debug break function matching the
421    // calling convention used by the call site.
422    Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode));
423    rinfo()->set_target_address(dbgbrk_code->entry());
424
425    // For stubs that refer back to an inlined version clear the cached map for
426    // the inlined case to always go through the IC. As long as the break point
427    // is set the patching performed by the runtime system will take place in
428    // the code copy and will therefore have no effect on the running code
429    // keeping it from using the inlined code.
430    if (code->is_keyed_load_stub()) KeyedLoadIC::ClearInlinedVersion(pc());
431    if (code->is_keyed_store_stub()) KeyedStoreIC::ClearInlinedVersion(pc());
432  }
433}
434
435
436void BreakLocationIterator::ClearDebugBreakAtIC() {
437  // Patch the code to the original invoke.
438  rinfo()->set_target_address(original_rinfo()->target_address());
439
440  RelocInfo::Mode mode = rmode();
441  if (RelocInfo::IsCodeTarget(mode)) {
442    Address target = original_rinfo()->target_address();
443    Handle<Code> code(Code::GetCodeFromTargetAddress(target));
444
445    // Restore the inlined version of keyed stores to get back to the
446    // fast case.  We need to patch back the keyed store because no
447    // patching happens when running normally.  For keyed loads, the
448    // map check will get patched back when running normally after ICs
449    // have been cleared at GC.
450    if (code->is_keyed_store_stub()) KeyedStoreIC::RestoreInlinedVersion(pc());
451  }
452}
453
454
455bool BreakLocationIterator::IsDebuggerStatement() {
456  if (RelocInfo::IsCodeTarget(rmode())) {
457    Address target = original_rinfo()->target_address();
458    Code* code = Code::GetCodeFromTargetAddress(target);
459    if (code->kind() == Code::STUB) {
460      CodeStub::Major major_key = code->major_key();
461      return (major_key == CodeStub::DebuggerStatement);
462    }
463  }
464  return false;
465}
466
467
468Object* BreakLocationIterator::BreakPointObjects() {
469  return debug_info_->GetBreakPointObjects(code_position());
470}
471
472
473// Clear out all the debug break code. This is ONLY supposed to be used when
474// shutting down the debugger as it will leave the break point information in
475// DebugInfo even though the code is patched back to the non break point state.
476void BreakLocationIterator::ClearAllDebugBreak() {
477  while (!Done()) {
478    ClearDebugBreak();
479    Next();
480  }
481}
482
483
484bool BreakLocationIterator::RinfoDone() const {
485  ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
486  return reloc_iterator_->done();
487}
488
489
490void BreakLocationIterator::RinfoNext() {
491  reloc_iterator_->next();
492  reloc_iterator_original_->next();
493#ifdef DEBUG
494  ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
495  if (!reloc_iterator_->done()) {
496    ASSERT(rmode() == original_rmode());
497  }
498#endif
499}
500
501
502bool Debug::has_break_points_ = false;
503ScriptCache* Debug::script_cache_ = NULL;
504DebugInfoListNode* Debug::debug_info_list_ = NULL;
505
506
507// Threading support.
508void Debug::ThreadInit() {
509  thread_local_.break_count_ = 0;
510  thread_local_.break_id_ = 0;
511  thread_local_.break_frame_id_ = StackFrame::NO_ID;
512  thread_local_.last_step_action_ = StepNone;
513  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
514  thread_local_.step_count_ = 0;
515  thread_local_.last_fp_ = 0;
516  thread_local_.step_into_fp_ = 0;
517  thread_local_.step_out_fp_ = 0;
518  thread_local_.after_break_target_ = 0;
519  thread_local_.debugger_entry_ = NULL;
520  thread_local_.pending_interrupts_ = 0;
521}
522
523
524JSCallerSavedBuffer Debug::registers_;
525Debug::ThreadLocal Debug::thread_local_;
526
527
528char* Debug::ArchiveDebug(char* storage) {
529  char* to = storage;
530  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
531  to += sizeof(ThreadLocal);
532  memcpy(to, reinterpret_cast<char*>(&registers_), sizeof(registers_));
533  ThreadInit();
534  ASSERT(to <= storage + ArchiveSpacePerThread());
535  return storage + ArchiveSpacePerThread();
536}
537
538
539char* Debug::RestoreDebug(char* storage) {
540  char* from = storage;
541  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
542  from += sizeof(ThreadLocal);
543  memcpy(reinterpret_cast<char*>(&registers_), from, sizeof(registers_));
544  ASSERT(from <= storage + ArchiveSpacePerThread());
545  return storage + ArchiveSpacePerThread();
546}
547
548
549int Debug::ArchiveSpacePerThread() {
550  return sizeof(ThreadLocal) + sizeof(registers_);
551}
552
553
554// Default break enabled.
555bool Debug::disable_break_ = false;
556
557// Default call debugger on uncaught exception.
558bool Debug::break_on_exception_ = false;
559bool Debug::break_on_uncaught_exception_ = true;
560
561Handle<Context> Debug::debug_context_ = Handle<Context>();
562Code* Debug::debug_break_return_ = NULL;
563
564
565void ScriptCache::Add(Handle<Script> script) {
566  // Create an entry in the hash map for the script.
567  int id = Smi::cast(script->id())->value();
568  HashMap::Entry* entry =
569      HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
570  if (entry->value != NULL) {
571    ASSERT(*script == *reinterpret_cast<Script**>(entry->value));
572    return;
573  }
574
575  // Globalize the script object, make it weak and use the location of the
576  // global handle as the value in the hash map.
577  Handle<Script> script_ =
578      Handle<Script>::cast((GlobalHandles::Create(*script)));
579  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
580                          this, ScriptCache::HandleWeakScript);
581  entry->value = script_.location();
582}
583
584
585Handle<FixedArray> ScriptCache::GetScripts() {
586  Handle<FixedArray> instances = Factory::NewFixedArray(occupancy());
587  int count = 0;
588  for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
589    ASSERT(entry->value != NULL);
590    if (entry->value != NULL) {
591      instances->set(count, *reinterpret_cast<Script**>(entry->value));
592      count++;
593    }
594  }
595  return instances;
596}
597
598
599void ScriptCache::ProcessCollectedScripts() {
600  for (int i = 0; i < collected_scripts_.length(); i++) {
601    Debugger::OnScriptCollected(collected_scripts_[i]);
602  }
603  collected_scripts_.Clear();
604}
605
606
607void ScriptCache::Clear() {
608  // Iterate the script cache to get rid of all the weak handles.
609  for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
610    ASSERT(entry != NULL);
611    Object** location = reinterpret_cast<Object**>(entry->value);
612    ASSERT((*location)->IsScript());
613    GlobalHandles::ClearWeakness(location);
614    GlobalHandles::Destroy(location);
615  }
616  // Clear the content of the hash map.
617  HashMap::Clear();
618}
619
620
621void ScriptCache::HandleWeakScript(v8::Persistent<v8::Value> obj, void* data) {
622  ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data);
623  // Find the location of the global handle.
624  Script** location =
625      reinterpret_cast<Script**>(Utils::OpenHandle(*obj).location());
626  ASSERT((*location)->IsScript());
627
628  // Remove the entry from the cache.
629  int id = Smi::cast((*location)->id())->value();
630  script_cache->Remove(reinterpret_cast<void*>(id), Hash(id));
631  script_cache->collected_scripts_.Add(id);
632
633  // Clear the weak handle.
634  obj.Dispose();
635  obj.Clear();
636}
637
638
639void Debug::Setup(bool create_heap_objects) {
640  ThreadInit();
641  if (create_heap_objects) {
642    // Get code to handle debug break on return.
643    debug_break_return_ =
644        Builtins::builtin(Builtins::Return_DebugBreak);
645    ASSERT(debug_break_return_->IsCode());
646  }
647}
648
649
650void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) {
651  DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data);
652  RemoveDebugInfo(node->debug_info());
653#ifdef DEBUG
654  node = Debug::debug_info_list_;
655  while (node != NULL) {
656    ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data));
657    node = node->next();
658  }
659#endif
660}
661
662
663DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
664  // Globalize the request debug info object and make it weak.
665  debug_info_ = Handle<DebugInfo>::cast((GlobalHandles::Create(debug_info)));
666  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
667                          this, Debug::HandleWeakDebugInfo);
668}
669
670
671DebugInfoListNode::~DebugInfoListNode() {
672  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location()));
673}
674
675
676bool Debug::CompileDebuggerScript(int index) {
677  HandleScope scope;
678
679  // Bail out if the index is invalid.
680  if (index == -1) {
681    return false;
682  }
683
684  // Find source and name for the requested script.
685  Handle<String> source_code = Bootstrapper::NativesSourceLookup(index);
686  Vector<const char> name = Natives::GetScriptName(index);
687  Handle<String> script_name = Factory::NewStringFromAscii(name);
688
689  // Compile the script.
690  bool allow_natives_syntax = FLAG_allow_natives_syntax;
691  FLAG_allow_natives_syntax = true;
692  Handle<JSFunction> boilerplate;
693  boilerplate = Compiler::Compile(source_code,
694                                  script_name,
695                                  0,
696                                  0,
697                                  NULL,
698                                  NULL,
699                                  NATIVES_CODE);
700  FLAG_allow_natives_syntax = allow_natives_syntax;
701
702  // Silently ignore stack overflows during compilation.
703  if (boilerplate.is_null()) {
704    ASSERT(Top::has_pending_exception());
705    Top::clear_pending_exception();
706    return false;
707  }
708
709  // Execute the boilerplate function in the debugger context.
710  Handle<Context> context = Top::global_context();
711  bool caught_exception = false;
712  Handle<JSFunction> function =
713      Factory::NewFunctionFromBoilerplate(boilerplate, context);
714  Handle<Object> result =
715      Execution::TryCall(function, Handle<Object>(context->global()),
716                         0, NULL, &caught_exception);
717
718  // Check for caught exceptions.
719  if (caught_exception) {
720    Handle<Object> message = MessageHandler::MakeMessageObject(
721        "error_loading_debugger", NULL, Vector<Handle<Object> >::empty(),
722        Handle<String>());
723    MessageHandler::ReportMessage(NULL, message);
724    return false;
725  }
726
727  // Mark this script as native and return successfully.
728  Handle<Script> script(Script::cast(function->shared()->script()));
729  return true;
730}
731
732
733bool Debug::Load() {
734  // Return if debugger is already loaded.
735  if (IsLoaded()) return true;
736
737  // Bail out if we're already in the process of compiling the native
738  // JavaScript source code for the debugger.
739  if (Debugger::compiling_natives() || Debugger::is_loading_debugger())
740    return false;
741  Debugger::set_loading_debugger(true);
742
743  // Disable breakpoints and interrupts while compiling and running the
744  // debugger scripts including the context creation code.
745  DisableBreak disable(true);
746  PostponeInterruptsScope postpone;
747
748  // Create the debugger context.
749  HandleScope scope;
750  Handle<Context> context =
751      Bootstrapper::CreateEnvironment(Handle<Object>::null(),
752                                      v8::Handle<ObjectTemplate>(),
753                                      NULL);
754
755  // Use the debugger context.
756  SaveContext save;
757  Top::set_context(*context);
758
759  // Expose the builtins object in the debugger context.
760  Handle<String> key = Factory::LookupAsciiSymbol("builtins");
761  Handle<GlobalObject> global = Handle<GlobalObject>(context->global());
762  SetProperty(global, key, Handle<Object>(global->builtins()), NONE);
763
764  // Compile the JavaScript for the debugger in the debugger context.
765  Debugger::set_compiling_natives(true);
766  bool caught_exception =
767      !CompileDebuggerScript(Natives::GetIndex("mirror")) ||
768      !CompileDebuggerScript(Natives::GetIndex("debug"));
769  Debugger::set_compiling_natives(false);
770
771  // Make sure we mark the debugger as not loading before we might
772  // return.
773  Debugger::set_loading_debugger(false);
774
775  // Check for caught exceptions.
776  if (caught_exception) return false;
777
778  // Debugger loaded.
779  debug_context_ = Handle<Context>::cast(GlobalHandles::Create(*context));
780
781  return true;
782}
783
784
785void Debug::Unload() {
786  // Return debugger is not loaded.
787  if (!IsLoaded()) {
788    return;
789  }
790
791  // Clear the script cache.
792  DestroyScriptCache();
793
794  // Clear debugger context global handle.
795  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
796  debug_context_ = Handle<Context>();
797}
798
799
800// Set the flag indicating that preemption happened during debugging.
801void Debug::PreemptionWhileInDebugger() {
802  ASSERT(InDebugger());
803  Debug::set_interrupts_pending(PREEMPT);
804}
805
806
807void Debug::Iterate(ObjectVisitor* v) {
808  v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_)));
809}
810
811
812Object* Debug::Break(Arguments args) {
813  HandleScope scope;
814  ASSERT(args.length() == 0);
815
816  // Get the top-most JavaScript frame.
817  JavaScriptFrameIterator it;
818  JavaScriptFrame* frame = it.frame();
819
820  // Just continue if breaks are disabled or debugger cannot be loaded.
821  if (disable_break() || !Load()) {
822    SetAfterBreakTarget(frame);
823    return Heap::undefined_value();
824  }
825
826  // Enter the debugger.
827  EnterDebugger debugger;
828  if (debugger.FailedToEnter()) {
829    return Heap::undefined_value();
830  }
831
832  // Postpone interrupt during breakpoint processing.
833  PostponeInterruptsScope postpone;
834
835  // Get the debug info (create it if it does not exist).
836  Handle<SharedFunctionInfo> shared =
837      Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
838  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
839
840  // Find the break point where execution has stopped.
841  BreakLocationIterator break_location_iterator(debug_info,
842                                                ALL_BREAK_LOCATIONS);
843  break_location_iterator.FindBreakLocationFromAddress(frame->pc());
844
845  // Check whether step next reached a new statement.
846  if (!StepNextContinue(&break_location_iterator, frame)) {
847    // Decrease steps left if performing multiple steps.
848    if (thread_local_.step_count_ > 0) {
849      thread_local_.step_count_--;
850    }
851  }
852
853  // If there is one or more real break points check whether any of these are
854  // triggered.
855  Handle<Object> break_points_hit(Heap::undefined_value());
856  if (break_location_iterator.HasBreakPoint()) {
857    Handle<Object> break_point_objects =
858        Handle<Object>(break_location_iterator.BreakPointObjects());
859    break_points_hit = CheckBreakPoints(break_point_objects);
860  }
861
862  // If step out is active skip everything until the frame where we need to step
863  // out to is reached, unless real breakpoint is hit.
864  if (Debug::StepOutActive() && frame->fp() != Debug::step_out_fp() &&
865      break_points_hit->IsUndefined() ) {
866      // Step count should always be 0 for StepOut.
867      ASSERT(thread_local_.step_count_ == 0);
868  } else if (!break_points_hit->IsUndefined() ||
869             (thread_local_.last_step_action_ != StepNone &&
870              thread_local_.step_count_ == 0)) {
871    // Notify debugger if a real break point is triggered or if performing
872    // single stepping with no more steps to perform. Otherwise do another step.
873
874    // Clear all current stepping setup.
875    ClearStepping();
876
877    // Notify the debug event listeners.
878    Debugger::OnDebugBreak(break_points_hit, false);
879  } else if (thread_local_.last_step_action_ != StepNone) {
880    // Hold on to last step action as it is cleared by the call to
881    // ClearStepping.
882    StepAction step_action = thread_local_.last_step_action_;
883    int step_count = thread_local_.step_count_;
884
885    // Clear all current stepping setup.
886    ClearStepping();
887
888    // Set up for the remaining steps.
889    PrepareStep(step_action, step_count);
890  }
891
892  // Install jump to the call address which was overwritten.
893  SetAfterBreakTarget(frame);
894
895  return Heap::undefined_value();
896}
897
898
899// Check the break point objects for whether one or more are actually
900// triggered. This function returns a JSArray with the break point objects
901// which is triggered.
902Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
903  int break_points_hit_count = 0;
904  Handle<JSArray> break_points_hit = Factory::NewJSArray(1);
905
906  // If there are multiple break points they are in a FixedArray.
907  ASSERT(!break_point_objects->IsUndefined());
908  if (break_point_objects->IsFixedArray()) {
909    Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
910    for (int i = 0; i < array->length(); i++) {
911      Handle<Object> o(array->get(i));
912      if (CheckBreakPoint(o)) {
913        break_points_hit->SetElement(break_points_hit_count++, *o);
914      }
915    }
916  } else {
917    if (CheckBreakPoint(break_point_objects)) {
918      break_points_hit->SetElement(break_points_hit_count++,
919                                   *break_point_objects);
920    }
921  }
922
923  // Return undefined if no break points where triggered.
924  if (break_points_hit_count == 0) {
925    return Factory::undefined_value();
926  }
927  return break_points_hit;
928}
929
930
931// Check whether a single break point object is triggered.
932bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
933  HandleScope scope;
934
935  // Ignore check if break point object is not a JSObject.
936  if (!break_point_object->IsJSObject()) return true;
937
938  // Get the function CheckBreakPoint (defined in debug.js).
939  Handle<JSFunction> check_break_point =
940    Handle<JSFunction>(JSFunction::cast(
941      debug_context()->global()->GetProperty(
942          *Factory::LookupAsciiSymbol("IsBreakPointTriggered"))));
943
944  // Get the break id as an object.
945  Handle<Object> break_id = Factory::NewNumberFromInt(Debug::break_id());
946
947  // Call HandleBreakPointx.
948  bool caught_exception = false;
949  const int argc = 2;
950  Object** argv[argc] = {
951    break_id.location(),
952    reinterpret_cast<Object**>(break_point_object.location())
953  };
954  Handle<Object> result = Execution::TryCall(check_break_point,
955                                             Top::builtins(), argc, argv,
956                                             &caught_exception);
957
958  // If exception or non boolean result handle as not triggered
959  if (caught_exception || !result->IsBoolean()) {
960    return false;
961  }
962
963  // Return whether the break point is triggered.
964  return *result == Heap::true_value();
965}
966
967
968// Check whether the function has debug information.
969bool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) {
970  return !shared->debug_info()->IsUndefined();
971}
972
973
974// Return the debug info for this function. EnsureDebugInfo must be called
975// prior to ensure the debug info has been generated for shared.
976Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) {
977  ASSERT(HasDebugInfo(shared));
978  return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info()));
979}
980
981
982void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared,
983                          int source_position,
984                          Handle<Object> break_point_object) {
985  HandleScope scope;
986
987  if (!EnsureDebugInfo(shared)) {
988    // Return if retrieving debug info failed.
989    return;
990  }
991
992  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
993  // Source positions starts with zero.
994  ASSERT(source_position >= 0);
995
996  // Find the break point and change it.
997  BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
998  it.FindBreakLocationFromPosition(source_position);
999  it.SetBreakPoint(break_point_object);
1000
1001  // At least one active break point now.
1002  ASSERT(debug_info->GetBreakPointCount() > 0);
1003}
1004
1005
1006void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
1007  HandleScope scope;
1008
1009  DebugInfoListNode* node = debug_info_list_;
1010  while (node != NULL) {
1011    Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),
1012                                                   break_point_object);
1013    if (!result->IsUndefined()) {
1014      // Get information in the break point.
1015      BreakPointInfo* break_point_info = BreakPointInfo::cast(result);
1016      Handle<DebugInfo> debug_info = node->debug_info();
1017      Handle<SharedFunctionInfo> shared(debug_info->shared());
1018      int source_position =  break_point_info->statement_position()->value();
1019
1020      // Source positions starts with zero.
1021      ASSERT(source_position >= 0);
1022
1023      // Find the break point and clear it.
1024      BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
1025      it.FindBreakLocationFromPosition(source_position);
1026      it.ClearBreakPoint(break_point_object);
1027
1028      // If there are no more break points left remove the debug info for this
1029      // function.
1030      if (debug_info->GetBreakPointCount() == 0) {
1031        RemoveDebugInfo(debug_info);
1032      }
1033
1034      return;
1035    }
1036    node = node->next();
1037  }
1038}
1039
1040
1041void Debug::ClearAllBreakPoints() {
1042  DebugInfoListNode* node = debug_info_list_;
1043  while (node != NULL) {
1044    // Remove all debug break code.
1045    BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1046    it.ClearAllDebugBreak();
1047    node = node->next();
1048  }
1049
1050  // Remove all debug info.
1051  while (debug_info_list_ != NULL) {
1052    RemoveDebugInfo(debug_info_list_->debug_info());
1053  }
1054}
1055
1056
1057void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
1058  // Make sure the function has setup the debug info.
1059  if (!EnsureDebugInfo(shared)) {
1060    // Return if we failed to retrieve the debug info.
1061    return;
1062  }
1063
1064  // Flood the function with break points.
1065  BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS);
1066  while (!it.Done()) {
1067    it.SetOneShot();
1068    it.Next();
1069  }
1070}
1071
1072
1073void Debug::FloodHandlerWithOneShot() {
1074  // Iterate through the JavaScript stack looking for handlers.
1075  StackFrame::Id id = break_frame_id();
1076  if (id == StackFrame::NO_ID) {
1077    // If there is no JavaScript stack don't do anything.
1078    return;
1079  }
1080  for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) {
1081    JavaScriptFrame* frame = it.frame();
1082    if (frame->HasHandler()) {
1083      Handle<SharedFunctionInfo> shared =
1084          Handle<SharedFunctionInfo>(
1085              JSFunction::cast(frame->function())->shared());
1086      // Flood the function with the catch block with break points
1087      FloodWithOneShot(shared);
1088      return;
1089    }
1090  }
1091}
1092
1093
1094void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
1095  if (type == BreakUncaughtException) {
1096    break_on_uncaught_exception_ = enable;
1097  } else {
1098    break_on_exception_ = enable;
1099  }
1100}
1101
1102
1103void Debug::PrepareStep(StepAction step_action, int step_count) {
1104  HandleScope scope;
1105  ASSERT(Debug::InDebugger());
1106
1107  // Remember this step action and count.
1108  thread_local_.last_step_action_ = step_action;
1109  if (step_action == StepOut) {
1110    // For step out target frame will be found on the stack so there is no need
1111    // to set step counter for it. It's expected to always be 0 for StepOut.
1112    thread_local_.step_count_ = 0;
1113  } else {
1114    thread_local_.step_count_ = step_count;
1115  }
1116
1117  // Get the frame where the execution has stopped and skip the debug frame if
1118  // any. The debug frame will only be present if execution was stopped due to
1119  // hitting a break point. In other situations (e.g. unhandled exception) the
1120  // debug frame is not present.
1121  StackFrame::Id id = break_frame_id();
1122  if (id == StackFrame::NO_ID) {
1123    // If there is no JavaScript stack don't do anything.
1124    return;
1125  }
1126  JavaScriptFrameIterator frames_it(id);
1127  JavaScriptFrame* frame = frames_it.frame();
1128
1129  // First of all ensure there is one-shot break points in the top handler
1130  // if any.
1131  FloodHandlerWithOneShot();
1132
1133  // If the function on the top frame is unresolved perform step out. This will
1134  // be the case when calling unknown functions and having the debugger stopped
1135  // in an unhandled exception.
1136  if (!frame->function()->IsJSFunction()) {
1137    // Step out: Find the calling JavaScript frame and flood it with
1138    // breakpoints.
1139    frames_it.Advance();
1140    // Fill the function to return to with one-shot break points.
1141    JSFunction* function = JSFunction::cast(frames_it.frame()->function());
1142    FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
1143    return;
1144  }
1145
1146  // Get the debug info (create it if it does not exist).
1147  Handle<SharedFunctionInfo> shared =
1148      Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
1149  if (!EnsureDebugInfo(shared)) {
1150    // Return if ensuring debug info failed.
1151    return;
1152  }
1153  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1154
1155  // Find the break location where execution has stopped.
1156  BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS);
1157  it.FindBreakLocationFromAddress(frame->pc());
1158
1159  // Compute whether or not the target is a call target.
1160  bool is_call_target = false;
1161  bool is_load_or_store = false;
1162  bool is_inline_cache_stub = false;
1163  Handle<Code> call_function_stub;
1164  if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
1165    Address target = it.rinfo()->target_address();
1166    Code* code = Code::GetCodeFromTargetAddress(target);
1167    if (code->is_call_stub()) {
1168      is_call_target = true;
1169    }
1170    if (code->is_inline_cache_stub()) {
1171      is_inline_cache_stub = true;
1172      is_load_or_store = !is_call_target;
1173    }
1174
1175    // Check if target code is CallFunction stub.
1176    Code* maybe_call_function_stub = code;
1177    // If there is a breakpoint at this line look at the original code to
1178    // check if it is a CallFunction stub.
1179    if (it.IsDebugBreak()) {
1180      Address original_target = it.original_rinfo()->target_address();
1181      maybe_call_function_stub =
1182          Code::GetCodeFromTargetAddress(original_target);
1183    }
1184    if (maybe_call_function_stub->kind() == Code::STUB &&
1185        maybe_call_function_stub->major_key() == CodeStub::CallFunction) {
1186      // Save reference to the code as we may need it to find out arguments
1187      // count for 'step in' later.
1188      call_function_stub = Handle<Code>(maybe_call_function_stub);
1189    }
1190  }
1191
1192  // If this is the last break code target step out is the only possibility.
1193  if (it.IsExit() || step_action == StepOut) {
1194    if (step_action == StepOut) {
1195      // Skip step_count frames starting with the current one.
1196      while (step_count-- > 0 && !frames_it.done()) {
1197        frames_it.Advance();
1198      }
1199    } else {
1200      ASSERT(it.IsExit());
1201      frames_it.Advance();
1202    }
1203    // Skip builtin functions on the stack.
1204    while (!frames_it.done() &&
1205           JSFunction::cast(frames_it.frame()->function())->IsBuiltin()) {
1206      frames_it.Advance();
1207    }
1208    // Step out: If there is a JavaScript caller frame, we need to
1209    // flood it with breakpoints.
1210    if (!frames_it.done()) {
1211      // Fill the function to return to with one-shot break points.
1212      JSFunction* function = JSFunction::cast(frames_it.frame()->function());
1213      FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
1214      // Set target frame pointer.
1215      ActivateStepOut(frames_it.frame());
1216    }
1217  } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
1218               !call_function_stub.is_null())
1219             || step_action == StepNext || step_action == StepMin) {
1220    // Step next or step min.
1221
1222    // Fill the current function with one-shot break points.
1223    FloodWithOneShot(shared);
1224
1225    // Remember source position and frame to handle step next.
1226    thread_local_.last_statement_position_ =
1227        debug_info->code()->SourceStatementPosition(frame->pc());
1228    thread_local_.last_fp_ = frame->fp();
1229  } else {
1230    // If it's CallFunction stub ensure target function is compiled and flood
1231    // it with one shot breakpoints.
1232    if (!call_function_stub.is_null()) {
1233      // Find out number of arguments from the stub minor key.
1234      // Reverse lookup required as the minor key cannot be retrieved
1235      // from the code object.
1236      Handle<Object> obj(
1237          Heap::code_stubs()->SlowReverseLookup(*call_function_stub));
1238      ASSERT(*obj != Heap::undefined_value());
1239      ASSERT(obj->IsSmi());
1240      // Get the STUB key and extract major and minor key.
1241      uint32_t key = Smi::cast(*obj)->value();
1242      // Argc in the stub is the number of arguments passed - not the
1243      // expected arguments of the called function.
1244      int call_function_arg_count =
1245          CallFunctionStub::ExtractArgcFromMinorKey(
1246              CodeStub::MinorKeyFromKey(key));
1247      ASSERT(call_function_stub->major_key() ==
1248             CodeStub::MajorKeyFromKey(key));
1249
1250      // Find target function on the expression stack.
1251      // Expression stack looks like this (top to bottom):
1252      // argN
1253      // ...
1254      // arg0
1255      // Receiver
1256      // Function to call
1257      int expressions_count = frame->ComputeExpressionsCount();
1258      ASSERT(expressions_count - 2 - call_function_arg_count >= 0);
1259      Object* fun = frame->GetExpression(
1260          expressions_count - 2 - call_function_arg_count);
1261      if (fun->IsJSFunction()) {
1262        Handle<JSFunction> js_function(JSFunction::cast(fun));
1263        // Don't step into builtins.
1264        if (!js_function->IsBuiltin()) {
1265          // It will also compile target function if it's not compiled yet.
1266          FloodWithOneShot(Handle<SharedFunctionInfo>(js_function->shared()));
1267        }
1268      }
1269    }
1270
1271    // Fill the current function with one-shot break points even for step in on
1272    // a call target as the function called might be a native function for
1273    // which step in will not stop. It also prepares for stepping in
1274    // getters/setters.
1275    FloodWithOneShot(shared);
1276
1277    if (is_load_or_store) {
1278      // Remember source position and frame to handle step in getter/setter. If
1279      // there is a custom getter/setter it will be handled in
1280      // Object::Get/SetPropertyWithCallback, otherwise the step action will be
1281      // propagated on the next Debug::Break.
1282      thread_local_.last_statement_position_ =
1283          debug_info->code()->SourceStatementPosition(frame->pc());
1284      thread_local_.last_fp_ = frame->fp();
1285    }
1286
1287    // Step in or Step in min
1288    it.PrepareStepIn();
1289    ActivateStepIn(frame);
1290  }
1291}
1292
1293
1294// Check whether the current debug break should be reported to the debugger. It
1295// is used to have step next and step in only report break back to the debugger
1296// if on a different frame or in a different statement. In some situations
1297// there will be several break points in the same statement when the code is
1298// flooded with one-shot break points. This function helps to perform several
1299// steps before reporting break back to the debugger.
1300bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
1301                             JavaScriptFrame* frame) {
1302  // If the step last action was step next or step in make sure that a new
1303  // statement is hit.
1304  if (thread_local_.last_step_action_ == StepNext ||
1305      thread_local_.last_step_action_ == StepIn) {
1306    // Never continue if returning from function.
1307    if (break_location_iterator->IsExit()) return false;
1308
1309    // Continue if we are still on the same frame and in the same statement.
1310    int current_statement_position =
1311        break_location_iterator->code()->SourceStatementPosition(frame->pc());
1312    return thread_local_.last_fp_ == frame->fp() &&
1313        thread_local_.last_statement_position_ == current_statement_position;
1314  }
1315
1316  // No step next action - don't continue.
1317  return false;
1318}
1319
1320
1321// Check whether the code object at the specified address is a debug break code
1322// object.
1323bool Debug::IsDebugBreak(Address addr) {
1324  Code* code = Code::GetCodeFromTargetAddress(addr);
1325  return code->ic_state() == DEBUG_BREAK;
1326}
1327
1328
1329// Check whether a code stub with the specified major key is a possible break
1330// point location when looking for source break locations.
1331bool Debug::IsSourceBreakStub(Code* code) {
1332  CodeStub::Major major_key = code->major_key();
1333  return major_key == CodeStub::CallFunction;
1334}
1335
1336
1337// Check whether a code stub with the specified major key is a possible break
1338// location.
1339bool Debug::IsBreakStub(Code* code) {
1340  CodeStub::Major major_key = code->major_key();
1341  return major_key == CodeStub::CallFunction ||
1342         major_key == CodeStub::StackCheck;
1343}
1344
1345
1346// Find the builtin to use for invoking the debug break
1347Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
1348  // Find the builtin debug break function matching the calling convention
1349  // used by the call site.
1350  if (code->is_inline_cache_stub()) {
1351    if (code->is_call_stub()) {
1352      return ComputeCallDebugBreak(code->arguments_count());
1353    }
1354    if (code->is_load_stub()) {
1355      return Handle<Code>(Builtins::builtin(Builtins::LoadIC_DebugBreak));
1356    }
1357    if (code->is_store_stub()) {
1358      return Handle<Code>(Builtins::builtin(Builtins::StoreIC_DebugBreak));
1359    }
1360    if (code->is_keyed_load_stub()) {
1361      Handle<Code> result =
1362          Handle<Code>(Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak));
1363      return result;
1364    }
1365    if (code->is_keyed_store_stub()) {
1366      Handle<Code> result =
1367          Handle<Code>(Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak));
1368      return result;
1369    }
1370  }
1371  if (RelocInfo::IsConstructCall(mode)) {
1372    Handle<Code> result =
1373        Handle<Code>(Builtins::builtin(Builtins::ConstructCall_DebugBreak));
1374    return result;
1375  }
1376  if (code->kind() == Code::STUB) {
1377    ASSERT(code->major_key() == CodeStub::CallFunction ||
1378           code->major_key() == CodeStub::StackCheck);
1379    Handle<Code> result =
1380        Handle<Code>(Builtins::builtin(Builtins::StubNoRegisters_DebugBreak));
1381    return result;
1382  }
1383
1384  UNREACHABLE();
1385  return Handle<Code>::null();
1386}
1387
1388
1389// Simple function for returning the source positions for active break points.
1390Handle<Object> Debug::GetSourceBreakLocations(
1391    Handle<SharedFunctionInfo> shared) {
1392  if (!HasDebugInfo(shared)) return Handle<Object>(Heap::undefined_value());
1393  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1394  if (debug_info->GetBreakPointCount() == 0) {
1395    return Handle<Object>(Heap::undefined_value());
1396  }
1397  Handle<FixedArray> locations =
1398      Factory::NewFixedArray(debug_info->GetBreakPointCount());
1399  int count = 0;
1400  for (int i = 0; i < debug_info->break_points()->length(); i++) {
1401    if (!debug_info->break_points()->get(i)->IsUndefined()) {
1402      BreakPointInfo* break_point_info =
1403          BreakPointInfo::cast(debug_info->break_points()->get(i));
1404      if (break_point_info->GetBreakPointCount() > 0) {
1405        locations->set(count++, break_point_info->statement_position());
1406      }
1407    }
1408  }
1409  return locations;
1410}
1411
1412
1413void Debug::NewBreak(StackFrame::Id break_frame_id) {
1414  thread_local_.break_frame_id_ = break_frame_id;
1415  thread_local_.break_id_ = ++thread_local_.break_count_;
1416}
1417
1418
1419void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) {
1420  thread_local_.break_frame_id_ = break_frame_id;
1421  thread_local_.break_id_ = break_id;
1422}
1423
1424
1425// Handle stepping into a function.
1426void Debug::HandleStepIn(Handle<JSFunction> function,
1427                         Handle<Object> holder,
1428                         Address fp,
1429                         bool is_constructor) {
1430  // If the frame pointer is not supplied by the caller find it.
1431  if (fp == 0) {
1432    StackFrameIterator it;
1433    it.Advance();
1434    // For constructor functions skip another frame.
1435    if (is_constructor) {
1436      ASSERT(it.frame()->is_construct());
1437      it.Advance();
1438    }
1439    fp = it.frame()->fp();
1440  }
1441
1442  // Flood the function with one-shot break points if it is called from where
1443  // step into was requested.
1444  if (fp == Debug::step_in_fp()) {
1445    // Don't allow step into functions in the native context.
1446    if (!function->IsBuiltin()) {
1447      if (function->shared()->code() ==
1448          Builtins::builtin(Builtins::FunctionApply) ||
1449          function->shared()->code() ==
1450          Builtins::builtin(Builtins::FunctionCall)) {
1451        // Handle function.apply and function.call separately to flood the
1452        // function to be called and not the code for Builtins::FunctionApply or
1453        // Builtins::FunctionCall. The receiver of call/apply is the target
1454        // function.
1455        if (!holder.is_null() && holder->IsJSFunction() &&
1456            !JSFunction::cast(*holder)->IsBuiltin()) {
1457          Handle<SharedFunctionInfo> shared_info(
1458              JSFunction::cast(*holder)->shared());
1459          Debug::FloodWithOneShot(shared_info);
1460        }
1461      } else {
1462        Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
1463      }
1464    }
1465  }
1466}
1467
1468
1469void Debug::ClearStepping() {
1470  // Clear the various stepping setup.
1471  ClearOneShot();
1472  ClearStepIn();
1473  ClearStepOut();
1474  ClearStepNext();
1475
1476  // Clear multiple step counter.
1477  thread_local_.step_count_ = 0;
1478}
1479
1480// Clears all the one-shot break points that are currently set. Normally this
1481// function is called each time a break point is hit as one shot break points
1482// are used to support stepping.
1483void Debug::ClearOneShot() {
1484  // The current implementation just runs through all the breakpoints. When the
1485  // last break point for a function is removed that function is automatically
1486  // removed from the list.
1487
1488  DebugInfoListNode* node = debug_info_list_;
1489  while (node != NULL) {
1490    BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1491    while (!it.Done()) {
1492      it.ClearOneShot();
1493      it.Next();
1494    }
1495    node = node->next();
1496  }
1497}
1498
1499
1500void Debug::ActivateStepIn(StackFrame* frame) {
1501  ASSERT(!StepOutActive());
1502  thread_local_.step_into_fp_ = frame->fp();
1503}
1504
1505
1506void Debug::ClearStepIn() {
1507  thread_local_.step_into_fp_ = 0;
1508}
1509
1510
1511void Debug::ActivateStepOut(StackFrame* frame) {
1512  ASSERT(!StepInActive());
1513  thread_local_.step_out_fp_ = frame->fp();
1514}
1515
1516
1517void Debug::ClearStepOut() {
1518  thread_local_.step_out_fp_ = 0;
1519}
1520
1521
1522void Debug::ClearStepNext() {
1523  thread_local_.last_step_action_ = StepNone;
1524  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
1525  thread_local_.last_fp_ = 0;
1526}
1527
1528
1529// Ensures the debug information is present for shared.
1530bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
1531  // Return if we already have the debug info for shared.
1532  if (HasDebugInfo(shared)) return true;
1533
1534  // Ensure shared in compiled. Return false if this failed.
1535  if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
1536
1537  // Create the debug info object.
1538  Handle<DebugInfo> debug_info = Factory::NewDebugInfo(shared);
1539
1540  // Add debug info to the list.
1541  DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
1542  node->set_next(debug_info_list_);
1543  debug_info_list_ = node;
1544
1545  // Now there is at least one break point.
1546  has_break_points_ = true;
1547
1548  return true;
1549}
1550
1551
1552void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
1553  ASSERT(debug_info_list_ != NULL);
1554  // Run through the debug info objects to find this one and remove it.
1555  DebugInfoListNode* prev = NULL;
1556  DebugInfoListNode* current = debug_info_list_;
1557  while (current != NULL) {
1558    if (*current->debug_info() == *debug_info) {
1559      // Unlink from list. If prev is NULL we are looking at the first element.
1560      if (prev == NULL) {
1561        debug_info_list_ = current->next();
1562      } else {
1563        prev->set_next(current->next());
1564      }
1565      current->debug_info()->shared()->set_debug_info(Heap::undefined_value());
1566      delete current;
1567
1568      // If there are no more debug info objects there are not more break
1569      // points.
1570      has_break_points_ = debug_info_list_ != NULL;
1571
1572      return;
1573    }
1574    // Move to next in list.
1575    prev = current;
1576    current = current->next();
1577  }
1578  UNREACHABLE();
1579}
1580
1581
1582void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
1583  HandleScope scope;
1584
1585  // Get the executing function in which the debug break occurred.
1586  Handle<SharedFunctionInfo> shared =
1587      Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
1588  if (!EnsureDebugInfo(shared)) {
1589    // Return if we failed to retrieve the debug info.
1590    return;
1591  }
1592  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1593  Handle<Code> code(debug_info->code());
1594  Handle<Code> original_code(debug_info->original_code());
1595#ifdef DEBUG
1596  // Get the code which is actually executing.
1597  Handle<Code> frame_code(frame->code());
1598  ASSERT(frame_code.is_identical_to(code));
1599#endif
1600
1601  // Find the call address in the running code. This address holds the call to
1602  // either a DebugBreakXXX or to the debug break return entry code if the
1603  // break point is still active after processing the break point.
1604  Address addr = frame->pc() - Assembler::kCallTargetAddressOffset;
1605
1606  // Check if the location is at JS exit.
1607  bool at_js_return = false;
1608  bool break_at_js_return_active = false;
1609  RelocIterator it(debug_info->code());
1610  while (!it.done()) {
1611    if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
1612      at_js_return = (it.rinfo()->pc() ==
1613          addr - Assembler::kPatchReturnSequenceAddressOffset);
1614      break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence();
1615    }
1616    it.next();
1617  }
1618
1619  // Handle the jump to continue execution after break point depending on the
1620  // break location.
1621  if (at_js_return) {
1622    // If the break point as return is still active jump to the corresponding
1623    // place in the original code. If not the break point was removed during
1624    // break point processing.
1625    if (break_at_js_return_active) {
1626      addr +=  original_code->instruction_start() - code->instruction_start();
1627    }
1628
1629    // Move back to where the call instruction sequence started.
1630    thread_local_.after_break_target_ =
1631        addr - Assembler::kPatchReturnSequenceAddressOffset;
1632  } else {
1633    // Check if there still is a debug break call at the target address. If the
1634    // break point has been removed it will have disappeared. If it have
1635    // disappeared don't try to look in the original code as the running code
1636    // will have the right address. This takes care of the case where the last
1637    // break point is removed from the function and therefore no "original code"
1638    // is available. If the debug break call is still there find the address in
1639    // the original code.
1640    if (IsDebugBreak(Assembler::target_address_at(addr))) {
1641      // If the break point is still there find the call address which was
1642      // overwritten in the original code by the call to DebugBreakXXX.
1643
1644      // Find the corresponding address in the original code.
1645      addr += original_code->instruction_start() - code->instruction_start();
1646    }
1647
1648    // Install jump to the call address in the original code. This will be the
1649    // call which was overwritten by the call to DebugBreakXXX.
1650    thread_local_.after_break_target_ = Assembler::target_address_at(addr);
1651  }
1652}
1653
1654
1655bool Debug::IsDebugGlobal(GlobalObject* global) {
1656  return IsLoaded() && global == Debug::debug_context()->global();
1657}
1658
1659
1660void Debug::ClearMirrorCache() {
1661  HandleScope scope;
1662  ASSERT(Top::context() == *Debug::debug_context());
1663
1664  // Clear the mirror cache.
1665  Handle<String> function_name =
1666      Factory::LookupSymbol(CStrVector("ClearMirrorCache"));
1667  Handle<Object> fun(Top::global()->GetProperty(*function_name));
1668  ASSERT(fun->IsJSFunction());
1669  bool caught_exception;
1670  Handle<Object> js_object = Execution::TryCall(
1671      Handle<JSFunction>::cast(fun),
1672      Handle<JSObject>(Debug::debug_context()->global()),
1673      0, NULL, &caught_exception);
1674}
1675
1676
1677void Debug::CreateScriptCache() {
1678  HandleScope scope;
1679
1680  // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
1681  // rid of all the cached script wrappers and the second gets rid of the
1682  // scripts which are no longer referenced.
1683  Heap::CollectAllGarbage(false);
1684  Heap::CollectAllGarbage(false);
1685
1686  ASSERT(script_cache_ == NULL);
1687  script_cache_ = new ScriptCache();
1688
1689  // Scan heap for Script objects.
1690  int count = 0;
1691  HeapIterator iterator;
1692  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1693    if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
1694      script_cache_->Add(Handle<Script>(Script::cast(obj)));
1695      count++;
1696    }
1697  }
1698}
1699
1700
1701void Debug::DestroyScriptCache() {
1702  // Get rid of the script cache if it was created.
1703  if (script_cache_ != NULL) {
1704    delete script_cache_;
1705    script_cache_ = NULL;
1706  }
1707}
1708
1709
1710void Debug::AddScriptToScriptCache(Handle<Script> script) {
1711  if (script_cache_ != NULL) {
1712    script_cache_->Add(script);
1713  }
1714}
1715
1716
1717Handle<FixedArray> Debug::GetLoadedScripts() {
1718  // Create and fill the script cache when the loaded scripts is requested for
1719  // the first time.
1720  if (script_cache_ == NULL) {
1721    CreateScriptCache();
1722  }
1723
1724  // If the script cache is not active just return an empty array.
1725  ASSERT(script_cache_ != NULL);
1726  if (script_cache_ == NULL) {
1727    Factory::NewFixedArray(0);
1728  }
1729
1730  // Perform GC to get unreferenced scripts evicted from the cache before
1731  // returning the content.
1732  Heap::CollectAllGarbage(false);
1733
1734  // Get the scripts from the cache.
1735  return script_cache_->GetScripts();
1736}
1737
1738
1739void Debug::AfterGarbageCollection() {
1740  // Generate events for collected scripts.
1741  if (script_cache_ != NULL) {
1742    script_cache_->ProcessCollectedScripts();
1743  }
1744}
1745
1746
1747Mutex* Debugger::debugger_access_ = OS::CreateMutex();
1748Handle<Object> Debugger::event_listener_ = Handle<Object>();
1749Handle<Object> Debugger::event_listener_data_ = Handle<Object>();
1750bool Debugger::compiling_natives_ = false;
1751bool Debugger::is_loading_debugger_ = false;
1752bool Debugger::never_unload_debugger_ = false;
1753v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL;
1754bool Debugger::debugger_unload_pending_ = false;
1755v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
1756Mutex* Debugger::dispatch_handler_access_ = OS::CreateMutex();
1757v8::Debug::DebugMessageDispatchHandler
1758    Debugger::debug_message_dispatch_handler_ = NULL;
1759MessageDispatchHelperThread* Debugger::message_dispatch_helper_thread_ = NULL;
1760int Debugger::host_dispatch_micros_ = 100 * 1000;
1761DebuggerAgent* Debugger::agent_ = NULL;
1762LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize);
1763Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0);
1764
1765
1766Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
1767                                      int argc, Object*** argv,
1768                                      bool* caught_exception) {
1769  ASSERT(Top::context() == *Debug::debug_context());
1770
1771  // Create the execution state object.
1772  Handle<String> constructor_str = Factory::LookupSymbol(constructor_name);
1773  Handle<Object> constructor(Top::global()->GetProperty(*constructor_str));
1774  ASSERT(constructor->IsJSFunction());
1775  if (!constructor->IsJSFunction()) {
1776    *caught_exception = true;
1777    return Factory::undefined_value();
1778  }
1779  Handle<Object> js_object = Execution::TryCall(
1780      Handle<JSFunction>::cast(constructor),
1781      Handle<JSObject>(Debug::debug_context()->global()), argc, argv,
1782      caught_exception);
1783  return js_object;
1784}
1785
1786
1787Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) {
1788  // Create the execution state object.
1789  Handle<Object> break_id = Factory::NewNumberFromInt(Debug::break_id());
1790  const int argc = 1;
1791  Object** argv[argc] = { break_id.location() };
1792  return MakeJSObject(CStrVector("MakeExecutionState"),
1793                      argc, argv, caught_exception);
1794}
1795
1796
1797Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state,
1798                                        Handle<Object> break_points_hit,
1799                                        bool* caught_exception) {
1800  // Create the new break event object.
1801  const int argc = 2;
1802  Object** argv[argc] = { exec_state.location(),
1803                          break_points_hit.location() };
1804  return MakeJSObject(CStrVector("MakeBreakEvent"),
1805                      argc,
1806                      argv,
1807                      caught_exception);
1808}
1809
1810
1811Handle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state,
1812                                            Handle<Object> exception,
1813                                            bool uncaught,
1814                                            bool* caught_exception) {
1815  // Create the new exception event object.
1816  const int argc = 3;
1817  Object** argv[argc] = { exec_state.location(),
1818                          exception.location(),
1819                          uncaught ? Factory::true_value().location() :
1820                                     Factory::false_value().location()};
1821  return MakeJSObject(CStrVector("MakeExceptionEvent"),
1822                      argc, argv, caught_exception);
1823}
1824
1825
1826Handle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function,
1827                                              bool* caught_exception) {
1828  // Create the new function event object.
1829  const int argc = 1;
1830  Object** argv[argc] = { function.location() };
1831  return MakeJSObject(CStrVector("MakeNewFunctionEvent"),
1832                      argc, argv, caught_exception);
1833}
1834
1835
1836Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
1837                                          bool before,
1838                                          bool* caught_exception) {
1839  // Create the compile event object.
1840  Handle<Object> exec_state = MakeExecutionState(caught_exception);
1841  Handle<Object> script_wrapper = GetScriptWrapper(script);
1842  const int argc = 3;
1843  Object** argv[argc] = { exec_state.location(),
1844                          script_wrapper.location(),
1845                          before ? Factory::true_value().location() :
1846                                   Factory::false_value().location() };
1847
1848  return MakeJSObject(CStrVector("MakeCompileEvent"),
1849                      argc,
1850                      argv,
1851                      caught_exception);
1852}
1853
1854
1855Handle<Object> Debugger::MakeScriptCollectedEvent(int id,
1856                                                  bool* caught_exception) {
1857  // Create the script collected event object.
1858  Handle<Object> exec_state = MakeExecutionState(caught_exception);
1859  Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id));
1860  const int argc = 2;
1861  Object** argv[argc] = { exec_state.location(), id_object.location() };
1862
1863  return MakeJSObject(CStrVector("MakeScriptCollectedEvent"),
1864                      argc,
1865                      argv,
1866                      caught_exception);
1867}
1868
1869
1870void Debugger::OnException(Handle<Object> exception, bool uncaught) {
1871  HandleScope scope;
1872
1873  // Bail out based on state or if there is no listener for this event
1874  if (Debug::InDebugger()) return;
1875  if (!Debugger::EventActive(v8::Exception)) return;
1876
1877  // Bail out if exception breaks are not active
1878  if (uncaught) {
1879    // Uncaught exceptions are reported by either flags.
1880    if (!(Debug::break_on_uncaught_exception() ||
1881          Debug::break_on_exception())) return;
1882  } else {
1883    // Caught exceptions are reported is activated.
1884    if (!Debug::break_on_exception()) return;
1885  }
1886
1887  // Enter the debugger.
1888  EnterDebugger debugger;
1889  if (debugger.FailedToEnter()) return;
1890
1891  // Clear all current stepping setup.
1892  Debug::ClearStepping();
1893  // Create the event data object.
1894  bool caught_exception = false;
1895  Handle<Object> exec_state = MakeExecutionState(&caught_exception);
1896  Handle<Object> event_data;
1897  if (!caught_exception) {
1898    event_data = MakeExceptionEvent(exec_state, exception, uncaught,
1899                                    &caught_exception);
1900  }
1901  // Bail out and don't call debugger if exception.
1902  if (caught_exception) {
1903    return;
1904  }
1905
1906  // Process debug event.
1907  ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
1908  // Return to continue execution from where the exception was thrown.
1909}
1910
1911
1912void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
1913                            bool auto_continue) {
1914  HandleScope scope;
1915
1916  // Debugger has already been entered by caller.
1917  ASSERT(Top::context() == *Debug::debug_context());
1918
1919  // Bail out if there is no listener for this event
1920  if (!Debugger::EventActive(v8::Break)) return;
1921
1922  // Debugger must be entered in advance.
1923  ASSERT(Top::context() == *Debug::debug_context());
1924
1925  // Create the event data object.
1926  bool caught_exception = false;
1927  Handle<Object> exec_state = MakeExecutionState(&caught_exception);
1928  Handle<Object> event_data;
1929  if (!caught_exception) {
1930    event_data = MakeBreakEvent(exec_state, break_points_hit,
1931                                &caught_exception);
1932  }
1933  // Bail out and don't call debugger if exception.
1934  if (caught_exception) {
1935    return;
1936  }
1937
1938  // Process debug event.
1939  ProcessDebugEvent(v8::Break,
1940                    Handle<JSObject>::cast(event_data),
1941                    auto_continue);
1942}
1943
1944
1945void Debugger::OnBeforeCompile(Handle<Script> script) {
1946  HandleScope scope;
1947
1948  // Bail out based on state or if there is no listener for this event
1949  if (Debug::InDebugger()) return;
1950  if (compiling_natives()) return;
1951  if (!EventActive(v8::BeforeCompile)) return;
1952
1953  // Enter the debugger.
1954  EnterDebugger debugger;
1955  if (debugger.FailedToEnter()) return;
1956
1957  // Create the event data object.
1958  bool caught_exception = false;
1959  Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception);
1960  // Bail out and don't call debugger if exception.
1961  if (caught_exception) {
1962    return;
1963  }
1964
1965  // Process debug event.
1966  ProcessDebugEvent(v8::BeforeCompile,
1967                    Handle<JSObject>::cast(event_data),
1968                    true);
1969}
1970
1971
1972// Handle debugger actions when a new script is compiled.
1973void Debugger::OnAfterCompile(Handle<Script> script, Handle<JSFunction> fun) {
1974  HandleScope scope;
1975
1976  // Add the newly compiled script to the script cache.
1977  Debug::AddScriptToScriptCache(script);
1978
1979  // No more to do if not debugging.
1980  if (!IsDebuggerActive()) return;
1981
1982  // No compile events while compiling natives.
1983  if (compiling_natives()) return;
1984
1985  // Store whether in debugger before entering debugger.
1986  bool in_debugger = Debug::InDebugger();
1987
1988  // Enter the debugger.
1989  EnterDebugger debugger;
1990  if (debugger.FailedToEnter()) return;
1991
1992  // If debugging there might be script break points registered for this
1993  // script. Make sure that these break points are set.
1994
1995  // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
1996  Handle<Object> update_script_break_points =
1997      Handle<Object>(Debug::debug_context()->global()->GetProperty(
1998          *Factory::LookupAsciiSymbol("UpdateScriptBreakPoints")));
1999  if (!update_script_break_points->IsJSFunction()) {
2000    return;
2001  }
2002  ASSERT(update_script_break_points->IsJSFunction());
2003
2004  // Wrap the script object in a proper JS object before passing it
2005  // to JavaScript.
2006  Handle<JSValue> wrapper = GetScriptWrapper(script);
2007
2008  // Call UpdateScriptBreakPoints expect no exceptions.
2009  bool caught_exception = false;
2010  const int argc = 1;
2011  Object** argv[argc] = { reinterpret_cast<Object**>(wrapper.location()) };
2012  Handle<Object> result = Execution::TryCall(
2013      Handle<JSFunction>::cast(update_script_break_points),
2014      Top::builtins(), argc, argv,
2015      &caught_exception);
2016  if (caught_exception) {
2017    return;
2018  }
2019  // Bail out based on state or if there is no listener for this event
2020  if (in_debugger) return;
2021  if (!Debugger::EventActive(v8::AfterCompile)) return;
2022
2023  // Create the compile state object.
2024  Handle<Object> event_data = MakeCompileEvent(script,
2025                                               false,
2026                                               &caught_exception);
2027  // Bail out and don't call debugger if exception.
2028  if (caught_exception) {
2029    return;
2030  }
2031  // Process debug event.
2032  ProcessDebugEvent(v8::AfterCompile,
2033                    Handle<JSObject>::cast(event_data),
2034                    true);
2035}
2036
2037
2038void Debugger::OnNewFunction(Handle<JSFunction> function) {
2039  return;
2040  HandleScope scope;
2041
2042  // Bail out based on state or if there is no listener for this event
2043  if (Debug::InDebugger()) return;
2044  if (compiling_natives()) return;
2045  if (!Debugger::EventActive(v8::NewFunction)) return;
2046
2047  // Enter the debugger.
2048  EnterDebugger debugger;
2049  if (debugger.FailedToEnter()) return;
2050
2051  // Create the event object.
2052  bool caught_exception = false;
2053  Handle<Object> event_data = MakeNewFunctionEvent(function, &caught_exception);
2054  // Bail out and don't call debugger if exception.
2055  if (caught_exception) {
2056    return;
2057  }
2058  // Process debug event.
2059  ProcessDebugEvent(v8::NewFunction, Handle<JSObject>::cast(event_data), true);
2060}
2061
2062
2063void Debugger::OnScriptCollected(int id) {
2064  HandleScope scope;
2065
2066  // No more to do if not debugging.
2067  if (!IsDebuggerActive()) return;
2068  if (!Debugger::EventActive(v8::ScriptCollected)) return;
2069
2070  // Enter the debugger.
2071  EnterDebugger debugger;
2072  if (debugger.FailedToEnter()) return;
2073
2074  // Create the script collected state object.
2075  bool caught_exception = false;
2076  Handle<Object> event_data = MakeScriptCollectedEvent(id,
2077                                                       &caught_exception);
2078  // Bail out and don't call debugger if exception.
2079  if (caught_exception) {
2080    return;
2081  }
2082
2083  // Process debug event.
2084  ProcessDebugEvent(v8::ScriptCollected,
2085                    Handle<JSObject>::cast(event_data),
2086                    true);
2087}
2088
2089
2090void Debugger::ProcessDebugEvent(v8::DebugEvent event,
2091                                 Handle<JSObject> event_data,
2092                                 bool auto_continue) {
2093  HandleScope scope;
2094
2095  // Clear any pending debug break if this is a real break.
2096  if (!auto_continue) {
2097    Debug::clear_interrupt_pending(DEBUGBREAK);
2098  }
2099
2100  // Create the execution state.
2101  bool caught_exception = false;
2102  Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2103  if (caught_exception) {
2104    return;
2105  }
2106  // First notify the message handler if any.
2107  if (message_handler_ != NULL) {
2108    NotifyMessageHandler(event,
2109                         Handle<JSObject>::cast(exec_state),
2110                         event_data,
2111                         auto_continue);
2112  }
2113  // Notify registered debug event listener. This can be either a C or a
2114  // JavaScript function.
2115  if (!event_listener_.is_null()) {
2116    if (event_listener_->IsProxy()) {
2117      // C debug event listener.
2118      Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_));
2119      v8::Debug::EventCallback callback =
2120            FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy());
2121      callback(event,
2122               v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
2123               v8::Utils::ToLocal(event_data),
2124               v8::Utils::ToLocal(Handle<Object>::cast(event_listener_data_)));
2125    } else {
2126      // JavaScript debug event listener.
2127      ASSERT(event_listener_->IsJSFunction());
2128      Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
2129
2130      // Invoke the JavaScript debug event listener.
2131      const int argc = 4;
2132      Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(),
2133                              exec_state.location(),
2134                              Handle<Object>::cast(event_data).location(),
2135                              event_listener_data_.location() };
2136      Handle<Object> result = Execution::TryCall(fun, Top::global(),
2137                                                 argc, argv, &caught_exception);
2138      // Silently ignore exceptions from debug event listeners.
2139    }
2140  }
2141}
2142
2143
2144void Debugger::UnloadDebugger() {
2145  // Make sure that there are no breakpoints left.
2146  Debug::ClearAllBreakPoints();
2147
2148  // Unload the debugger if feasible.
2149  if (!never_unload_debugger_) {
2150    Debug::Unload();
2151  }
2152
2153  // Clear the flag indicating that the debugger should be unloaded.
2154  debugger_unload_pending_ = false;
2155}
2156
2157
2158void Debugger::NotifyMessageHandler(v8::DebugEvent event,
2159                                    Handle<JSObject> exec_state,
2160                                    Handle<JSObject> event_data,
2161                                    bool auto_continue) {
2162  HandleScope scope;
2163
2164  if (!Debug::Load()) return;
2165
2166  // Process the individual events.
2167  bool sendEventMessage = false;
2168  switch (event) {
2169    case v8::Break:
2170      sendEventMessage = !auto_continue;
2171      break;
2172    case v8::Exception:
2173      sendEventMessage = true;
2174      break;
2175    case v8::BeforeCompile:
2176      break;
2177    case v8::AfterCompile:
2178      sendEventMessage = true;
2179      break;
2180    case v8::ScriptCollected:
2181      sendEventMessage = true;
2182      break;
2183    case v8::NewFunction:
2184      break;
2185    default:
2186      UNREACHABLE();
2187  }
2188
2189  // The debug command interrupt flag might have been set when the command was
2190  // added. It should be enough to clear the flag only once while we are in the
2191  // debugger.
2192  ASSERT(Debug::InDebugger());
2193  StackGuard::Continue(DEBUGCOMMAND);
2194
2195  // Notify the debugger that a debug event has occurred unless auto continue is
2196  // active in which case no event is send.
2197  if (sendEventMessage) {
2198    MessageImpl message = MessageImpl::NewEvent(
2199        event,
2200        auto_continue,
2201        Handle<JSObject>::cast(exec_state),
2202        Handle<JSObject>::cast(event_data));
2203    InvokeMessageHandler(message);
2204  }
2205
2206  // If auto continue don't make the event cause a break, but process messages
2207  // in the queue if any. For script collected events don't even process
2208  // messages in the queue as the execution state might not be what is expected
2209  // by the client.
2210  if ((auto_continue && !HasCommands()) || event == v8::ScriptCollected) {
2211    return;
2212  }
2213
2214  v8::TryCatch try_catch;
2215
2216  // DebugCommandProcessor goes here.
2217  v8::Local<v8::Object> cmd_processor;
2218  {
2219    v8::Local<v8::Object> api_exec_state =
2220        v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state));
2221    v8::Local<v8::String> fun_name =
2222        v8::String::New("debugCommandProcessor");
2223    v8::Local<v8::Function> fun =
2224        v8::Function::Cast(*api_exec_state->Get(fun_name));
2225
2226    v8::Handle<v8::Boolean> running =
2227        auto_continue ? v8::True() : v8::False();
2228    static const int kArgc = 1;
2229    v8::Handle<Value> argv[kArgc] = { running };
2230    cmd_processor = v8::Object::Cast(*fun->Call(api_exec_state, kArgc, argv));
2231    if (try_catch.HasCaught()) {
2232      PrintLn(try_catch.Exception());
2233      return;
2234    }
2235  }
2236
2237  bool running = auto_continue;
2238
2239  // Process requests from the debugger.
2240  while (true) {
2241    // Wait for new command in the queue.
2242    if (Debugger::host_dispatch_handler_) {
2243      // In case there is a host dispatch - do periodic dispatches.
2244      if (!command_received_->Wait(host_dispatch_micros_)) {
2245        // Timout expired, do the dispatch.
2246        Debugger::host_dispatch_handler_();
2247        continue;
2248      }
2249    } else {
2250      // In case there is no host dispatch - just wait.
2251      command_received_->Wait();
2252    }
2253
2254    // Get the command from the queue.
2255    CommandMessage command = command_queue_.Get();
2256    Logger::DebugTag("Got request from command queue, in interactive loop.");
2257    if (!Debugger::IsDebuggerActive()) {
2258      // Delete command text and user data.
2259      command.Dispose();
2260      return;
2261    }
2262
2263    // Invoke JavaScript to process the debug request.
2264    v8::Local<v8::String> fun_name;
2265    v8::Local<v8::Function> fun;
2266    v8::Local<v8::Value> request;
2267    v8::TryCatch try_catch;
2268    fun_name = v8::String::New("processDebugRequest");
2269    fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
2270
2271    request = v8::String::New(command.text().start(),
2272                              command.text().length());
2273    static const int kArgc = 1;
2274    v8::Handle<Value> argv[kArgc] = { request };
2275    v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv);
2276
2277    // Get the response.
2278    v8::Local<v8::String> response;
2279    if (!try_catch.HasCaught()) {
2280      // Get response string.
2281      if (!response_val->IsUndefined()) {
2282        response = v8::String::Cast(*response_val);
2283      } else {
2284        response = v8::String::New("");
2285      }
2286
2287      // Log the JSON request/response.
2288      if (FLAG_trace_debug_json) {
2289        PrintLn(request);
2290        PrintLn(response);
2291      }
2292
2293      // Get the running state.
2294      fun_name = v8::String::New("isRunning");
2295      fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
2296      static const int kArgc = 1;
2297      v8::Handle<Value> argv[kArgc] = { response };
2298      v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv);
2299      if (!try_catch.HasCaught()) {
2300        running = running_val->ToBoolean()->Value();
2301      }
2302    } else {
2303      // In case of failure the result text is the exception text.
2304      response = try_catch.Exception()->ToString();
2305    }
2306
2307    // Return the result.
2308    MessageImpl message = MessageImpl::NewResponse(
2309        event,
2310        running,
2311        Handle<JSObject>::cast(exec_state),
2312        Handle<JSObject>::cast(event_data),
2313        Handle<String>(Utils::OpenHandle(*response)),
2314        command.client_data());
2315    InvokeMessageHandler(message);
2316    command.Dispose();
2317
2318    // Return from debug event processing if either the VM is put into the
2319    // runnning state (through a continue command) or auto continue is active
2320    // and there are no more commands queued.
2321    if (running && !HasCommands()) {
2322      return;
2323    }
2324  }
2325}
2326
2327
2328void Debugger::SetEventListener(Handle<Object> callback,
2329                                Handle<Object> data) {
2330  HandleScope scope;
2331
2332  // Clear the global handles for the event listener and the event listener data
2333  // object.
2334  if (!event_listener_.is_null()) {
2335    GlobalHandles::Destroy(
2336        reinterpret_cast<Object**>(event_listener_.location()));
2337    event_listener_ = Handle<Object>();
2338  }
2339  if (!event_listener_data_.is_null()) {
2340    GlobalHandles::Destroy(
2341        reinterpret_cast<Object**>(event_listener_data_.location()));
2342    event_listener_data_ = Handle<Object>();
2343  }
2344
2345  // If there is a new debug event listener register it together with its data
2346  // object.
2347  if (!callback->IsUndefined() && !callback->IsNull()) {
2348    event_listener_ = Handle<Object>::cast(GlobalHandles::Create(*callback));
2349    if (data.is_null()) {
2350      data = Factory::undefined_value();
2351    }
2352    event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data));
2353  }
2354
2355  ListenersChanged();
2356}
2357
2358
2359void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) {
2360  ScopedLock with(debugger_access_);
2361
2362  message_handler_ = handler;
2363  ListenersChanged();
2364  if (handler == NULL) {
2365    // Send an empty command to the debugger if in a break to make JavaScript
2366    // run again if the debugger is closed.
2367    if (Debug::InDebugger()) {
2368      ProcessCommand(Vector<const uint16_t>::empty());
2369    }
2370  }
2371}
2372
2373
2374void Debugger::ListenersChanged() {
2375  if (IsDebuggerActive()) {
2376    // Disable the compilation cache when the debugger is active.
2377    CompilationCache::Disable();
2378    debugger_unload_pending_ = false;
2379  } else {
2380    CompilationCache::Enable();
2381    // Unload the debugger if event listener and message handler cleared.
2382    // Schedule this for later, because we may be in non-V8 thread.
2383    debugger_unload_pending_ = true;
2384  }
2385}
2386
2387
2388void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
2389                                      int period) {
2390  host_dispatch_handler_ = handler;
2391  host_dispatch_micros_ = period * 1000;
2392}
2393
2394
2395void Debugger::SetDebugMessageDispatchHandler(
2396    v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) {
2397  ScopedLock with(dispatch_handler_access_);
2398  debug_message_dispatch_handler_ = handler;
2399
2400  if (provide_locker && message_dispatch_helper_thread_ == NULL) {
2401    message_dispatch_helper_thread_ = new MessageDispatchHelperThread;
2402    message_dispatch_helper_thread_->Start();
2403  }
2404}
2405
2406
2407// Calls the registered debug message handler. This callback is part of the
2408// public API.
2409void Debugger::InvokeMessageHandler(MessageImpl message) {
2410  ScopedLock with(debugger_access_);
2411
2412  if (message_handler_ != NULL) {
2413    message_handler_(message);
2414  }
2415}
2416
2417
2418// Puts a command coming from the public API on the queue.  Creates
2419// a copy of the command string managed by the debugger.  Up to this
2420// point, the command data was managed by the API client.  Called
2421// by the API client thread.
2422void Debugger::ProcessCommand(Vector<const uint16_t> command,
2423                              v8::Debug::ClientData* client_data) {
2424  // Need to cast away const.
2425  CommandMessage message = CommandMessage::New(
2426      Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
2427                       command.length()),
2428      client_data);
2429  Logger::DebugTag("Put command on command_queue.");
2430  command_queue_.Put(message);
2431  command_received_->Signal();
2432
2433  // Set the debug command break flag to have the command processed.
2434  if (!Debug::InDebugger()) {
2435    StackGuard::DebugCommand();
2436  }
2437
2438  MessageDispatchHelperThread* dispatch_thread;
2439  {
2440    ScopedLock with(dispatch_handler_access_);
2441    dispatch_thread = message_dispatch_helper_thread_;
2442  }
2443
2444  if (dispatch_thread == NULL) {
2445    CallMessageDispatchHandler();
2446  } else {
2447    dispatch_thread->Schedule();
2448  }
2449}
2450
2451
2452bool Debugger::HasCommands() {
2453  return !command_queue_.IsEmpty();
2454}
2455
2456
2457bool Debugger::IsDebuggerActive() {
2458  ScopedLock with(debugger_access_);
2459
2460  return message_handler_ != NULL || !event_listener_.is_null();
2461}
2462
2463
2464Handle<Object> Debugger::Call(Handle<JSFunction> fun,
2465                              Handle<Object> data,
2466                              bool* pending_exception) {
2467  // When calling functions in the debugger prevent it from beeing unloaded.
2468  Debugger::never_unload_debugger_ = true;
2469
2470  // Enter the debugger.
2471  EnterDebugger debugger;
2472  if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) {
2473    return Factory::undefined_value();
2474  }
2475
2476  // Create the execution state.
2477  bool caught_exception = false;
2478  Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2479  if (caught_exception) {
2480    return Factory::undefined_value();
2481  }
2482
2483  static const int kArgc = 2;
2484  Object** argv[kArgc] = { exec_state.location(), data.location() };
2485  Handle<Object> result = Execution::Call(fun, Factory::undefined_value(),
2486                                          kArgc, argv, pending_exception);
2487  return result;
2488}
2489
2490
2491static void StubMessageHandler2(const v8::Debug::Message& message) {
2492  // Simply ignore message.
2493}
2494
2495
2496bool Debugger::StartAgent(const char* name, int port,
2497                          bool wait_for_connection) {
2498  if (wait_for_connection) {
2499    // Suspend V8 if it is already running or set V8 to suspend whenever
2500    // it starts.
2501    // Provide stub message handler; V8 auto-continues each suspend
2502    // when there is no message handler; we doesn't need it.
2503    // Once become suspended, V8 will stay so indefinitely long, until remote
2504    // debugger connects and issues "continue" command.
2505    Debugger::message_handler_ = StubMessageHandler2;
2506    v8::Debug::DebugBreak();
2507  }
2508
2509  if (Socket::Setup()) {
2510    agent_ = new DebuggerAgent(name, port);
2511    agent_->Start();
2512    return true;
2513  }
2514
2515  return false;
2516}
2517
2518
2519void Debugger::StopAgent() {
2520  if (agent_ != NULL) {
2521    agent_->Shutdown();
2522    agent_->Join();
2523    delete agent_;
2524    agent_ = NULL;
2525  }
2526}
2527
2528
2529void Debugger::WaitForAgent() {
2530  if (agent_ != NULL)
2531    agent_->WaitUntilListening();
2532}
2533
2534
2535void Debugger::CallMessageDispatchHandler() {
2536  v8::Debug::DebugMessageDispatchHandler handler;
2537  {
2538    ScopedLock with(dispatch_handler_access_);
2539    handler = Debugger::debug_message_dispatch_handler_;
2540  }
2541  if (handler != NULL) {
2542    handler();
2543  }
2544}
2545
2546
2547MessageImpl MessageImpl::NewEvent(DebugEvent event,
2548                                  bool running,
2549                                  Handle<JSObject> exec_state,
2550                                  Handle<JSObject> event_data) {
2551  MessageImpl message(true, event, running,
2552                      exec_state, event_data, Handle<String>(), NULL);
2553  return message;
2554}
2555
2556
2557MessageImpl MessageImpl::NewResponse(DebugEvent event,
2558                                     bool running,
2559                                     Handle<JSObject> exec_state,
2560                                     Handle<JSObject> event_data,
2561                                     Handle<String> response_json,
2562                                     v8::Debug::ClientData* client_data) {
2563  MessageImpl message(false, event, running,
2564                      exec_state, event_data, response_json, client_data);
2565  return message;
2566}
2567
2568
2569MessageImpl::MessageImpl(bool is_event,
2570                         DebugEvent event,
2571                         bool running,
2572                         Handle<JSObject> exec_state,
2573                         Handle<JSObject> event_data,
2574                         Handle<String> response_json,
2575                         v8::Debug::ClientData* client_data)
2576    : is_event_(is_event),
2577      event_(event),
2578      running_(running),
2579      exec_state_(exec_state),
2580      event_data_(event_data),
2581      response_json_(response_json),
2582      client_data_(client_data) {}
2583
2584
2585bool MessageImpl::IsEvent() const {
2586  return is_event_;
2587}
2588
2589
2590bool MessageImpl::IsResponse() const {
2591  return !is_event_;
2592}
2593
2594
2595DebugEvent MessageImpl::GetEvent() const {
2596  return event_;
2597}
2598
2599
2600bool MessageImpl::WillStartRunning() const {
2601  return running_;
2602}
2603
2604
2605v8::Handle<v8::Object> MessageImpl::GetExecutionState() const {
2606  return v8::Utils::ToLocal(exec_state_);
2607}
2608
2609
2610v8::Handle<v8::Object> MessageImpl::GetEventData() const {
2611  return v8::Utils::ToLocal(event_data_);
2612}
2613
2614
2615v8::Handle<v8::String> MessageImpl::GetJSON() const {
2616  v8::HandleScope scope;
2617
2618  if (IsEvent()) {
2619    // Call toJSONProtocol on the debug event object.
2620    Handle<Object> fun = GetProperty(event_data_, "toJSONProtocol");
2621    if (!fun->IsJSFunction()) {
2622      return v8::Handle<v8::String>();
2623    }
2624    bool caught_exception;
2625    Handle<Object> json = Execution::TryCall(Handle<JSFunction>::cast(fun),
2626                                             event_data_,
2627                                             0, NULL, &caught_exception);
2628    if (caught_exception || !json->IsString()) {
2629      return v8::Handle<v8::String>();
2630    }
2631    return scope.Close(v8::Utils::ToLocal(Handle<String>::cast(json)));
2632  } else {
2633    return v8::Utils::ToLocal(response_json_);
2634  }
2635}
2636
2637
2638v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
2639  Handle<Context> context = Debug::debugger_entry()->GetContext();
2640  // Top::context() may have been NULL when "script collected" event occured.
2641  if (*context == NULL) {
2642    ASSERT(event_ == v8::ScriptCollected);
2643    return v8::Local<v8::Context>();
2644  }
2645  Handle<Context> global_context(context->global_context());
2646  return v8::Utils::ToLocal(global_context);
2647}
2648
2649
2650v8::Debug::ClientData* MessageImpl::GetClientData() const {
2651  return client_data_;
2652}
2653
2654
2655CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
2656                                   client_data_(NULL) {
2657}
2658
2659
2660CommandMessage::CommandMessage(const Vector<uint16_t>& text,
2661                               v8::Debug::ClientData* data)
2662    : text_(text),
2663      client_data_(data) {
2664}
2665
2666
2667CommandMessage::~CommandMessage() {
2668}
2669
2670
2671void CommandMessage::Dispose() {
2672  text_.Dispose();
2673  delete client_data_;
2674  client_data_ = NULL;
2675}
2676
2677
2678CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
2679                                   v8::Debug::ClientData* data) {
2680  return CommandMessage(command.Clone(), data);
2681}
2682
2683
2684CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
2685                                                     size_(size) {
2686  messages_ = NewArray<CommandMessage>(size);
2687}
2688
2689
2690CommandMessageQueue::~CommandMessageQueue() {
2691  while (!IsEmpty()) {
2692    CommandMessage m = Get();
2693    m.Dispose();
2694  }
2695  DeleteArray(messages_);
2696}
2697
2698
2699CommandMessage CommandMessageQueue::Get() {
2700  ASSERT(!IsEmpty());
2701  int result = start_;
2702  start_ = (start_ + 1) % size_;
2703  return messages_[result];
2704}
2705
2706
2707void CommandMessageQueue::Put(const CommandMessage& message) {
2708  if ((end_ + 1) % size_ == start_) {
2709    Expand();
2710  }
2711  messages_[end_] = message;
2712  end_ = (end_ + 1) % size_;
2713}
2714
2715
2716void CommandMessageQueue::Expand() {
2717  CommandMessageQueue new_queue(size_ * 2);
2718  while (!IsEmpty()) {
2719    new_queue.Put(Get());
2720  }
2721  CommandMessage* array_to_free = messages_;
2722  *this = new_queue;
2723  new_queue.messages_ = array_to_free;
2724  // Make the new_queue empty so that it doesn't call Dispose on any messages.
2725  new_queue.start_ = new_queue.end_;
2726  // Automatic destructor called on new_queue, freeing array_to_free.
2727}
2728
2729
2730LockingCommandMessageQueue::LockingCommandMessageQueue(int size)
2731    : queue_(size) {
2732  lock_ = OS::CreateMutex();
2733}
2734
2735
2736LockingCommandMessageQueue::~LockingCommandMessageQueue() {
2737  delete lock_;
2738}
2739
2740
2741bool LockingCommandMessageQueue::IsEmpty() const {
2742  ScopedLock sl(lock_);
2743  return queue_.IsEmpty();
2744}
2745
2746
2747CommandMessage LockingCommandMessageQueue::Get() {
2748  ScopedLock sl(lock_);
2749  CommandMessage result = queue_.Get();
2750  Logger::DebugEvent("Get", result.text());
2751  return result;
2752}
2753
2754
2755void LockingCommandMessageQueue::Put(const CommandMessage& message) {
2756  ScopedLock sl(lock_);
2757  queue_.Put(message);
2758  Logger::DebugEvent("Put", message.text());
2759}
2760
2761
2762void LockingCommandMessageQueue::Clear() {
2763  ScopedLock sl(lock_);
2764  queue_.Clear();
2765}
2766
2767
2768MessageDispatchHelperThread::MessageDispatchHelperThread()
2769    : sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
2770      already_signalled_(false) {
2771}
2772
2773
2774MessageDispatchHelperThread::~MessageDispatchHelperThread() {
2775  delete mutex_;
2776  delete sem_;
2777}
2778
2779
2780void MessageDispatchHelperThread::Schedule() {
2781  {
2782    ScopedLock lock(mutex_);
2783    if (already_signalled_) {
2784      return;
2785    }
2786    already_signalled_ = true;
2787  }
2788  sem_->Signal();
2789}
2790
2791
2792void MessageDispatchHelperThread::Run() {
2793  while (true) {
2794    sem_->Wait();
2795    {
2796      ScopedLock lock(mutex_);
2797      already_signalled_ = false;
2798    }
2799    {
2800      Locker locker;
2801      Debugger::CallMessageDispatchHandler();
2802    }
2803  }
2804}
2805
2806#endif  // ENABLE_DEBUGGER_SUPPORT
2807
2808} }  // namespace v8::internal
2809