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