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