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