V8 Project
debug.cc
Go to the documentation of this file.
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/v8.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/debug.h"
15 #include "src/deoptimizer.h"
16 #include "src/execution.h"
17 #include "src/full-codegen.h"
18 #include "src/global-handles.h"
19 #include "src/isolate-inl.h"
20 #include "src/list.h"
21 #include "src/log.h"
22 #include "src/messages.h"
23 #include "src/natives.h"
24 
25 #include "include/v8-debug.h"
26 
27 namespace v8 {
28 namespace internal {
29 
31  : debug_context_(Handle<Context>()),
32  event_listener_(Handle<Object>()),
33  event_listener_data_(Handle<Object>()),
34  message_handler_(NULL),
35  command_received_(0),
36  command_queue_(isolate->logger(), kQueueInitialSize),
37  event_command_queue_(isolate->logger(), kQueueInitialSize),
38  is_active_(false),
39  is_suppressed_(false),
40  live_edit_enabled_(true), // TODO(yangguo): set to false by default.
41  has_break_points_(false),
42  break_disabled_(false),
43  break_on_exception_(false),
44  break_on_uncaught_exception_(false),
45  script_cache_(NULL),
46  debug_info_list_(NULL),
47  isolate_(isolate) {
48  ThreadInit();
49 }
50 
51 
53  Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
54  // Isolate::context() may have been NULL when "script collected" event
55  // occured.
56  if (context.is_null()) return v8::Local<v8::Context>();
57  Handle<Context> native_context(context->native_context());
58  return v8::Utils::ToLocal(native_context);
59 }
60 
61 
63  BreakLocatorType type) {
64  debug_info_ = debug_info;
65  type_ = type;
68  Reset(); // Initialize the rest of the member variables.
69 }
70 
71 
75  delete reloc_iterator_;
77 }
78 
79 
80 // Check whether a code stub with the specified major key is a possible break
81 // point location when looking for source break locations.
82 static bool IsSourceBreakStub(Code* code) {
83  CodeStub::Major major_key = CodeStub::GetMajorKey(code);
84  return major_key == CodeStub::CallFunction;
85 }
86 
87 
88 // Check whether a code stub with the specified major key is a possible break
89 // location.
90 static bool IsBreakStub(Code* code) {
91  CodeStub::Major major_key = CodeStub::GetMajorKey(code);
92  return major_key == CodeStub::CallFunction;
93 }
94 
95 
98  DCHECK(!RinfoDone());
99 
100  // Iterate through reloc info for code and original code stopping at each
101  // breakable code target.
102  bool first = break_point_ == -1;
103  while (!RinfoDone()) {
104  if (!first) RinfoNext();
105  first = false;
106  if (RinfoDone()) return;
107 
108  // Whenever a statement position or (plain) position is passed update the
109  // current value of these.
110  if (RelocInfo::IsPosition(rmode())) {
112  statement_position_ = static_cast<int>(
113  rinfo()->data() - debug_info_->shared()->start_position());
114  }
115  // Always update the position as we don't want that to be before the
116  // statement position.
117  position_ = static_cast<int>(
118  rinfo()->data() - debug_info_->shared()->start_position());
119  DCHECK(position_ >= 0);
121  }
122 
123  if (IsDebugBreakSlot()) {
124  // There is always a possible break point at a debug break slot.
125  break_point_++;
126  return;
127  } else if (RelocInfo::IsCodeTarget(rmode())) {
128  // Check for breakable code target. Look in the original code as setting
129  // break points can cause the code targets in the running (debugged) code
130  // to be of a different kind than in the original code.
131  Address target = original_rinfo()->target_address();
133  if ((code->is_inline_cache_stub() &&
134  !code->is_binary_op_stub() &&
135  !code->is_compare_ic_stub() &&
138  break_point_++;
139  return;
140  }
141  if (code->kind() == Code::STUB) {
142  if (IsDebuggerStatement()) {
143  break_point_++;
144  return;
145  } else if (type_ == ALL_BREAK_LOCATIONS) {
146  if (IsBreakStub(code)) {
147  break_point_++;
148  return;
149  }
150  } else {
152  if (IsSourceBreakStub(code)) {
153  break_point_++;
154  return;
155  }
156  }
157  }
158  }
159 
160  // Check for break at return.
161  if (RelocInfo::IsJSReturn(rmode())) {
162  // Set the positions to the end of the function.
163  if (debug_info_->shared()->HasSourceCode()) {
164  position_ = debug_info_->shared()->end_position() -
165  debug_info_->shared()->start_position() - 1;
166  } else {
167  position_ = 0;
168  }
170  break_point_++;
171  return;
172  }
173  }
174 }
175 
176 
178  while (count > 0) {
179  Next();
180  count--;
181  }
182 }
183 
184 
185 // Find the break point at the supplied address, or the closest one before
186 // the address.
188  // Run through all break points to locate the one closest to the address.
189  int closest_break_point = 0;
190  int distance = kMaxInt;
191  while (!Done()) {
192  // Check if this break point is closer that what was previously found.
193  if (this->pc() <= pc && pc - this->pc() < distance) {
194  closest_break_point = break_point();
195  distance = static_cast<int>(pc - this->pc());
196  // Check whether we can't get any closer.
197  if (distance == 0) break;
198  }
199  Next();
200  }
201 
202  // Move to the break point found.
203  Reset();
204  Next(closest_break_point);
205 }
206 
207 
208 // Find the break point closest to the supplied source position.
210  BreakPositionAlignment alignment) {
211  // Run through all break points to locate the one closest to the source
212  // position.
213  int closest_break_point = 0;
214  int distance = kMaxInt;
215 
216  while (!Done()) {
217  int next_position;
218  switch (alignment) {
219  case STATEMENT_ALIGNED:
220  next_position = this->statement_position();
221  break;
223  next_position = this->position();
224  break;
225  default:
226  UNREACHABLE();
227  next_position = this->statement_position();
228  }
229  // Check if this break point is closer that what was previously found.
230  if (position <= next_position && next_position - position < distance) {
231  closest_break_point = break_point();
232  distance = next_position - position;
233  // Check whether we can't get any closer.
234  if (distance == 0) break;
235  }
236  Next();
237  }
238 
239  // Move to the break point found.
240  Reset();
241  Next(closest_break_point);
242 }
243 
244 
246  // Create relocation iterators for the two code objects.
247  if (reloc_iterator_ != NULL) delete reloc_iterator_;
250  debug_info_->code(),
253  debug_info_->original_code(),
255 
256  // Position at the first break point.
257  break_point_ = -1;
258  position_ = 1;
260  Next();
261 }
262 
263 
265  return RinfoDone();
266 }
267 
268 
270  // If there is not already a real break point here patch code with debug
271  // break.
272  if (!HasBreakPoint()) SetDebugBreak();
274  // Set the break point information.
277  break_point_object);
278 }
279 
280 
282  // Clear the break point information.
283  DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
284  // If there are no more break points here remove the debug break.
285  if (!HasBreakPoint()) {
286  ClearDebugBreak();
287  DCHECK(!IsDebugBreak());
288  }
289 }
290 
291 
293  // Debugger statement always calls debugger. No need to modify it.
294  if (IsDebuggerStatement()) return;
295 
296  // If there is a real break point here no more to do.
297  if (HasBreakPoint()) {
298  DCHECK(IsDebugBreak());
299  return;
300  }
301 
302  // Patch code with debug break.
303  SetDebugBreak();
304 }
305 
306 
308  // Debugger statement always calls debugger. No need to modify it.
309  if (IsDebuggerStatement()) return;
310 
311  // If there is a real break point here no more to do.
312  if (HasBreakPoint()) {
313  DCHECK(IsDebugBreak());
314  return;
315  }
316 
317  // Patch code removing debug break.
318  ClearDebugBreak();
319  DCHECK(!IsDebugBreak());
320 }
321 
322 
324  // Debugger statement always calls debugger. No need to modify it.
325  if (IsDebuggerStatement()) return;
326 
327  // If there is already a break point here just return. This might happen if
328  // the same code is flooded with break points twice. Flooding the same
329  // function twice might happen when stepping in a function with an exception
330  // handler as the handler and the function is the same.
331  if (IsDebugBreak()) return;
332 
333  if (RelocInfo::IsJSReturn(rmode())) {
334  // Patch the frame exit code with a break point.
336  } else if (IsDebugBreakSlot()) {
337  // Patch the code in the break slot.
339  } else {
340  // Patch the IC call.
342  }
343  DCHECK(IsDebugBreak());
344 }
345 
346 
348  // Debugger statement always calls debugger. No need to modify it.
349  if (IsDebuggerStatement()) return;
350 
351  if (RelocInfo::IsJSReturn(rmode())) {
352  // Restore the frame exit code.
354  } else if (IsDebugBreakSlot()) {
355  // Restore the code in the break slot.
357  } else {
358  // Patch the IC call.
360  }
361  DCHECK(!IsDebugBreak());
362 }
363 
364 
367  return true;
368  } else if (RelocInfo::IsCodeTarget(rmode())) {
369  HandleScope scope(debug_info_->GetIsolate());
370  Address target = original_rinfo()->target_address();
371  Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
372  if (target_code->kind() == Code::STUB) {
373  return CodeStub::GetMajorKey(*target_code) == CodeStub::CallFunction;
374  }
375  return target_code->is_call_stub();
376  }
377  return false;
378 }
379 
380 
382 #ifdef DEBUG
383  HandleScope scope(isolate);
384  // Step in can only be prepared if currently positioned on an IC call,
385  // construct call or CallFunction stub call.
386  Address target = rinfo()->target_address();
387  Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
388  // All the following stuff is needed only for assertion checks so the code
389  // is wrapped in ifdef.
390  Handle<Code> maybe_call_function_stub = target_code;
391  if (IsDebugBreak()) {
392  Address original_target = original_rinfo()->target_address();
393  maybe_call_function_stub =
395  }
396  bool is_call_function_stub =
397  (maybe_call_function_stub->kind() == Code::STUB &&
398  CodeStub::GetMajorKey(*maybe_call_function_stub) ==
399  CodeStub::CallFunction);
400 
401  // Step in through construct call requires no changes to the running code.
402  // Step in through getters/setters should already be prepared as well
403  // because caller of this function (Debug::PrepareStep) is expected to
404  // flood the top frame's function with one shot breakpoints.
405  // Step in through CallFunction stub should also be prepared by caller of
406  // this function (Debug::PrepareStep) which should flood target function
407  // with breakpoints.
409  target_code->is_inline_cache_stub() ||
410  is_call_function_stub);
411 #endif
412 }
413 
414 
415 // Check whether the break point is at a position which will exit the function.
417  return (RelocInfo::IsJSReturn(rmode()));
418 }
419 
420 
422  return debug_info_->HasBreakPoint(code_position());
423 }
424 
425 
426 // Check whether there is a debug break at the current position.
428  if (RelocInfo::IsJSReturn(rmode())) {
429  return IsDebugBreakAtReturn();
430  } else if (IsDebugBreakSlot()) {
431  return IsDebugBreakAtSlot();
432  } else {
433  return Debug::IsDebugBreak(rinfo()->target_address());
434  }
435 }
436 
437 
438 // Find the builtin to use for invoking the debug break
440  Isolate* isolate = code->GetIsolate();
441 
442  // Find the builtin debug break function matching the calling convention
443  // used by the call site.
444  if (code->is_inline_cache_stub()) {
445  switch (code->kind()) {
446  case Code::CALL_IC:
447  return isolate->builtins()->CallICStub_DebugBreak();
448 
449  case Code::LOAD_IC:
450  return isolate->builtins()->LoadIC_DebugBreak();
451 
452  case Code::STORE_IC:
453  return isolate->builtins()->StoreIC_DebugBreak();
454 
455  case Code::KEYED_LOAD_IC:
456  return isolate->builtins()->KeyedLoadIC_DebugBreak();
457 
458  case Code::KEYED_STORE_IC:
459  return isolate->builtins()->KeyedStoreIC_DebugBreak();
460 
461  case Code::COMPARE_NIL_IC:
462  return isolate->builtins()->CompareNilIC_DebugBreak();
463 
464  default:
465  UNREACHABLE();
466  }
467  }
469  if (code->has_function_cache()) {
470  return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
471  } else {
472  return isolate->builtins()->CallConstructStub_DebugBreak();
473  }
474  }
475  if (code->kind() == Code::STUB) {
476  DCHECK(CodeStub::GetMajorKey(*code) == CodeStub::CallFunction);
477  return isolate->builtins()->CallFunctionStub_DebugBreak();
478  }
479 
480  UNREACHABLE();
481  return Handle<Code>::null();
482 }
483 
484 
486  // Patch the original code with the current address as the current address
487  // might have changed by the inline caching since the code was copied.
488  original_rinfo()->set_target_address(rinfo()->target_address());
489 
492  Address target = rinfo()->target_address();
493  Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
494 
495  // Patch the code to invoke the builtin debug break function matching the
496  // calling convention used by the call site.
497  Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode);
498  rinfo()->set_target_address(dbgbrk_code->entry());
499  }
500 }
501 
502 
504  // Patch the code to the original invoke.
505  rinfo()->set_target_address(original_rinfo()->target_address());
506 }
507 
508 
510  return RelocInfo::DEBUG_BREAK == rmode();
511 }
512 
513 
516 }
517 
518 
520  return debug_info_->GetBreakPointObjects(code_position());
521 }
522 
523 
524 // Clear out all the debug break code. This is ONLY supposed to be used when
525 // shutting down the debugger as it will leave the break point information in
526 // DebugInfo even though the code is patched back to the non break point state.
528  while (!Done()) {
529  ClearDebugBreak();
530  Next();
531  }
532 }
533 
534 
537  return reloc_iterator_->done();
538 }
539 
540 
544 #ifdef DEBUG
546  if (!reloc_iterator_->done()) {
547  DCHECK(rmode() == original_rmode());
548  }
549 #endif
550 }
551 
552 
553 // Threading support.
557  thread_local_.break_frame_id_ = StackFrame::NO_ID;
565  // TODO(isolates): frames_are_dropped_?
568 }
569 
570 
571 char* Debug::ArchiveDebug(char* storage) {
572  char* to = storage;
573  MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
574  ThreadInit();
575  return storage + ArchiveSpacePerThread();
576 }
577 
578 
579 char* Debug::RestoreDebug(char* storage) {
580  char* from = storage;
581  MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
582  return storage + ArchiveSpacePerThread();
583 }
584 
585 
587  return sizeof(ThreadLocal);
588 }
589 
590 
591 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch),
592  isolate_(isolate) {
593  Heap* heap = isolate_->heap();
594  HandleScope scope(isolate_);
595 
596  // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
597  // rid of all the cached script wrappers and the second gets rid of the
598  // scripts which are no longer referenced.
599  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
600  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
601 
602  // Scan heap for Script objects.
603  HeapIterator iterator(heap);
604  DisallowHeapAllocation no_allocation;
605 
606  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
607  if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
608  Add(Handle<Script>(Script::cast(obj)));
609  }
610  }
611 }
612 
613 
615  GlobalHandles* global_handles = isolate_->global_handles();
616  // Create an entry in the hash map for the script.
617  int id = script->id()->value();
618  HashMap::Entry* entry =
619  HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
620  if (entry->value != NULL) {
621 #ifdef DEBUG
622  // The code deserializer may introduce duplicate Script objects.
623  // Assert that the Script objects with the same id have the same name.
624  Handle<Script> found(reinterpret_cast<Script**>(entry->value));
625  DCHECK(script->id() == found->id());
626  DCHECK(!script->name()->IsString() ||
627  String::cast(script->name())->Equals(String::cast(found->name())));
628 #endif
629  return;
630  }
631  // Globalize the script object, make it weak and use the location of the
632  // global handle as the value in the hash map.
633  Handle<Script> script_ =
634  Handle<Script>::cast(global_handles->Create(*script));
635  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
636  this,
638  entry->value = script_.location();
639 }
640 
641 
643  Factory* factory = isolate_->factory();
644  Handle<FixedArray> instances = factory->NewFixedArray(occupancy());
645  int count = 0;
646  for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
647  DCHECK(entry->value != NULL);
648  if (entry->value != NULL) {
649  instances->set(count, *reinterpret_cast<Script**>(entry->value));
650  count++;
651  }
652  }
653  return instances;
654 }
655 
656 
658  // Iterate the script cache to get rid of all the weak handles.
659  for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
660  DCHECK(entry != NULL);
661  Object** location = reinterpret_cast<Object**>(entry->value);
662  DCHECK((*location)->IsScript());
664  GlobalHandles::Destroy(location);
665  }
666  // Clear the content of the hash map.
667  HashMap::Clear();
668 }
669 
670 
673  // Retrieve the script identifier.
674  Handle<Object> object = Utils::OpenHandle(*data.GetValue());
675  int id = Handle<Script>::cast(object)->id()->value();
676  void* key = reinterpret_cast<void*>(id);
677  uint32_t hash = Hash(id);
678 
679  // Remove the corresponding entry from the cache.
680  ScriptCache* script_cache =
681  reinterpret_cast<ScriptCache*>(data.GetParameter());
682  HashMap::Entry* entry = script_cache->Lookup(key, hash, false);
683  Object** location = reinterpret_cast<Object**>(entry->value);
684  script_cache->Remove(key, hash);
685 
686  // Clear the weak handle.
687  GlobalHandles::Destroy(location);
688 }
689 
690 
693  Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
694  DebugInfoListNode* node =
695  reinterpret_cast<DebugInfoListNode*>(data.GetParameter());
696  // We need to clear all breakpoints associated with the function to restore
697  // original code and avoid patching the code twice later because
698  // the function will live in the heap until next gc, and can be found by
699  // Debug::FindSharedFunctionInfoInScript.
701  it.ClearAllDebugBreak();
702  debug->RemoveDebugInfo(node->debug_info());
703 #ifdef DEBUG
704  for (DebugInfoListNode* n = debug->debug_info_list_;
705  n != NULL;
706  n = n->next()) {
707  DCHECK(n != node);
708  }
709 #endif
710 }
711 
712 
714  // Globalize the request debug info object and make it weak.
715  GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
717  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
718  this,
720 }
721 
722 
724  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location()));
725 }
726 
727 
728 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
729  Factory* factory = isolate->factory();
730  HandleScope scope(isolate);
731 
732  // Bail out if the index is invalid.
733  if (index == -1) return false;
734 
735  // Find source and name for the requested script.
736  Handle<String> source_code =
737  isolate->bootstrapper()->NativesSourceLookup(index);
739  Handle<String> script_name =
740  factory->NewStringFromAscii(name).ToHandleChecked();
741  Handle<Context> context = isolate->native_context();
742 
743  // Compile the script.
744  Handle<SharedFunctionInfo> function_info;
745  function_info = Compiler::CompileScript(
746  source_code, script_name, 0, 0, false, context, NULL, NULL,
748 
749  // Silently ignore stack overflows during compilation.
750  if (function_info.is_null()) {
751  DCHECK(isolate->has_pending_exception());
752  isolate->clear_pending_exception();
753  return false;
754  }
755 
756  // Execute the shared function in the debugger context.
757  Handle<JSFunction> function =
758  factory->NewFunctionFromSharedFunctionInfo(function_info, context);
759 
760  MaybeHandle<Object> maybe_exception;
761  MaybeHandle<Object> result = Execution::TryCall(
762  function, handle(context->global_proxy()), 0, NULL, &maybe_exception);
763 
764  // Check for caught exceptions.
765  if (result.is_null()) {
766  DCHECK(!isolate->has_pending_exception());
767  MessageLocation computed_location;
768  isolate->ComputeLocation(&computed_location);
770  isolate, "error_loading_debugger", &computed_location,
771  Vector<Handle<Object> >::empty(), Handle<JSArray>());
772  DCHECK(!isolate->has_pending_exception());
773  Handle<Object> exception;
774  if (maybe_exception.ToHandle(&exception)) {
775  isolate->set_pending_exception(*exception);
776  MessageHandler::ReportMessage(isolate, NULL, message);
777  isolate->clear_pending_exception();
778  }
779  return false;
780  }
781 
782  // Mark this script as native and return successfully.
783  Handle<Script> script(Script::cast(function->shared()->script()));
784  script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
785  return true;
786 }
787 
788 
789 bool Debug::Load() {
790  // Return if debugger is already loaded.
791  if (is_loaded()) return true;
792 
793  // Bail out if we're already in the process of compiling the native
794  // JavaScript source code for the debugger.
795  if (is_suppressed_) return false;
796  SuppressDebug while_loading(this);
797 
798  // Disable breakpoints and interrupts while compiling and running the
799  // debugger scripts including the context creation code.
800  DisableBreak disable(this, true);
801  PostponeInterruptsScope postpone(isolate_);
802 
803  // Create the debugger context.
804  HandleScope scope(isolate_);
805  ExtensionConfiguration no_extensions;
806  Handle<Context> context =
807  isolate_->bootstrapper()->CreateEnvironment(
810  &no_extensions);
811 
812  // Fail if no context could be created.
813  if (context.is_null()) return false;
814 
815  // Use the debugger context.
816  SaveContext save(isolate_);
817  isolate_->set_context(*context);
818 
819  // Expose the builtins object in the debugger context.
820  Handle<String> key = isolate_->factory()->InternalizeOneByteString(
821  STATIC_CHAR_VECTOR("builtins"));
822  Handle<GlobalObject> global =
823  Handle<GlobalObject>(context->global_object(), isolate_);
824  Handle<JSBuiltinsObject> builtin =
825  Handle<JSBuiltinsObject>(global->builtins(), isolate_);
827  isolate_, Object::SetProperty(global, key, builtin, SLOPPY), false);
828 
829  // Compile the JavaScript for the debugger in the debugger context.
830  bool caught_exception =
833 
834  if (FLAG_enable_liveedit) {
835  caught_exception = caught_exception ||
837  }
838  // Check for caught exceptions.
839  if (caught_exception) return false;
840 
842  isolate_->global_handles()->Create(*context));
843  return true;
844 }
845 
846 
849  ClearStepping();
850 
851  // Return debugger is not loaded.
852  if (!is_loaded()) return;
853 
854  // Clear the script cache.
855  if (script_cache_ != NULL) {
856  delete script_cache_;
858  }
859 
860  // Clear debugger context global handle.
863 }
864 
865 
867  Heap* heap = isolate_->heap();
868  HandleScope scope(isolate_);
869  DCHECK(args.length() == 0);
870 
871  // Initialize LiveEdit.
873 
874  // Just continue if breaks are disabled or debugger cannot be loaded.
875  if (break_disabled_) return;
876 
877  // Enter the debugger.
878  DebugScope debug_scope(this);
879  if (debug_scope.failed()) return;
880 
881  // Postpone interrupt during breakpoint processing.
882  PostponeInterruptsScope postpone(isolate_);
883 
884  // Get the debug info (create it if it does not exist).
886  Handle<SharedFunctionInfo>(frame->function()->shared());
887  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
888 
889  // Find the break point where execution has stopped.
890  BreakLocationIterator break_location_iterator(debug_info,
892  // pc points to the instruction after the current one, possibly a break
893  // location as well. So the "- 1" to exclude it from the search.
894  break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
895 
896  // Check whether step next reached a new statement.
897  if (!StepNextContinue(&break_location_iterator, frame)) {
898  // Decrease steps left if performing multiple steps.
899  if (thread_local_.step_count_ > 0) {
901  }
902  }
903 
904  // If there is one or more real break points check whether any of these are
905  // triggered.
906  Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
907  if (break_location_iterator.HasBreakPoint()) {
908  Handle<Object> break_point_objects =
909  Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_);
910  break_points_hit = CheckBreakPoints(break_point_objects);
911  }
912 
913  // If step out is active skip everything until the frame where we need to step
914  // out to is reached, unless real breakpoint is hit.
915  if (StepOutActive() &&
916  frame->fp() != thread_local_.step_out_fp_ &&
917  break_points_hit->IsUndefined() ) {
918  // Step count should always be 0 for StepOut.
920  } else if (!break_points_hit->IsUndefined() ||
922  thread_local_.step_count_ == 0)) {
923  // Notify debugger if a real break point is triggered or if performing
924  // single stepping with no more steps to perform. Otherwise do another step.
925 
926  // Clear all current stepping setup.
927  ClearStepping();
928 
930  // Perform queued steps
931  int step_count = thread_local_.queued_step_count_;
932 
933  // Clear queue
935 
936  PrepareStep(StepNext, step_count, StackFrame::NO_ID);
937  } else {
938  // Notify the debug event listeners.
939  OnDebugBreak(break_points_hit, false);
940  }
941  } else if (thread_local_.last_step_action_ != StepNone) {
942  // Hold on to last step action as it is cleared by the call to
943  // ClearStepping.
945  int step_count = thread_local_.step_count_;
946 
947  // If StepNext goes deeper in code, StepOut until original frame
948  // and keep step count queued up in the meantime.
949  if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
950  // Count frames until target frame
951  int count = 0;
952  JavaScriptFrameIterator it(isolate_);
953  while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) {
954  count++;
955  it.Advance();
956  }
957 
958  // Check that we indeed found the frame we are looking for.
959  CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_));
960  if (step_count > 1) {
961  // Save old count and action to continue stepping after StepOut.
962  thread_local_.queued_step_count_ = step_count - 1;
963  }
964 
965  // Set up for StepOut to reach target frame.
966  step_action = StepOut;
967  step_count = count;
968  }
969 
970  // Clear all current stepping setup.
971  ClearStepping();
972 
973  // Set up for the remaining steps.
974  PrepareStep(step_action, step_count, StackFrame::NO_ID);
975  }
976 }
977 
978 
979 RUNTIME_FUNCTION(Debug_Break) {
980  // Get the top-most JavaScript frame.
981  JavaScriptFrameIterator it(isolate);
982  isolate->debug()->Break(args, it.frame());
983  isolate->debug()->SetAfterBreakTarget(it.frame());
984  return isolate->heap()->undefined_value();
985 }
986 
987 
988 // Check the break point objects for whether one or more are actually
989 // triggered. This function returns a JSArray with the break point objects
990 // which is triggered.
992  Factory* factory = isolate_->factory();
993 
994  // Count the number of break points hit. If there are multiple break points
995  // they are in a FixedArray.
996  Handle<FixedArray> break_points_hit;
997  int break_points_hit_count = 0;
998  DCHECK(!break_point_objects->IsUndefined());
999  if (break_point_objects->IsFixedArray()) {
1000  Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
1001  break_points_hit = factory->NewFixedArray(array->length());
1002  for (int i = 0; i < array->length(); i++) {
1003  Handle<Object> o(array->get(i), isolate_);
1004  if (CheckBreakPoint(o)) {
1005  break_points_hit->set(break_points_hit_count++, *o);
1006  }
1007  }
1008  } else {
1009  break_points_hit = factory->NewFixedArray(1);
1010  if (CheckBreakPoint(break_point_objects)) {
1011  break_points_hit->set(break_points_hit_count++, *break_point_objects);
1012  }
1013  }
1014 
1015  // Return undefined if no break points were triggered.
1016  if (break_points_hit_count == 0) {
1017  return factory->undefined_value();
1018  }
1019  // Return break points hit as a JSArray.
1020  Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
1021  result->set_length(Smi::FromInt(break_points_hit_count));
1022  return result;
1023 }
1024 
1025 
1026 // Check whether a single break point object is triggered.
1027 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
1028  Factory* factory = isolate_->factory();
1029  HandleScope scope(isolate_);
1030 
1031  // Ignore check if break point object is not a JSObject.
1032  if (!break_point_object->IsJSObject()) return true;
1033 
1034  // Get the function IsBreakPointTriggered (defined in debug-debugger.js).
1035  Handle<String> is_break_point_triggered_string =
1036  factory->InternalizeOneByteString(
1037  STATIC_CHAR_VECTOR("IsBreakPointTriggered"));
1038  Handle<GlobalObject> debug_global(debug_context()->global_object());
1039  Handle<JSFunction> check_break_point =
1041  debug_global, is_break_point_triggered_string).ToHandleChecked());
1042 
1043  // Get the break id as an object.
1044  Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
1045 
1046  // Call HandleBreakPointx.
1047  Handle<Object> argv[] = { break_id, break_point_object };
1048  Handle<Object> result;
1049  if (!Execution::TryCall(check_break_point,
1051  arraysize(argv),
1052  argv).ToHandle(&result)) {
1053  return false;
1054  }
1055 
1056  // Return whether the break point is triggered.
1057  return result->IsTrue();
1058 }
1059 
1060 
1061 // Check whether the function has debug information.
1063  return !shared->debug_info()->IsUndefined();
1064 }
1065 
1066 
1067 // Return the debug info for this function. EnsureDebugInfo must be called
1068 // prior to ensure the debug info has been generated for shared.
1070  DCHECK(HasDebugInfo(shared));
1071  return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info()));
1072 }
1073 
1074 
1076  Handle<Object> break_point_object,
1077  int* source_position) {
1078  HandleScope scope(isolate_);
1079 
1081 
1082  // Make sure the function is compiled and has set up the debug info.
1083  Handle<SharedFunctionInfo> shared(function->shared());
1084  if (!EnsureDebugInfo(shared, function)) {
1085  // Return if retrieving debug info failed.
1086  return true;
1087  }
1088 
1089  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1090  // Source positions starts with zero.
1091  DCHECK(*source_position >= 0);
1092 
1093  // Find the break point and change it.
1095  it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED);
1096  it.SetBreakPoint(break_point_object);
1097 
1098  *source_position = it.position();
1099 
1100  // At least one active break point now.
1101  return debug_info->GetBreakPointCount() > 0;
1102 }
1103 
1104 
1106  Handle<Object> break_point_object,
1107  int* source_position,
1108  BreakPositionAlignment alignment) {
1109  HandleScope scope(isolate_);
1110 
1112 
1113  // Obtain shared function info for the function.
1114  Object* result = FindSharedFunctionInfoInScript(script, *source_position);
1115  if (result->IsUndefined()) return false;
1116 
1117  // Make sure the function has set up the debug info.
1118  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
1119  if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
1120  // Return if retrieving debug info failed.
1121  return false;
1122  }
1123 
1124  // Find position within function. The script position might be before the
1125  // source position of the first function.
1126  int position;
1127  if (shared->start_position() > *source_position) {
1128  position = 0;
1129  } else {
1130  position = *source_position - shared->start_position();
1131  }
1132 
1133  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1134  // Source positions starts with zero.
1135  DCHECK(position >= 0);
1136 
1137  // Find the break point and change it.
1139  it.FindBreakLocationFromPosition(position, alignment);
1140  it.SetBreakPoint(break_point_object);
1141 
1142  *source_position = it.position() + shared->start_position();
1143 
1144  // At least one active break point now.
1145  DCHECK(debug_info->GetBreakPointCount() > 0);
1146  return true;
1147 }
1148 
1149 
1150 void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
1151  HandleScope scope(isolate_);
1152 
1154  while (node != NULL) {
1156  break_point_object);
1157  if (!result->IsUndefined()) {
1158  // Get information in the break point.
1159  BreakPointInfo* break_point_info = BreakPointInfo::cast(result);
1160  Handle<DebugInfo> debug_info = node->debug_info();
1161 
1162  // Find the break point and clear it.
1164  it.FindBreakLocationFromAddress(debug_info->code()->entry() +
1165  break_point_info->code_position()->value());
1166  it.ClearBreakPoint(break_point_object);
1167 
1168  // If there are no more break points left remove the debug info for this
1169  // function.
1170  if (debug_info->GetBreakPointCount() == 0) {
1171  RemoveDebugInfo(debug_info);
1172  }
1173 
1174  return;
1175  }
1176  node = node->next();
1177  }
1178 }
1179 
1180 
1183  while (node != NULL) {
1184  // Remove all debug break code.
1186  it.ClearAllDebugBreak();
1187  node = node->next();
1188  }
1189 
1190  // Remove all debug info.
1191  while (debug_info_list_ != NULL) {
1193  }
1194 }
1195 
1196 
1199 
1200  // Make sure the function is compiled and has set up the debug info.
1201  Handle<SharedFunctionInfo> shared(function->shared());
1202  if (!EnsureDebugInfo(shared, function)) {
1203  // Return if we failed to retrieve the debug info.
1204  return;
1205  }
1206 
1207  // Flood the function with break points.
1209  while (!it.Done()) {
1210  it.SetOneShot();
1211  it.Next();
1212  }
1213 }
1214 
1215 
1217  Handle<FixedArray> new_bindings(function->function_bindings());
1218  Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex),
1219  isolate_);
1220 
1221  if (!bindee.is_null() && bindee->IsJSFunction() &&
1222  !JSFunction::cast(*bindee)->IsFromNativeScript()) {
1223  Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
1224  Debug::FloodWithOneShot(bindee_function);
1225  }
1226 }
1227 
1228 
1230  // Iterate through the JavaScript stack looking for handlers.
1231  StackFrame::Id id = break_frame_id();
1232  if (id == StackFrame::NO_ID) {
1233  // If there is no JavaScript stack don't do anything.
1234  return;
1235  }
1236  for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
1237  JavaScriptFrame* frame = it.frame();
1238  if (frame->HasHandler()) {
1239  // Flood the function with the catch block with break points
1241  return;
1242  }
1243  }
1244 }
1245 
1246 
1248  if (type == BreakUncaughtException) {
1250  } else {
1251  break_on_exception_ = enable;
1252  }
1253 }
1254 
1255 
1257  if (type == BreakUncaughtException) {
1259  } else {
1260  return break_on_exception_;
1261  }
1262 }
1263 
1264 
1268  isolate_->factory()->NewStringFromStaticChars(
1269  "PromiseHasRejectHandler")));
1270  Handle<Object> result =
1271  Execution::Call(isolate_, fun, promise, 0, NULL).ToHandleChecked();
1272  return result->IsTrue();
1273 }
1274 
1275 
1277  int step_count,
1278  StackFrame::Id frame_id) {
1279  HandleScope scope(isolate_);
1280 
1282 
1284 
1285  // Remember this step action and count.
1286  thread_local_.last_step_action_ = step_action;
1287  if (step_action == StepOut) {
1288  // For step out target frame will be found on the stack so there is no need
1289  // to set step counter for it. It's expected to always be 0 for StepOut.
1291  } else {
1292  thread_local_.step_count_ = step_count;
1293  }
1294 
1295  // Get the frame where the execution has stopped and skip the debug frame if
1296  // any. The debug frame will only be present if execution was stopped due to
1297  // hitting a break point. In other situations (e.g. unhandled exception) the
1298  // debug frame is not present.
1299  StackFrame::Id id = break_frame_id();
1300  if (id == StackFrame::NO_ID) {
1301  // If there is no JavaScript stack don't do anything.
1302  return;
1303  }
1304  if (frame_id != StackFrame::NO_ID) {
1305  id = frame_id;
1306  }
1307  JavaScriptFrameIterator frames_it(isolate_, id);
1308  JavaScriptFrame* frame = frames_it.frame();
1309 
1310  // First of all ensure there is one-shot break points in the top handler
1311  // if any.
1313 
1314  // If the function on the top frame is unresolved perform step out. This will
1315  // be the case when calling unknown functions and having the debugger stopped
1316  // in an unhandled exception.
1317  if (!frame->function()->IsJSFunction()) {
1318  // Step out: Find the calling JavaScript frame and flood it with
1319  // breakpoints.
1320  frames_it.Advance();
1321  // Fill the function to return to with one-shot break points.
1322  JSFunction* function = frames_it.frame()->function();
1324  return;
1325  }
1326 
1327  // Get the debug info (create it if it does not exist).
1328  Handle<JSFunction> function(frame->function());
1329  Handle<SharedFunctionInfo> shared(function->shared());
1330  if (!EnsureDebugInfo(shared, function)) {
1331  // Return if ensuring debug info failed.
1332  return;
1333  }
1334  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1335 
1336  // Find the break location where execution has stopped.
1338  // pc points to the instruction after the current one, possibly a break
1339  // location as well. So the "- 1" to exclude it from the search.
1340  it.FindBreakLocationFromAddress(frame->pc() - 1);
1341 
1342  // Compute whether or not the target is a call target.
1343  bool is_load_or_store = false;
1344  bool is_inline_cache_stub = false;
1345  bool is_at_restarted_function = false;
1346  Handle<Code> call_function_stub;
1347 
1349  if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
1350  bool is_call_target = false;
1351  Address target = it.rinfo()->target_address();
1352  Code* code = Code::GetCodeFromTargetAddress(target);
1353  if (code->is_call_stub()) {
1354  is_call_target = true;
1355  }
1356  if (code->is_inline_cache_stub()) {
1357  is_inline_cache_stub = true;
1358  is_load_or_store = !is_call_target;
1359  }
1360 
1361  // Check if target code is CallFunction stub.
1362  Code* maybe_call_function_stub = code;
1363  // If there is a breakpoint at this line look at the original code to
1364  // check if it is a CallFunction stub.
1365  if (it.IsDebugBreak()) {
1366  Address original_target = it.original_rinfo()->target_address();
1367  maybe_call_function_stub =
1368  Code::GetCodeFromTargetAddress(original_target);
1369  }
1370  if ((maybe_call_function_stub->kind() == Code::STUB &&
1371  CodeStub::GetMajorKey(maybe_call_function_stub) ==
1372  CodeStub::CallFunction) ||
1373  maybe_call_function_stub->kind() == Code::CALL_IC) {
1374  // Save reference to the code as we may need it to find out arguments
1375  // count for 'step in' later.
1376  call_function_stub = Handle<Code>(maybe_call_function_stub);
1377  }
1378  }
1379  } else {
1380  is_at_restarted_function = true;
1381  }
1382 
1383  // If this is the last break code target step out is the only possibility.
1384  if (it.IsExit() || step_action == StepOut) {
1385  if (step_action == StepOut) {
1386  // Skip step_count frames starting with the current one.
1387  while (step_count-- > 0 && !frames_it.done()) {
1388  frames_it.Advance();
1389  }
1390  } else {
1391  DCHECK(it.IsExit());
1392  frames_it.Advance();
1393  }
1394  // Skip builtin functions on the stack.
1395  while (!frames_it.done() &&
1396  frames_it.frame()->function()->IsFromNativeScript()) {
1397  frames_it.Advance();
1398  }
1399  // Step out: If there is a JavaScript caller frame, we need to
1400  // flood it with breakpoints.
1401  if (!frames_it.done()) {
1402  // Fill the function to return to with one-shot break points.
1403  JSFunction* function = frames_it.frame()->function();
1405  // Set target frame pointer.
1406  ActivateStepOut(frames_it.frame());
1407  }
1408  } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
1409  !call_function_stub.is_null() || is_at_restarted_function)
1410  || step_action == StepNext || step_action == StepMin) {
1411  // Step next or step min.
1412 
1413  // Fill the current function with one-shot break points.
1414  FloodWithOneShot(function);
1415 
1416  // Remember source position and frame to handle step next.
1418  debug_info->code()->SourceStatementPosition(frame->pc());
1419  thread_local_.last_fp_ = frame->UnpaddedFP();
1420  } else {
1421  // If there's restarter frame on top of the stack, just get the pointer
1422  // to function which is going to be restarted.
1423  if (is_at_restarted_function) {
1424  Handle<JSFunction> restarted_function(
1426  FloodWithOneShot(restarted_function);
1427  } else if (!call_function_stub.is_null()) {
1428  // If it's CallFunction stub ensure target function is compiled and flood
1429  // it with one shot breakpoints.
1430  bool is_call_ic = call_function_stub->kind() == Code::CALL_IC;
1431 
1432  // Find out number of arguments from the stub minor key.
1433  uint32_t key = call_function_stub->stub_key();
1434  // Argc in the stub is the number of arguments passed - not the
1435  // expected arguments of the called function.
1436  int call_function_arg_count = is_call_ic
1437  ? CallICStub::ExtractArgcFromMinorKey(CodeStub::MinorKeyFromKey(key))
1439  CodeStub::MinorKeyFromKey(key));
1440 
1441  DCHECK(is_call_ic ||
1442  CodeStub::GetMajorKey(*call_function_stub) ==
1443  CodeStub::MajorKeyFromKey(key));
1444 
1445  // Find target function on the expression stack.
1446  // Expression stack looks like this (top to bottom):
1447  // argN
1448  // ...
1449  // arg0
1450  // Receiver
1451  // Function to call
1452  int expressions_count = frame->ComputeExpressionsCount();
1453  DCHECK(expressions_count - 2 - call_function_arg_count >= 0);
1454  Object* fun = frame->GetExpression(
1455  expressions_count - 2 - call_function_arg_count);
1456 
1457  // Flood the actual target of call/apply.
1458  if (fun->IsJSFunction()) {
1459  Isolate* isolate = JSFunction::cast(fun)->GetIsolate();
1460  Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply);
1461  Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall);
1462  while (fun->IsJSFunction()) {
1463  Code* code = JSFunction::cast(fun)->shared()->code();
1464  if (code != apply && code != call) break;
1465  fun = frame->GetExpression(
1466  expressions_count - 1 - call_function_arg_count);
1467  }
1468  }
1469 
1470  if (fun->IsJSFunction()) {
1471  Handle<JSFunction> js_function(JSFunction::cast(fun));
1472  if (js_function->shared()->bound()) {
1474  } else if (!js_function->IsFromNativeScript()) {
1475  // Don't step into builtins.
1476  // It will also compile target function if it's not compiled yet.
1477  FloodWithOneShot(js_function);
1478  }
1479  }
1480  }
1481 
1482  // Fill the current function with one-shot break points even for step in on
1483  // a call target as the function called might be a native function for
1484  // which step in will not stop. It also prepares for stepping in
1485  // getters/setters.
1486  FloodWithOneShot(function);
1487 
1488  if (is_load_or_store) {
1489  // Remember source position and frame to handle step in getter/setter. If
1490  // there is a custom getter/setter it will be handled in
1491  // Object::Get/SetPropertyWithAccessor, otherwise the step action will be
1492  // propagated on the next Debug::Break.
1494  debug_info->code()->SourceStatementPosition(frame->pc());
1495  thread_local_.last_fp_ = frame->UnpaddedFP();
1496  }
1497 
1498  // Step in or Step in min
1499  it.PrepareStepIn(isolate_);
1500  ActivateStepIn(frame);
1501  }
1502 }
1503 
1504 
1505 // Check whether the current debug break should be reported to the debugger. It
1506 // is used to have step next and step in only report break back to the debugger
1507 // if on a different frame or in a different statement. In some situations
1508 // there will be several break points in the same statement when the code is
1509 // flooded with one-shot break points. This function helps to perform several
1510 // steps before reporting break back to the debugger.
1511 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
1512  JavaScriptFrame* frame) {
1513  // StepNext and StepOut shouldn't bring us deeper in code, so last frame
1514  // shouldn't be a parent of current frame.
1517  if (frame->fp() < thread_local_.last_fp_) return true;
1518  }
1519 
1520  // If the step last action was step next or step in make sure that a new
1521  // statement is hit.
1524  // Never continue if returning from function.
1525  if (break_location_iterator->IsExit()) return false;
1526 
1527  // Continue if we are still on the same frame and in the same statement.
1528  int current_statement_position =
1529  break_location_iterator->code()->SourceStatementPosition(frame->pc());
1530  return thread_local_.last_fp_ == frame->UnpaddedFP() &&
1531  thread_local_.last_statement_position_ == current_statement_position;
1532  }
1533 
1534  // No step next action - don't continue.
1535  return false;
1536 }
1537 
1538 
1539 // Check whether the code object at the specified address is a debug break code
1540 // object.
1542  Code* code = Code::GetCodeFromTargetAddress(addr);
1543  return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK;
1544 }
1545 
1546 
1547 
1548 
1549 
1550 // Simple function for returning the source positions for active break points.
1553  BreakPositionAlignment position_alignment) {
1554  Isolate* isolate = shared->GetIsolate();
1555  Heap* heap = isolate->heap();
1556  if (!HasDebugInfo(shared)) {
1557  return Handle<Object>(heap->undefined_value(), isolate);
1558  }
1559  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1560  if (debug_info->GetBreakPointCount() == 0) {
1561  return Handle<Object>(heap->undefined_value(), isolate);
1562  }
1563  Handle<FixedArray> locations =
1564  isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1565  int count = 0;
1566  for (int i = 0; i < debug_info->break_points()->length(); i++) {
1567  if (!debug_info->break_points()->get(i)->IsUndefined()) {
1568  BreakPointInfo* break_point_info =
1569  BreakPointInfo::cast(debug_info->break_points()->get(i));
1570  if (break_point_info->GetBreakPointCount() > 0) {
1571  Smi* position;
1572  switch (position_alignment) {
1573  case STATEMENT_ALIGNED:
1574  position = break_point_info->statement_position();
1575  break;
1577  position = break_point_info->source_position();
1578  break;
1579  default:
1580  UNREACHABLE();
1581  position = break_point_info->statement_position();
1582  }
1583 
1584  locations->set(count++, position);
1585  }
1586  }
1587  }
1588  return locations;
1589 }
1590 
1591 
1592 // Handle stepping into a function.
1594  Handle<Object> holder,
1595  Address fp,
1596  bool is_constructor) {
1597  Isolate* isolate = function->GetIsolate();
1598  // If the frame pointer is not supplied by the caller find it.
1599  if (fp == 0) {
1600  StackFrameIterator it(isolate);
1601  it.Advance();
1602  // For constructor functions skip another frame.
1603  if (is_constructor) {
1604  DCHECK(it.frame()->is_construct());
1605  it.Advance();
1606  }
1607  fp = it.frame()->fp();
1608  }
1609 
1610  // Flood the function with one-shot break points if it is called from where
1611  // step into was requested.
1612  if (fp == thread_local_.step_into_fp_) {
1613  if (function->shared()->bound()) {
1614  // Handle Function.prototype.bind
1616  } else if (!function->IsFromNativeScript()) {
1617  // Don't allow step into functions in the native context.
1618  if (function->shared()->code() ==
1619  isolate->builtins()->builtin(Builtins::kFunctionApply) ||
1620  function->shared()->code() ==
1621  isolate->builtins()->builtin(Builtins::kFunctionCall)) {
1622  // Handle function.apply and function.call separately to flood the
1623  // function to be called and not the code for Builtins::FunctionApply or
1624  // Builtins::FunctionCall. The receiver of call/apply is the target
1625  // function.
1626  if (!holder.is_null() && holder->IsJSFunction()) {
1627  Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
1628  if (!js_function->IsFromNativeScript()) {
1629  Debug::FloodWithOneShot(js_function);
1630  } else if (js_function->shared()->bound()) {
1631  // Handle Function.prototype.bind
1633  }
1634  }
1635  } else {
1636  Debug::FloodWithOneShot(function);
1637  }
1638  }
1639  }
1640 }
1641 
1642 
1644  // Clear the various stepping setup.
1645  ClearOneShot();
1646  ClearStepIn();
1647  ClearStepOut();
1648  ClearStepNext();
1649 
1650  // Clear multiple step counter.
1652 }
1653 
1654 
1655 // Clears all the one-shot break points that are currently set. Normally this
1656 // function is called each time a break point is hit as one shot break points
1657 // are used to support stepping.
1659  // The current implementation just runs through all the breakpoints. When the
1660  // last break point for a function is removed that function is automatically
1661  // removed from the list.
1662 
1664  while (node != NULL) {
1666  while (!it.Done()) {
1667  it.ClearOneShot();
1668  it.Next();
1669  }
1670  node = node->next();
1671  }
1672 }
1673 
1674 
1676  DCHECK(!StepOutActive());
1677  thread_local_.step_into_fp_ = frame->UnpaddedFP();
1678 }
1679 
1680 
1683 }
1684 
1685 
1687  DCHECK(!StepInActive());
1688  thread_local_.step_out_fp_ = frame->UnpaddedFP();
1689 }
1690 
1691 
1694 }
1695 
1696 
1700  thread_local_.last_fp_ = 0;
1701 }
1702 
1703 
1705  Isolate* isolate,
1706  ThreadLocalTop* top,
1707  List<Handle<JSFunction> >* active_functions,
1708  Object* active_code_marker) {
1709  // Find all non-optimized code functions with activation frames
1710  // on the stack. This includes functions which have optimized
1711  // activations (including inlined functions) on the stack as the
1712  // non-optimized code is needed for the lazy deoptimization.
1713  for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1714  JavaScriptFrame* frame = it.frame();
1715  if (frame->is_optimized()) {
1716  List<JSFunction*> functions(FLAG_max_inlining_levels + 1);
1717  frame->GetFunctions(&functions);
1718  for (int i = 0; i < functions.length(); i++) {
1719  JSFunction* function = functions[i];
1720  active_functions->Add(Handle<JSFunction>(function));
1721  function->shared()->code()->set_gc_metadata(active_code_marker);
1722  }
1723  } else if (frame->function()->IsJSFunction()) {
1724  JSFunction* function = frame->function();
1725  DCHECK(frame->LookupCode()->kind() == Code::FUNCTION);
1726  active_functions->Add(Handle<JSFunction>(function));
1727  function->shared()->code()->set_gc_metadata(active_code_marker);
1728  }
1729  }
1730 }
1731 
1732 
1733 // Figure out how many bytes of "pc_offset" correspond to actual code by
1734 // subtracting off the bytes that correspond to constant/veneer pools. See
1735 // Assembler::CheckConstPool() and Assembler::CheckVeneerPool(). Note that this
1736 // is only useful for architectures using constant pools or veneer pools.
1737 static int ComputeCodeOffsetFromPcOffset(Code *code, int pc_offset) {
1738  DCHECK_EQ(code->kind(), Code::FUNCTION);
1739  DCHECK(!code->has_debug_break_slots());
1740  DCHECK_LE(0, pc_offset);
1741  DCHECK_LT(pc_offset, code->instruction_end() - code->instruction_start());
1742 
1745  byte *pc = code->instruction_start() + pc_offset;
1746  int code_offset = pc_offset;
1747  for (RelocIterator it(code, mask); !it.done(); it.next()) {
1748  RelocInfo* info = it.rinfo();
1749  if (info->pc() >= pc) break;
1751  code_offset -= static_cast<int>(info->data());
1752  DCHECK_LE(0, code_offset);
1753  }
1754 
1755  return code_offset;
1756 }
1757 
1758 
1759 // The inverse of ComputeCodeOffsetFromPcOffset.
1760 static int ComputePcOffsetFromCodeOffset(Code *code, int code_offset) {
1761  DCHECK_EQ(code->kind(), Code::FUNCTION);
1762 
1766  int reloc = 0;
1767  for (RelocIterator it(code, mask); !it.done(); it.next()) {
1768  RelocInfo* info = it.rinfo();
1769  if (info->pc() - code->instruction_start() - reloc >= code_offset) break;
1770  if (RelocInfo::IsDebugBreakSlot(info->rmode())) {
1772  } else {
1774  reloc += static_cast<int>(info->data());
1775  }
1776  }
1777 
1778  int pc_offset = code_offset + reloc;
1779 
1780  DCHECK_LT(code->instruction_start() + pc_offset, code->instruction_end());
1781 
1782  return pc_offset;
1783 }
1784 
1785 
1787  Isolate* isolate,
1788  ThreadLocalTop* top) {
1789  for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1790  JavaScriptFrame* frame = it.frame();
1791 
1792  if (frame->is_optimized() || !frame->function()->IsJSFunction()) continue;
1793 
1794  JSFunction* function = frame->function();
1795 
1796  DCHECK(frame->LookupCode()->kind() == Code::FUNCTION);
1797 
1798  Handle<Code> frame_code(frame->LookupCode());
1799  if (frame_code->has_debug_break_slots()) continue;
1800 
1801  Handle<Code> new_code(function->shared()->code());
1802  if (new_code->kind() != Code::FUNCTION ||
1803  !new_code->has_debug_break_slots()) {
1804  continue;
1805  }
1806 
1807  int old_pc_offset =
1808  static_cast<int>(frame->pc() - frame_code->instruction_start());
1809  int code_offset = ComputeCodeOffsetFromPcOffset(*frame_code, old_pc_offset);
1810  int new_pc_offset = ComputePcOffsetFromCodeOffset(*new_code, code_offset);
1811 
1812  // Compute the equivalent pc in the new code.
1813  byte* new_pc = new_code->instruction_start() + new_pc_offset;
1814 
1815  if (FLAG_trace_deopt) {
1816  PrintF("Replacing code %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
1817  "with %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
1818  "for debugging, "
1819  "changing pc from %08" V8PRIxPTR " to %08" V8PRIxPTR "\n",
1820  reinterpret_cast<intptr_t>(
1821  frame_code->instruction_start()),
1822  reinterpret_cast<intptr_t>(
1823  frame_code->instruction_start()) +
1824  frame_code->instruction_size(),
1825  frame_code->instruction_size(),
1826  reinterpret_cast<intptr_t>(new_code->instruction_start()),
1827  reinterpret_cast<intptr_t>(new_code->instruction_start()) +
1828  new_code->instruction_size(),
1829  new_code->instruction_size(),
1830  reinterpret_cast<intptr_t>(frame->pc()),
1831  reinterpret_cast<intptr_t>(new_pc));
1832  }
1833 
1834  if (FLAG_enable_ool_constant_pool) {
1835  // Update constant pool pointer for new code.
1836  frame->set_constant_pool(new_code->constant_pool());
1837  }
1838 
1839  // Patch the return address to return into the code with
1840  // debug break slots.
1841  frame->set_pc(new_pc);
1842  }
1843 }
1844 
1845 
1847  public:
1848  explicit ActiveFunctionsCollector(List<Handle<JSFunction> >* active_functions,
1849  Object* active_code_marker)
1850  : active_functions_(active_functions),
1851  active_code_marker_(active_code_marker) { }
1852 
1853  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1855  top,
1858  }
1859 
1860  private:
1863 };
1864 
1865 
1867  public:
1868  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1870  }
1871 };
1872 
1873 
1875  if (function->code()->kind() == Code::FUNCTION &&
1876  function->code()->has_debug_break_slots()) {
1877  // Nothing to do. Function code already had debug break slots.
1878  return;
1879  }
1880  // Make sure that the shared full code is compiled with debug
1881  // break slots.
1882  if (!function->shared()->code()->has_debug_break_slots()) {
1883  MaybeHandle<Code> code = Compiler::GetDebugCode(function);
1884  // Recompilation can fail. In that case leave the code as it was.
1885  if (!code.is_null()) function->ReplaceCode(*code.ToHandleChecked());
1886  } else {
1887  // Simply use shared code if it has debug break slots.
1888  function->ReplaceCode(function->shared()->code());
1889  }
1890 }
1891 
1892 
1894  const List<Handle<JSGeneratorObject> > &generators) {
1895  for (int i = 0; i < generators.length(); i++) {
1896  Handle<JSFunction> fun(generators[i]->function());
1897 
1899 
1900  int code_offset = generators[i]->continuation();
1901  int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset);
1902  generators[i]->set_continuation(pc_offset);
1903  }
1904 }
1905 
1906 
1908  // If preparing for the first break point make sure to deoptimize all
1909  // functions as debugging does not work with optimized code.
1910  if (!has_break_points_) {
1913  }
1914 
1916 
1917  Handle<Code> lazy_compile = isolate_->builtins()->CompileLazy();
1918 
1919  // There will be at least one break point when we are done.
1920  has_break_points_ = true;
1921 
1922  // Keep the list of activated functions in a handlified list as it
1923  // is used both in GC and non-GC code.
1924  List<Handle<JSFunction> > active_functions(100);
1925 
1926  // A list of all suspended generators.
1927  List<Handle<JSGeneratorObject> > suspended_generators;
1928 
1929  // A list of all generator functions. We need to recompile all functions,
1930  // but we don't know until after visiting the whole heap which generator
1931  // functions have suspended activations and which do not. As in the case of
1932  // functions with activations on the stack, we need to be careful with
1933  // generator functions with suspended activations because although they
1934  // should be recompiled, recompilation can fail, and we need to avoid
1935  // leaving the heap in an inconsistent state.
1936  //
1937  // We could perhaps avoid this list and instead re-use the GC metadata
1938  // links.
1939  List<Handle<JSFunction> > generator_functions;
1940 
1941  {
1942  // We are going to iterate heap to find all functions without
1943  // debug break slots.
1944  Heap* heap = isolate_->heap();
1946  "preparing for breakpoints");
1947  HeapIterator iterator(heap);
1948 
1949  // Ensure no GC in this scope as we are going to use gc_metadata
1950  // field in the Code object to mark active functions.
1951  DisallowHeapAllocation no_allocation;
1952 
1953  Object* active_code_marker = heap->the_hole_value();
1954 
1957  &active_functions,
1958  active_code_marker);
1959  ActiveFunctionsCollector active_functions_collector(&active_functions,
1960  active_code_marker);
1962  &active_functions_collector);
1963 
1964  // Scan the heap for all non-optimized functions which have no
1965  // debug break slots and are not active or inlined into an active
1966  // function and mark them for lazy compilation.
1967  HeapObject* obj = NULL;
1968  while (((obj = iterator.next()) != NULL)) {
1969  if (obj->IsJSFunction()) {
1970  JSFunction* function = JSFunction::cast(obj);
1971  SharedFunctionInfo* shared = function->shared();
1972 
1973  if (!shared->allows_lazy_compilation()) continue;
1974  if (!shared->script()->IsScript()) continue;
1975  if (function->IsFromNativeScript()) continue;
1976  if (shared->code()->gc_metadata() == active_code_marker) continue;
1977 
1978  if (shared->is_generator()) {
1979  generator_functions.Add(Handle<JSFunction>(function, isolate_));
1980  continue;
1981  }
1982 
1983  Code::Kind kind = function->code()->kind();
1984  if (kind == Code::FUNCTION &&
1985  !function->code()->has_debug_break_slots()) {
1986  function->ReplaceCode(*lazy_compile);
1987  function->shared()->ReplaceCode(*lazy_compile);
1988  } else if (kind == Code::BUILTIN &&
1989  (function->IsInOptimizationQueue() ||
1990  function->IsMarkedForOptimization() ||
1991  function->IsMarkedForConcurrentOptimization())) {
1992  // Abort in-flight compilation.
1993  Code* shared_code = function->shared()->code();
1994  if (shared_code->kind() == Code::FUNCTION &&
1995  shared_code->has_debug_break_slots()) {
1996  function->ReplaceCode(shared_code);
1997  } else {
1998  function->ReplaceCode(*lazy_compile);
1999  function->shared()->ReplaceCode(*lazy_compile);
2000  }
2001  }
2002  } else if (obj->IsJSGeneratorObject()) {
2003  JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
2004  if (!gen->is_suspended()) continue;
2005 
2006  JSFunction* fun = gen->function();
2007  DCHECK_EQ(fun->code()->kind(), Code::FUNCTION);
2008  if (fun->code()->has_debug_break_slots()) continue;
2009 
2010  int pc_offset = gen->continuation();
2011  DCHECK_LT(0, pc_offset);
2012 
2013  int code_offset =
2014  ComputeCodeOffsetFromPcOffset(fun->code(), pc_offset);
2015 
2016  // This will be fixed after we recompile the functions.
2017  gen->set_continuation(code_offset);
2018 
2019  suspended_generators.Add(Handle<JSGeneratorObject>(gen, isolate_));
2020  }
2021  }
2022 
2023  // Clear gc_metadata field.
2024  for (int i = 0; i < active_functions.length(); i++) {
2025  Handle<JSFunction> function = active_functions[i];
2026  function->shared()->code()->set_gc_metadata(Smi::FromInt(0));
2027  }
2028  }
2029 
2030  // Recompile generator functions that have suspended activations, and
2031  // relocate those activations.
2032  RecompileAndRelocateSuspendedGenerators(suspended_generators);
2033 
2034  // Mark generator functions that didn't have suspended activations for lazy
2035  // recompilation. Note that this set does not include any active functions.
2036  for (int i = 0; i < generator_functions.length(); i++) {
2037  Handle<JSFunction> &function = generator_functions[i];
2038  if (function->code()->kind() != Code::FUNCTION) continue;
2039  if (function->code()->has_debug_break_slots()) continue;
2040  function->ReplaceCode(*lazy_compile);
2041  function->shared()->ReplaceCode(*lazy_compile);
2042  }
2043 
2044  // Now recompile all functions with activation frames and and
2045  // patch the return address to run in the new compiled code. It could be
2046  // that some active functions were recompiled already by the suspended
2047  // generator recompilation pass above; a generator with suspended
2048  // activations could also have active activations. That's fine.
2049  for (int i = 0; i < active_functions.length(); i++) {
2050  Handle<JSFunction> function = active_functions[i];
2051  Handle<SharedFunctionInfo> shared(function->shared());
2052 
2053  // If recompilation is not possible just skip it.
2054  if (shared->is_toplevel()) continue;
2055  if (!shared->allows_lazy_compilation()) continue;
2056  if (shared->code()->kind() == Code::BUILTIN) continue;
2057 
2059  }
2060 
2063 
2064  ActiveFunctionsRedirector active_functions_redirector;
2066  &active_functions_redirector);
2067  }
2068 }
2069 
2070 
2072  int position) {
2073  // Iterate the heap looking for SharedFunctionInfo generated from the
2074  // script. The inner most SharedFunctionInfo containing the source position
2075  // for the requested break point is found.
2076  // NOTE: This might require several heap iterations. If the SharedFunctionInfo
2077  // which is found is not compiled it is compiled and the heap is iterated
2078  // again as the compilation might create inner functions from the newly
2079  // compiled function and the actual requested break point might be in one of
2080  // these functions.
2081  // NOTE: The below fix-point iteration depends on all functions that cannot be
2082  // compiled lazily without a context to not be compiled at all. Compilation
2083  // will be triggered at points where we do not need a context.
2084  bool done = false;
2085  // The current candidate for the source position:
2086  int target_start_position = RelocInfo::kNoPosition;
2087  Handle<JSFunction> target_function;
2089  Heap* heap = isolate_->heap();
2090  while (!done) {
2091  { // Extra scope for iterator.
2092  HeapIterator iterator(heap);
2093  for (HeapObject* obj = iterator.next();
2094  obj != NULL; obj = iterator.next()) {
2095  bool found_next_candidate = false;
2096  Handle<JSFunction> function;
2098  if (obj->IsJSFunction()) {
2099  function = Handle<JSFunction>(JSFunction::cast(obj));
2100  shared = Handle<SharedFunctionInfo>(function->shared());
2101  DCHECK(shared->allows_lazy_compilation() || shared->is_compiled());
2102  found_next_candidate = true;
2103  } else if (obj->IsSharedFunctionInfo()) {
2104  shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj));
2105  // Skip functions that we cannot compile lazily without a context,
2106  // which is not available here, because there is no closure.
2107  found_next_candidate = shared->is_compiled() ||
2108  shared->allows_lazy_compilation_without_context();
2109  }
2110  if (!found_next_candidate) continue;
2111  if (shared->script() == *script) {
2112  // If the SharedFunctionInfo found has the requested script data and
2113  // contains the source position it is a candidate.
2114  int start_position = shared->function_token_position();
2115  if (start_position == RelocInfo::kNoPosition) {
2116  start_position = shared->start_position();
2117  }
2118  if (start_position <= position &&
2119  position <= shared->end_position()) {
2120  // If there is no candidate or this function is within the current
2121  // candidate this is the new candidate.
2122  if (target.is_null()) {
2123  target_start_position = start_position;
2124  target_function = function;
2125  target = shared;
2126  } else {
2127  if (target_start_position == start_position &&
2128  shared->end_position() == target->end_position()) {
2129  // If a top-level function contains only one function
2130  // declaration the source for the top-level and the function
2131  // is the same. In that case prefer the non top-level function.
2132  if (!shared->is_toplevel()) {
2133  target_start_position = start_position;
2134  target_function = function;
2135  target = shared;
2136  }
2137  } else if (target_start_position <= start_position &&
2138  shared->end_position() <= target->end_position()) {
2139  // This containment check includes equality as a function
2140  // inside a top-level function can share either start or end
2141  // position with the top-level function.
2142  target_start_position = start_position;
2143  target_function = function;
2144  target = shared;
2145  }
2146  }
2147  }
2148  }
2149  } // End for loop.
2150  } // End no-allocation scope.
2151 
2152  if (target.is_null()) return heap->undefined_value();
2153 
2154  // There will be at least one break point when we are done.
2155  has_break_points_ = true;
2156 
2157  // If the candidate found is compiled we are done.
2158  done = target->is_compiled();
2159  if (!done) {
2160  // If the candidate is not compiled, compile it to reveal any inner
2161  // functions which might contain the requested source position. This
2162  // will compile all inner functions that cannot be compiled without a
2163  // context, because Compiler::BuildFunctionInfo checks whether the
2164  // debugger is active.
2165  MaybeHandle<Code> maybe_result = target_function.is_null()
2167  : Compiler::GetUnoptimizedCode(target_function);
2168  if (maybe_result.is_null()) return isolate_->heap()->undefined_value();
2169  }
2170  } // End while loop.
2171 
2172  return *target;
2173 }
2174 
2175 
2176 // Ensures the debug information is present for shared.
2178  Handle<JSFunction> function) {
2179  Isolate* isolate = shared->GetIsolate();
2180 
2181  // Return if we already have the debug info for shared.
2182  if (HasDebugInfo(shared)) {
2183  DCHECK(shared->is_compiled());
2184  return true;
2185  }
2186 
2187  // There will be at least one break point when we are done.
2188  has_break_points_ = true;
2189 
2190  // Ensure function is compiled. Return false if this failed.
2191  if (!function.is_null() &&
2193  return false;
2194  }
2195 
2196  // Create the debug info object.
2197  Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared);
2198 
2199  // Add debug info to the list.
2200  DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
2201  node->set_next(debug_info_list_);
2202  debug_info_list_ = node;
2203 
2204  return true;
2205 }
2206 
2207 
2210  // Run through the debug info objects to find this one and remove it.
2211  DebugInfoListNode* prev = NULL;
2213  while (current != NULL) {
2214  if (*current->debug_info() == *debug_info) {
2215  // Unlink from list. If prev is NULL we are looking at the first element.
2216  if (prev == NULL) {
2217  debug_info_list_ = current->next();
2218  } else {
2219  prev->set_next(current->next());
2220  }
2221  current->debug_info()->shared()->set_debug_info(
2222  isolate_->heap()->undefined_value());
2223  delete current;
2224 
2225  // If there are no more debug info objects there are not more break
2226  // points.
2228 
2229  return;
2230  }
2231  // Move to next in list.
2232  prev = current;
2233  current = current->next();
2234  }
2235  UNREACHABLE();
2236 }
2237 
2238 
2241 
2242  if (LiveEdit::SetAfterBreakTarget(this)) return; // LiveEdit did the job.
2243 
2244  HandleScope scope(isolate_);
2246 
2247  // Get the executing function in which the debug break occurred.
2248  Handle<JSFunction> function(JSFunction::cast(frame->function()));
2249  Handle<SharedFunctionInfo> shared(function->shared());
2250  if (!EnsureDebugInfo(shared, function)) {
2251  // Return if we failed to retrieve the debug info.
2252  return;
2253  }
2254  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
2255  Handle<Code> code(debug_info->code());
2256  Handle<Code> original_code(debug_info->original_code());
2257 #ifdef DEBUG
2258  // Get the code which is actually executing.
2259  Handle<Code> frame_code(frame->LookupCode());
2260  DCHECK(frame_code.is_identical_to(code));
2261 #endif
2262 
2263  // Find the call address in the running code. This address holds the call to
2264  // either a DebugBreakXXX or to the debug break return entry code if the
2265  // break point is still active after processing the break point.
2267 
2268  // Check if the location is at JS exit or debug break slot.
2269  bool at_js_return = false;
2270  bool break_at_js_return_active = false;
2271  bool at_debug_break_slot = false;
2272  RelocIterator it(debug_info->code());
2273  while (!it.done() && !at_js_return && !at_debug_break_slot) {
2274  if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
2275  at_js_return = (it.rinfo()->pc() ==
2277  break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence();
2278  }
2279  if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) {
2280  at_debug_break_slot = (it.rinfo()->pc() ==
2282  }
2283  it.next();
2284  }
2285 
2286  // Handle the jump to continue execution after break point depending on the
2287  // break location.
2288  if (at_js_return) {
2289  // If the break point as return is still active jump to the corresponding
2290  // place in the original code. If not the break point was removed during
2291  // break point processing.
2292  if (break_at_js_return_active) {
2293  addr += original_code->instruction_start() - code->instruction_start();
2294  }
2295 
2296  // Move back to where the call instruction sequence started.
2298  } else if (at_debug_break_slot) {
2299  // Address of where the debug break slot starts.
2301 
2302  // Continue just after the slot.
2304  } else {
2306  if (IsDebugBreak(Assembler::target_address_at(addr, *code))) {
2307  // We now know that there is still a debug break call at the target
2308  // address, so the break point is still there and the original code will
2309  // hold the address to jump to in order to complete the call which is
2310  // replaced by a call to DebugBreakXXX.
2311 
2312  // Find the corresponding address in the original code.
2313  addr += original_code->instruction_start() - code->instruction_start();
2314 
2315  // Install jump to the call address in the original code. This will be the
2316  // call which was overwritten by the call to DebugBreakXXX.
2317  after_break_target_ = Assembler::target_address_at(addr, *original_code);
2318  } else {
2319  // There is no longer a break point present. Don't try to look in the
2320  // original code as the running code will have the right address. This
2321  // takes care of the case where the last break point is removed from the
2322  // function and therefore no "original code" is available.
2324  }
2325  }
2326 }
2327 
2328 
2330  HandleScope scope(isolate_);
2331 
2332  // If there are no break points this cannot be break at return, as
2333  // the debugger statement and stack guard bebug break cannot be at
2334  // return.
2335  if (!has_break_points_) {
2336  return false;
2337  }
2338 
2340 
2341  // Get the executing function in which the debug break occurred.
2342  Handle<JSFunction> function(JSFunction::cast(frame->function()));
2343  Handle<SharedFunctionInfo> shared(function->shared());
2344  if (!EnsureDebugInfo(shared, function)) {
2345  // Return if we failed to retrieve the debug info.
2346  return false;
2347  }
2348  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
2349  Handle<Code> code(debug_info->code());
2350 #ifdef DEBUG
2351  // Get the code which is actually executing.
2352  Handle<Code> frame_code(frame->LookupCode());
2353  DCHECK(frame_code.is_identical_to(code));
2354 #endif
2355 
2356  // Find the call address in the running code.
2358 
2359  // Check if the location is at JS return.
2360  RelocIterator it(debug_info->code());
2361  while (!it.done()) {
2362  if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
2363  return (it.rinfo()->pc() ==
2365  }
2366  it.next();
2367  }
2368  return false;
2369 }
2370 
2371 
2372 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
2374  Object** restarter_frame_function_pointer) {
2377  }
2378  thread_local_.break_frame_id_ = new_break_frame_id;
2380  restarter_frame_function_pointer;
2381 }
2382 
2383 
2385  return is_loaded() && global == debug_context()->global_object();
2386 }
2387 
2388 
2390  PostponeInterruptsScope postpone(isolate_);
2391  HandleScope scope(isolate_);
2393  Factory* factory = isolate_->factory();
2395  JSObject::SetProperty(global,
2396  factory->NewStringFromAsciiChecked("next_handle_"),
2397  handle(Smi::FromInt(0), isolate_), SLOPPY).Check();
2398  JSObject::SetProperty(global,
2399  factory->NewStringFromAsciiChecked("mirror_cache_"),
2400  factory->NewJSArray(0, FAST_ELEMENTS), SLOPPY).Check();
2401 }
2402 
2403 
2405  // Create and fill the script cache when the loaded scripts is requested for
2406  // the first time.
2408 
2409  // Perform GC to get unreferenced scripts evicted from the cache before
2410  // returning the content.
2412  "Debug::GetLoadedScripts");
2413 
2414  // Get the scripts from the cache.
2415  return script_cache_->GetScripts();
2416 }
2417 
2418 
2420  script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
2421  // For eval scripts add information on the function from which eval was
2422  // called.
2423  StackTraceFrameIterator it(script->GetIsolate());
2424  if (!it.done()) {
2425  script->set_eval_from_shared(it.frame()->function()->shared());
2426  Code* code = it.frame()->LookupCode();
2427  int offset = static_cast<int>(
2428  it.frame()->pc() - code->instruction_start());
2429  script->set_eval_from_instructions_offset(Smi::FromInt(offset));
2430  }
2431 }
2432 
2433 
2434 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
2435  int argc,
2436  Handle<Object> argv[]) {
2438  // Create the execution state object.
2440  Handle<Object> constructor = Object::GetProperty(
2441  isolate_, global, constructor_name).ToHandleChecked();
2442  DCHECK(constructor->IsJSFunction());
2443  if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
2444  // We do not handle interrupts here. In particular, termination interrupts.
2445  PostponeInterruptsScope no_interrupts(isolate_);
2446  return Execution::TryCall(Handle<JSFunction>::cast(constructor),
2447  handle(debug_context()->global_proxy()),
2448  argc,
2449  argv);
2450 }
2451 
2452 
2454  // Create the execution state object.
2455  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
2456  return MakeJSObject("MakeExecutionState", arraysize(argv), argv);
2457 }
2458 
2459 
2461  // Create the new break event object.
2462  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
2463  break_points_hit };
2464  return MakeJSObject("MakeBreakEvent", arraysize(argv), argv);
2465 }
2466 
2467 
2469  bool uncaught,
2470  Handle<Object> promise) {
2471  // Create the new exception event object.
2472  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
2473  exception,
2474  isolate_->factory()->ToBoolean(uncaught),
2475  promise };
2476  return MakeJSObject("MakeExceptionEvent", arraysize(argv), argv);
2477 }
2478 
2479 
2481  v8::DebugEvent type) {
2482  // Create the compile event object.
2483  Handle<Object> script_wrapper = Script::GetWrapper(script);
2484  Handle<Object> argv[] = { script_wrapper,
2485  isolate_->factory()->NewNumberFromInt(type) };
2486  return MakeJSObject("MakeCompileEvent", arraysize(argv), argv);
2487 }
2488 
2489 
2491  // Create the promise event object.
2492  Handle<Object> argv[] = { event_data };
2493  return MakeJSObject("MakePromiseEvent", arraysize(argv), argv);
2494 }
2495 
2496 
2498  // Create the async task event object.
2499  Handle<Object> argv[] = { task_event };
2500  return MakeJSObject("MakeAsyncTaskEvent", arraysize(argv), argv);
2501 }
2502 
2503 
2504 void Debug::OnThrow(Handle<Object> exception, bool uncaught) {
2505  if (in_debug_scope() || ignore_events()) return;
2506  // Temporarily clear any scheduled_exception to allow evaluating
2507  // JavaScript from the debug event handler.
2508  HandleScope scope(isolate_);
2509  Handle<Object> scheduled_exception;
2511  scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
2513  }
2514  OnException(exception, uncaught, isolate_->GetPromiseOnStackOnThrow());
2515  if (!scheduled_exception.is_null()) {
2516  isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
2517  }
2518 }
2519 
2520 
2522  if (in_debug_scope() || ignore_events()) return;
2523  HandleScope scope(isolate_);
2524  OnException(value, false, promise);
2525 }
2526 
2527 
2528 void Debug::OnException(Handle<Object> exception, bool uncaught,
2529  Handle<Object> promise) {
2530  if (promise->IsJSObject()) {
2531  uncaught |= !PromiseHasRejectHandler(Handle<JSObject>::cast(promise));
2532  }
2533  // Bail out if exception breaks are not active
2534  if (uncaught) {
2535  // Uncaught exceptions are reported by either flags.
2537  } else {
2538  // Caught exceptions are reported is activated.
2539  if (!break_on_exception_) return;
2540  }
2541 
2542  DebugScope debug_scope(this);
2543  if (debug_scope.failed()) return;
2544 
2545  // Clear all current stepping setup.
2546  ClearStepping();
2547 
2548  // Create the event data object.
2549  Handle<Object> event_data;
2550  // Bail out and don't call debugger if exception.
2551  if (!MakeExceptionEvent(
2552  exception, uncaught, promise).ToHandle(&event_data)) {
2553  return;
2554  }
2555 
2556  // Process debug event.
2558  // Return to continue execution from where the exception was thrown.
2559 }
2560 
2561 
2563  // No more to do if not debugging.
2564  if (in_debug_scope() || ignore_events()) return;
2565 
2566  HandleScope scope(isolate_);
2567  DebugScope debug_scope(this);
2568  if (debug_scope.failed()) return;
2569 
2570  // Create the compile state object.
2571  Handle<Object> event_data;
2572  // Bail out and don't call debugger if exception.
2573  if (!MakeCompileEvent(script, v8::CompileError).ToHandle(&event_data)) return;
2574 
2575  // Process debug event.
2577 }
2578 
2579 
2580 void Debug::OnDebugBreak(Handle<Object> break_points_hit,
2581  bool auto_continue) {
2582  // The caller provided for DebugScope.
2584  // Bail out if there is no listener for this event
2585  if (ignore_events()) return;
2586 
2587  HandleScope scope(isolate_);
2588  // Create the event data object.
2589  Handle<Object> event_data;
2590  // Bail out and don't call debugger if exception.
2591  if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
2592 
2593  // Process debug event.
2595  Handle<JSObject>::cast(event_data),
2596  auto_continue);
2597 }
2598 
2599 
2601  if (in_debug_scope() || ignore_events()) return;
2602 
2603  HandleScope scope(isolate_);
2604  DebugScope debug_scope(this);
2605  if (debug_scope.failed()) return;
2606 
2607  // Create the event data object.
2608  Handle<Object> event_data;
2609  // Bail out and don't call debugger if exception.
2610  if (!MakeCompileEvent(script, v8::BeforeCompile).ToHandle(&event_data))
2611  return;
2612 
2613  // Process debug event.
2615  Handle<JSObject>::cast(event_data),
2616  true);
2617 }
2618 
2619 
2620 // Handle debugger actions when a new script is compiled.
2622  // Add the newly compiled script to the script cache.
2623  if (script_cache_ != NULL) script_cache_->Add(script);
2624 
2625  // No more to do if not debugging.
2626  if (in_debug_scope() || ignore_events()) return;
2627 
2628  HandleScope scope(isolate_);
2629  DebugScope debug_scope(this);
2630  if (debug_scope.failed()) return;
2631 
2632  // If debugging there might be script break points registered for this
2633  // script. Make sure that these break points are set.
2634 
2635  // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
2636  Handle<String> update_script_break_points_string =
2637  isolate_->factory()->InternalizeOneByteString(
2638  STATIC_CHAR_VECTOR("UpdateScriptBreakPoints"));
2639  Handle<GlobalObject> debug_global(debug_context()->global_object());
2640  Handle<Object> update_script_break_points =
2642  debug_global, update_script_break_points_string).ToHandleChecked();
2643  if (!update_script_break_points->IsJSFunction()) {
2644  return;
2645  }
2646  DCHECK(update_script_break_points->IsJSFunction());
2647 
2648  // Wrap the script object in a proper JS object before passing it
2649  // to JavaScript.
2650  Handle<Object> wrapper = Script::GetWrapper(script);
2651 
2652  // Call UpdateScriptBreakPoints expect no exceptions.
2653  Handle<Object> argv[] = { wrapper };
2654  if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
2656  arraysize(argv),
2657  argv).is_null()) {
2658  return;
2659  }
2660 
2661  // Create the compile state object.
2662  Handle<Object> event_data;
2663  // Bail out and don't call debugger if exception.
2664  if (!MakeCompileEvent(script, v8::AfterCompile).ToHandle(&event_data)) return;
2665 
2666  // Process debug event.
2668 }
2669 
2670 
2672  if (in_debug_scope() || ignore_events()) return;
2673 
2674  HandleScope scope(isolate_);
2675  DebugScope debug_scope(this);
2676  if (debug_scope.failed()) return;
2677 
2678  // Create the script collected state object.
2679  Handle<Object> event_data;
2680  // Bail out and don't call debugger if exception.
2681  if (!MakePromiseEvent(data).ToHandle(&event_data)) return;
2682 
2683  // Process debug event.
2685  Handle<JSObject>::cast(event_data),
2686  true);
2687 }
2688 
2689 
2691  if (in_debug_scope() || ignore_events()) return;
2692 
2693  HandleScope scope(isolate_);
2694  DebugScope debug_scope(this);
2695  if (debug_scope.failed()) return;
2696 
2697  // Create the script collected state object.
2698  Handle<Object> event_data;
2699  // Bail out and don't call debugger if exception.
2700  if (!MakeAsyncTaskEvent(data).ToHandle(&event_data)) return;
2701 
2702  // Process debug event.
2704  Handle<JSObject>::cast(event_data),
2705  true);
2706 }
2707 
2708 
2710  Handle<JSObject> event_data,
2711  bool auto_continue) {
2712  HandleScope scope(isolate_);
2713 
2714  // Create the execution state.
2715  Handle<Object> exec_state;
2716  // Bail out and don't call debugger if exception.
2717  if (!MakeExecutionState().ToHandle(&exec_state)) return;
2718 
2719  // First notify the message handler if any.
2720  if (message_handler_ != NULL) {
2721  NotifyMessageHandler(event,
2722  Handle<JSObject>::cast(exec_state),
2723  event_data,
2724  auto_continue);
2725  }
2726  // Notify registered debug event listener. This can be either a C or
2727  // a JavaScript function. Don't call event listener for v8::Break
2728  // here, if it's only a debug command -- they will be processed later.
2729  if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
2730  CallEventCallback(event, exec_state, event_data, NULL);
2731  }
2732  // Process pending debug commands.
2733  if (event == v8::Break) {
2734  while (!event_command_queue_.IsEmpty()) {
2735  CommandMessage command = event_command_queue_.Get();
2736  if (!event_listener_.is_null()) {
2738  exec_state,
2739  event_data,
2740  command.client_data());
2741  }
2742  command.Dispose();
2743  }
2744  }
2745 }
2746 
2747 
2749  Handle<Object> exec_state,
2750  Handle<Object> event_data,
2751  v8::Debug::ClientData* client_data) {
2752  if (event_listener_->IsForeign()) {
2753  // Invoke the C debug event listener.
2754  v8::Debug::EventCallback callback =
2755  FUNCTION_CAST<v8::Debug::EventCallback>(
2756  Handle<Foreign>::cast(event_listener_)->foreign_address());
2757  EventDetailsImpl event_details(event,
2758  Handle<JSObject>::cast(exec_state),
2759  Handle<JSObject>::cast(event_data),
2761  client_data);
2762  callback(event_details);
2764  } else {
2765  // Invoke the JavaScript debug event listener.
2766  DCHECK(event_listener_->IsJSFunction());
2767  Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
2768  exec_state,
2769  event_data,
2772  Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
2773  global, arraysize(argv), argv);
2774  }
2775 }
2776 
2777 
2779  DebugScope debug_scope(this);
2780  // The global handle may be destroyed soon after. Return it reboxed.
2781  return handle(*debug_context(), isolate_);
2782 }
2783 
2784 
2786  Handle<JSObject> exec_state,
2787  Handle<JSObject> event_data,
2788  bool auto_continue) {
2789  // Prevent other interrupts from triggering, for example API callbacks,
2790  // while dispatching message handler callbacks.
2791  PostponeInterruptsScope no_interrupts(isolate_);
2792  DCHECK(is_active_);
2793  HandleScope scope(isolate_);
2794  // Process the individual events.
2795  bool sendEventMessage = false;
2796  switch (event) {
2797  case v8::Break:
2798  case v8::BreakForCommand:
2799  sendEventMessage = !auto_continue;
2800  break;
2801  case v8::Exception:
2802  sendEventMessage = true;
2803  break;
2804  case v8::BeforeCompile:
2805  break;
2806  case v8::AfterCompile:
2807  sendEventMessage = true;
2808  break;
2809  case v8::NewFunction:
2810  break;
2811  default:
2812  UNREACHABLE();
2813  }
2814 
2815  // The debug command interrupt flag might have been set when the command was
2816  // added. It should be enough to clear the flag only once while we are in the
2817  // debugger.
2819  isolate_->stack_guard()->ClearDebugCommand();
2820 
2821  // Notify the debugger that a debug event has occurred unless auto continue is
2822  // active in which case no event is send.
2823  if (sendEventMessage) {
2825  event,
2826  auto_continue,
2827  Handle<JSObject>::cast(exec_state),
2828  Handle<JSObject>::cast(event_data));
2829  InvokeMessageHandler(message);
2830  }
2831 
2832  // If auto continue don't make the event cause a break, but process messages
2833  // in the queue if any. For script collected events don't even process
2834  // messages in the queue as the execution state might not be what is expected
2835  // by the client.
2836  if (auto_continue && !has_commands()) return;
2837 
2838  // DebugCommandProcessor goes here.
2839  bool running = auto_continue;
2840 
2841  Handle<Object> cmd_processor_ctor = Object::GetProperty(
2842  isolate_, exec_state, "debugCommandProcessor").ToHandleChecked();
2843  Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
2844  Handle<Object> cmd_processor = Execution::Call(
2845  isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked();
2846  Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
2848  isolate_, cmd_processor, "processDebugRequest").ToHandleChecked());
2849  Handle<Object> is_running = Object::GetProperty(
2850  isolate_, cmd_processor, "isRunning").ToHandleChecked();
2851 
2852  // Process requests from the debugger.
2853  do {
2854  // Wait for new command in the queue.
2855  command_received_.Wait();
2856 
2857  // Get the command from the queue.
2858  CommandMessage command = command_queue_.Get();
2859  isolate_->logger()->DebugTag(
2860  "Got request from command queue, in interactive loop.");
2861  if (!is_active()) {
2862  // Delete command text and user data.
2863  command.Dispose();
2864  return;
2865  }
2866 
2867  Vector<const uc16> command_text(
2868  const_cast<const uc16*>(command.text().start()),
2869  command.text().length());
2870  Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
2871  command_text).ToHandleChecked();
2872  Handle<Object> request_args[] = { request_text };
2873  Handle<Object> answer_value;
2874  Handle<String> answer;
2875  MaybeHandle<Object> maybe_exception;
2876  MaybeHandle<Object> maybe_result =
2877  Execution::TryCall(process_debug_request, cmd_processor, 1,
2878  request_args, &maybe_exception);
2879 
2880  if (maybe_result.ToHandle(&answer_value)) {
2881  if (answer_value->IsUndefined()) {
2882  answer = isolate_->factory()->empty_string();
2883  } else {
2884  answer = Handle<String>::cast(answer_value);
2885  }
2886 
2887  // Log the JSON request/response.
2888  if (FLAG_trace_debug_json) {
2889  PrintF("%s\n", request_text->ToCString().get());
2890  PrintF("%s\n", answer->ToCString().get());
2891  }
2892 
2893  Handle<Object> is_running_args[] = { answer };
2894  maybe_result = Execution::Call(
2895  isolate_, is_running, cmd_processor, 1, is_running_args);
2896  Handle<Object> result;
2897  if (!maybe_result.ToHandle(&result)) break;
2898  running = result->IsTrue();
2899  } else {
2900  Handle<Object> exception;
2901  if (!maybe_exception.ToHandle(&exception)) break;
2902  Handle<Object> result;
2903  if (!Execution::ToString(isolate_, exception).ToHandle(&result)) break;
2904  answer = Handle<String>::cast(result);
2905  }
2906 
2907  // Return the result.
2909  event, running, exec_state, event_data, answer, command.client_data());
2910  InvokeMessageHandler(message);
2911  command.Dispose();
2912 
2913  // Return from debug event processing if either the VM is put into the
2914  // running state (through a continue command) or auto continue is active
2915  // and there are no more commands queued.
2916  } while (!running || has_commands());
2917  command_queue_.Clear();
2918 }
2919 
2920 
2922  Handle<Object> data) {
2923  GlobalHandles* global_handles = isolate_->global_handles();
2924 
2925  // Remove existing entry.
2930 
2931  // Set new entry.
2932  if (!callback->IsUndefined() && !callback->IsNull()) {
2933  event_listener_ = global_handles->Create(*callback);
2934  if (data.is_null()) data = isolate_->factory()->undefined_value();
2935  event_listener_data_ = global_handles->Create(*data);
2936  }
2937 
2938  UpdateState();
2939 }
2940 
2941 
2943  message_handler_ = handler;
2944  UpdateState();
2945  if (handler == NULL && in_debug_scope()) {
2946  // Send an empty command to the debugger if in a break to make JavaScript
2947  // run again if the debugger is closed.
2949  }
2950 }
2951 
2952 
2953 
2955  is_active_ = message_handler_ != NULL || !event_listener_.is_null();
2956  if (is_active_ || in_debug_scope()) {
2957  // Note that the debug context could have already been loaded to
2958  // bootstrap test cases.
2960  is_active_ = Load();
2961  } else if (is_loaded()) {
2963  Unload();
2964  }
2965 }
2966 
2967 
2968 // Calls the registered debug message handler. This callback is part of the
2969 // public API.
2971  if (message_handler_ != NULL) message_handler_(message);
2972 }
2973 
2974 
2975 // Puts a command coming from the public API on the queue. Creates
2976 // a copy of the command string managed by the debugger. Up to this
2977 // point, the command data was managed by the API client. Called
2978 // by the API client thread.
2980  v8::Debug::ClientData* client_data) {
2981  // Need to cast away const.
2983  Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
2984  command.length()),
2985  client_data);
2986  isolate_->logger()->DebugTag("Put command on command_queue.");
2987  command_queue_.Put(message);
2988  command_received_.Signal();
2989 
2990  // Set the debug command break flag to have the command processed.
2991  if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
2992 }
2993 
2994 
2996  CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
2997  event_command_queue_.Put(message);
2998 
2999  // Set the debug command break flag to have the command processed.
3000  if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
3001 }
3002 
3003 
3005  DebugScope debug_scope(this);
3006  if (debug_scope.failed()) return isolate_->factory()->undefined_value();
3007 
3008  // Create the execution state.
3009  Handle<Object> exec_state;
3010  if (!MakeExecutionState().ToHandle(&exec_state)) {
3011  return isolate_->factory()->undefined_value();
3012  }
3013 
3014  Handle<Object> argv[] = { exec_state, data };
3015  return Execution::Call(
3016  isolate_,
3017  fun,
3018  Handle<Object>(debug_context()->global_proxy(), isolate_),
3019  arraysize(argv),
3020  argv);
3021 }
3022 
3023 
3025  // Ignore debug break during bootstrapping.
3026  if (isolate_->bootstrapper()->IsActive()) return;
3027  // Just continue if breaks are disabled.
3028  if (break_disabled_) return;
3029  // Ignore debug break if debugger is not active.
3030  if (!is_active()) return;
3031 
3032  StackLimitCheck check(isolate_);
3033  if (check.HasOverflowed()) return;
3034 
3035  { JavaScriptFrameIterator it(isolate_);
3036  DCHECK(!it.done());
3037  Object* fun = it.frame()->function();
3038  if (fun && fun->IsJSFunction()) {
3039  // Don't stop in builtin functions.
3040  if (JSFunction::cast(fun)->IsBuiltin()) return;
3041  GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
3042  // Don't stop in debugger functions.
3043  if (IsDebugGlobal(global)) return;
3044  }
3045  }
3046 
3047  // Collect the break state before clearing the flags.
3048  bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
3049  !isolate_->stack_guard()->CheckDebugBreak();
3050 
3051  isolate_->stack_guard()->ClearDebugBreak();
3052 
3053  ProcessDebugMessages(debug_command_only);
3054 }
3055 
3056 
3057 void Debug::ProcessDebugMessages(bool debug_command_only) {
3058  isolate_->stack_guard()->ClearDebugCommand();
3059 
3060  StackLimitCheck check(isolate_);
3061  if (check.HasOverflowed()) return;
3062 
3063  HandleScope scope(isolate_);
3064  DebugScope debug_scope(this);
3065  if (debug_scope.failed()) return;
3066 
3067  // Notify the debug event listeners. Indicate auto continue if the break was
3068  // a debug command break.
3069  OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
3070 }
3071 
3072 
3073 DebugScope::DebugScope(Debug* debug)
3074  : debug_(debug),
3075  prev_(debug->debugger_entry()),
3076  save_(debug_->isolate_),
3077  no_termination_exceptons_(debug_->isolate_,
3078  StackGuard::TERMINATE_EXECUTION) {
3079  // Link recursive debugger entry.
3080  debug_->thread_local_.current_debug_scope_ = this;
3081 
3082  // Store the previous break id and frame id.
3083  break_id_ = debug_->break_id();
3084  break_frame_id_ = debug_->break_frame_id();
3085 
3086  // Create the new break info. If there is no JavaScript frames there is no
3087  // break frame id.
3088  JavaScriptFrameIterator it(isolate());
3089  bool has_js_frames = !it.done();
3090  debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
3091  : StackFrame::NO_ID;
3092  debug_->SetNextBreakId();
3093 
3094  debug_->UpdateState();
3095  // Make sure that debugger is loaded and enter the debugger context.
3096  // The previous context is kept in save_.
3097  failed_ = !debug_->is_loaded();
3098  if (!failed_) isolate()->set_context(*debug->debug_context());
3099 }
3100 
3101 
3102 
3103 DebugScope::~DebugScope() {
3104  if (!failed_ && prev_ == NULL) {
3105  // Clear mirror cache when leaving the debugger. Skip this if there is a
3106  // pending exception as clearing the mirror cache calls back into
3107  // JavaScript. This can happen if the v8::Debug::Call is used in which
3108  // case the exception should end up in the calling code.
3109  if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
3110 
3111  // If there are commands in the queue when leaving the debugger request
3112  // that these commands are processed.
3113  if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
3114  }
3115 
3116  // Leaving this debugger entry.
3117  debug_->thread_local_.current_debug_scope_ = prev_;
3118 
3119  // Restore to the previous break state.
3120  debug_->thread_local_.break_frame_id_ = break_frame_id_;
3121  debug_->thread_local_.break_id_ = break_id_;
3122 
3123  debug_->UpdateState();
3124 }
3125 
3126 
3128  bool running,
3129  Handle<JSObject> exec_state,
3130  Handle<JSObject> event_data) {
3131  MessageImpl message(true, event, running,
3132  exec_state, event_data, Handle<String>(), NULL);
3133  return message;
3134 }
3135 
3136 
3138  bool running,
3139  Handle<JSObject> exec_state,
3140  Handle<JSObject> event_data,
3141  Handle<String> response_json,
3142  v8::Debug::ClientData* client_data) {
3143  MessageImpl message(false, event, running,
3144  exec_state, event_data, response_json, client_data);
3145  return message;
3146 }
3147 
3148 
3150  DebugEvent event,
3151  bool running,
3152  Handle<JSObject> exec_state,
3153  Handle<JSObject> event_data,
3154  Handle<String> response_json,
3155  v8::Debug::ClientData* client_data)
3156  : is_event_(is_event),
3157  event_(event),
3158  running_(running),
3159  exec_state_(exec_state),
3160  event_data_(event_data),
3161  response_json_(response_json),
3162  client_data_(client_data) {}
3163 
3164 
3165 bool MessageImpl::IsEvent() const {
3166  return is_event_;
3167 }
3168 
3169 
3171  return !is_event_;
3172 }
3173 
3174 
3176  return event_;
3177 }
3178 
3179 
3181  return running_;
3182 }
3183 
3184 
3187 }
3188 
3189 
3191  return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
3192 }
3193 
3194 
3197 }
3198 
3199 
3201  Isolate* isolate = event_data_->GetIsolate();
3202  v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
3203 
3204  if (IsEvent()) {
3205  // Call toJSONProtocol on the debug event object.
3207  isolate, event_data_, "toJSONProtocol").ToHandleChecked();
3208  if (!fun->IsJSFunction()) {
3209  return v8::Handle<v8::String>();
3210  }
3211 
3212  MaybeHandle<Object> maybe_json =
3213  Execution::TryCall(Handle<JSFunction>::cast(fun), event_data_, 0, NULL);
3214  Handle<Object> json;
3215  if (!maybe_json.ToHandle(&json) || !json->IsString()) {
3216  return v8::Handle<v8::String>();
3217  }
3218  return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
3219  } else {
3221  }
3222 }
3223 
3224 
3226  Isolate* isolate = event_data_->GetIsolate();
3227  v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
3228  // Isolate::context() may be NULL when "script collected" event occures.
3229  DCHECK(!context.IsEmpty());
3230  return context;
3231 }
3232 
3233 
3235  return client_data_;
3236 }
3237 
3238 
3240  Handle<JSObject> exec_state,
3241  Handle<JSObject> event_data,
3242  Handle<Object> callback_data,
3243  v8::Debug::ClientData* client_data)
3244  : event_(event),
3245  exec_state_(exec_state),
3246  event_data_(event_data),
3247  callback_data_(callback_data),
3248  client_data_(client_data) {}
3249 
3250 
3252  return event_;
3253 }
3254 
3255 
3258 }
3259 
3260 
3263 }
3264 
3265 
3267  return GetDebugEventContext(exec_state_->GetIsolate());
3268 }
3269 
3270 
3273 }
3274 
3275 
3277  return client_data_;
3278 }
3279 
3280 
3282  client_data_(NULL) {
3283 }
3284 
3285 
3287  v8::Debug::ClientData* data)
3288  : text_(text),
3289  client_data_(data) {
3290 }
3291 
3292 
3294  text_.Dispose();
3295  delete client_data_;
3296  client_data_ = NULL;
3297 }
3298 
3299 
3301  v8::Debug::ClientData* data) {
3302  return CommandMessage(command.Clone(), data);
3303 }
3304 
3305 
3306 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
3307  size_(size) {
3308  messages_ = NewArray<CommandMessage>(size);
3309 }
3310 
3311 
3312 CommandMessageQueue::~CommandMessageQueue() {
3313  while (!IsEmpty()) Get().Dispose();
3314  DeleteArray(messages_);
3315 }
3316 
3317 
3318 CommandMessage CommandMessageQueue::Get() {
3319  DCHECK(!IsEmpty());
3320  int result = start_;
3321  start_ = (start_ + 1) % size_;
3322  return messages_[result];
3323 }
3324 
3325 
3326 void CommandMessageQueue::Put(const CommandMessage& message) {
3327  if ((end_ + 1) % size_ == start_) {
3328  Expand();
3329  }
3330  messages_[end_] = message;
3331  end_ = (end_ + 1) % size_;
3332 }
3333 
3334 
3335 void CommandMessageQueue::Expand() {
3336  CommandMessageQueue new_queue(size_ * 2);
3337  while (!IsEmpty()) {
3338  new_queue.Put(Get());
3339  }
3340  CommandMessage* array_to_free = messages_;
3341  *this = new_queue;
3342  new_queue.messages_ = array_to_free;
3343  // Make the new_queue empty so that it doesn't call Dispose on any messages.
3344  new_queue.start_ = new_queue.end_;
3345  // Automatic destructor called on new_queue, freeing array_to_free.
3346 }
3347 
3348 
3349 LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
3350  : logger_(logger), queue_(size) {}
3351 
3352 
3353 bool LockingCommandMessageQueue::IsEmpty() const {
3354  base::LockGuard<base::Mutex> lock_guard(&mutex_);
3355  return queue_.IsEmpty();
3356 }
3357 
3358 
3359 CommandMessage LockingCommandMessageQueue::Get() {
3360  base::LockGuard<base::Mutex> lock_guard(&mutex_);
3361  CommandMessage result = queue_.Get();
3362  logger_->DebugEvent("Get", result.text());
3363  return result;
3364 }
3365 
3366 
3367 void LockingCommandMessageQueue::Put(const CommandMessage& message) {
3368  base::LockGuard<base::Mutex> lock_guard(&mutex_);
3369  queue_.Put(message);
3370  logger_->DebugEvent("Put", message.text());
3371 }
3372 
3373 
3374 void LockingCommandMessageQueue::Clear() {
3375  base::LockGuard<base::Mutex> lock_guard(&mutex_);
3376  queue_.Clear();
3377 }
3378 
3379 } } // namespace v8::internal
#define BUILTIN(name)
Definition: builtins.cc:122
A client object passed to the v8 debugger whose ownership will be taken by it.
Definition: v8-debug.h:35
void(* MessageHandler)(const Message &message)
Debug message callback function.
Definition: v8-debug.h:152
void(* EventCallback)(const EventDetails &event_details)
Debug event callback function.
Definition: v8-debug.h:142
A HandleScope which first allocates a handle in the current scope which will be later filled with the...
Definition: v8.h:855
Local< T > Escape(Local< T > value)
Pushes the value into the previous scope and returns a handle to it.
Definition: v8.h:865
Create new error objects by calling the corresponding error object constructor with the message.
Definition: v8.h:4130
A container for extension names.
Definition: v8.h:5424
bool IsEmpty() const
Returns true if the handle is empty.
Definition: v8.h:228
Isolate represents an isolated instance of the V8 engine.
Definition: v8.h:4356
@ kNoCompileOptions
Definition: v8.h:1160
A single JavaScript stack frame.
Definition: v8.h:1358
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
Definition: api.h:288
Isolate * GetIsolate() const
Definition: v8.h:421
P * GetParameter() const
Definition: v8.h:423
Local< T > GetValue() const
Definition: v8.h:422
ActiveFunctionsCollector(List< Handle< JSFunction > > *active_functions, Object *active_code_marker)
Definition: debug.cc:1848
List< Handle< JSFunction > > * active_functions_
Definition: debug.cc:1861
void VisitThread(Isolate *isolate, ThreadLocalTop *top)
Definition: debug.cc:1853
void VisitThread(Isolate *isolate, ThreadLocalTop *top)
Definition: debug.cc:1868
static Address target_address_at(Address pc, ConstantPoolArray *constant_pool)
static const int kPatchDebugBreakSlotAddressOffset
static Address break_address_from_return_address(Address pc)
static Address target_address_from_return_address(Address pc)
static const int kDebugBreakSlotLength
static const int kPatchReturnSequenceAddressOffset
Handle< DebugInfo > debug_info_
Definition: debug.h:123
void ClearBreakPoint(Handle< Object > break_point_object)
Definition: debug.cc:281
void FindBreakLocationFromAddress(Address pc)
Definition: debug.cc:187
BreakLocationIterator(Handle< DebugInfo > debug_info, BreakLocatorType type)
Definition: debug.cc:62
RelocInfo::Mode rmode() const
Definition: debug.h:103
RelocIterator * reloc_iterator_
Definition: debug.h:124
void SetBreakPoint(Handle< Object > break_point_object)
Definition: debug.cc:269
RelocIterator * reloc_iterator_original_
Definition: debug.h:125
bool IsStepInLocation(Isolate *isolate)
Definition: debug.cc:365
void PrepareStepIn(Isolate *isolate)
Definition: debug.cc:381
RelocInfo::Mode original_rmode() const
Definition: debug.h:109
void FindBreakLocationFromPosition(int position, BreakPositionAlignment alignment)
Definition: debug.cc:209
Code * builtin(Name name)
Definition: builtins.h:254
static int ExtractArgcFromMinorKey(int minor_key)
Definition: code-stubs.h:1535
static int ExtractArgcFromMinorKey(int minor_key)
Definition: code-stubs.h:797
bool is_compare_ic_stub()
Definition: objects.h:5055
static Code * GetCodeFromTargetAddress(Address address)
Definition: objects-inl.h:5018
ExtraICState extra_ic_state()
Definition: objects-inl.h:4647
bool is_inline_cache_stub()
Definition: objects-inl.h:4921
int SourceStatementPosition(Address pc)
Definition: objects.cc:10224
bool is_call_stub()
Definition: objects.h:5053
byte * instruction_end()
Definition: objects-inl.h:6181
bool is_binary_op_stub()
Definition: objects.h:5054
byte * instruction_start()
Definition: objects-inl.h:6176
bool is_to_boolean_ic_stub()
Definition: objects.h:5057
bool has_debug_break_slots()
Definition: objects-inl.h:4729
Vector< uint16_t > text() const
Definition: debug.h:285
static CommandMessage New(const Vector< uint16_t > &command, v8::Debug::ClientData *data)
Definition: debug.cc:3300
v8::Debug::ClientData * client_data() const
Definition: debug.h:286
Vector< uint16_t > text_
Definition: debug.h:291
v8::Debug::ClientData * client_data_
Definition: debug.h:292
static MUST_USE_RESULT MaybeHandle< Code > GetDebugCode(Handle< JSFunction > function)
Definition: compiler.cc:934
static bool EnsureCompiled(Handle< JSFunction > function, ClearExceptionFlag flag)
Definition: compiler.cc:876
static MUST_USE_RESULT MaybeHandle< Code > GetUnoptimizedCode(Handle< JSFunction > function)
Definition: compiler.cc:805
static Handle< SharedFunctionInfo > CompileScript(Handle< String > source, Handle< Object > script_name, int line_offset, int column_offset, bool is_shared_cross_origin, Handle< Context > context, v8::Extension *extension, ScriptData **cached_data, ScriptCompiler::CompileOptions compile_options, NativesFlag is_natives_code)
Definition: compiler.cc:1134
Handle< DebugInfo > debug_info_
Definition: debug.h:192
void set_next(DebugInfoListNode *next)
Definition: debug.h:187
DebugInfoListNode * next()
Definition: debug.h:186
Handle< DebugInfo > debug_info()
Definition: debug.h:188
DebugInfoListNode(DebugInfo *debug_info)
Definition: debug.cc:713
static Object * FindBreakPointInfo(Handle< DebugInfo > debug_info, Handle< Object > break_point_object)
Definition: objects.cc:15983
static void ClearBreakPoint(Handle< DebugInfo > debug_info, int code_position, Handle< Object > break_point_object)
Definition: objects.cc:15891
static void SetBreakPoint(Handle< DebugInfo > debug_info, int code_position, int source_position, int statement_position, Handle< Object > break_point_object)
Definition: objects.cc:15903
Object ** restarter_frame_function_pointer_
Definition: debug.h:638
LiveEdit::FrameDropMode frame_drop_mode_
Definition: debug.h:633
DebugScope * current_debug_scope_
Definition: debug.h:598
StackFrame::Id break_frame_id_
Definition: debug.h:607
static bool HasDebugInfo(Handle< SharedFunctionInfo > shared)
Definition: debug.cc:1062
Handle< Context > GetDebugContext()
Definition: debug.cc:2778
void OnException(Handle< Object > exception, bool uncaught, Handle< Object > promise)
Definition: debug.cc:2528
void UpdateState()
Definition: debug.cc:2954
MUST_USE_RESULT MaybeHandle< Object > MakeAsyncTaskEvent(Handle< JSObject > task_event)
Definition: debug.cc:2497
bool ignore_events() const
Definition: debug.h:505
static void HandleWeakDebugInfo(const v8::WeakCallbackData< v8::Value, void > &data)
Definition: debug.cc:691
bool StepInActive()
Definition: debug.h:402
void OnThrow(Handle< Object > exception, bool uncaught)
Definition: debug.cc:2504
bool has_break_points_
Definition: debug.h:581
bool StepOutActive()
Definition: debug.h:407
void AssertDebugContext()
Definition: debug.h:559
void EnqueueCommandMessage(Vector< const uint16_t > command, v8::Debug::ClientData *client_data=NULL)
Definition: debug.cc:2979
void ActivateStepIn(StackFrame *frame)
Definition: debug.cc:1675
bool break_disabled_
Definition: debug.h:582
Handle< Object > event_listener_data_
Definition: debug.h:569
bool EnsureDebugInfo(Handle< SharedFunctionInfo > shared, Handle< JSFunction > function)
Definition: debug.cc:2177
void PrepareForBreakPoints()
Definition: debug.cc:1907
void ClearAllBreakPoints()
Definition: debug.cc:1181
void HandleStepIn(Handle< JSFunction > function, Handle< Object > holder, Address fp, bool is_constructor)
Definition: debug.cc:1593
ScriptCache * script_cache_
Definition: debug.h:586
void ActivateStepOut(StackFrame *frame)
Definition: debug.cc:1686
static void RecordEvalCaller(Handle< Script > script)
Definition: debug.cc:2419
void OnAsyncTaskEvent(Handle< JSObject > data)
Definition: debug.cc:2690
MUST_USE_RESULT MaybeHandle< Object > MakeBreakEvent(Handle< Object > break_points_hit)
Definition: debug.cc:2460
Address after_break_target_
Definition: debug.h:592
LockingCommandMessageQueue event_command_queue_
Definition: debug.h:576
MUST_USE_RESULT MaybeHandle< Object > Call(Handle< JSFunction > fun, Handle< Object > data)
Definition: debug.cc:3004
void Break(Arguments args, JavaScriptFrame *)
Definition: debug.cc:866
Handle< Object > event_listener_
Definition: debug.h:568
void InvokeMessageHandler(MessageImpl message)
Definition: debug.cc:2970
ThreadLocal thread_local_
Definition: debug.h:642
void RemoveDebugInfo(Handle< DebugInfo > debug_info)
Definition: debug.cc:2208
bool PromiseHasRejectHandler(Handle< JSObject > promise)
Definition: debug.cc:1265
void ClearStepNext()
Definition: debug.cc:1697
void ClearMirrorCache()
Definition: debug.cc:2389
void SetMessageHandler(v8::Debug::MessageHandler handler)
Definition: debug.cc:2942
DebugScope * debugger_entry()
Definition: debug.h:458
friend class SuppressDebug
Definition: debug.h:650
void ClearStepIn()
Definition: debug.cc:1681
MUST_USE_RESULT MaybeHandle< Object > MakeExecutionState()
Definition: debug.cc:2453
bool has_commands() const
Definition: debug.h:504
friend class DebugScope
Definition: debug.h:647
StackFrame::Id break_frame_id()
Definition: debug.h:473
MUST_USE_RESULT MaybeHandle< Object > MakeJSObject(const char *constructor_name, int argc, Handle< Object > argv[])
Definition: debug.cc:2434
char * ArchiveDebug(char *to)
Definition: debug.cc:571
static Handle< DebugInfo > GetDebugInfo(Handle< SharedFunctionInfo > shared)
Definition: debug.cc:1069
void ClearOneShot()
Definition: debug.cc:1658
void ChangeBreakOnException(ExceptionBreakType type, bool enable)
Definition: debug.cc:1247
v8::Debug::MessageHandler message_handler_
Definition: debug.h:571
Object * FindSharedFunctionInfoInScript(Handle< Script > script, int position)
Definition: debug.cc:2071
void HandleDebugBreak()
Definition: debug.cc:3024
bool CheckBreakPoint(Handle< Object > break_point_object)
Definition: debug.cc:1027
static Handle< Object > GetSourceBreakLocations(Handle< SharedFunctionInfo > shared, BreakPositionAlignment position_aligment)
Definition: debug.cc:1551
LockingCommandMessageQueue command_queue_
Definition: debug.h:575
bool break_on_exception_
Definition: debug.h:583
void OnAfterCompile(Handle< Script > script)
Definition: debug.cc:2621
void FloodBoundFunctionWithOneShot(Handle< JSFunction > function)
Definition: debug.cc:1216
bool break_on_uncaught_exception_
Definition: debug.h:584
void OnCompileError(Handle< Script > script)
Definition: debug.cc:2562
void ProcessDebugEvent(v8::DebugEvent event, Handle< JSObject > event_data, bool auto_continue)
Definition: debug.cc:2709
void FloodWithOneShot(Handle< JSFunction > function)
Definition: debug.cc:1197
void OnDebugBreak(Handle< Object > break_points_hit, bool auto_continue)
Definition: debug.cc:2580
bool SetBreakPoint(Handle< JSFunction > function, Handle< Object > break_point_object, int *source_position)
Definition: debug.cc:1075
void SetEventListener(Handle< Object > callback, Handle< Object > data)
Definition: debug.cc:2921
bool is_loaded() const
Definition: debug.h:466
void ClearBreakPoint(Handle< Object > break_point_object)
Definition: debug.cc:1150
bool SetBreakPointForScript(Handle< Script > script, Handle< Object > break_point_object, int *source_position, BreakPositionAlignment alignment)
Definition: debug.cc:1105
friend class DisableBreak
Definition: debug.h:648
bool IsDebugGlobal(GlobalObject *global)
Definition: debug.cc:2384
void ProcessDebugMessages(bool debug_command_only)
Definition: debug.cc:3057
bool in_debug_scope() const
Definition: debug.h:468
void ThreadInit()
Definition: debug.cc:554
void OnBeforeCompile(Handle< Script > script)
Definition: debug.cc:2600
void SetAfterBreakTarget(JavaScriptFrame *frame)
Definition: debug.cc:2239
Isolate * isolate_
Definition: debug.h:644
void PrepareStep(StepAction step_action, int step_count, StackFrame::Id frame_id)
Definition: debug.cc:1276
void OnPromiseReject(Handle< JSObject > promise, Handle< Object > value)
Definition: debug.cc:2521
void FloodHandlerWithOneShot()
Definition: debug.cc:1229
void OnPromiseEvent(Handle< JSObject > data)
Definition: debug.cc:2671
MUST_USE_RESULT MaybeHandle< Object > MakeCompileEvent(Handle< Script > script, v8::DebugEvent type)
Definition: debug.cc:2480
DebugInfoListNode * debug_info_list_
Definition: debug.h:587
static bool CompileDebuggerScript(Isolate *isolate, int index)
Definition: debug.cc:728
bool is_active() const
Definition: debug.h:465
void NotifyMessageHandler(v8::DebugEvent event, Handle< JSObject > exec_state, Handle< JSObject > event_data, bool auto_continue)
Definition: debug.cc:2785
Handle< Context > debug_context_
Definition: debug.h:567
static int ArchiveSpacePerThread()
Definition: debug.cc:586
void ClearStepping()
Definition: debug.cc:1643
char * RestoreDebug(char *from)
Definition: debug.cc:579
bool is_suppressed_
Definition: debug.h:579
MUST_USE_RESULT MaybeHandle< Object > MakePromiseEvent(Handle< JSObject > promise_event)
Definition: debug.cc:2490
void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, LiveEdit::FrameDropMode mode, Object **restarter_frame_function_pointer)
Definition: debug.cc:2372
Handle< Context > debug_context()
Definition: debug.h:459
base::Semaphore command_received_
Definition: debug.h:574
bool IsBreakOnException(ExceptionBreakType type)
Definition: debug.cc:1256
Handle< FixedArray > GetLoadedScripts()
Definition: debug.cc:2404
void CallEventCallback(v8::DebugEvent event, Handle< Object > exec_state, Handle< Object > event_data, v8::Debug::ClientData *client_data)
Definition: debug.cc:2748
MUST_USE_RESULT MaybeHandle< Object > MakeExceptionEvent(Handle< Object > exception, bool uncaught, Handle< Object > promise)
Definition: debug.cc:2468
static bool IsDebugBreak(Address addr)
Definition: debug.cc:1541
void ClearStepOut()
Definition: debug.cc:1692
bool IsBreakAtReturn(JavaScriptFrame *frame)
Definition: debug.cc:2329
Handle< Object > CheckBreakPoints(Handle< Object > break_point)
Definition: debug.cc:991
Debug(Isolate *isolate)
Definition: debug.cc:30
void EnqueueDebugCommand(v8::Debug::ClientData *client_data=NULL)
Definition: debug.cc:2995
bool StepNextContinue(BreakLocationIterator *break_location_iterator, JavaScriptFrame *frame)
Definition: debug.cc:1511
static void DeoptimizeAll(Isolate *isolate)
Definition: deoptimizer.cc:437
EventDetailsImpl(DebugEvent event, Handle< JSObject > exec_state, Handle< JSObject > event_data, Handle< Object > callback_data, v8::Debug::ClientData *client_data)
Definition: debug.cc:3239
Handle< JSObject > event_data_
Definition: debug.h:266
Handle< Object > callback_data_
Definition: debug.h:267
virtual DebugEvent GetEvent() const
Event type.
Definition: debug.cc:3251
virtual v8::Handle< v8::Object > GetEventData() const
Definition: debug.cc:3261
virtual v8::Handle< v8::Object > GetExecutionState() const
Access to execution state and event data of the debug event.
Definition: debug.cc:3256
virtual v8::Handle< v8::Value > GetCallbackData() const
Client data passed with the corresponding callback when it was registered.
Definition: debug.cc:3271
virtual v8::Handle< v8::Context > GetEventContext() const
Get the context active when the debug event happened.
Definition: debug.cc:3266
virtual v8::Debug::ClientData * GetClientData() const
Client data passed to DebugBreakForCommand function.
Definition: debug.cc:3276
Handle< JSObject > exec_state_
Definition: debug.h:265
v8::Debug::ClientData * client_data_
Definition: debug.h:269
static void MakeWeak(Object **location, void *parameter, WeakCallback weak_callback)
static void * ClearWeakness(Object **location)
static void Destroy(Object **location)
Handle< Object > Create(Object *value)
static Handle< T > cast(Handle< S > that)
Definition: handles.h:116
bool is_null() const
Definition: handles.h:124
static Handle< T > null()
Definition: handles.h:123
static const int kMakeHeapIterableMask
Definition: heap.h:721
static const int kNoGCFlags
Definition: heap.h:716
void CollectAllGarbage(int flags, const char *gc_reason=NULL, const GCCallbackFlags gc_callback_flags=kNoGCCallbackFlags)
Definition: heap.cc:724
Handle< GlobalObject > global_object()
Definition: isolate.h:670
void clear_scheduled_exception()
Definition: isolate.h:631
bool has_scheduled_exception()
Definition: isolate.h:627
Object * scheduled_exception()
Definition: isolate.h:622
StackGuard * stack_guard()
Definition: isolate.h:872
Handle< Context > native_context()
Definition: isolate.cc:1339
Builtins * builtins()
Definition: isolate.h:947
void set_context(Context *context)
Definition: isolate.h:549
Handle< JSBuiltinsObject > js_builtins_object()
Definition: isolate.h:679
OptimizingCompilerThread * optimizing_compiler_thread()
Definition: isolate.h:1059
ThreadLocalTop * thread_local_top()
Definition: isolate.h:878
ThreadManager * thread_manager()
Definition: isolate.h:921
Handle< Object > GetPromiseOnStackOnThrow()
Definition: isolate.cc:1308
void set_pending_exception(Object *exception_obj)
Definition: isolate.h:567
JSObject * global_proxy()
Definition: isolate.h:675
bool concurrent_recompilation_enabled()
Definition: isolate.h:1045
void clear_pending_exception()
Definition: isolate.h:572
CompilationCache * compilation_cache()
Definition: isolate.h:865
void ComputeLocation(MessageLocation *target)
Definition: isolate.cc:932
Logger * logger()
Definition: isolate.h:866
Factory * factory()
Definition: isolate.h:982
GlobalHandles * global_handles()
Definition: isolate.h:917
Bootstrapper * bootstrapper()
Definition: isolate.h:856
bool has_pending_exception()
Definition: isolate.h:581
static const int kBoundFunctionIndex
Definition: objects.h:7392
void set_continuation(int continuation)
static Handle< Object > GetDataProperty(Handle< JSObject > object, Handle< Name > key)
Definition: objects.cc:140
virtual void GetFunctions(List< JSFunction * > *functions)
Definition: frames.cc:762
JSFunction * function() const
Definition: frames-inl.h:265
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:17
static bool SetAfterBreakTarget(Debug *debug)
Definition: liveedit.cc:813
static void InitializeThreadLocal(Debug *debug)
Definition: liveedit.cc:808
void DebugTag(const char *call_site_tag)
Definition: log.cc:1496
bool is_null() const
Definition: handles.h:66
static void ReportMessage(Isolate *isolate, MessageLocation *loc, Handle< Object > message)
Definition: messages.cc:77
static Handle< JSMessageObject > MakeMessageObject(Isolate *isolate, const char *type, MessageLocation *loc, Vector< Handle< Object > > args, Handle< JSArray > stack_frames)
Definition: messages.cc:36
virtual bool WillStartRunning() const
Indicate whether this is a response to a continue command which will start the VM running after this ...
Definition: debug.cc:3180
virtual bool IsResponse() const
Definition: debug.cc:3170
virtual DebugEvent GetEvent() const
Definition: debug.cc:3175
virtual v8::Handle< v8::Object > GetEventData() const
Definition: debug.cc:3195
static MessageImpl NewResponse(DebugEvent event, bool running, Handle< JSObject > exec_state, Handle< JSObject > event_data, Handle< String > response_json, v8::Debug::ClientData *client_data)
Definition: debug.cc:3137
virtual v8::Debug::ClientData * GetClientData() const
Client data passed with the corresponding request if any.
Definition: debug.cc:3234
Handle< String > response_json_
Definition: debug.h:244
Handle< JSObject > event_data_
Definition: debug.h:243
virtual v8::Isolate * GetIsolate() const
Definition: debug.cc:3190
virtual v8::Handle< v8::Context > GetEventContext() const
Get the context active when the debug event happened.
Definition: debug.cc:3225
virtual v8::Handle< v8::Object > GetExecutionState() const
Access to execution state and event data.
Definition: debug.cc:3185
virtual v8::Handle< v8::String > GetJSON() const
Get the debugger protocol JSON.
Definition: debug.cc:3200
Handle< JSObject > exec_state_
Definition: debug.h:242
MessageImpl(bool is_event, DebugEvent event, bool running, Handle< JSObject > exec_state, Handle< JSObject > event_data, Handle< String > response_json, v8::Debug::ClientData *client_data)
Definition: debug.cc:3149
v8::Debug::ClientData * client_data_
Definition: debug.h:245
static MessageImpl NewEvent(DebugEvent event, bool running, Handle< JSObject > exec_state, Handle< JSObject > event_data)
Definition: debug.cc:3127
virtual bool IsEvent() const
Check type of message.
Definition: debug.cc:3165
static Vector< const char > GetScriptName(int index)
static int GetIndex(const char *name)
static MUST_USE_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it)
Definition: objects.cc:109
static MUST_USE_RESULT MaybeHandle< Object > SetProperty(Handle< Object > object, Handle< Name > key, Handle< Object > value, StrictMode strict_mode, StoreFromKeyed store_mode=MAY_BE_STORE_FROM_KEYED)
Definition: objects.cc:2798
static int ModeMask(Mode mode)
Definition: assembler.h:445
static bool IsDebugBreakSlot(Mode mode)
Definition: assembler.h:436
static bool IsJSReturn(Mode mode)
Definition: assembler.h:412
static bool IsPosition(Mode mode)
Definition: assembler.h:424
static bool IsCodeTarget(Mode mode)
Definition: assembler.h:399
byte * pc() const
Definition: assembler.h:457
static bool IsConstPool(Mode mode)
Definition: assembler.h:418
static bool IsConstructCall(Mode mode)
Definition: assembler.h:396
intptr_t data() const
Definition: assembler.h:460
static bool IsStatementPosition(Mode mode)
Definition: assembler.h:427
Mode rmode() const
Definition: assembler.h:459
static const int kNoPosition
Definition: assembler.h:317
Handle< FixedArray > GetScripts()
Definition: debug.cc:642
static void HandleWeakScript(const v8::WeakCallbackData< v8::Value, void > &data)
Definition: debug.cc:671
ScriptCache(Isolate *isolate)
Definition: debug.cc:591
static uint32_t Hash(int key)
Definition: debug.h:164
void Add(Handle< Script > script)
Definition: debug.cc:614
static Handle< JSObject > GetWrapper(Handle< Script > script)
Definition: objects.cc:9741
static Smi * FromInt(int value)
Definition: objects-inl.h:1321
StackFrame * frame() const
Definition: frames.h:842
Object * GetExpression(int index) const
Definition: frames-inl.h:154
int ComputeExpressionsCount() const
Definition: frames.cc:580
Entry * Lookup(void *key, uint32_t hash, bool insert, FreeStoreAllocationPolicy allocator=FreeStoreAllocationPolicy())
Definition: hashmap.h:114
void * Remove(void *key, uint32_t hash)
Definition: hashmap.h:145
void IterateArchivedThreads(ThreadVisitor *v)
Definition: v8threads.cc:342
Vector< T > Clone() const
Definition: vector.h:62
T * start() const
Definition: vector.h:47
int length() const
Definition: vector.h:41
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes to(mksnapshot only)") DEFINE_STRING(raw_context_file
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions true
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define RETURN_ON_EXCEPTION_VALUE(isolate, call, value)
Definition: isolate.h:154
#define UNREACHABLE()
Definition: logging.h:30
#define DCHECK_LE(v1, v2)
Definition: logging.h:210
#define CHECK(condition)
Definition: logging.h:36
#define DCHECK(condition)
Definition: logging.h:205
#define DCHECK_LT(v1, v2)
Definition: logging.h:209
#define DCHECK_EQ(v1, v2)
Definition: logging.h:206
#define arraysize(array)
Definition: macros.h:86
#define V8PRIxPTR
Definition: macros.h:363
unsigned short uint16_t
Definition: unicode.cc:23
void DeleteArray(T *array)
Definition: allocation.h:68
@ CLEAR_EXCEPTION
Definition: globals.h:762
static void RecompileAndRelocateSuspendedGenerators(const List< Handle< JSGeneratorObject > > &generators)
Definition: debug.cc:1893
static int ComputeCodeOffsetFromPcOffset(Code *code, int pc_offset)
Definition: debug.cc:1737
static v8::Handle< v8::Context > GetDebugEventContext(Isolate *isolate)
Definition: debug.cc:52
const Register fp
const int kMaxInt
Definition: globals.h:109
ExceptionBreakType
Definition: debug.h:45
@ BreakUncaughtException
Definition: debug.h:47
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:146
static Handle< Code > DebugBreakForIC(Handle< Code > code, RelocInfo::Mode mode)
Definition: debug.cc:439
BreakPositionAlignment
Definition: debug.h:60
@ STATEMENT_ALIGNED
Definition: debug.h:61
@ BREAK_POSITION_ALIGNED
Definition: debug.h:62
const Register pc
static bool IsSourceBreakStub(Code *code)
Definition: debug.cc:82
byte * Address
Definition: globals.h:101
void PrintF(const char *format,...)
Definition: utils.cc:80
static void RedirectActivationsToRecompiledCodeOnThread(Isolate *isolate, ThreadLocalTop *top)
Definition: debug.cc:1786
@ StepMin
Definition: debug.h:38
@ StepNext
Definition: debug.h:35
@ StepNone
Definition: debug.h:33
@ StepIn
Definition: debug.h:36
@ StepOut
Definition: debug.h:34
BreakLocatorType
Definition: debug.h:52
@ ALL_BREAK_LOCATIONS
Definition: debug.h:53
@ SOURCE_BREAK_LOCATIONS
Definition: debug.h:54
uint16_t uc16
Definition: globals.h:184
@ NATIVES_CODE
Definition: globals.h:401
void MemCopy(void *dest, const void *src, size_t size)
Definition: utils.h:350
static void CollectActiveFunctionsFromThread(Isolate *isolate, ThreadLocalTop *top, List< Handle< JSFunction > > *active_functions, Object *active_code_marker)
Definition: debug.cc:1704
static bool IsBreakStub(Code *code)
Definition: debug.cc:90
static int ComputePcOffsetFromCodeOffset(Code *code, int code_offset)
Definition: debug.cc:1760
@ RUNTIME_FUNCTION
Definition: serialize.h:23
static void EnsureFunctionHasDebugBreakSlots(Handle< JSFunction > function)
Definition: debug.cc:1874
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
DebugEvent
Definition: v8-debug.h:16
@ PromiseEvent
Definition: v8-debug.h:23
@ BeforeCompile
Definition: v8-debug.h:20
@ AfterCompile
Definition: v8-debug.h:21
@ Exception
Definition: v8-debug.h:18
@ BreakForCommand
Definition: v8-debug.h:25
@ AsyncTaskEvent
Definition: v8-debug.h:24
@ CompileError
Definition: v8-debug.h:22
@ Break
Definition: v8-debug.h:17
@ NewFunction
Definition: v8-debug.h:19
#define STATIC_CHAR_VECTOR(x)
Definition: vector.h:154