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