[es6] Implement spec compliant ToPrimitive in the runtime.
[platform/upstream/v8.git] / src / debug / debug.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/debug/debug.h"
6
7 #include "src/api.h"
8 #include "src/arguments.h"
9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h"
11 #include "src/codegen.h"
12 #include "src/compilation-cache.h"
13 #include "src/compiler.h"
14 #include "src/deoptimizer.h"
15 #include "src/execution.h"
16 #include "src/frames-inl.h"
17 #include "src/full-codegen/full-codegen.h"
18 #include "src/global-handles.h"
19 #include "src/list.h"
20 #include "src/log.h"
21 #include "src/messages.h"
22 #include "src/snapshot/natives.h"
23
24 #include "include/v8-debug.h"
25
26 namespace v8 {
27 namespace internal {
28
29 Debug::Debug(Isolate* isolate)
30     : debug_context_(Handle<Context>()),
31       event_listener_(Handle<Object>()),
32       event_listener_data_(Handle<Object>()),
33       message_handler_(NULL),
34       command_received_(0),
35       command_queue_(isolate->logger(), kQueueInitialSize),
36       is_active_(false),
37       is_suppressed_(false),
38       live_edit_enabled_(true),  // TODO(yangguo): set to false by default.
39       break_disabled_(false),
40       in_debug_event_listener_(false),
41       break_on_exception_(false),
42       break_on_uncaught_exception_(false),
43       debug_info_list_(NULL),
44       isolate_(isolate) {
45   ThreadInit();
46 }
47
48
49 static v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
50   Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
51   // Isolate::context() may have been NULL when "script collected" event
52   // occured.
53   if (context.is_null()) return v8::Local<v8::Context>();
54   Handle<Context> native_context(context->native_context());
55   return v8::Utils::ToLocal(native_context);
56 }
57
58
59 BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo,
60                              int position, int statement_position)
61     : debug_info_(debug_info),
62       pc_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())),
63       rmode_(rinfo->rmode()),
64       data_(rinfo->data()),
65       position_(position),
66       statement_position_(statement_position) {}
67
68
69 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
70                                   BreakLocatorType type)
71     : debug_info_(debug_info),
72       reloc_iterator_(debug_info->code(), GetModeMask(type)),
73       break_index_(-1),
74       position_(1),
75       statement_position_(1) {
76   if (!Done()) Next();
77 }
78
79
80 int BreakLocation::Iterator::GetModeMask(BreakLocatorType type) {
81   int mask = 0;
82   mask |= RelocInfo::ModeMask(RelocInfo::POSITION);
83   mask |= RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION);
84   mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
85   mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL);
86   mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CONSTRUCT_CALL);
87   if (type == ALL_BREAK_LOCATIONS) {
88     mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
89     mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT);
90   }
91   return mask;
92 }
93
94
95 void BreakLocation::Iterator::Next() {
96   DisallowHeapAllocation no_gc;
97   DCHECK(!Done());
98
99   // Iterate through reloc info for code and original code stopping at each
100   // breakable code target.
101   bool first = break_index_ == -1;
102   while (!Done()) {
103     if (!first) reloc_iterator_.next();
104     first = false;
105     if (Done()) return;
106
107     // Whenever a statement position or (plain) position is passed update the
108     // current value of these.
109     if (RelocInfo::IsPosition(rmode())) {
110       if (RelocInfo::IsStatementPosition(rmode())) {
111         statement_position_ = static_cast<int>(
112             rinfo()->data() - debug_info_->shared()->start_position());
113       }
114       // Always update the position as we don't want that to be before the
115       // statement position.
116       position_ = static_cast<int>(rinfo()->data() -
117                                    debug_info_->shared()->start_position());
118       DCHECK(position_ >= 0);
119       DCHECK(statement_position_ >= 0);
120       continue;
121     }
122
123     DCHECK(RelocInfo::IsDebugBreakSlot(rmode()) ||
124            RelocInfo::IsDebuggerStatement(rmode()));
125
126     if (RelocInfo::IsDebugBreakSlotAtReturn(rmode())) {
127       // Set the positions to the end of the function.
128       if (debug_info_->shared()->HasSourceCode()) {
129         position_ = debug_info_->shared()->end_position() -
130                     debug_info_->shared()->start_position() - 1;
131       } else {
132         position_ = 0;
133       }
134       statement_position_ = position_;
135     }
136
137     break;
138   }
139   break_index_++;
140 }
141
142
143 // Find the break point at the supplied address, or the closest one before
144 // the address.
145 BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info,
146                                          BreakLocatorType type, Address pc) {
147   Iterator it(debug_info, type);
148   it.SkipTo(BreakIndexFromAddress(debug_info, type, pc));
149   return it.GetBreakLocation();
150 }
151
152
153 // Find the break point at the supplied address, or the closest one before
154 // the address.
155 void BreakLocation::FromAddressSameStatement(Handle<DebugInfo> debug_info,
156                                              BreakLocatorType type, Address pc,
157                                              List<BreakLocation>* result_out) {
158   int break_index = BreakIndexFromAddress(debug_info, type, pc);
159   Iterator it(debug_info, type);
160   it.SkipTo(break_index);
161   int statement_position = it.statement_position();
162   while (!it.Done() && it.statement_position() == statement_position) {
163     result_out->Add(it.GetBreakLocation());
164     it.Next();
165   }
166 }
167
168
169 int BreakLocation::BreakIndexFromAddress(Handle<DebugInfo> debug_info,
170                                          BreakLocatorType type, Address pc) {
171   // Run through all break points to locate the one closest to the address.
172   int closest_break = 0;
173   int distance = kMaxInt;
174   for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
175     // Check if this break point is closer that what was previously found.
176     if (it.pc() <= pc && pc - it.pc() < distance) {
177       closest_break = it.break_index();
178       distance = static_cast<int>(pc - it.pc());
179       // Check whether we can't get any closer.
180       if (distance == 0) break;
181     }
182   }
183   return closest_break;
184 }
185
186
187 BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info,
188                                           BreakLocatorType type, int position,
189                                           BreakPositionAlignment alignment) {
190   // Run through all break points to locate the one closest to the source
191   // position.
192   int closest_break = 0;
193   int distance = kMaxInt;
194
195   for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
196     int next_position;
197     if (alignment == STATEMENT_ALIGNED) {
198       next_position = it.statement_position();
199     } else {
200       DCHECK(alignment == BREAK_POSITION_ALIGNED);
201       next_position = it.position();
202     }
203     if (position <= next_position && next_position - position < distance) {
204       closest_break = it.break_index();
205       distance = next_position - position;
206       // Check whether we can't get any closer.
207       if (distance == 0) break;
208     }
209   }
210
211   Iterator it(debug_info, type);
212   it.SkipTo(closest_break);
213   return it.GetBreakLocation();
214 }
215
216
217 void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
218   // If there is not already a real break point here patch code with debug
219   // break.
220   if (!HasBreakPoint()) SetDebugBreak();
221   DCHECK(IsDebugBreak() || IsDebuggerStatement());
222   // Set the break point information.
223   DebugInfo::SetBreakPoint(debug_info_, pc_offset_, position_,
224                            statement_position_, break_point_object);
225 }
226
227
228 void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) {
229   // Clear the break point information.
230   DebugInfo::ClearBreakPoint(debug_info_, pc_offset_, break_point_object);
231   // If there are no more break points here remove the debug break.
232   if (!HasBreakPoint()) {
233     ClearDebugBreak();
234     DCHECK(!IsDebugBreak());
235   }
236 }
237
238
239 void BreakLocation::SetOneShot() {
240   // Debugger statement always calls debugger. No need to modify it.
241   if (IsDebuggerStatement()) return;
242
243   // If there is a real break point here no more to do.
244   if (HasBreakPoint()) {
245     DCHECK(IsDebugBreak());
246     return;
247   }
248
249   // Patch code with debug break.
250   SetDebugBreak();
251 }
252
253
254 void BreakLocation::ClearOneShot() {
255   // Debugger statement always calls debugger. No need to modify it.
256   if (IsDebuggerStatement()) return;
257
258   // If there is a real break point here no more to do.
259   if (HasBreakPoint()) {
260     DCHECK(IsDebugBreak());
261     return;
262   }
263
264   // Patch code removing debug break.
265   ClearDebugBreak();
266   DCHECK(!IsDebugBreak());
267 }
268
269
270 void BreakLocation::SetDebugBreak() {
271   // Debugger statement always calls debugger. No need to modify it.
272   if (IsDebuggerStatement()) return;
273
274   // If there is already a break point here just return. This might happen if
275   // the same code is flooded with break points twice. Flooding the same
276   // function twice might happen when stepping in a function with an exception
277   // handler as the handler and the function is the same.
278   if (IsDebugBreak()) return;
279
280   DCHECK(IsDebugBreakSlot());
281   Builtins* builtins = debug_info_->GetIsolate()->builtins();
282   Handle<Code> target =
283       IsReturn() ? builtins->Return_DebugBreak() : builtins->Slot_DebugBreak();
284   DebugCodegen::PatchDebugBreakSlot(pc(), target);
285   DCHECK(IsDebugBreak());
286 }
287
288
289 void BreakLocation::ClearDebugBreak() {
290   // Debugger statement always calls debugger. No need to modify it.
291   if (IsDebuggerStatement()) return;
292
293   DCHECK(IsDebugBreakSlot());
294   DebugCodegen::ClearDebugBreakSlot(pc());
295   DCHECK(!IsDebugBreak());
296 }
297
298
299 bool BreakLocation::IsStepInLocation() const {
300   return IsConstructCall() || IsCall();
301 }
302
303
304 bool BreakLocation::IsDebugBreak() const {
305   if (IsDebugBreakSlot()) {
306     return rinfo().IsPatchedDebugBreakSlotSequence();
307   }
308   return false;
309 }
310
311
312 Handle<Object> BreakLocation::BreakPointObjects() const {
313   return debug_info_->GetBreakPointObjects(pc_offset_);
314 }
315
316
317 // Threading support.
318 void Debug::ThreadInit() {
319   thread_local_.break_count_ = 0;
320   thread_local_.break_id_ = 0;
321   thread_local_.break_frame_id_ = StackFrame::NO_ID;
322   thread_local_.last_step_action_ = StepNone;
323   thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
324   thread_local_.step_count_ = 0;
325   thread_local_.last_fp_ = 0;
326   thread_local_.queued_step_count_ = 0;
327   thread_local_.step_into_fp_ = 0;
328   thread_local_.step_out_fp_ = 0;
329   // TODO(isolates): frames_are_dropped_?
330   base::NoBarrier_Store(&thread_local_.current_debug_scope_,
331                         static_cast<base::AtomicWord>(0));
332   thread_local_.restarter_frame_function_pointer_ = NULL;
333 }
334
335
336 char* Debug::ArchiveDebug(char* storage) {
337   char* to = storage;
338   MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
339   ThreadInit();
340   return storage + ArchiveSpacePerThread();
341 }
342
343
344 char* Debug::RestoreDebug(char* storage) {
345   char* from = storage;
346   MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
347   return storage + ArchiveSpacePerThread();
348 }
349
350
351 int Debug::ArchiveSpacePerThread() {
352   return sizeof(ThreadLocal);
353 }
354
355
356 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
357   // Globalize the request debug info object and make it weak.
358   GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
359   debug_info_ =
360       Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location();
361 }
362
363
364 DebugInfoListNode::~DebugInfoListNode() {
365   if (debug_info_ == nullptr) return;
366   GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_));
367   debug_info_ = nullptr;
368 }
369
370
371 bool Debug::Load() {
372   // Return if debugger is already loaded.
373   if (is_loaded()) return true;
374
375   // Bail out if we're already in the process of compiling the native
376   // JavaScript source code for the debugger.
377   if (is_suppressed_) return false;
378   SuppressDebug while_loading(this);
379
380   // Disable breakpoints and interrupts while compiling and running the
381   // debugger scripts including the context creation code.
382   DisableBreak disable(this, true);
383   PostponeInterruptsScope postpone(isolate_);
384
385   // Create the debugger context.
386   HandleScope scope(isolate_);
387   ExtensionConfiguration no_extensions;
388   Handle<Context> context = isolate_->bootstrapper()->CreateEnvironment(
389       MaybeHandle<JSGlobalProxy>(), v8::Local<ObjectTemplate>(), &no_extensions,
390       DEBUG_CONTEXT);
391
392   // Fail if no context could be created.
393   if (context.is_null()) return false;
394
395   debug_context_ = Handle<Context>::cast(
396       isolate_->global_handles()->Create(*context));
397   return true;
398 }
399
400
401 void Debug::Unload() {
402   ClearAllBreakPoints();
403   ClearStepping();
404
405   // Return debugger is not loaded.
406   if (!is_loaded()) return;
407
408   // Clear debugger context global handle.
409   GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
410   debug_context_ = Handle<Context>();
411 }
412
413
414 void Debug::Break(Arguments args, JavaScriptFrame* frame) {
415   Heap* heap = isolate_->heap();
416   HandleScope scope(isolate_);
417   DCHECK(args.length() == 0);
418
419   // Initialize LiveEdit.
420   LiveEdit::InitializeThreadLocal(this);
421
422   // Just continue if breaks are disabled or debugger cannot be loaded.
423   if (break_disabled()) return;
424
425   // Enter the debugger.
426   DebugScope debug_scope(this);
427   if (debug_scope.failed()) return;
428
429   // Postpone interrupt during breakpoint processing.
430   PostponeInterruptsScope postpone(isolate_);
431
432   // Get the debug info (create it if it does not exist).
433   Handle<JSFunction> function(frame->function());
434   Handle<SharedFunctionInfo> shared(function->shared());
435   if (!EnsureDebugInfo(shared, function)) {
436     // Return if we failed to retrieve the debug info.
437     return;
438   }
439   Handle<DebugInfo> debug_info(shared->GetDebugInfo());
440
441   // Find the break point where execution has stopped.
442   // PC points to the instruction after the current one, possibly a break
443   // location as well. So the "- 1" to exclude it from the search.
444   Address call_pc = frame->pc() - 1;
445   BreakLocation break_location =
446       BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
447
448   // Check whether step next reached a new statement.
449   if (!StepNextContinue(&break_location, frame)) {
450     // Decrease steps left if performing multiple steps.
451     if (thread_local_.step_count_ > 0) {
452       thread_local_.step_count_--;
453     }
454   }
455
456   // If there is one or more real break points check whether any of these are
457   // triggered.
458   Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
459   if (break_location.HasBreakPoint()) {
460     Handle<Object> break_point_objects = break_location.BreakPointObjects();
461     break_points_hit = CheckBreakPoints(break_point_objects);
462   }
463
464   // If step out is active skip everything until the frame where we need to step
465   // out to is reached, unless real breakpoint is hit.
466   if (StepOutActive() &&
467       frame->fp() != thread_local_.step_out_fp_ &&
468       break_points_hit->IsUndefined() ) {
469       // Step count should always be 0 for StepOut.
470       DCHECK(thread_local_.step_count_ == 0);
471   } else if (!break_points_hit->IsUndefined() ||
472              (thread_local_.last_step_action_ != StepNone &&
473               thread_local_.step_count_ == 0)) {
474     // Notify debugger if a real break point is triggered or if performing
475     // single stepping with no more steps to perform. Otherwise do another step.
476
477     // Clear all current stepping setup.
478     ClearStepping();
479
480     if (thread_local_.queued_step_count_ > 0) {
481       // Perform queued steps
482       int step_count = thread_local_.queued_step_count_;
483
484       // Clear queue
485       thread_local_.queued_step_count_ = 0;
486
487       PrepareStep(StepNext, step_count, StackFrame::NO_ID);
488     } else {
489       // Notify the debug event listeners.
490       OnDebugBreak(break_points_hit, false);
491     }
492   } else if (thread_local_.last_step_action_ != StepNone) {
493     // Hold on to last step action as it is cleared by the call to
494     // ClearStepping.
495     StepAction step_action = thread_local_.last_step_action_;
496     int step_count = thread_local_.step_count_;
497
498     // If StepNext goes deeper in code, StepOut until original frame
499     // and keep step count queued up in the meantime.
500     if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
501       // Count frames until target frame
502       int count = 0;
503       JavaScriptFrameIterator it(isolate_);
504       while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) {
505         count++;
506         it.Advance();
507       }
508
509       // Check that we indeed found the frame we are looking for.
510       CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_));
511       if (step_count > 1) {
512         // Save old count and action to continue stepping after StepOut.
513         thread_local_.queued_step_count_ = step_count - 1;
514       }
515
516       // Set up for StepOut to reach target frame.
517       step_action = StepOut;
518       step_count = count;
519     }
520
521     // Clear all current stepping setup.
522     ClearStepping();
523
524     // Set up for the remaining steps.
525     PrepareStep(step_action, step_count, StackFrame::NO_ID);
526   }
527 }
528
529
530 // Check the break point objects for whether one or more are actually
531 // triggered. This function returns a JSArray with the break point objects
532 // which is triggered.
533 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
534   Factory* factory = isolate_->factory();
535
536   // Count the number of break points hit. If there are multiple break points
537   // they are in a FixedArray.
538   Handle<FixedArray> break_points_hit;
539   int break_points_hit_count = 0;
540   DCHECK(!break_point_objects->IsUndefined());
541   if (break_point_objects->IsFixedArray()) {
542     Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
543     break_points_hit = factory->NewFixedArray(array->length());
544     for (int i = 0; i < array->length(); i++) {
545       Handle<Object> o(array->get(i), isolate_);
546       if (CheckBreakPoint(o)) {
547         break_points_hit->set(break_points_hit_count++, *o);
548       }
549     }
550   } else {
551     break_points_hit = factory->NewFixedArray(1);
552     if (CheckBreakPoint(break_point_objects)) {
553       break_points_hit->set(break_points_hit_count++, *break_point_objects);
554     }
555   }
556
557   // Return undefined if no break points were triggered.
558   if (break_points_hit_count == 0) {
559     return factory->undefined_value();
560   }
561   // Return break points hit as a JSArray.
562   Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
563   result->set_length(Smi::FromInt(break_points_hit_count));
564   return result;
565 }
566
567
568 MaybeHandle<Object> Debug::CallFunction(const char* name, int argc,
569                                         Handle<Object> args[]) {
570   PostponeInterruptsScope no_interrupts(isolate_);
571   AssertDebugContext();
572   Handle<Object> holder = isolate_->natives_utils_object();
573   Handle<JSFunction> fun = Handle<JSFunction>::cast(
574       Object::GetProperty(isolate_, holder, name, STRICT).ToHandleChecked());
575   Handle<Object> undefined = isolate_->factory()->undefined_value();
576   return Execution::TryCall(fun, undefined, argc, args);
577 }
578
579
580 // Check whether a single break point object is triggered.
581 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
582   Factory* factory = isolate_->factory();
583   HandleScope scope(isolate_);
584
585   // Ignore check if break point object is not a JSObject.
586   if (!break_point_object->IsJSObject()) return true;
587
588   // Get the break id as an object.
589   Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
590
591   // Call IsBreakPointTriggered.
592   Handle<Object> argv[] = { break_id, break_point_object };
593   Handle<Object> result;
594   if (!CallFunction("IsBreakPointTriggered", arraysize(argv), argv)
595            .ToHandle(&result)) {
596     return false;
597   }
598
599   // Return whether the break point is triggered.
600   return result->IsTrue();
601 }
602
603
604 bool Debug::SetBreakPoint(Handle<JSFunction> function,
605                           Handle<Object> break_point_object,
606                           int* source_position) {
607   HandleScope scope(isolate_);
608
609   // Make sure the function is compiled and has set up the debug info.
610   Handle<SharedFunctionInfo> shared(function->shared());
611   if (!EnsureDebugInfo(shared, function)) {
612     // Return if retrieving debug info failed.
613     return true;
614   }
615
616   Handle<DebugInfo> debug_info(shared->GetDebugInfo());
617   // Source positions starts with zero.
618   DCHECK(*source_position >= 0);
619
620   // Find the break point and change it.
621   BreakLocation location = BreakLocation::FromPosition(
622       debug_info, ALL_BREAK_LOCATIONS, *source_position, STATEMENT_ALIGNED);
623   *source_position = location.statement_position();
624   location.SetBreakPoint(break_point_object);
625
626   // At least one active break point now.
627   return debug_info->GetBreakPointCount() > 0;
628 }
629
630
631 bool Debug::SetBreakPointForScript(Handle<Script> script,
632                                    Handle<Object> break_point_object,
633                                    int* source_position,
634                                    BreakPositionAlignment alignment) {
635   HandleScope scope(isolate_);
636
637   // Obtain shared function info for the function.
638   Handle<Object> result =
639       FindSharedFunctionInfoInScript(script, *source_position);
640   if (result->IsUndefined()) return false;
641
642   // Make sure the function has set up the debug info.
643   Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
644   if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
645     // Return if retrieving debug info failed.
646     return false;
647   }
648
649   // Find position within function. The script position might be before the
650   // source position of the first function.
651   int position;
652   if (shared->start_position() > *source_position) {
653     position = 0;
654   } else {
655     position = *source_position - shared->start_position();
656   }
657
658   Handle<DebugInfo> debug_info(shared->GetDebugInfo());
659   // Source positions starts with zero.
660   DCHECK(position >= 0);
661
662   // Find the break point and change it.
663   BreakLocation location = BreakLocation::FromPosition(
664       debug_info, ALL_BREAK_LOCATIONS, position, alignment);
665   location.SetBreakPoint(break_point_object);
666
667   position = (alignment == STATEMENT_ALIGNED) ? location.statement_position()
668                                               : location.position();
669
670   *source_position = position + shared->start_position();
671
672   // At least one active break point now.
673   DCHECK(debug_info->GetBreakPointCount() > 0);
674   return true;
675 }
676
677
678 void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
679   HandleScope scope(isolate_);
680
681   DebugInfoListNode* node = debug_info_list_;
682   while (node != NULL) {
683     Handle<Object> result =
684         DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object);
685     if (!result->IsUndefined()) {
686       // Get information in the break point.
687       Handle<BreakPointInfo> break_point_info =
688           Handle<BreakPointInfo>::cast(result);
689       Handle<DebugInfo> debug_info = node->debug_info();
690
691       // Find the break point and clear it.
692       Address pc = debug_info->code()->entry() +
693                    break_point_info->code_position()->value();
694
695       BreakLocation location =
696           BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, pc);
697       location.ClearBreakPoint(break_point_object);
698
699       // If there are no more break points left remove the debug info for this
700       // function.
701       if (debug_info->GetBreakPointCount() == 0) {
702         RemoveDebugInfoAndClearFromShared(debug_info);
703       }
704
705       return;
706     }
707     node = node->next();
708   }
709 }
710
711
712 // Clear out all the debug break code. This is ONLY supposed to be used when
713 // shutting down the debugger as it will leave the break point information in
714 // DebugInfo even though the code is patched back to the non break point state.
715 void Debug::ClearAllBreakPoints() {
716   for (DebugInfoListNode* node = debug_info_list_; node != NULL;
717        node = node->next()) {
718     for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
719          !it.Done(); it.Next()) {
720       it.GetBreakLocation().ClearDebugBreak();
721     }
722   }
723   // Remove all debug info.
724   while (debug_info_list_ != NULL) {
725     RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
726   }
727 }
728
729
730 void Debug::FloodWithOneShot(Handle<JSFunction> function,
731                              BreakLocatorType type) {
732   // Make sure the function is compiled and has set up the debug info.
733   Handle<SharedFunctionInfo> shared(function->shared());
734   if (!EnsureDebugInfo(shared, function)) {
735     // Return if we failed to retrieve the debug info.
736     return;
737   }
738
739   // Flood the function with break points.
740   Handle<DebugInfo> debug_info(shared->GetDebugInfo());
741   for (BreakLocation::Iterator it(debug_info, type); !it.Done(); it.Next()) {
742     it.GetBreakLocation().SetOneShot();
743   }
744 }
745
746
747 void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) {
748   Handle<FixedArray> new_bindings(function->function_bindings());
749   Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex),
750                         isolate_);
751
752   if (!bindee.is_null() && bindee->IsJSFunction()) {
753     Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
754     FloodWithOneShotGeneric(bindee_function);
755   }
756 }
757
758
759 void Debug::FloodDefaultConstructorWithOneShot(Handle<JSFunction> function) {
760   DCHECK(function->shared()->is_default_constructor());
761   // Instead of stepping into the function we directly step into the super class
762   // constructor.
763   Isolate* isolate = function->GetIsolate();
764   PrototypeIterator iter(isolate, function);
765   Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
766   if (!proto->IsJSFunction()) return;  // Object.prototype
767   Handle<JSFunction> function_proto = Handle<JSFunction>::cast(proto);
768   FloodWithOneShotGeneric(function_proto);
769 }
770
771
772 void Debug::FloodWithOneShotGeneric(Handle<JSFunction> function,
773                                     Handle<Object> holder) {
774   if (function->shared()->bound()) {
775     FloodBoundFunctionWithOneShot(function);
776   } else if (function->shared()->is_default_constructor()) {
777     FloodDefaultConstructorWithOneShot(function);
778   } else {
779     Isolate* isolate = function->GetIsolate();
780     // Don't allow step into functions in the native context.
781     if (function->shared()->code() ==
782             isolate->builtins()->builtin(Builtins::kFunctionApply) ||
783         function->shared()->code() ==
784             isolate->builtins()->builtin(Builtins::kFunctionCall)) {
785       // Handle function.apply and function.call separately to flood the
786       // function to be called and not the code for Builtins::FunctionApply or
787       // Builtins::FunctionCall. The receiver of call/apply is the target
788       // function.
789       if (!holder.is_null() && holder->IsJSFunction()) {
790         Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
791         FloodWithOneShotGeneric(js_function);
792       }
793     } else {
794       FloodWithOneShot(function);
795     }
796   }
797 }
798
799
800 void Debug::FloodHandlerWithOneShot() {
801   // Iterate through the JavaScript stack looking for handlers.
802   StackFrame::Id id = break_frame_id();
803   if (id == StackFrame::NO_ID) {
804     // If there is no JavaScript stack don't do anything.
805     return;
806   }
807   for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
808     JavaScriptFrame* frame = it.frame();
809     int stack_slots = 0;  // The computed stack slot count is not used.
810     if (frame->LookupExceptionHandlerInTable(&stack_slots, NULL) > 0) {
811       // Flood the function with the catch/finally block with break points.
812       FloodWithOneShot(Handle<JSFunction>(frame->function()));
813       return;
814     }
815   }
816 }
817
818
819 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
820   if (type == BreakUncaughtException) {
821     break_on_uncaught_exception_ = enable;
822   } else {
823     break_on_exception_ = enable;
824   }
825 }
826
827
828 bool Debug::IsBreakOnException(ExceptionBreakType type) {
829   if (type == BreakUncaughtException) {
830     return break_on_uncaught_exception_;
831   } else {
832     return break_on_exception_;
833   }
834 }
835
836
837 FrameSummary GetFirstFrameSummary(JavaScriptFrame* frame) {
838   List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
839   frame->Summarize(&frames);
840   return frames.first();
841 }
842
843
844 void Debug::PrepareStep(StepAction step_action,
845                         int step_count,
846                         StackFrame::Id frame_id) {
847   HandleScope scope(isolate_);
848
849   DCHECK(in_debug_scope());
850
851   // Remember this step action and count.
852   thread_local_.last_step_action_ = step_action;
853   if (step_action == StepOut) {
854     // For step out target frame will be found on the stack so there is no need
855     // to set step counter for it. It's expected to always be 0 for StepOut.
856     thread_local_.step_count_ = 0;
857   } else {
858     thread_local_.step_count_ = step_count;
859   }
860
861   // Get the frame where the execution has stopped and skip the debug frame if
862   // any. The debug frame will only be present if execution was stopped due to
863   // hitting a break point. In other situations (e.g. unhandled exception) the
864   // debug frame is not present.
865   StackFrame::Id id = break_frame_id();
866   if (id == StackFrame::NO_ID) {
867     // If there is no JavaScript stack don't do anything.
868     return;
869   }
870   if (frame_id != StackFrame::NO_ID) {
871     id = frame_id;
872   }
873   JavaScriptFrameIterator frames_it(isolate_, id);
874   JavaScriptFrame* frame = frames_it.frame();
875
876   // First of all ensure there is one-shot break points in the top handler
877   // if any.
878   FloodHandlerWithOneShot();
879
880   // If the function on the top frame is unresolved perform step out. This will
881   // be the case when calling unknown function and having the debugger stopped
882   // in an unhandled exception.
883   if (!frame->function()->IsJSFunction()) {
884     // Step out: Find the calling JavaScript frame and flood it with
885     // breakpoints.
886     frames_it.Advance();
887     // Fill the function to return to with one-shot break points.
888     JSFunction* function = frames_it.frame()->function();
889     FloodWithOneShot(Handle<JSFunction>(function));
890     return;
891   }
892
893   // Get the debug info (create it if it does not exist).
894   FrameSummary summary = GetFirstFrameSummary(frame);
895   Handle<JSFunction> function(summary.function());
896   Handle<SharedFunctionInfo> shared(function->shared());
897   if (!EnsureDebugInfo(shared, function)) {
898     // Return if ensuring debug info failed.
899     return;
900   }
901
902   Handle<DebugInfo> debug_info(shared->GetDebugInfo());
903   // Refresh frame summary if the code has been recompiled for debugging.
904   if (shared->code() != *summary.code()) summary = GetFirstFrameSummary(frame);
905
906   // PC points to the instruction after the current one, possibly a break
907   // location as well. So the "- 1" to exclude it from the search.
908   Address call_pc = summary.pc() - 1;
909   BreakLocation location =
910       BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
911
912   // If this is the last break code target step out is the only possibility.
913   if (location.IsReturn() || step_action == StepOut) {
914     if (step_action == StepOut) {
915       // Skip step_count frames starting with the current one.
916       while (step_count-- > 0 && !frames_it.done()) {
917         frames_it.Advance();
918       }
919     } else {
920       DCHECK(location.IsReturn());
921       frames_it.Advance();
922     }
923     // Skip native and extension functions on the stack.
924     while (!frames_it.done() &&
925            !frames_it.frame()->function()->IsSubjectToDebugging()) {
926       frames_it.Advance();
927     }
928     // Step out: If there is a JavaScript caller frame, we need to
929     // flood it with breakpoints.
930     if (!frames_it.done()) {
931       // Fill the function to return to with one-shot break points.
932       JSFunction* function = frames_it.frame()->function();
933       FloodWithOneShot(Handle<JSFunction>(function));
934       // Set target frame pointer.
935       ActivateStepOut(frames_it.frame());
936     }
937     return;
938   }
939
940   if (step_action != StepNext && step_action != StepMin) {
941     // If there's restarter frame on top of the stack, just get the pointer
942     // to function which is going to be restarted.
943     if (thread_local_.restarter_frame_function_pointer_ != NULL) {
944       Handle<JSFunction> restarted_function(
945           JSFunction::cast(*thread_local_.restarter_frame_function_pointer_));
946       FloodWithOneShot(restarted_function);
947     } else if (location.IsCall()) {
948       // Find target function on the expression stack.
949       // Expression stack looks like this (top to bottom):
950       // argN
951       // ...
952       // arg0
953       // Receiver
954       // Function to call
955       int num_expressions_without_args =
956           frame->ComputeExpressionsCount() - location.CallArgumentsCount();
957       DCHECK(num_expressions_without_args >= 2);
958       Object* fun = frame->GetExpression(num_expressions_without_args - 2);
959
960       // Flood the actual target of call/apply.
961       if (fun->IsJSFunction()) {
962         Isolate* isolate = JSFunction::cast(fun)->GetIsolate();
963         Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply);
964         Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall);
965         // Find target function on the expression stack for expression like
966         // Function.call.call...apply(...)
967         int i = 1;
968         while (fun->IsJSFunction()) {
969           Code* code = JSFunction::cast(fun)->shared()->code();
970           if (code != apply && code != call) break;
971           DCHECK(num_expressions_without_args >= i);
972           fun = frame->GetExpression(num_expressions_without_args - i);
973           i--;
974         }
975       }
976
977       if (fun->IsJSFunction()) {
978         Handle<JSFunction> js_function(JSFunction::cast(fun));
979         FloodWithOneShotGeneric(js_function);
980       }
981     }
982
983     ActivateStepIn(frame);
984   }
985
986   // Fill the current function with one-shot break points even for step in on
987   // a call target as the function called might be a native function for
988   // which step in will not stop. It also prepares for stepping in
989   // getters/setters.
990   // If we are stepping into another frame, only fill calls and returns.
991   FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS
992                                                       : ALL_BREAK_LOCATIONS);
993
994   // Remember source position and frame to handle step next.
995   thread_local_.last_statement_position_ =
996       debug_info->code()->SourceStatementPosition(summary.pc());
997   thread_local_.last_fp_ = frame->UnpaddedFP();
998 }
999
1000
1001 // Check whether the current debug break should be reported to the debugger. It
1002 // is used to have step next and step in only report break back to the debugger
1003 // if on a different frame or in a different statement. In some situations
1004 // there will be several break points in the same statement when the code is
1005 // flooded with one-shot break points. This function helps to perform several
1006 // steps before reporting break back to the debugger.
1007 bool Debug::StepNextContinue(BreakLocation* break_location,
1008                              JavaScriptFrame* frame) {
1009   // StepNext and StepOut shouldn't bring us deeper in code, so last frame
1010   // shouldn't be a parent of current frame.
1011   StepAction step_action = thread_local_.last_step_action_;
1012
1013   if (step_action == StepNext || step_action == StepOut) {
1014     if (frame->fp() < thread_local_.last_fp_) return true;
1015   }
1016
1017   // We stepped into a new frame if the frame pointer changed.
1018   if (step_action == StepFrame) {
1019     return frame->UnpaddedFP() == thread_local_.last_fp_;
1020   }
1021
1022   // If the step last action was step next or step in make sure that a new
1023   // statement is hit.
1024   if (step_action == StepNext || step_action == StepIn) {
1025     // Never continue if returning from function.
1026     if (break_location->IsReturn()) return false;
1027
1028     // Continue if we are still on the same frame and in the same statement.
1029     int current_statement_position =
1030         break_location->code()->SourceStatementPosition(frame->pc());
1031     return thread_local_.last_fp_ == frame->UnpaddedFP() &&
1032         thread_local_.last_statement_position_ == current_statement_position;
1033   }
1034
1035   // No step next action - don't continue.
1036   return false;
1037 }
1038
1039
1040 // Check whether the code object at the specified address is a debug break code
1041 // object.
1042 bool Debug::IsDebugBreak(Address addr) {
1043   Code* code = Code::GetCodeFromTargetAddress(addr);
1044   return code->is_debug_stub();
1045 }
1046
1047
1048 // Simple function for returning the source positions for active break points.
1049 Handle<Object> Debug::GetSourceBreakLocations(
1050     Handle<SharedFunctionInfo> shared,
1051     BreakPositionAlignment position_alignment) {
1052   Isolate* isolate = shared->GetIsolate();
1053   Heap* heap = isolate->heap();
1054   if (!shared->HasDebugInfo()) {
1055     return Handle<Object>(heap->undefined_value(), isolate);
1056   }
1057   Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1058   if (debug_info->GetBreakPointCount() == 0) {
1059     return Handle<Object>(heap->undefined_value(), isolate);
1060   }
1061   Handle<FixedArray> locations =
1062       isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1063   int count = 0;
1064   for (int i = 0; i < debug_info->break_points()->length(); ++i) {
1065     if (!debug_info->break_points()->get(i)->IsUndefined()) {
1066       BreakPointInfo* break_point_info =
1067           BreakPointInfo::cast(debug_info->break_points()->get(i));
1068       int break_points = break_point_info->GetBreakPointCount();
1069       if (break_points == 0) continue;
1070       Smi* position = NULL;
1071       switch (position_alignment) {
1072         case STATEMENT_ALIGNED:
1073           position = break_point_info->statement_position();
1074           break;
1075         case BREAK_POSITION_ALIGNED:
1076           position = break_point_info->source_position();
1077           break;
1078       }
1079       for (int j = 0; j < break_points; ++j) locations->set(count++, position);
1080     }
1081   }
1082   return locations;
1083 }
1084
1085
1086 // Handle stepping into a function.
1087 void Debug::HandleStepIn(Handle<Object> function_obj, bool is_constructor) {
1088   // Flood getter/setter if we either step in or step to another frame.
1089   bool step_frame = thread_local_.last_step_action_ == StepFrame;
1090   if (!StepInActive() && !step_frame) return;
1091   if (!function_obj->IsJSFunction()) return;
1092   Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj);
1093   Isolate* isolate = function->GetIsolate();
1094
1095   StackFrameIterator it(isolate);
1096   it.Advance();
1097   // For constructor functions skip another frame.
1098   if (is_constructor) {
1099     DCHECK(it.frame()->is_construct());
1100     it.Advance();
1101   }
1102   Address fp = it.frame()->fp();
1103
1104   // Flood the function with one-shot break points if it is called from where
1105   // step into was requested, or when stepping into a new frame.
1106   if (fp == thread_local_.step_into_fp_ || step_frame) {
1107     FloodWithOneShotGeneric(function, Handle<Object>());
1108   }
1109 }
1110
1111
1112 void Debug::ClearStepping() {
1113   // Clear the various stepping setup.
1114   ClearOneShot();
1115   ClearStepIn();
1116   ClearStepOut();
1117   ClearStepNext();
1118
1119   // Clear multiple step counter.
1120   thread_local_.step_count_ = 0;
1121 }
1122
1123
1124 // Clears all the one-shot break points that are currently set. Normally this
1125 // function is called each time a break point is hit as one shot break points
1126 // are used to support stepping.
1127 void Debug::ClearOneShot() {
1128   // The current implementation just runs through all the breakpoints. When the
1129   // last break point for a function is removed that function is automatically
1130   // removed from the list.
1131   for (DebugInfoListNode* node = debug_info_list_; node != NULL;
1132        node = node->next()) {
1133     for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1134          !it.Done(); it.Next()) {
1135       it.GetBreakLocation().ClearOneShot();
1136     }
1137   }
1138 }
1139
1140
1141 void Debug::ActivateStepIn(StackFrame* frame) {
1142   DCHECK(!StepOutActive());
1143   thread_local_.step_into_fp_ = frame->UnpaddedFP();
1144 }
1145
1146
1147 void Debug::ClearStepIn() {
1148   thread_local_.step_into_fp_ = 0;
1149 }
1150
1151
1152 void Debug::ActivateStepOut(StackFrame* frame) {
1153   DCHECK(!StepInActive());
1154   thread_local_.step_out_fp_ = frame->UnpaddedFP();
1155 }
1156
1157
1158 void Debug::ClearStepOut() {
1159   thread_local_.step_out_fp_ = 0;
1160 }
1161
1162
1163 void Debug::ClearStepNext() {
1164   thread_local_.last_step_action_ = StepNone;
1165   thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
1166   thread_local_.last_fp_ = 0;
1167 }
1168
1169
1170 bool MatchingCodeTargets(Code* target1, Code* target2) {
1171   if (target1 == target2) return true;
1172   if (target1->kind() != target2->kind()) return false;
1173   return target1->is_handler() || target1->is_inline_cache_stub();
1174 }
1175
1176
1177 // Count the number of calls before the current frame PC to find the
1178 // corresponding PC in the newly recompiled code.
1179 static Address ComputeNewPcForRedirect(Code* new_code, Code* old_code,
1180                                        Address old_pc) {
1181   DCHECK_EQ(old_code->kind(), Code::FUNCTION);
1182   DCHECK_EQ(new_code->kind(), Code::FUNCTION);
1183   DCHECK(new_code->has_debug_break_slots());
1184   static const int mask = RelocInfo::kCodeTargetMask;
1185
1186   // Find the target of the current call.
1187   Code* target = NULL;
1188   intptr_t delta = 0;
1189   for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
1190     RelocInfo* rinfo = it.rinfo();
1191     Address current_pc = rinfo->pc();
1192     // The frame PC is behind the call instruction by the call instruction size.
1193     if (current_pc > old_pc) break;
1194     delta = old_pc - current_pc;
1195     target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1196   }
1197
1198   // Count the number of calls to the same target before the current call.
1199   int index = 0;
1200   for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
1201     RelocInfo* rinfo = it.rinfo();
1202     Address current_pc = rinfo->pc();
1203     if (current_pc > old_pc) break;
1204     Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
1205     if (MatchingCodeTargets(target, current)) index++;
1206   }
1207
1208   DCHECK(index > 0);
1209
1210   // Repeat the count on the new code to find corresponding call.
1211   for (RelocIterator it(new_code, mask); !it.done(); it.next()) {
1212     RelocInfo* rinfo = it.rinfo();
1213     Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
1214     if (MatchingCodeTargets(target, current)) index--;
1215     if (index == 0) return rinfo->pc() + delta;
1216   }
1217
1218   UNREACHABLE();
1219   return NULL;
1220 }
1221
1222
1223 // Count the number of continuations at which the current pc offset is at.
1224 static int ComputeContinuationIndexFromPcOffset(Code* code, int pc_offset) {
1225   DCHECK_EQ(code->kind(), Code::FUNCTION);
1226   Address pc = code->instruction_start() + pc_offset;
1227   int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
1228   int index = 0;
1229   for (RelocIterator it(code, mask); !it.done(); it.next()) {
1230     index++;
1231     RelocInfo* rinfo = it.rinfo();
1232     Address current_pc = rinfo->pc();
1233     if (current_pc == pc) break;
1234     DCHECK(current_pc < pc);
1235   }
1236   return index;
1237 }
1238
1239
1240 // Find the pc offset for the given continuation index.
1241 static int ComputePcOffsetFromContinuationIndex(Code* code, int index) {
1242   DCHECK_EQ(code->kind(), Code::FUNCTION);
1243   DCHECK(code->has_debug_break_slots());
1244   int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
1245   RelocIterator it(code, mask);
1246   for (int i = 1; i < index; i++) it.next();
1247   return static_cast<int>(it.rinfo()->pc() - code->instruction_start());
1248 }
1249
1250
1251 class RedirectActiveFunctions : public ThreadVisitor {
1252  public:
1253   explicit RedirectActiveFunctions(SharedFunctionInfo* shared)
1254       : shared_(shared) {
1255     DCHECK(shared->HasDebugCode());
1256   }
1257
1258   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1259     for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1260       JavaScriptFrame* frame = it.frame();
1261       JSFunction* function = frame->function();
1262       if (frame->is_optimized()) continue;
1263       if (!function->Inlines(shared_)) continue;
1264
1265       Code* frame_code = frame->LookupCode();
1266       DCHECK(frame_code->kind() == Code::FUNCTION);
1267       if (frame_code->has_debug_break_slots()) continue;
1268
1269       Code* new_code = function->shared()->code();
1270       Address old_pc = frame->pc();
1271       Address new_pc = ComputeNewPcForRedirect(new_code, frame_code, old_pc);
1272
1273       if (FLAG_trace_deopt) {
1274         PrintF("Replacing pc for debugging: %08" V8PRIxPTR " => %08" V8PRIxPTR
1275                "\n",
1276                reinterpret_cast<intptr_t>(old_pc),
1277                reinterpret_cast<intptr_t>(new_pc));
1278       }
1279
1280       if (FLAG_enable_embedded_constant_pool) {
1281         // Update constant pool pointer for new code.
1282         frame->set_constant_pool(new_code->constant_pool());
1283       }
1284
1285       // Patch the return address to return into the code with
1286       // debug break slots.
1287       frame->set_pc(new_pc);
1288     }
1289   }
1290
1291  private:
1292   SharedFunctionInfo* shared_;
1293   DisallowHeapAllocation no_gc_;
1294 };
1295
1296
1297 bool Debug::PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared) {
1298   DCHECK(shared->is_compiled());
1299
1300   if (isolate_->concurrent_recompilation_enabled()) {
1301     isolate_->optimizing_compile_dispatcher()->Flush();
1302   }
1303
1304   List<Handle<JSFunction> > functions;
1305   List<Handle<JSGeneratorObject> > suspended_generators;
1306
1307   if (!shared->optimized_code_map()->IsSmi()) {
1308     shared->ClearOptimizedCodeMap();
1309   }
1310
1311   // Make sure we abort incremental marking.
1312   isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
1313                                       "prepare for break points");
1314
1315   {
1316     HeapIterator iterator(isolate_->heap());
1317     HeapObject* obj;
1318     bool include_generators = shared->is_generator();
1319
1320     while ((obj = iterator.next())) {
1321       if (obj->IsJSFunction()) {
1322         JSFunction* function = JSFunction::cast(obj);
1323         if (!function->Inlines(*shared)) continue;
1324         if (function->code()->kind() == Code::OPTIMIZED_FUNCTION) {
1325           Deoptimizer::DeoptimizeFunction(function);
1326         }
1327         if (function->shared() == *shared) functions.Add(handle(function));
1328       } else if (include_generators && obj->IsJSGeneratorObject()) {
1329         JSGeneratorObject* generator_obj = JSGeneratorObject::cast(obj);
1330         if (!generator_obj->is_suspended()) continue;
1331         JSFunction* function = generator_obj->function();
1332         if (!function->Inlines(*shared)) continue;
1333         int pc_offset = generator_obj->continuation();
1334         int index =
1335             ComputeContinuationIndexFromPcOffset(function->code(), pc_offset);
1336         generator_obj->set_continuation(index);
1337         suspended_generators.Add(handle(generator_obj));
1338       }
1339     }
1340   }
1341
1342   if (!shared->HasDebugCode()) {
1343     DCHECK(functions.length() > 0);
1344     if (!Compiler::CompileDebugCode(functions.first())) return false;
1345   }
1346
1347   for (Handle<JSFunction> const function : functions) {
1348     function->ReplaceCode(shared->code());
1349   }
1350
1351   for (Handle<JSGeneratorObject> const generator_obj : suspended_generators) {
1352     int index = generator_obj->continuation();
1353     int pc_offset = ComputePcOffsetFromContinuationIndex(shared->code(), index);
1354     generator_obj->set_continuation(pc_offset);
1355   }
1356
1357   // Update PCs on the stack to point to recompiled code.
1358   RedirectActiveFunctions redirect_visitor(*shared);
1359   redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top());
1360   isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor);
1361
1362   return true;
1363 }
1364
1365
1366 class SharedFunctionInfoFinder {
1367  public:
1368   explicit SharedFunctionInfoFinder(int target_position)
1369       : current_candidate_(NULL),
1370         current_candidate_closure_(NULL),
1371         current_start_position_(RelocInfo::kNoPosition),
1372         target_position_(target_position) {}
1373
1374   void NewCandidate(SharedFunctionInfo* shared, JSFunction* closure = NULL) {
1375     int start_position = shared->function_token_position();
1376     if (start_position == RelocInfo::kNoPosition) {
1377       start_position = shared->start_position();
1378     }
1379
1380     if (start_position > target_position_) return;
1381     if (target_position_ > shared->end_position()) return;
1382
1383     if (current_candidate_ != NULL) {
1384       if (current_start_position_ == start_position &&
1385           shared->end_position() == current_candidate_->end_position()) {
1386         // If we already have a matching closure, do not throw it away.
1387         if (current_candidate_closure_ != NULL && closure == NULL) return;
1388         // If a top-level function contains only one function
1389         // declaration the source for the top-level and the function
1390         // is the same. In that case prefer the non top-level function.
1391         if (!current_candidate_->is_toplevel() && shared->is_toplevel()) return;
1392       } else if (start_position < current_start_position_ ||
1393                  current_candidate_->end_position() < shared->end_position()) {
1394         return;
1395       }
1396     }
1397
1398     current_start_position_ = start_position;
1399     current_candidate_ = shared;
1400     current_candidate_closure_ = closure;
1401   }
1402
1403   SharedFunctionInfo* Result() { return current_candidate_; }
1404
1405   JSFunction* ResultClosure() { return current_candidate_closure_; }
1406
1407  private:
1408   SharedFunctionInfo* current_candidate_;
1409   JSFunction* current_candidate_closure_;
1410   int current_start_position_;
1411   int target_position_;
1412   DisallowHeapAllocation no_gc_;
1413 };
1414
1415
1416 // We need to find a SFI for a literal that may not yet have been compiled yet,
1417 // and there may not be a JSFunction referencing it. Find the SFI closest to
1418 // the given position, compile it to reveal possible inner SFIs and repeat.
1419 // While we are at this, also ensure code with debug break slots so that we do
1420 // not have to compile a SFI without JSFunction, which is paifu for those that
1421 // cannot be compiled without context (need to find outer compilable SFI etc.)
1422 Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
1423                                                      int position) {
1424   while (true) {
1425     // Go through all shared function infos associated with this script to
1426     // find the inner most function containing this position.
1427     // If there is no shared function info for this script at all, there is
1428     // no point in looking for it by walking the heap.
1429     if (!script->shared_function_infos()->IsWeakFixedArray()) break;
1430
1431     SharedFunctionInfo* shared;
1432     {
1433       SharedFunctionInfoFinder finder(position);
1434       WeakFixedArray::Iterator iterator(script->shared_function_infos());
1435       SharedFunctionInfo* candidate;
1436       while ((candidate = iterator.Next<SharedFunctionInfo>())) {
1437         finder.NewCandidate(candidate);
1438       }
1439       shared = finder.Result();
1440       if (shared == NULL) break;
1441       // We found it if it's already compiled and has debug code.
1442       if (shared->HasDebugCode()) return handle(shared);
1443     }
1444     // If not, compile to reveal inner functions, if possible.
1445     if (shared->allows_lazy_compilation_without_context()) {
1446       HandleScope scope(isolate_);
1447       if (!Compiler::CompileDebugCode(handle(shared))) break;
1448       continue;
1449     }
1450
1451     // If not possible, comb the heap for the best suitable compile target.
1452     JSFunction* closure;
1453     {
1454       HeapIterator it(isolate_->heap());
1455       SharedFunctionInfoFinder finder(position);
1456       while (HeapObject* object = it.next()) {
1457         JSFunction* candidate_closure = NULL;
1458         SharedFunctionInfo* candidate = NULL;
1459         if (object->IsJSFunction()) {
1460           candidate_closure = JSFunction::cast(object);
1461           candidate = candidate_closure->shared();
1462         } else if (object->IsSharedFunctionInfo()) {
1463           candidate = SharedFunctionInfo::cast(object);
1464           if (!candidate->allows_lazy_compilation_without_context()) continue;
1465         } else {
1466           continue;
1467         }
1468         if (candidate->script() == *script) {
1469           finder.NewCandidate(candidate, candidate_closure);
1470         }
1471       }
1472       closure = finder.ResultClosure();
1473       shared = finder.Result();
1474     }
1475     HandleScope scope(isolate_);
1476     if (closure == NULL) {
1477       if (!Compiler::CompileDebugCode(handle(shared))) break;
1478     } else {
1479       if (!Compiler::CompileDebugCode(handle(closure))) break;
1480     }
1481   }
1482   return isolate_->factory()->undefined_value();
1483 }
1484
1485
1486 // Ensures the debug information is present for shared.
1487 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
1488                             Handle<JSFunction> function) {
1489   if (!shared->IsSubjectToDebugging()) return false;
1490
1491   // Return if we already have the debug info for shared.
1492   if (shared->HasDebugInfo()) return true;
1493
1494   if (function.is_null()) {
1495     DCHECK(shared->HasDebugCode());
1496   } else if (!Compiler::Compile(function, CLEAR_EXCEPTION)) {
1497     return false;
1498   }
1499
1500   if (!PrepareFunctionForBreakPoints(shared)) return false;
1501
1502   // Make sure IC state is clean. This is so that we correctly flood
1503   // accessor pairs when stepping in.
1504   shared->code()->ClearInlineCaches();
1505   shared->feedback_vector()->ClearICSlots(*shared);
1506
1507   // Create the debug info object.
1508   DCHECK(shared->HasDebugCode());
1509   Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared);
1510
1511   // Add debug info to the list.
1512   DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
1513   node->set_next(debug_info_list_);
1514   debug_info_list_ = node;
1515
1516   return true;
1517 }
1518
1519
1520 void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
1521   HandleScope scope(isolate_);
1522   Handle<SharedFunctionInfo> shared(debug_info->shared());
1523
1524   DCHECK_NOT_NULL(debug_info_list_);
1525   // Run through the debug info objects to find this one and remove it.
1526   DebugInfoListNode* prev = NULL;
1527   DebugInfoListNode* current = debug_info_list_;
1528   while (current != NULL) {
1529     if (current->debug_info().is_identical_to(debug_info)) {
1530       // Unlink from list. If prev is NULL we are looking at the first element.
1531       if (prev == NULL) {
1532         debug_info_list_ = current->next();
1533       } else {
1534         prev->set_next(current->next());
1535       }
1536       delete current;
1537       shared->set_debug_info(isolate_->heap()->undefined_value());
1538       return;
1539     }
1540     // Move to next in list.
1541     prev = current;
1542     current = current->next();
1543   }
1544
1545   UNREACHABLE();
1546 }
1547
1548
1549 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
1550   after_break_target_ = NULL;
1551
1552   if (LiveEdit::SetAfterBreakTarget(this)) return;  // LiveEdit did the job.
1553
1554   // Continue just after the slot.
1555   after_break_target_ = frame->pc();
1556 }
1557
1558
1559 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
1560   HandleScope scope(isolate_);
1561
1562   // Get the executing function in which the debug break occurred.
1563   Handle<JSFunction> function(JSFunction::cast(frame->function()));
1564   Handle<SharedFunctionInfo> shared(function->shared());
1565
1566   // With no debug info there are no break points, so we can't be at a return.
1567   if (!shared->HasDebugInfo()) return false;
1568   Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1569   Handle<Code> code(debug_info->code());
1570 #ifdef DEBUG
1571   // Get the code which is actually executing.
1572   Handle<Code> frame_code(frame->LookupCode());
1573   DCHECK(frame_code.is_identical_to(code));
1574 #endif
1575
1576   // Find the reloc info matching the start of the debug break slot.
1577   Address slot_pc = frame->pc() - Assembler::kDebugBreakSlotLength;
1578   int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
1579   for (RelocIterator it(*code, mask); !it.done(); it.next()) {
1580     if (it.rinfo()->pc() == slot_pc) return true;
1581   }
1582   return false;
1583 }
1584
1585
1586 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
1587                                   LiveEdit::FrameDropMode mode,
1588                                   Object** restarter_frame_function_pointer) {
1589   if (mode != LiveEdit::CURRENTLY_SET_MODE) {
1590     thread_local_.frame_drop_mode_ = mode;
1591   }
1592   thread_local_.break_frame_id_ = new_break_frame_id;
1593   thread_local_.restarter_frame_function_pointer_ =
1594       restarter_frame_function_pointer;
1595 }
1596
1597
1598 bool Debug::IsDebugGlobal(GlobalObject* global) {
1599   return is_loaded() && global == debug_context()->global_object();
1600 }
1601
1602
1603 void Debug::ClearMirrorCache() {
1604   PostponeInterruptsScope postpone(isolate_);
1605   HandleScope scope(isolate_);
1606   CallFunction("ClearMirrorCache", 0, NULL);
1607 }
1608
1609
1610 Handle<FixedArray> Debug::GetLoadedScripts() {
1611   isolate_->heap()->CollectAllGarbage();
1612   Factory* factory = isolate_->factory();
1613   if (!factory->script_list()->IsWeakFixedArray()) {
1614     return factory->empty_fixed_array();
1615   }
1616   Handle<WeakFixedArray> array =
1617       Handle<WeakFixedArray>::cast(factory->script_list());
1618   Handle<FixedArray> results = factory->NewFixedArray(array->Length());
1619   int length = 0;
1620   {
1621     Script::Iterator iterator(isolate_);
1622     Script* script;
1623     while ((script = iterator.Next())) {
1624       if (script->HasValidSource()) results->set(length++, script);
1625     }
1626   }
1627   results->Shrink(length);
1628   return results;
1629 }
1630
1631
1632 void Debug::GetStepinPositions(JavaScriptFrame* frame, StackFrame::Id frame_id,
1633                                List<int>* results_out) {
1634   FrameSummary summary = GetFirstFrameSummary(frame);
1635
1636   Handle<JSFunction> fun = Handle<JSFunction>(summary.function());
1637   Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared());
1638
1639   if (!EnsureDebugInfo(shared, fun)) return;
1640
1641   Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1642   // Refresh frame summary if the code has been recompiled for debugging.
1643   if (shared->code() != *summary.code()) summary = GetFirstFrameSummary(frame);
1644
1645   // Find range of break points starting from the break point where execution
1646   // has stopped.
1647   Address call_pc = summary.pc() - 1;
1648   List<BreakLocation> locations;
1649   BreakLocation::FromAddressSameStatement(debug_info, ALL_BREAK_LOCATIONS,
1650                                           call_pc, &locations);
1651
1652   for (BreakLocation location : locations) {
1653     if (location.pc() <= summary.pc()) {
1654       // The break point is near our pc. Could be a step-in possibility,
1655       // that is currently taken by active debugger call.
1656       if (break_frame_id() == StackFrame::NO_ID) {
1657         continue;  // We are not stepping.
1658       } else {
1659         JavaScriptFrameIterator frame_it(isolate_, break_frame_id());
1660         // If our frame is a top frame and we are stepping, we can do step-in
1661         // at this place.
1662         if (frame_it.frame()->id() != frame_id) continue;
1663       }
1664     }
1665     if (location.IsStepInLocation()) results_out->Add(location.position());
1666   }
1667 }
1668
1669
1670 void Debug::RecordEvalCaller(Handle<Script> script) {
1671   script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
1672   // For eval scripts add information on the function from which eval was
1673   // called.
1674   StackTraceFrameIterator it(script->GetIsolate());
1675   if (!it.done()) {
1676     script->set_eval_from_shared(it.frame()->function()->shared());
1677     Code* code = it.frame()->LookupCode();
1678     int offset = static_cast<int>(
1679         it.frame()->pc() - code->instruction_start());
1680     script->set_eval_from_instructions_offset(Smi::FromInt(offset));
1681   }
1682 }
1683
1684
1685 MaybeHandle<Object> Debug::MakeExecutionState() {
1686   // Create the execution state object.
1687   Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
1688   return CallFunction("MakeExecutionState", arraysize(argv), argv);
1689 }
1690
1691
1692 MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
1693   // Create the new break event object.
1694   Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
1695                             break_points_hit };
1696   return CallFunction("MakeBreakEvent", arraysize(argv), argv);
1697 }
1698
1699
1700 MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
1701                                               bool uncaught,
1702                                               Handle<Object> promise) {
1703   // Create the new exception event object.
1704   Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
1705                             exception,
1706                             isolate_->factory()->ToBoolean(uncaught),
1707                             promise };
1708   return CallFunction("MakeExceptionEvent", arraysize(argv), argv);
1709 }
1710
1711
1712 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
1713                                             v8::DebugEvent type) {
1714   // Create the compile event object.
1715   Handle<Object> script_wrapper = Script::GetWrapper(script);
1716   Handle<Object> argv[] = { script_wrapper,
1717                             isolate_->factory()->NewNumberFromInt(type) };
1718   return CallFunction("MakeCompileEvent", arraysize(argv), argv);
1719 }
1720
1721
1722 MaybeHandle<Object> Debug::MakePromiseEvent(Handle<JSObject> event_data) {
1723   // Create the promise event object.
1724   Handle<Object> argv[] = { event_data };
1725   return CallFunction("MakePromiseEvent", arraysize(argv), argv);
1726 }
1727
1728
1729 MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
1730   // Create the async task event object.
1731   Handle<Object> argv[] = { task_event };
1732   return CallFunction("MakeAsyncTaskEvent", arraysize(argv), argv);
1733 }
1734
1735
1736 void Debug::OnThrow(Handle<Object> exception) {
1737   if (in_debug_scope() || ignore_events()) return;
1738   // Temporarily clear any scheduled_exception to allow evaluating
1739   // JavaScript from the debug event handler.
1740   HandleScope scope(isolate_);
1741   Handle<Object> scheduled_exception;
1742   if (isolate_->has_scheduled_exception()) {
1743     scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
1744     isolate_->clear_scheduled_exception();
1745   }
1746   OnException(exception, isolate_->GetPromiseOnStackOnThrow());
1747   if (!scheduled_exception.is_null()) {
1748     isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
1749   }
1750 }
1751
1752
1753 void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) {
1754   if (in_debug_scope() || ignore_events()) return;
1755   HandleScope scope(isolate_);
1756   // Check whether the promise has been marked as having triggered a message.
1757   Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
1758   if (JSReceiver::GetDataProperty(promise, key)->IsUndefined()) {
1759     OnException(value, promise);
1760   }
1761 }
1762
1763
1764 MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler(
1765     Handle<JSObject> promise) {
1766   Handle<JSFunction> fun = isolate_->promise_has_user_defined_reject_handler();
1767   return Execution::Call(isolate_, fun, promise, 0, NULL);
1768 }
1769
1770
1771 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
1772   // In our prediction, try-finally is not considered to catch.
1773   Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher();
1774   bool uncaught = (catch_type == Isolate::NOT_CAUGHT);
1775   if (promise->IsJSObject()) {
1776     Handle<JSObject> jspromise = Handle<JSObject>::cast(promise);
1777     // Mark the promise as already having triggered a message.
1778     Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
1779     JSObject::SetProperty(jspromise, key, key, STRICT).Assert();
1780     // Check whether the promise reject is considered an uncaught exception.
1781     Handle<Object> has_reject_handler;
1782     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
1783         isolate_, has_reject_handler,
1784         PromiseHasUserDefinedRejectHandler(jspromise), /* void */);
1785     uncaught = has_reject_handler->IsFalse();
1786   }
1787   // Bail out if exception breaks are not active
1788   if (uncaught) {
1789     // Uncaught exceptions are reported by either flags.
1790     if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
1791   } else {
1792     // Caught exceptions are reported is activated.
1793     if (!break_on_exception_) return;
1794   }
1795
1796   DebugScope debug_scope(this);
1797   if (debug_scope.failed()) return;
1798
1799   // Clear all current stepping setup.
1800   ClearStepping();
1801
1802   // Create the event data object.
1803   Handle<Object> event_data;
1804   // Bail out and don't call debugger if exception.
1805   if (!MakeExceptionEvent(
1806           exception, uncaught, promise).ToHandle(&event_data)) {
1807     return;
1808   }
1809
1810   // Process debug event.
1811   ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
1812   // Return to continue execution from where the exception was thrown.
1813 }
1814
1815
1816 void Debug::OnCompileError(Handle<Script> script) {
1817   if (ignore_events()) return;
1818
1819   if (in_debug_scope()) {
1820     ProcessCompileEventInDebugScope(v8::CompileError, script);
1821     return;
1822   }
1823
1824   HandleScope scope(isolate_);
1825   DebugScope debug_scope(this);
1826   if (debug_scope.failed()) return;
1827
1828   // Create the compile state object.
1829   Handle<Object> event_data;
1830   // Bail out and don't call debugger if exception.
1831   if (!MakeCompileEvent(script, v8::CompileError).ToHandle(&event_data)) return;
1832
1833   // Process debug event.
1834   ProcessDebugEvent(v8::CompileError, Handle<JSObject>::cast(event_data), true);
1835 }
1836
1837
1838 void Debug::OnDebugBreak(Handle<Object> break_points_hit,
1839                             bool auto_continue) {
1840   // The caller provided for DebugScope.
1841   AssertDebugContext();
1842   // Bail out if there is no listener for this event
1843   if (ignore_events()) return;
1844
1845   HandleScope scope(isolate_);
1846   // Create the event data object.
1847   Handle<Object> event_data;
1848   // Bail out and don't call debugger if exception.
1849   if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
1850
1851   // Process debug event.
1852   ProcessDebugEvent(v8::Break,
1853                     Handle<JSObject>::cast(event_data),
1854                     auto_continue);
1855 }
1856
1857
1858 void Debug::OnBeforeCompile(Handle<Script> script) {
1859   if (in_debug_scope() || ignore_events()) return;
1860
1861   HandleScope scope(isolate_);
1862   DebugScope debug_scope(this);
1863   if (debug_scope.failed()) return;
1864
1865   // Create the event data object.
1866   Handle<Object> event_data;
1867   // Bail out and don't call debugger if exception.
1868   if (!MakeCompileEvent(script, v8::BeforeCompile).ToHandle(&event_data))
1869     return;
1870
1871   // Process debug event.
1872   ProcessDebugEvent(v8::BeforeCompile,
1873                     Handle<JSObject>::cast(event_data),
1874                     true);
1875 }
1876
1877
1878 // Handle debugger actions when a new script is compiled.
1879 void Debug::OnAfterCompile(Handle<Script> script) {
1880   if (ignore_events()) return;
1881
1882   if (in_debug_scope()) {
1883     ProcessCompileEventInDebugScope(v8::AfterCompile, script);
1884     return;
1885   }
1886
1887   HandleScope scope(isolate_);
1888   DebugScope debug_scope(this);
1889   if (debug_scope.failed()) return;
1890
1891   // If debugging there might be script break points registered for this
1892   // script. Make sure that these break points are set.
1893   Handle<Object> argv[] = {Script::GetWrapper(script)};
1894   if (CallFunction("UpdateScriptBreakPoints", arraysize(argv), argv)
1895           .is_null()) {
1896     return;
1897   }
1898
1899   // Create the compile state object.
1900   Handle<Object> event_data;
1901   // Bail out and don't call debugger if exception.
1902   if (!MakeCompileEvent(script, v8::AfterCompile).ToHandle(&event_data)) return;
1903
1904   // Process debug event.
1905   ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
1906 }
1907
1908
1909 void Debug::OnPromiseEvent(Handle<JSObject> data) {
1910   if (in_debug_scope() || ignore_events()) return;
1911
1912   HandleScope scope(isolate_);
1913   DebugScope debug_scope(this);
1914   if (debug_scope.failed()) return;
1915
1916   // Create the script collected state object.
1917   Handle<Object> event_data;
1918   // Bail out and don't call debugger if exception.
1919   if (!MakePromiseEvent(data).ToHandle(&event_data)) return;
1920
1921   // Process debug event.
1922   ProcessDebugEvent(v8::PromiseEvent,
1923                     Handle<JSObject>::cast(event_data),
1924                     true);
1925 }
1926
1927
1928 void Debug::OnAsyncTaskEvent(Handle<JSObject> data) {
1929   if (in_debug_scope() || ignore_events()) return;
1930
1931   HandleScope scope(isolate_);
1932   DebugScope debug_scope(this);
1933   if (debug_scope.failed()) return;
1934
1935   // Create the script collected state object.
1936   Handle<Object> event_data;
1937   // Bail out and don't call debugger if exception.
1938   if (!MakeAsyncTaskEvent(data).ToHandle(&event_data)) return;
1939
1940   // Process debug event.
1941   ProcessDebugEvent(v8::AsyncTaskEvent,
1942                     Handle<JSObject>::cast(event_data),
1943                     true);
1944 }
1945
1946
1947 void Debug::ProcessDebugEvent(v8::DebugEvent event,
1948                               Handle<JSObject> event_data,
1949                               bool auto_continue) {
1950   HandleScope scope(isolate_);
1951
1952   // Create the execution state.
1953   Handle<Object> exec_state;
1954   // Bail out and don't call debugger if exception.
1955   if (!MakeExecutionState().ToHandle(&exec_state)) return;
1956
1957   // First notify the message handler if any.
1958   if (message_handler_ != NULL) {
1959     NotifyMessageHandler(event,
1960                          Handle<JSObject>::cast(exec_state),
1961                          event_data,
1962                          auto_continue);
1963   }
1964   // Notify registered debug event listener. This can be either a C or
1965   // a JavaScript function. Don't call event listener for v8::Break
1966   // here, if it's only a debug command -- they will be processed later.
1967   if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
1968     CallEventCallback(event, exec_state, event_data, NULL);
1969   }
1970 }
1971
1972
1973 void Debug::CallEventCallback(v8::DebugEvent event,
1974                               Handle<Object> exec_state,
1975                               Handle<Object> event_data,
1976                               v8::Debug::ClientData* client_data) {
1977   bool previous = in_debug_event_listener_;
1978   in_debug_event_listener_ = true;
1979   if (event_listener_->IsForeign()) {
1980     // Invoke the C debug event listener.
1981     v8::Debug::EventCallback callback =
1982         FUNCTION_CAST<v8::Debug::EventCallback>(
1983             Handle<Foreign>::cast(event_listener_)->foreign_address());
1984     EventDetailsImpl event_details(event,
1985                                    Handle<JSObject>::cast(exec_state),
1986                                    Handle<JSObject>::cast(event_data),
1987                                    event_listener_data_,
1988                                    client_data);
1989     callback(event_details);
1990     DCHECK(!isolate_->has_scheduled_exception());
1991   } else {
1992     // Invoke the JavaScript debug event listener.
1993     DCHECK(event_listener_->IsJSFunction());
1994     Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
1995                               exec_state,
1996                               event_data,
1997                               event_listener_data_ };
1998     Handle<JSReceiver> global(isolate_->global_proxy());
1999     Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
2000                        global, arraysize(argv), argv);
2001   }
2002   in_debug_event_listener_ = previous;
2003 }
2004
2005
2006 void Debug::ProcessCompileEventInDebugScope(v8::DebugEvent event,
2007                                             Handle<Script> script) {
2008   if (event_listener_.is_null()) return;
2009
2010   SuppressDebug while_processing(this);
2011   DebugScope debug_scope(this);
2012   if (debug_scope.failed()) return;
2013
2014   Handle<Object> event_data;
2015   // Bail out and don't call debugger if exception.
2016   if (!MakeCompileEvent(script, event).ToHandle(&event_data)) return;
2017
2018   // Create the execution state.
2019   Handle<Object> exec_state;
2020   // Bail out and don't call debugger if exception.
2021   if (!MakeExecutionState().ToHandle(&exec_state)) return;
2022
2023   CallEventCallback(event, exec_state, event_data, NULL);
2024 }
2025
2026
2027 Handle<Context> Debug::GetDebugContext() {
2028   if (!is_loaded()) return Handle<Context>();
2029   DebugScope debug_scope(this);
2030   if (debug_scope.failed()) return Handle<Context>();
2031   // The global handle may be destroyed soon after.  Return it reboxed.
2032   return handle(*debug_context(), isolate_);
2033 }
2034
2035
2036 void Debug::NotifyMessageHandler(v8::DebugEvent event,
2037                                  Handle<JSObject> exec_state,
2038                                  Handle<JSObject> event_data,
2039                                  bool auto_continue) {
2040   // Prevent other interrupts from triggering, for example API callbacks,
2041   // while dispatching message handler callbacks.
2042   PostponeInterruptsScope no_interrupts(isolate_);
2043   DCHECK(is_active_);
2044   HandleScope scope(isolate_);
2045   // Process the individual events.
2046   bool sendEventMessage = false;
2047   switch (event) {
2048     case v8::Break:
2049       sendEventMessage = !auto_continue;
2050       break;
2051     case v8::NewFunction:
2052     case v8::BeforeCompile:
2053     case v8::CompileError:
2054     case v8::PromiseEvent:
2055     case v8::AsyncTaskEvent:
2056       break;
2057     case v8::Exception:
2058     case v8::AfterCompile:
2059       sendEventMessage = true;
2060       break;
2061   }
2062
2063   // The debug command interrupt flag might have been set when the command was
2064   // added. It should be enough to clear the flag only once while we are in the
2065   // debugger.
2066   DCHECK(in_debug_scope());
2067   isolate_->stack_guard()->ClearDebugCommand();
2068
2069   // Notify the debugger that a debug event has occurred unless auto continue is
2070   // active in which case no event is send.
2071   if (sendEventMessage) {
2072     MessageImpl message = MessageImpl::NewEvent(
2073         event,
2074         auto_continue,
2075         Handle<JSObject>::cast(exec_state),
2076         Handle<JSObject>::cast(event_data));
2077     InvokeMessageHandler(message);
2078   }
2079
2080   // If auto continue don't make the event cause a break, but process messages
2081   // in the queue if any. For script collected events don't even process
2082   // messages in the queue as the execution state might not be what is expected
2083   // by the client.
2084   if (auto_continue && !has_commands()) return;
2085
2086   // DebugCommandProcessor goes here.
2087   bool running = auto_continue;
2088
2089   Handle<Object> cmd_processor_ctor = Object::GetProperty(
2090       isolate_, exec_state, "debugCommandProcessor").ToHandleChecked();
2091   Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
2092   Handle<Object> cmd_processor = Execution::Call(
2093       isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked();
2094   Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
2095       Object::GetProperty(
2096           isolate_, cmd_processor, "processDebugRequest").ToHandleChecked());
2097   Handle<Object> is_running = Object::GetProperty(
2098       isolate_, cmd_processor, "isRunning").ToHandleChecked();
2099
2100   // Process requests from the debugger.
2101   do {
2102     // Wait for new command in the queue.
2103     command_received_.Wait();
2104
2105     // Get the command from the queue.
2106     CommandMessage command = command_queue_.Get();
2107     isolate_->logger()->DebugTag(
2108         "Got request from command queue, in interactive loop.");
2109     if (!is_active()) {
2110       // Delete command text and user data.
2111       command.Dispose();
2112       return;
2113     }
2114
2115     Vector<const uc16> command_text(
2116         const_cast<const uc16*>(command.text().start()),
2117         command.text().length());
2118     Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
2119         command_text).ToHandleChecked();
2120     Handle<Object> request_args[] = { request_text };
2121     Handle<Object> answer_value;
2122     Handle<String> answer;
2123     MaybeHandle<Object> maybe_exception;
2124     MaybeHandle<Object> maybe_result =
2125         Execution::TryCall(process_debug_request, cmd_processor, 1,
2126                            request_args, &maybe_exception);
2127
2128     if (maybe_result.ToHandle(&answer_value)) {
2129       if (answer_value->IsUndefined()) {
2130         answer = isolate_->factory()->empty_string();
2131       } else {
2132         answer = Handle<String>::cast(answer_value);
2133       }
2134
2135       // Log the JSON request/response.
2136       if (FLAG_trace_debug_json) {
2137         PrintF("%s\n", request_text->ToCString().get());
2138         PrintF("%s\n", answer->ToCString().get());
2139       }
2140
2141       Handle<Object> is_running_args[] = { answer };
2142       maybe_result = Execution::Call(
2143           isolate_, is_running, cmd_processor, 1, is_running_args);
2144       Handle<Object> result;
2145       if (!maybe_result.ToHandle(&result)) break;
2146       running = result->IsTrue();
2147     } else {
2148       Handle<Object> exception;
2149       if (!maybe_exception.ToHandle(&exception)) break;
2150       Handle<Object> result;
2151       if (!Object::ToString(isolate_, exception).ToHandle(&result)) break;
2152       answer = Handle<String>::cast(result);
2153     }
2154
2155     // Return the result.
2156     MessageImpl message = MessageImpl::NewResponse(
2157         event, running, exec_state, event_data, answer, command.client_data());
2158     InvokeMessageHandler(message);
2159     command.Dispose();
2160
2161     // Return from debug event processing if either the VM is put into the
2162     // running state (through a continue command) or auto continue is active
2163     // and there are no more commands queued.
2164   } while (!running || has_commands());
2165   command_queue_.Clear();
2166 }
2167
2168
2169 void Debug::SetEventListener(Handle<Object> callback,
2170                              Handle<Object> data) {
2171   GlobalHandles* global_handles = isolate_->global_handles();
2172
2173   // Remove existing entry.
2174   GlobalHandles::Destroy(event_listener_.location());
2175   event_listener_ = Handle<Object>();
2176   GlobalHandles::Destroy(event_listener_data_.location());
2177   event_listener_data_ = Handle<Object>();
2178
2179   // Set new entry.
2180   if (!callback->IsUndefined() && !callback->IsNull()) {
2181     event_listener_ = global_handles->Create(*callback);
2182     if (data.is_null()) data = isolate_->factory()->undefined_value();
2183     event_listener_data_ = global_handles->Create(*data);
2184   }
2185
2186   UpdateState();
2187 }
2188
2189
2190 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
2191   message_handler_ = handler;
2192   UpdateState();
2193   if (handler == NULL && in_debug_scope()) {
2194     // Send an empty command to the debugger if in a break to make JavaScript
2195     // run again if the debugger is closed.
2196     EnqueueCommandMessage(Vector<const uint16_t>::empty());
2197   }
2198 }
2199
2200
2201
2202 void Debug::UpdateState() {
2203   bool is_active = message_handler_ != NULL || !event_listener_.is_null();
2204   if (is_active || in_debug_scope()) {
2205     // Note that the debug context could have already been loaded to
2206     // bootstrap test cases.
2207     isolate_->compilation_cache()->Disable();
2208     is_active = Load();
2209   } else if (is_loaded()) {
2210     isolate_->compilation_cache()->Enable();
2211     Unload();
2212   }
2213   is_active_ = is_active;
2214 }
2215
2216
2217 // Calls the registered debug message handler. This callback is part of the
2218 // public API.
2219 void Debug::InvokeMessageHandler(MessageImpl message) {
2220   if (message_handler_ != NULL) message_handler_(message);
2221 }
2222
2223
2224 // Puts a command coming from the public API on the queue.  Creates
2225 // a copy of the command string managed by the debugger.  Up to this
2226 // point, the command data was managed by the API client.  Called
2227 // by the API client thread.
2228 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
2229                                   v8::Debug::ClientData* client_data) {
2230   // Need to cast away const.
2231   CommandMessage message = CommandMessage::New(
2232       Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
2233                        command.length()),
2234       client_data);
2235   isolate_->logger()->DebugTag("Put command on command_queue.");
2236   command_queue_.Put(message);
2237   command_received_.Signal();
2238
2239   // Set the debug command break flag to have the command processed.
2240   if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
2241 }
2242
2243
2244 MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
2245   DebugScope debug_scope(this);
2246   if (debug_scope.failed()) return isolate_->factory()->undefined_value();
2247
2248   // Create the execution state.
2249   Handle<Object> exec_state;
2250   if (!MakeExecutionState().ToHandle(&exec_state)) {
2251     return isolate_->factory()->undefined_value();
2252   }
2253
2254   Handle<Object> argv[] = { exec_state, data };
2255   return Execution::Call(
2256       isolate_,
2257       fun,
2258       Handle<Object>(debug_context()->global_proxy(), isolate_),
2259       arraysize(argv),
2260       argv);
2261 }
2262
2263
2264 void Debug::HandleDebugBreak() {
2265   // Ignore debug break during bootstrapping.
2266   if (isolate_->bootstrapper()->IsActive()) return;
2267   // Just continue if breaks are disabled.
2268   if (break_disabled()) return;
2269   // Ignore debug break if debugger is not active.
2270   if (!is_active()) return;
2271
2272   StackLimitCheck check(isolate_);
2273   if (check.HasOverflowed()) return;
2274
2275   { JavaScriptFrameIterator it(isolate_);
2276     DCHECK(!it.done());
2277     Object* fun = it.frame()->function();
2278     if (fun && fun->IsJSFunction()) {
2279       // Don't stop in builtin functions.
2280       if (!JSFunction::cast(fun)->IsSubjectToDebugging()) return;
2281       GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
2282       // Don't stop in debugger functions.
2283       if (IsDebugGlobal(global)) return;
2284     }
2285   }
2286
2287   // Collect the break state before clearing the flags.
2288   bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
2289                             !isolate_->stack_guard()->CheckDebugBreak();
2290
2291   isolate_->stack_guard()->ClearDebugBreak();
2292
2293   ProcessDebugMessages(debug_command_only);
2294 }
2295
2296
2297 void Debug::ProcessDebugMessages(bool debug_command_only) {
2298   isolate_->stack_guard()->ClearDebugCommand();
2299
2300   StackLimitCheck check(isolate_);
2301   if (check.HasOverflowed()) return;
2302
2303   HandleScope scope(isolate_);
2304   DebugScope debug_scope(this);
2305   if (debug_scope.failed()) return;
2306
2307   // Notify the debug event listeners. Indicate auto continue if the break was
2308   // a debug command break.
2309   OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
2310 }
2311
2312
2313 DebugScope::DebugScope(Debug* debug)
2314     : debug_(debug),
2315       prev_(debug->debugger_entry()),
2316       save_(debug_->isolate_),
2317       no_termination_exceptons_(debug_->isolate_,
2318                                 StackGuard::TERMINATE_EXECUTION) {
2319   // Link recursive debugger entry.
2320   base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
2321                         reinterpret_cast<base::AtomicWord>(this));
2322
2323   // Store the previous break id and frame id.
2324   break_id_ = debug_->break_id();
2325   break_frame_id_ = debug_->break_frame_id();
2326
2327   // Create the new break info. If there is no JavaScript frames there is no
2328   // break frame id.
2329   JavaScriptFrameIterator it(isolate());
2330   bool has_js_frames = !it.done();
2331   debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
2332                                                         : StackFrame::NO_ID;
2333   debug_->SetNextBreakId();
2334
2335   debug_->UpdateState();
2336   // Make sure that debugger is loaded and enter the debugger context.
2337   // The previous context is kept in save_.
2338   failed_ = !debug_->is_loaded();
2339   if (!failed_) isolate()->set_context(*debug->debug_context());
2340 }
2341
2342
2343
2344 DebugScope::~DebugScope() {
2345   if (!failed_ && prev_ == NULL) {
2346     // Clear mirror cache when leaving the debugger. Skip this if there is a
2347     // pending exception as clearing the mirror cache calls back into
2348     // JavaScript. This can happen if the v8::Debug::Call is used in which
2349     // case the exception should end up in the calling code.
2350     if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
2351
2352     // If there are commands in the queue when leaving the debugger request
2353     // that these commands are processed.
2354     if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
2355   }
2356
2357   // Leaving this debugger entry.
2358   base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
2359                         reinterpret_cast<base::AtomicWord>(prev_));
2360
2361   // Restore to the previous break state.
2362   debug_->thread_local_.break_frame_id_ = break_frame_id_;
2363   debug_->thread_local_.break_id_ = break_id_;
2364
2365   debug_->UpdateState();
2366 }
2367
2368
2369 MessageImpl MessageImpl::NewEvent(DebugEvent event,
2370                                   bool running,
2371                                   Handle<JSObject> exec_state,
2372                                   Handle<JSObject> event_data) {
2373   MessageImpl message(true, event, running,
2374                       exec_state, event_data, Handle<String>(), NULL);
2375   return message;
2376 }
2377
2378
2379 MessageImpl MessageImpl::NewResponse(DebugEvent event,
2380                                      bool running,
2381                                      Handle<JSObject> exec_state,
2382                                      Handle<JSObject> event_data,
2383                                      Handle<String> response_json,
2384                                      v8::Debug::ClientData* client_data) {
2385   MessageImpl message(false, event, running,
2386                       exec_state, event_data, response_json, client_data);
2387   return message;
2388 }
2389
2390
2391 MessageImpl::MessageImpl(bool is_event,
2392                          DebugEvent event,
2393                          bool running,
2394                          Handle<JSObject> exec_state,
2395                          Handle<JSObject> event_data,
2396                          Handle<String> response_json,
2397                          v8::Debug::ClientData* client_data)
2398     : is_event_(is_event),
2399       event_(event),
2400       running_(running),
2401       exec_state_(exec_state),
2402       event_data_(event_data),
2403       response_json_(response_json),
2404       client_data_(client_data) {}
2405
2406
2407 bool MessageImpl::IsEvent() const {
2408   return is_event_;
2409 }
2410
2411
2412 bool MessageImpl::IsResponse() const {
2413   return !is_event_;
2414 }
2415
2416
2417 DebugEvent MessageImpl::GetEvent() const {
2418   return event_;
2419 }
2420
2421
2422 bool MessageImpl::WillStartRunning() const {
2423   return running_;
2424 }
2425
2426
2427 v8::Local<v8::Object> MessageImpl::GetExecutionState() const {
2428   return v8::Utils::ToLocal(exec_state_);
2429 }
2430
2431
2432 v8::Isolate* MessageImpl::GetIsolate() const {
2433   return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
2434 }
2435
2436
2437 v8::Local<v8::Object> MessageImpl::GetEventData() const {
2438   return v8::Utils::ToLocal(event_data_);
2439 }
2440
2441
2442 v8::Local<v8::String> MessageImpl::GetJSON() const {
2443   Isolate* isolate = event_data_->GetIsolate();
2444   v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
2445
2446   if (IsEvent()) {
2447     // Call toJSONProtocol on the debug event object.
2448     Handle<Object> fun = Object::GetProperty(
2449         isolate, event_data_, "toJSONProtocol").ToHandleChecked();
2450     if (!fun->IsJSFunction()) {
2451       return v8::Local<v8::String>();
2452     }
2453
2454     MaybeHandle<Object> maybe_json =
2455         Execution::TryCall(Handle<JSFunction>::cast(fun), event_data_, 0, NULL);
2456     Handle<Object> json;
2457     if (!maybe_json.ToHandle(&json) || !json->IsString()) {
2458       return v8::Local<v8::String>();
2459     }
2460     return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
2461   } else {
2462     return v8::Utils::ToLocal(response_json_);
2463   }
2464 }
2465
2466
2467 v8::Local<v8::Context> MessageImpl::GetEventContext() const {
2468   Isolate* isolate = event_data_->GetIsolate();
2469   v8::Local<v8::Context> context = GetDebugEventContext(isolate);
2470   // Isolate::context() may be NULL when "script collected" event occurs.
2471   DCHECK(!context.IsEmpty());
2472   return context;
2473 }
2474
2475
2476 v8::Debug::ClientData* MessageImpl::GetClientData() const {
2477   return client_data_;
2478 }
2479
2480
2481 EventDetailsImpl::EventDetailsImpl(DebugEvent event,
2482                                    Handle<JSObject> exec_state,
2483                                    Handle<JSObject> event_data,
2484                                    Handle<Object> callback_data,
2485                                    v8::Debug::ClientData* client_data)
2486     : event_(event),
2487       exec_state_(exec_state),
2488       event_data_(event_data),
2489       callback_data_(callback_data),
2490       client_data_(client_data) {}
2491
2492
2493 DebugEvent EventDetailsImpl::GetEvent() const {
2494   return event_;
2495 }
2496
2497
2498 v8::Local<v8::Object> EventDetailsImpl::GetExecutionState() const {
2499   return v8::Utils::ToLocal(exec_state_);
2500 }
2501
2502
2503 v8::Local<v8::Object> EventDetailsImpl::GetEventData() const {
2504   return v8::Utils::ToLocal(event_data_);
2505 }
2506
2507
2508 v8::Local<v8::Context> EventDetailsImpl::GetEventContext() const {
2509   return GetDebugEventContext(exec_state_->GetIsolate());
2510 }
2511
2512
2513 v8::Local<v8::Value> EventDetailsImpl::GetCallbackData() const {
2514   return v8::Utils::ToLocal(callback_data_);
2515 }
2516
2517
2518 v8::Debug::ClientData* EventDetailsImpl::GetClientData() const {
2519   return client_data_;
2520 }
2521
2522
2523 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
2524                                    client_data_(NULL) {
2525 }
2526
2527
2528 CommandMessage::CommandMessage(const Vector<uint16_t>& text,
2529                                v8::Debug::ClientData* data)
2530     : text_(text),
2531       client_data_(data) {
2532 }
2533
2534
2535 void CommandMessage::Dispose() {
2536   text_.Dispose();
2537   delete client_data_;
2538   client_data_ = NULL;
2539 }
2540
2541
2542 CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
2543                                    v8::Debug::ClientData* data) {
2544   return CommandMessage(command.Clone(), data);
2545 }
2546
2547
2548 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
2549                                                      size_(size) {
2550   messages_ = NewArray<CommandMessage>(size);
2551 }
2552
2553
2554 CommandMessageQueue::~CommandMessageQueue() {
2555   while (!IsEmpty()) Get().Dispose();
2556   DeleteArray(messages_);
2557 }
2558
2559
2560 CommandMessage CommandMessageQueue::Get() {
2561   DCHECK(!IsEmpty());
2562   int result = start_;
2563   start_ = (start_ + 1) % size_;
2564   return messages_[result];
2565 }
2566
2567
2568 void CommandMessageQueue::Put(const CommandMessage& message) {
2569   if ((end_ + 1) % size_ == start_) {
2570     Expand();
2571   }
2572   messages_[end_] = message;
2573   end_ = (end_ + 1) % size_;
2574 }
2575
2576
2577 void CommandMessageQueue::Expand() {
2578   CommandMessageQueue new_queue(size_ * 2);
2579   while (!IsEmpty()) {
2580     new_queue.Put(Get());
2581   }
2582   CommandMessage* array_to_free = messages_;
2583   *this = new_queue;
2584   new_queue.messages_ = array_to_free;
2585   // Make the new_queue empty so that it doesn't call Dispose on any messages.
2586   new_queue.start_ = new_queue.end_;
2587   // Automatic destructor called on new_queue, freeing array_to_free.
2588 }
2589
2590
2591 LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
2592     : logger_(logger), queue_(size) {}
2593
2594
2595 bool LockingCommandMessageQueue::IsEmpty() const {
2596   base::LockGuard<base::Mutex> lock_guard(&mutex_);
2597   return queue_.IsEmpty();
2598 }
2599
2600
2601 CommandMessage LockingCommandMessageQueue::Get() {
2602   base::LockGuard<base::Mutex> lock_guard(&mutex_);
2603   CommandMessage result = queue_.Get();
2604   logger_->DebugEvent("Get", result.text());
2605   return result;
2606 }
2607
2608
2609 void LockingCommandMessageQueue::Put(const CommandMessage& message) {
2610   base::LockGuard<base::Mutex> lock_guard(&mutex_);
2611   queue_.Put(message);
2612   logger_->DebugEvent("Put", message.text());
2613 }
2614
2615
2616 void LockingCommandMessageQueue::Clear() {
2617   base::LockGuard<base::Mutex> lock_guard(&mutex_);
2618   queue_.Clear();
2619 }
2620
2621 }  // namespace internal
2622 }  // namespace v8