~james-page/ubuntu/precise/nodejs/0.6.x-merge

« back to all changes in this revision

Viewing changes to deps/v8/src/debug.cc

  • Committer: James Page
  • Date: 2012-03-30 12:09:16 UTC
  • mfrom: (7.1.23 sid)
  • Revision ID: james.page@canonical.com-20120330120916-40hfu9o00qr5t87b
* Merge from Debian unstable:
  - New upstream release (LP: #892034).
  - This package is x86/arm only. Update control to match
  - d/patches/2009_increase_test_timeout.patch: Increased default test
    timeout from 60 to 120 seconds to support reliable execution of all
    tests on armhf/armel architectures.
  - d/patches/2005_expected_failing_tests.patch: 
    - Allow racey tests to fail: test-cluster-kill-workers,
      test-child-process-fork2 
    - Allow test-fs-watch to fail as LP buildd's don't support
      inotify.
    - Revert all other Ubuntu changes as no longer required.
* Update Standards-Version to 3.9.3.
* Patch wscript to enable build on mipsel arch, libv8 being available.
  Upstream does not support that arch, failure expected.
* test-cluster-kill-workers is expected to fail on armhf,
  Bug#660802 will be closed when test pass.
* test-buffer is expected to fail on armel,
  Bug#660800 will be closed when test pass.
* Add epoch to dependency on libev >= 1:4.11. Closes: bug#658441.
* Remove tools/doc because node-doc-generator has no license for now.
* Add copyright for doc/sh* files (shjs).
* source.lintian-overrides : source-contains-waf-binary tools/node-waf
  it is simply not the case here.
* test-stream-pipe-multi expected to timeout sometimes on busy builds. 
* New upstream release.
* Remove upstream patches.
* test-dgram-pingpong expected to timeout, the test itself is buggy.
* test-buffer expected to fail on armel, allow building package to make
  it easier to find the cause of the failure.
  Closes: bug#639636.
* Expect tests dgram-multicast and broadcast to fail.
  debian/patches/2005_expected_failing_tests.patch
* Drop dpkg-source local-options: Defaults since dpkg-source 1.16.1.
* New upstream release.
* Depend on libev-dev 4.11, see bug#657080.
* Bump dependency on openssl to 1.0.0g.
* Remove useless uv_loop_refcount from libuv,
  refreshed 2009_fix_shared_ev.patch.
* Apply to upstream patches landed after 0.6.10 release,
  to fix debugger repl and http client.
* New upstream release. Closes:bug#650661
* Repackage to remove non-dfsg font files ./deps/npm/html/*/*.ttf
* Remove unneeded bundled dependencies: lighter tarball,
  debian/copyright is easier to maintain.
* Drop unneeded build-dependency on scons.
* Depend on zlib1g, libc-ares, libev.
  Patches done to support building with those shared libs.
* Fix DEB_UPSTREAM_URL in debian/rules, and debian/watch.
* nodejs.pc file for pkgconfig is no more available.
* Build-depend on procps package, a test is using /bin/ps.
* Refreshed debian/patches/2005_expected_failing_tests.patch,
  only for tests that need networking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
1
// Copyright 2011 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
40
40
#include "global-handles.h"
41
41
#include "ic.h"
42
42
#include "ic-inl.h"
 
43
#include "list.h"
43
44
#include "messages.h"
44
45
#include "natives.h"
45
46
#include "stub-cache.h"
51
52
namespace internal {
52
53
 
53
54
#ifdef ENABLE_DEBUGGER_SUPPORT
 
55
 
 
56
 
 
57
Debug::Debug(Isolate* isolate)
 
58
    : has_break_points_(false),
 
59
      script_cache_(NULL),
 
60
      debug_info_list_(NULL),
 
61
      disable_break_(false),
 
62
      break_on_exception_(false),
 
63
      break_on_uncaught_exception_(false),
 
64
      debug_break_return_(NULL),
 
65
      debug_break_slot_(NULL),
 
66
      isolate_(isolate) {
 
67
  memset(registers_, 0, sizeof(JSCallerSavedBuffer));
 
68
}
 
69
 
 
70
 
 
71
Debug::~Debug() {
 
72
}
 
73
 
 
74
 
54
75
static void PrintLn(v8::Local<v8::Value> value) {
55
76
  v8::Local<v8::String> s = value->ToString();
56
77
  ScopedVector<char> data(s->Length() + 1);
64
85
 
65
86
 
66
87
static Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind) {
67
 
  CALL_HEAP_FUNCTION(StubCache::ComputeCallDebugBreak(argc, kind), Code);
 
88
  Isolate* isolate = Isolate::Current();
 
89
  CALL_HEAP_FUNCTION(
 
90
      isolate,
 
91
      isolate->stub_cache()->ComputeCallDebugBreak(argc, kind),
 
92
      Code);
68
93
}
69
94
 
70
95
 
71
96
static Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind) {
 
97
  Isolate* isolate = Isolate::Current();
72
98
  CALL_HEAP_FUNCTION(
73
 
      StubCache::ComputeCallDebugPrepareStepIn(argc, kind), Code);
 
99
      isolate,
 
100
      isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind),
 
101
      Code);
74
102
}
75
103
 
76
104
 
77
 
static v8::Handle<v8::Context> GetDebugEventContext() {
78
 
  Handle<Context> context = Debug::debugger_entry()->GetContext();
79
 
  // Top::context() may have been NULL when "script collected" event occured.
80
 
  if (*context == NULL) {
81
 
    return v8::Local<v8::Context>();
82
 
  }
 
105
static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
 
106
  Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
 
107
  // Isolate::context() may have been NULL when "script collected" event
 
108
  // occured.
 
109
  if (context.is_null()) return v8::Local<v8::Context>();
83
110
  Handle<Context> global_context(context->global_context());
84
111
  return v8::Utils::ToLocal(global_context);
85
112
}
142
169
      Code* code = Code::GetCodeFromTargetAddress(target);
143
170
      if ((code->is_inline_cache_stub() &&
144
171
           !code->is_binary_op_stub() &&
145
 
           !code->is_type_recording_binary_op_stub() &&
146
 
           !code->is_compare_ic_stub()) ||
 
172
           !code->is_unary_op_stub() &&
 
173
           !code->is_compare_ic_stub() &&
 
174
           !code->is_to_boolean_ic_stub()) ||
147
175
          RelocInfo::IsConstructCall(rmode())) {
148
176
        break_point_++;
149
177
        return;
452
480
    // calling convention used by the call site.
453
481
    Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode));
454
482
    rinfo()->set_target_address(dbgbrk_code->entry());
455
 
 
456
 
    // For stubs that refer back to an inlined version clear the cached map for
457
 
    // the inlined case to always go through the IC. As long as the break point
458
 
    // is set the patching performed by the runtime system will take place in
459
 
    // the code copy and will therefore have no effect on the running code
460
 
    // keeping it from using the inlined code.
461
 
    if (code->is_keyed_load_stub()) {
462
 
      KeyedLoadIC::ClearInlinedVersion(pc());
463
 
    } else if (code->is_keyed_store_stub()) {
464
 
      KeyedStoreIC::ClearInlinedVersion(pc());
465
 
    } else if (code->is_load_stub()) {
466
 
      LoadIC::ClearInlinedVersion(pc());
467
 
    } else if (code->is_store_stub()) {
468
 
      StoreIC::ClearInlinedVersion(pc());
469
 
    }
470
483
  }
471
484
}
472
485
 
474
487
void BreakLocationIterator::ClearDebugBreakAtIC() {
475
488
  // Patch the code to the original invoke.
476
489
  rinfo()->set_target_address(original_rinfo()->target_address());
477
 
 
478
 
  RelocInfo::Mode mode = rmode();
479
 
  if (RelocInfo::IsCodeTarget(mode)) {
480
 
    AssertNoAllocation nogc;
481
 
    Address target = original_rinfo()->target_address();
482
 
    Code* code = Code::GetCodeFromTargetAddress(target);
483
 
 
484
 
    // Restore the inlined version of keyed stores to get back to the
485
 
    // fast case.  We need to patch back the keyed store because no
486
 
    // patching happens when running normally.  For keyed loads, the
487
 
    // map check will get patched back when running normally after ICs
488
 
    // have been cleared at GC.
489
 
    if (code->is_keyed_store_stub()) KeyedStoreIC::RestoreInlinedVersion(pc());
490
 
  }
491
490
}
492
491
 
493
492
 
535
534
}
536
535
 
537
536
 
538
 
bool Debug::has_break_points_ = false;
539
 
ScriptCache* Debug::script_cache_ = NULL;
540
 
DebugInfoListNode* Debug::debug_info_list_ = NULL;
541
 
 
542
 
 
543
537
// Threading support.
544
538
void Debug::ThreadInit() {
545
539
  thread_local_.break_count_ = 0;
549
543
  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
550
544
  thread_local_.step_count_ = 0;
551
545
  thread_local_.last_fp_ = 0;
 
546
  thread_local_.queued_step_count_ = 0;
552
547
  thread_local_.step_into_fp_ = 0;
553
548
  thread_local_.step_out_fp_ = 0;
554
549
  thread_local_.after_break_target_ = 0;
 
550
  // TODO(isolates): frames_are_dropped_?
555
551
  thread_local_.debugger_entry_ = NULL;
556
552
  thread_local_.pending_interrupts_ = 0;
557
553
  thread_local_.restarter_frame_function_pointer_ = NULL;
558
554
}
559
555
 
560
556
 
561
 
JSCallerSavedBuffer Debug::registers_;
562
 
Debug::ThreadLocal Debug::thread_local_;
563
 
 
564
 
 
565
557
char* Debug::ArchiveDebug(char* storage) {
566
558
  char* to = storage;
567
559
  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
584
576
 
585
577
 
586
578
int Debug::ArchiveSpacePerThread() {
587
 
  return sizeof(ThreadLocal) + sizeof(registers_);
 
579
  return sizeof(ThreadLocal) + sizeof(JSCallerSavedBuffer);
588
580
}
589
581
 
590
582
 
614
606
const int Debug::kFrameDropperFrameSize = 4;
615
607
 
616
608
 
617
 
 
618
 
 
619
 
 
620
 
// Default break enabled.
621
 
bool Debug::disable_break_ = false;
622
 
 
623
 
// Default call debugger on uncaught exception.
624
 
bool Debug::break_on_exception_ = false;
625
 
bool Debug::break_on_uncaught_exception_ = false;
626
 
 
627
 
Handle<Context> Debug::debug_context_ = Handle<Context>();
628
 
Code* Debug::debug_break_return_ = NULL;
629
 
Code* Debug::debug_break_slot_ = NULL;
630
 
 
631
 
 
632
609
void ScriptCache::Add(Handle<Script> script) {
 
610
  GlobalHandles* global_handles = Isolate::Current()->global_handles();
633
611
  // Create an entry in the hash map for the script.
634
612
  int id = Smi::cast(script->id())->value();
635
613
  HashMap::Entry* entry =
642
620
  // Globalize the script object, make it weak and use the location of the
643
621
  // global handle as the value in the hash map.
644
622
  Handle<Script> script_ =
645
 
      Handle<Script>::cast((GlobalHandles::Create(*script)));
646
 
  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
647
 
                          this, ScriptCache::HandleWeakScript);
 
623
      Handle<Script>::cast(
 
624
          (global_handles->Create(*script)));
 
625
  global_handles->MakeWeak(
 
626
      reinterpret_cast<Object**>(script_.location()),
 
627
      this,
 
628
      ScriptCache::HandleWeakScript);
648
629
  entry->value = script_.location();
649
630
}
650
631
 
651
632
 
652
633
Handle<FixedArray> ScriptCache::GetScripts() {
653
 
  Handle<FixedArray> instances = Factory::NewFixedArray(occupancy());
 
634
  Handle<FixedArray> instances = FACTORY->NewFixedArray(occupancy());
654
635
  int count = 0;
655
636
  for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
656
637
    ASSERT(entry->value != NULL);
664
645
 
665
646
 
666
647
void ScriptCache::ProcessCollectedScripts() {
 
648
  Debugger* debugger = Isolate::Current()->debugger();
667
649
  for (int i = 0; i < collected_scripts_.length(); i++) {
668
 
    Debugger::OnScriptCollected(collected_scripts_[i]);
 
650
    debugger->OnScriptCollected(collected_scripts_[i]);
669
651
  }
670
652
  collected_scripts_.Clear();
671
653
}
672
654
 
673
655
 
674
656
void ScriptCache::Clear() {
 
657
  GlobalHandles* global_handles = Isolate::Current()->global_handles();
675
658
  // Iterate the script cache to get rid of all the weak handles.
676
659
  for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
677
660
    ASSERT(entry != NULL);
678
661
    Object** location = reinterpret_cast<Object**>(entry->value);
679
662
    ASSERT((*location)->IsScript());
680
 
    GlobalHandles::ClearWeakness(location);
681
 
    GlobalHandles::Destroy(location);
 
663
    global_handles->ClearWeakness(location);
 
664
    global_handles->Destroy(location);
682
665
  }
683
666
  // Clear the content of the hash map.
684
667
  HashMap::Clear();
708
691
  if (create_heap_objects) {
709
692
    // Get code to handle debug break on return.
710
693
    debug_break_return_ =
711
 
        Builtins::builtin(Builtins::Return_DebugBreak);
 
694
        isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak);
712
695
    ASSERT(debug_break_return_->IsCode());
713
696
    // Get code to handle debug break in debug break slots.
714
697
    debug_break_slot_ =
715
 
        Builtins::builtin(Builtins::Slot_DebugBreak);
 
698
        isolate_->builtins()->builtin(Builtins::kSlot_DebugBreak);
716
699
    ASSERT(debug_break_slot_->IsCode());
717
700
  }
718
701
}
719
702
 
720
703
 
721
704
void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) {
 
705
  Debug* debug = Isolate::Current()->debug();
722
706
  DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data);
723
707
  // We need to clear all breakpoints associated with the function to restore
724
708
  // original code and avoid patching the code twice later because
726
710
  // Runtime::FindSharedFunctionInfoInScript.
727
711
  BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
728
712
  it.ClearAllDebugBreak();
729
 
  RemoveDebugInfo(node->debug_info());
 
713
  debug->RemoveDebugInfo(node->debug_info());
730
714
#ifdef DEBUG
731
 
  node = Debug::debug_info_list_;
 
715
  node = debug->debug_info_list_;
732
716
  while (node != NULL) {
733
717
    ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data));
734
718
    node = node->next();
738
722
 
739
723
 
740
724
DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
 
725
  GlobalHandles* global_handles = Isolate::Current()->global_handles();
741
726
  // Globalize the request debug info object and make it weak.
742
 
  debug_info_ = Handle<DebugInfo>::cast((GlobalHandles::Create(debug_info)));
743
 
  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
744
 
                          this, Debug::HandleWeakDebugInfo);
 
727
  debug_info_ = Handle<DebugInfo>::cast(
 
728
      (global_handles->Create(debug_info)));
 
729
  global_handles->MakeWeak(
 
730
      reinterpret_cast<Object**>(debug_info_.location()),
 
731
      this,
 
732
      Debug::HandleWeakDebugInfo);
745
733
}
746
734
 
747
735
 
748
736
DebugInfoListNode::~DebugInfoListNode() {
749
 
  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location()));
 
737
  Isolate::Current()->global_handles()->Destroy(
 
738
      reinterpret_cast<Object**>(debug_info_.location()));
750
739
}
751
740
 
752
741
 
753
742
bool Debug::CompileDebuggerScript(int index) {
754
 
  HandleScope scope;
 
743
  Isolate* isolate = Isolate::Current();
 
744
  Factory* factory = isolate->factory();
 
745
  HandleScope scope(isolate);
755
746
 
756
747
  // Bail out if the index is invalid.
757
748
  if (index == -1) {
759
750
  }
760
751
 
761
752
  // Find source and name for the requested script.
762
 
  Handle<String> source_code = Bootstrapper::NativesSourceLookup(index);
 
753
  Handle<String> source_code =
 
754
      isolate->bootstrapper()->NativesSourceLookup(index);
763
755
  Vector<const char> name = Natives::GetScriptName(index);
764
 
  Handle<String> script_name = Factory::NewStringFromAscii(name);
 
756
  Handle<String> script_name = factory->NewStringFromAscii(name);
765
757
 
766
758
  // Compile the script.
767
 
  bool allow_natives_syntax = FLAG_allow_natives_syntax;
768
 
  FLAG_allow_natives_syntax = true;
769
759
  Handle<SharedFunctionInfo> function_info;
770
760
  function_info = Compiler::Compile(source_code,
771
761
                                    script_name,
772
762
                                    0, 0, NULL, NULL,
773
763
                                    Handle<String>::null(),
774
764
                                    NATIVES_CODE);
775
 
  FLAG_allow_natives_syntax = allow_natives_syntax;
776
765
 
777
766
  // Silently ignore stack overflows during compilation.
778
767
  if (function_info.is_null()) {
779
 
    ASSERT(Top::has_pending_exception());
780
 
    Top::clear_pending_exception();
 
768
    ASSERT(isolate->has_pending_exception());
 
769
    isolate->clear_pending_exception();
781
770
    return false;
782
771
  }
783
772
 
784
773
  // Execute the shared function in the debugger context.
785
 
  Handle<Context> context = Top::global_context();
 
774
  Handle<Context> context = isolate->global_context();
786
775
  bool caught_exception = false;
787
776
  Handle<JSFunction> function =
788
 
      Factory::NewFunctionFromSharedFunctionInfo(function_info, context);
789
 
  Handle<Object> result =
790
 
      Execution::TryCall(function, Handle<Object>(context->global()),
791
 
                         0, NULL, &caught_exception);
 
777
      factory->NewFunctionFromSharedFunctionInfo(function_info, context);
 
778
 
 
779
  Execution::TryCall(function, Handle<Object>(context->global()),
 
780
                     0, NULL, &caught_exception);
792
781
 
793
782
  // Check for caught exceptions.
794
783
  if (caught_exception) {
795
784
    Handle<Object> message = MessageHandler::MakeMessageObject(
796
785
        "error_loading_debugger", NULL, Vector<Handle<Object> >::empty(),
797
786
        Handle<String>(), Handle<JSArray>());
798
 
    MessageHandler::ReportMessage(NULL, message);
 
787
    MessageHandler::ReportMessage(Isolate::Current(), NULL, message);
799
788
    return false;
800
789
  }
801
790
 
810
799
  // Return if debugger is already loaded.
811
800
  if (IsLoaded()) return true;
812
801
 
 
802
  Debugger* debugger = isolate_->debugger();
 
803
 
813
804
  // Bail out if we're already in the process of compiling the native
814
805
  // JavaScript source code for the debugger.
815
 
  if (Debugger::compiling_natives() || Debugger::is_loading_debugger())
 
806
  if (debugger->compiling_natives() ||
 
807
      debugger->is_loading_debugger())
816
808
    return false;
817
 
  Debugger::set_loading_debugger(true);
 
809
  debugger->set_loading_debugger(true);
818
810
 
819
811
  // Disable breakpoints and interrupts while compiling and running the
820
812
  // debugger scripts including the context creation code.
821
813
  DisableBreak disable(true);
822
 
  PostponeInterruptsScope postpone;
 
814
  PostponeInterruptsScope postpone(isolate_);
823
815
 
824
816
  // Create the debugger context.
825
 
  HandleScope scope;
 
817
  HandleScope scope(isolate_);
826
818
  Handle<Context> context =
827
 
      Bootstrapper::CreateEnvironment(Handle<Object>::null(),
828
 
                                      v8::Handle<ObjectTemplate>(),
829
 
                                      NULL);
 
819
      isolate_->bootstrapper()->CreateEnvironment(
 
820
          isolate_,
 
821
          Handle<Object>::null(),
 
822
          v8::Handle<ObjectTemplate>(),
 
823
          NULL);
830
824
 
831
825
  // Use the debugger context.
832
 
  SaveContext save;
833
 
  Top::set_context(*context);
 
826
  SaveContext save(isolate_);
 
827
  isolate_->set_context(*context);
834
828
 
835
829
  // Expose the builtins object in the debugger context.
836
 
  Handle<String> key = Factory::LookupAsciiSymbol("builtins");
 
830
  Handle<String> key = isolate_->factory()->LookupAsciiSymbol("builtins");
837
831
  Handle<GlobalObject> global = Handle<GlobalObject>(context->global());
838
832
  RETURN_IF_EMPTY_HANDLE_VALUE(
 
833
      isolate_,
839
834
      SetProperty(global, key, Handle<Object>(global->builtins()),
840
835
                  NONE, kNonStrictMode),
841
836
      false);
842
837
 
843
838
  // Compile the JavaScript for the debugger in the debugger context.
844
 
  Debugger::set_compiling_natives(true);
 
839
  debugger->set_compiling_natives(true);
845
840
  bool caught_exception =
846
841
      !CompileDebuggerScript(Natives::GetIndex("mirror")) ||
847
842
      !CompileDebuggerScript(Natives::GetIndex("debug"));
851
846
        !CompileDebuggerScript(Natives::GetIndex("liveedit"));
852
847
  }
853
848
 
854
 
  Debugger::set_compiling_natives(false);
 
849
  debugger->set_compiling_natives(false);
855
850
 
856
851
  // Make sure we mark the debugger as not loading before we might
857
852
  // return.
858
 
  Debugger::set_loading_debugger(false);
 
853
  debugger->set_loading_debugger(false);
859
854
 
860
855
  // Check for caught exceptions.
861
856
  if (caught_exception) return false;
877
872
  DestroyScriptCache();
878
873
 
879
874
  // Clear debugger context global handle.
880
 
  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
 
875
  Isolate::Current()->global_handles()->Destroy(
 
876
      reinterpret_cast<Object**>(debug_context_.location()));
881
877
  debug_context_ = Handle<Context>();
882
878
}
883
879
 
896
892
 
897
893
 
898
894
Object* Debug::Break(Arguments args) {
899
 
  HandleScope scope;
 
895
  Heap* heap = isolate_->heap();
 
896
  HandleScope scope(isolate_);
900
897
  ASSERT(args.length() == 0);
901
898
 
902
899
  thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED;
903
900
 
904
901
  // Get the top-most JavaScript frame.
905
 
  JavaScriptFrameIterator it;
 
902
  JavaScriptFrameIterator it(isolate_);
906
903
  JavaScriptFrame* frame = it.frame();
907
904
 
908
905
  // Just continue if breaks are disabled or debugger cannot be loaded.
909
906
  if (disable_break() || !Load()) {
910
907
    SetAfterBreakTarget(frame);
911
 
    return Heap::undefined_value();
 
908
    return heap->undefined_value();
912
909
  }
913
910
 
914
911
  // Enter the debugger.
915
912
  EnterDebugger debugger;
916
913
  if (debugger.FailedToEnter()) {
917
 
    return Heap::undefined_value();
 
914
    return heap->undefined_value();
918
915
  }
919
916
 
920
917
  // Postpone interrupt during breakpoint processing.
921
 
  PostponeInterruptsScope postpone;
 
918
  PostponeInterruptsScope postpone(isolate_);
922
919
 
923
920
  // Get the debug info (create it if it does not exist).
924
921
  Handle<SharedFunctionInfo> shared =
940
937
 
941
938
  // If there is one or more real break points check whether any of these are
942
939
  // triggered.
943
 
  Handle<Object> break_points_hit(Heap::undefined_value());
 
940
  Handle<Object> break_points_hit(heap->undefined_value());
944
941
  if (break_location_iterator.HasBreakPoint()) {
945
942
    Handle<Object> break_point_objects =
946
943
        Handle<Object>(break_location_iterator.BreakPointObjects());
949
946
 
950
947
  // If step out is active skip everything until the frame where we need to step
951
948
  // out to is reached, unless real breakpoint is hit.
952
 
  if (Debug::StepOutActive() && frame->fp() != Debug::step_out_fp() &&
 
949
  if (StepOutActive() && frame->fp() != step_out_fp() &&
953
950
      break_points_hit->IsUndefined() ) {
954
951
      // Step count should always be 0 for StepOut.
955
952
      ASSERT(thread_local_.step_count_ == 0);
962
959
    // Clear all current stepping setup.
963
960
    ClearStepping();
964
961
 
965
 
    // Notify the debug event listeners.
966
 
    Debugger::OnDebugBreak(break_points_hit, false);
 
962
    if (thread_local_.queued_step_count_ > 0) {
 
963
      // Perform queued steps
 
964
      int step_count = thread_local_.queued_step_count_;
 
965
 
 
966
      // Clear queue
 
967
      thread_local_.queued_step_count_ = 0;
 
968
 
 
969
      PrepareStep(StepNext, step_count);
 
970
    } else {
 
971
      // Notify the debug event listeners.
 
972
      isolate_->debugger()->OnDebugBreak(break_points_hit, false);
 
973
    }
967
974
  } else if (thread_local_.last_step_action_ != StepNone) {
968
975
    // Hold on to last step action as it is cleared by the call to
969
976
    // ClearStepping.
970
977
    StepAction step_action = thread_local_.last_step_action_;
971
978
    int step_count = thread_local_.step_count_;
972
979
 
 
980
    // If StepNext goes deeper in code, StepOut until original frame
 
981
    // and keep step count queued up in the meantime.
 
982
    if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
 
983
      // Count frames until target frame
 
984
      int count = 0;
 
985
      JavaScriptFrameIterator it(isolate_);
 
986
      while (!it.done() && it.frame()->fp() != thread_local_.last_fp_) {
 
987
        count++;
 
988
        it.Advance();
 
989
      }
 
990
 
 
991
      // If we found original frame
 
992
      if (it.frame()->fp() == thread_local_.last_fp_) {
 
993
        if (step_count > 1) {
 
994
          // Save old count and action to continue stepping after
 
995
          // StepOut
 
996
          thread_local_.queued_step_count_ = step_count - 1;
 
997
        }
 
998
 
 
999
        // Set up for StepOut to reach target frame
 
1000
        step_action = StepOut;
 
1001
        step_count = count;
 
1002
      }
 
1003
    }
 
1004
 
973
1005
    // Clear all current stepping setup.
974
1006
    ClearStepping();
975
1007
 
979
1011
 
980
1012
  if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) {
981
1013
    SetAfterBreakTarget(frame);
982
 
  } else if (thread_local_.frame_drop_mode_ == FRAME_DROPPED_IN_IC_CALL) {
 
1014
  } else if (thread_local_.frame_drop_mode_ ==
 
1015
      FRAME_DROPPED_IN_IC_CALL) {
983
1016
    // We must have been calling IC stub. Do not go there anymore.
984
 
    Code* plain_return = Builtins::builtin(Builtins::PlainReturn_LiveEdit);
 
1017
    Code* plain_return = isolate_->builtins()->builtin(
 
1018
        Builtins::kPlainReturn_LiveEdit);
985
1019
    thread_local_.after_break_target_ = plain_return->entry();
986
1020
  } else if (thread_local_.frame_drop_mode_ ==
987
1021
      FRAME_DROPPED_IN_DEBUG_SLOT_CALL) {
988
1022
    // Debug break slot stub does not return normally, instead it manually
989
1023
    // cleans the stack and jumps. We should patch the jump address.
990
 
    Code* plain_return = Builtins::builtin(Builtins::FrameDropper_LiveEdit);
 
1024
    Code* plain_return = isolate_->builtins()->builtin(
 
1025
        Builtins::kFrameDropper_LiveEdit);
991
1026
    thread_local_.after_break_target_ = plain_return->entry();
992
 
  } else if (thread_local_.frame_drop_mode_ == FRAME_DROPPED_IN_DIRECT_CALL) {
 
1027
  } else if (thread_local_.frame_drop_mode_ ==
 
1028
      FRAME_DROPPED_IN_DIRECT_CALL) {
993
1029
    // Nothing to do, after_break_target is not used here.
 
1030
  } else if (thread_local_.frame_drop_mode_ ==
 
1031
      FRAME_DROPPED_IN_RETURN_CALL) {
 
1032
    Code* plain_return = isolate_->builtins()->builtin(
 
1033
        Builtins::kFrameDropper_LiveEdit);
 
1034
    thread_local_.after_break_target_ = plain_return->entry();
994
1035
  } else {
995
1036
    UNREACHABLE();
996
1037
  }
997
1038
 
998
 
  return Heap::undefined_value();
 
1039
  return heap->undefined_value();
 
1040
}
 
1041
 
 
1042
 
 
1043
RUNTIME_FUNCTION(Object*, Debug_Break) {
 
1044
  return isolate->debug()->Break(args);
999
1045
}
1000
1046
 
1001
1047
 
1003
1049
// triggered. This function returns a JSArray with the break point objects
1004
1050
// which is triggered.
1005
1051
Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
 
1052
  Factory* factory = isolate_->factory();
 
1053
 
 
1054
  // Count the number of break points hit. If there are multiple break points
 
1055
  // they are in a FixedArray.
 
1056
  Handle<FixedArray> break_points_hit;
1006
1057
  int break_points_hit_count = 0;
1007
 
  Handle<JSArray> break_points_hit = Factory::NewJSArray(1);
1008
 
 
1009
 
  // If there are multiple break points they are in a FixedArray.
1010
1058
  ASSERT(!break_point_objects->IsUndefined());
1011
1059
  if (break_point_objects->IsFixedArray()) {
1012
1060
    Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
 
1061
    break_points_hit = factory->NewFixedArray(array->length());
1013
1062
    for (int i = 0; i < array->length(); i++) {
1014
1063
      Handle<Object> o(array->get(i));
1015
1064
      if (CheckBreakPoint(o)) {
1016
 
        SetElement(break_points_hit, break_points_hit_count++, o);
 
1065
        break_points_hit->set(break_points_hit_count++, *o);
1017
1066
      }
1018
1067
    }
1019
1068
  } else {
 
1069
    break_points_hit = factory->NewFixedArray(1);
1020
1070
    if (CheckBreakPoint(break_point_objects)) {
1021
 
      SetElement(break_points_hit,
1022
 
                 break_points_hit_count++,
1023
 
                 break_point_objects);
 
1071
      break_points_hit->set(break_points_hit_count++, *break_point_objects);
1024
1072
    }
1025
1073
  }
1026
1074
 
1027
1075
  // Return undefined if no break points were triggered.
1028
1076
  if (break_points_hit_count == 0) {
1029
 
    return Factory::undefined_value();
 
1077
    return factory->undefined_value();
1030
1078
  }
1031
 
  return break_points_hit;
 
1079
  // Return break points hit as a JSArray.
 
1080
  Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
 
1081
  result->set_length(Smi::FromInt(break_points_hit_count));
 
1082
  return result;
1032
1083
}
1033
1084
 
1034
1085
 
1035
1086
// Check whether a single break point object is triggered.
1036
1087
bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
1037
 
  HandleScope scope;
 
1088
  Factory* factory = isolate_->factory();
 
1089
  HandleScope scope(isolate_);
1038
1090
 
1039
1091
  // Ignore check if break point object is not a JSObject.
1040
1092
  if (!break_point_object->IsJSObject()) return true;
1041
1093
 
1042
 
  // Get the function CheckBreakPoint (defined in debug.js).
 
1094
  // Get the function IsBreakPointTriggered (defined in debug-debugger.js).
1043
1095
  Handle<String> is_break_point_triggered_symbol =
1044
 
      Factory::LookupAsciiSymbol("IsBreakPointTriggered");
 
1096
      factory->LookupAsciiSymbol("IsBreakPointTriggered");
1045
1097
  Handle<JSFunction> check_break_point =
1046
1098
    Handle<JSFunction>(JSFunction::cast(
1047
1099
        debug_context()->global()->GetPropertyNoExceptionThrown(
1048
1100
            *is_break_point_triggered_symbol)));
1049
1101
 
1050
1102
  // Get the break id as an object.
1051
 
  Handle<Object> break_id = Factory::NewNumberFromInt(Debug::break_id());
 
1103
  Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
1052
1104
 
1053
1105
  // Call HandleBreakPointx.
1054
1106
  bool caught_exception = false;
1058
1110
    reinterpret_cast<Object**>(break_point_object.location())
1059
1111
  };
1060
1112
  Handle<Object> result = Execution::TryCall(check_break_point,
1061
 
                                             Top::builtins(), argc, argv,
1062
 
                                             &caught_exception);
 
1113
      isolate_->js_builtins_object(), argc, argv, &caught_exception);
1063
1114
 
1064
1115
  // If exception or non boolean result handle as not triggered
1065
1116
  if (caught_exception || !result->IsBoolean()) {
1067
1118
  }
1068
1119
 
1069
1120
  // Return whether the break point is triggered.
1070
 
  return *result == Heap::true_value();
 
1121
  ASSERT(!result.is_null());
 
1122
  return (*result)->IsTrue();
1071
1123
}
1072
1124
 
1073
1125
 
1088
1140
void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared,
1089
1141
                          Handle<Object> break_point_object,
1090
1142
                          int* source_position) {
1091
 
  HandleScope scope;
 
1143
  HandleScope scope(isolate_);
 
1144
 
 
1145
  PrepareForBreakPoints();
1092
1146
 
1093
1147
  if (!EnsureDebugInfo(shared)) {
1094
1148
    // Return if retrieving debug info failed.
1112
1166
 
1113
1167
 
1114
1168
void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
1115
 
  HandleScope scope;
 
1169
  HandleScope scope(isolate_);
1116
1170
 
1117
1171
  DebugInfoListNode* node = debug_info_list_;
1118
1172
  while (node != NULL) {
1163
1217
 
1164
1218
 
1165
1219
void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
 
1220
  PrepareForBreakPoints();
1166
1221
  // Make sure the function has setup the debug info.
1167
1222
  if (!EnsureDebugInfo(shared)) {
1168
1223
    // Return if we failed to retrieve the debug info.
1185
1240
    // If there is no JavaScript stack don't do anything.
1186
1241
    return;
1187
1242
  }
1188
 
  for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) {
 
1243
  for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
1189
1244
    JavaScriptFrame* frame = it.frame();
1190
1245
    if (frame->HasHandler()) {
1191
1246
      Handle<SharedFunctionInfo> shared =
1218
1273
 
1219
1274
 
1220
1275
void Debug::PrepareStep(StepAction step_action, int step_count) {
1221
 
  HandleScope scope;
 
1276
  HandleScope scope(isolate_);
 
1277
 
 
1278
  PrepareForBreakPoints();
 
1279
 
1222
1280
  ASSERT(Debug::InDebugger());
1223
1281
 
1224
1282
  // Remember this step action and count.
1240
1298
    // If there is no JavaScript stack don't do anything.
1241
1299
    return;
1242
1300
  }
1243
 
  JavaScriptFrameIterator frames_it(id);
 
1301
  JavaScriptFrameIterator frames_it(isolate_, id);
1244
1302
  JavaScriptFrame* frame = frames_it.frame();
1245
1303
 
1246
1304
  // First of all ensure there is one-shot break points in the top handler
1366
1424
      // Reverse lookup required as the minor key cannot be retrieved
1367
1425
      // from the code object.
1368
1426
      Handle<Object> obj(
1369
 
          Heap::code_stubs()->SlowReverseLookup(*call_function_stub));
1370
 
      ASSERT(*obj != Heap::undefined_value());
 
1427
          isolate_->heap()->code_stubs()->SlowReverseLookup(
 
1428
              *call_function_stub));
 
1429
      ASSERT(!obj.is_null());
 
1430
      ASSERT(!(*obj)->IsUndefined());
1371
1431
      ASSERT(obj->IsSmi());
1372
1432
      // Get the STUB key and extract major and minor key.
1373
1433
      uint32_t key = Smi::cast(*obj)->value();
1431
1491
// steps before reporting break back to the debugger.
1432
1492
bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
1433
1493
                             JavaScriptFrame* frame) {
 
1494
  // StepNext and StepOut shouldn't bring us deeper in code, so last frame
 
1495
  // shouldn't be a parent of current frame.
 
1496
  if (thread_local_.last_step_action_ == StepNext ||
 
1497
      thread_local_.last_step_action_ == StepOut) {
 
1498
    if (frame->fp() < thread_local_.last_fp_) return true;
 
1499
  }
 
1500
 
1434
1501
  // If the step last action was step next or step in make sure that a new
1435
1502
  // statement is hit.
1436
1503
  if (thread_local_.last_step_action_ == StepNext ||
1485
1552
        return ComputeCallDebugBreak(code->arguments_count(), code->kind());
1486
1553
 
1487
1554
      case Code::LOAD_IC:
1488
 
        return Handle<Code>(Builtins::builtin(Builtins::LoadIC_DebugBreak));
 
1555
        return Isolate::Current()->builtins()->LoadIC_DebugBreak();
1489
1556
 
1490
1557
      case Code::STORE_IC:
1491
 
        return Handle<Code>(Builtins::builtin(Builtins::StoreIC_DebugBreak));
 
1558
        return Isolate::Current()->builtins()->StoreIC_DebugBreak();
1492
1559
 
1493
1560
      case Code::KEYED_LOAD_IC:
1494
 
        return Handle<Code>(
1495
 
            Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak));
 
1561
        return Isolate::Current()->builtins()->KeyedLoadIC_DebugBreak();
1496
1562
 
1497
1563
      case Code::KEYED_STORE_IC:
1498
 
        return Handle<Code>(
1499
 
            Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak));
 
1564
        return Isolate::Current()->builtins()->KeyedStoreIC_DebugBreak();
1500
1565
 
1501
1566
      default:
1502
1567
        UNREACHABLE();
1504
1569
  }
1505
1570
  if (RelocInfo::IsConstructCall(mode)) {
1506
1571
    Handle<Code> result =
1507
 
        Handle<Code>(Builtins::builtin(Builtins::ConstructCall_DebugBreak));
 
1572
        Isolate::Current()->builtins()->ConstructCall_DebugBreak();
1508
1573
    return result;
1509
1574
  }
1510
1575
  if (code->kind() == Code::STUB) {
1511
1576
    ASSERT(code->major_key() == CodeStub::CallFunction);
1512
1577
    Handle<Code> result =
1513
 
        Handle<Code>(Builtins::builtin(Builtins::StubNoRegisters_DebugBreak));
 
1578
        Isolate::Current()->builtins()->StubNoRegisters_DebugBreak();
1514
1579
    return result;
1515
1580
  }
1516
1581
 
1522
1587
// Simple function for returning the source positions for active break points.
1523
1588
Handle<Object> Debug::GetSourceBreakLocations(
1524
1589
    Handle<SharedFunctionInfo> shared) {
1525
 
  if (!HasDebugInfo(shared)) return Handle<Object>(Heap::undefined_value());
 
1590
  Isolate* isolate = Isolate::Current();
 
1591
  Heap* heap = isolate->heap();
 
1592
  if (!HasDebugInfo(shared)) return Handle<Object>(heap->undefined_value());
1526
1593
  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
1527
1594
  if (debug_info->GetBreakPointCount() == 0) {
1528
 
    return Handle<Object>(Heap::undefined_value());
 
1595
    return Handle<Object>(heap->undefined_value());
1529
1596
  }
1530
1597
  Handle<FixedArray> locations =
1531
 
      Factory::NewFixedArray(debug_info->GetBreakPointCount());
 
1598
      isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1532
1599
  int count = 0;
1533
1600
  for (int i = 0; i < debug_info->break_points()->length(); i++) {
1534
1601
    if (!debug_info->break_points()->get(i)->IsUndefined()) {
1574
1641
 
1575
1642
  // Flood the function with one-shot break points if it is called from where
1576
1643
  // step into was requested.
1577
 
  if (fp == Debug::step_in_fp()) {
 
1644
  if (fp == step_in_fp()) {
1578
1645
    // Don't allow step into functions in the native context.
1579
1646
    if (!function->IsBuiltin()) {
1580
1647
      if (function->shared()->code() ==
1581
 
          Builtins::builtin(Builtins::FunctionApply) ||
 
1648
          Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) ||
1582
1649
          function->shared()->code() ==
1583
 
          Builtins::builtin(Builtins::FunctionCall)) {
 
1650
          Isolate::Current()->builtins()->builtin(Builtins::kFunctionCall)) {
1584
1651
        // Handle function.apply and function.call separately to flood the
1585
1652
        // function to be called and not the code for Builtins::FunctionApply or
1586
1653
        // Builtins::FunctionCall. The receiver of call/apply is the target
1659
1726
}
1660
1727
 
1661
1728
 
 
1729
void Debug::PrepareForBreakPoints() {
 
1730
  // If preparing for the first break point make sure to deoptimize all
 
1731
  // functions as debugging does not work with optimized code.
 
1732
  if (!has_break_points_) {
 
1733
    Deoptimizer::DeoptimizeAll();
 
1734
  }
 
1735
}
 
1736
 
 
1737
 
1662
1738
// Ensures the debug information is present for shared.
1663
1739
bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
1664
1740
  // Return if we already have the debug info for shared.
1665
 
  if (HasDebugInfo(shared)) return true;
 
1741
  if (HasDebugInfo(shared)) {
 
1742
    ASSERT(shared->is_compiled());
 
1743
    return true;
 
1744
  }
1666
1745
 
1667
1746
  // Ensure shared in compiled. Return false if this failed.
1668
1747
  if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
1669
1748
 
1670
 
  // If preparing for the first break point make sure to deoptimize all
1671
 
  // functions as debugging does not work with optimized code.
1672
 
  if (!has_break_points_) {
1673
 
    Deoptimizer::DeoptimizeAll();
1674
 
  }
1675
 
 
1676
1749
  // Create the debug info object.
1677
 
  Handle<DebugInfo> debug_info = Factory::NewDebugInfo(shared);
 
1750
  Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared);
1678
1751
 
1679
1752
  // Add debug info to the list.
1680
1753
  DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
1701
1774
      } else {
1702
1775
        prev->set_next(current->next());
1703
1776
      }
1704
 
      current->debug_info()->shared()->set_debug_info(Heap::undefined_value());
 
1777
      current->debug_info()->shared()->set_debug_info(
 
1778
              isolate_->heap()->undefined_value());
1705
1779
      delete current;
1706
1780
 
1707
1781
      // If there are no more debug info objects there are not more break
1719
1793
 
1720
1794
 
1721
1795
void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
1722
 
  HandleScope scope;
 
1796
  HandleScope scope(isolate_);
 
1797
 
 
1798
  PrepareForBreakPoints();
1723
1799
 
1724
1800
  // Get the executing function in which the debug break occurred.
1725
1801
  Handle<SharedFunctionInfo> shared =
1733
1809
  Handle<Code> original_code(debug_info->original_code());
1734
1810
#ifdef DEBUG
1735
1811
  // Get the code which is actually executing.
1736
 
  Handle<Code> frame_code(frame->code());
 
1812
  Handle<Code> frame_code(frame->LookupCode());
1737
1813
  ASSERT(frame_code.is_identical_to(code));
1738
1814
#endif
1739
1815
 
1802
1878
 
1803
1879
 
1804
1880
bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
1805
 
  HandleScope scope;
 
1881
  HandleScope scope(isolate_);
 
1882
 
 
1883
  // If there are no break points this cannot be break at return, as
 
1884
  // the debugger statement and stack guard bebug break cannot be at
 
1885
  // return.
 
1886
  if (!has_break_points_) {
 
1887
    return false;
 
1888
  }
 
1889
 
 
1890
  PrepareForBreakPoints();
1806
1891
 
1807
1892
  // Get the executing function in which the debug break occurred.
1808
1893
  Handle<SharedFunctionInfo> shared =
1815
1900
  Handle<Code> code(debug_info->code());
1816
1901
#ifdef DEBUG
1817
1902
  // Get the code which is actually executing.
1818
 
  Handle<Code> frame_code(frame->code());
 
1903
  Handle<Code> frame_code(frame->LookupCode());
1819
1904
  ASSERT(frame_code.is_identical_to(code));
1820
1905
#endif
1821
1906
 
1846
1931
 
1847
1932
 
1848
1933
bool Debug::IsDebugGlobal(GlobalObject* global) {
1849
 
  return IsLoaded() && global == Debug::debug_context()->global();
 
1934
  return IsLoaded() && global == debug_context()->global();
1850
1935
}
1851
1936
 
1852
1937
 
1853
1938
void Debug::ClearMirrorCache() {
1854
 
  PostponeInterruptsScope postpone;
1855
 
  HandleScope scope;
1856
 
  ASSERT(Top::context() == *Debug::debug_context());
 
1939
  PostponeInterruptsScope postpone(isolate_);
 
1940
  HandleScope scope(isolate_);
 
1941
  ASSERT(isolate_->context() == *Debug::debug_context());
1857
1942
 
1858
1943
  // Clear the mirror cache.
1859
1944
  Handle<String> function_name =
1860
 
      Factory::LookupSymbol(CStrVector("ClearMirrorCache"));
1861
 
  Handle<Object> fun(Top::global()->GetPropertyNoExceptionThrown(
 
1945
      isolate_->factory()->LookupSymbol(CStrVector("ClearMirrorCache"));
 
1946
  Handle<Object> fun(Isolate::Current()->global()->GetPropertyNoExceptionThrown(
1862
1947
      *function_name));
1863
1948
  ASSERT(fun->IsJSFunction());
1864
1949
  bool caught_exception;
1865
 
  Handle<Object> js_object = Execution::TryCall(
1866
 
      Handle<JSFunction>::cast(fun),
 
1950
  Execution::TryCall(Handle<JSFunction>::cast(fun),
1867
1951
      Handle<JSObject>(Debug::debug_context()->global()),
1868
1952
      0, NULL, &caught_exception);
1869
1953
}
1870
1954
 
1871
1955
 
1872
1956
void Debug::CreateScriptCache() {
1873
 
  HandleScope scope;
 
1957
  Heap* heap = isolate_->heap();
 
1958
  HandleScope scope(isolate_);
1874
1959
 
1875
1960
  // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
1876
1961
  // rid of all the cached script wrappers and the second gets rid of the
1877
1962
  // scripts which are no longer referenced.
1878
 
  Heap::CollectAllGarbage(false);
1879
 
  Heap::CollectAllGarbage(false);
 
1963
  heap->CollectAllGarbage(false);
 
1964
  heap->CollectAllGarbage(false);
1880
1965
 
1881
1966
  ASSERT(script_cache_ == NULL);
1882
1967
  script_cache_ = new ScriptCache();
1919
2004
  // If the script cache is not active just return an empty array.
1920
2005
  ASSERT(script_cache_ != NULL);
1921
2006
  if (script_cache_ == NULL) {
1922
 
    Factory::NewFixedArray(0);
 
2007
    isolate_->factory()->NewFixedArray(0);
1923
2008
  }
1924
2009
 
1925
2010
  // Perform GC to get unreferenced scripts evicted from the cache before
1926
2011
  // returning the content.
1927
 
  Heap::CollectAllGarbage(false);
 
2012
  isolate_->heap()->CollectAllGarbage(false);
1928
2013
 
1929
2014
  // Get the scripts from the cache.
1930
2015
  return script_cache_->GetScripts();
1939
2024
}
1940
2025
 
1941
2026
 
1942
 
Mutex* Debugger::debugger_access_ = OS::CreateMutex();
1943
 
Handle<Object> Debugger::event_listener_ = Handle<Object>();
1944
 
Handle<Object> Debugger::event_listener_data_ = Handle<Object>();
1945
 
bool Debugger::compiling_natives_ = false;
1946
 
bool Debugger::is_loading_debugger_ = false;
1947
 
bool Debugger::never_unload_debugger_ = false;
1948
 
v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL;
1949
 
bool Debugger::debugger_unload_pending_ = false;
1950
 
v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
1951
 
Mutex* Debugger::dispatch_handler_access_ = OS::CreateMutex();
1952
 
v8::Debug::DebugMessageDispatchHandler
1953
 
    Debugger::debug_message_dispatch_handler_ = NULL;
1954
 
MessageDispatchHelperThread* Debugger::message_dispatch_helper_thread_ = NULL;
1955
 
int Debugger::host_dispatch_micros_ = 100 * 1000;
1956
 
DebuggerAgent* Debugger::agent_ = NULL;
1957
 
LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize);
1958
 
Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0);
1959
 
LockingCommandMessageQueue Debugger::event_command_queue_(kQueueInitialSize);
 
2027
Debugger::Debugger(Isolate* isolate)
 
2028
    : debugger_access_(isolate->debugger_access()),
 
2029
      event_listener_(Handle<Object>()),
 
2030
      event_listener_data_(Handle<Object>()),
 
2031
      compiling_natives_(false),
 
2032
      is_loading_debugger_(false),
 
2033
      never_unload_debugger_(false),
 
2034
      message_handler_(NULL),
 
2035
      debugger_unload_pending_(false),
 
2036
      host_dispatch_handler_(NULL),
 
2037
      dispatch_handler_access_(OS::CreateMutex()),
 
2038
      debug_message_dispatch_handler_(NULL),
 
2039
      message_dispatch_helper_thread_(NULL),
 
2040
      host_dispatch_micros_(100 * 1000),
 
2041
      agent_(NULL),
 
2042
      command_queue_(isolate->logger(), kQueueInitialSize),
 
2043
      command_received_(OS::CreateSemaphore(0)),
 
2044
      event_command_queue_(isolate->logger(), kQueueInitialSize),
 
2045
      isolate_(isolate) {
 
2046
}
 
2047
 
 
2048
 
 
2049
Debugger::~Debugger() {
 
2050
  delete dispatch_handler_access_;
 
2051
  dispatch_handler_access_ = 0;
 
2052
  delete command_received_;
 
2053
  command_received_ = 0;
 
2054
}
1960
2055
 
1961
2056
 
1962
2057
Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
1963
2058
                                      int argc, Object*** argv,
1964
2059
                                      bool* caught_exception) {
1965
 
  ASSERT(Top::context() == *Debug::debug_context());
 
2060
  ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
1966
2061
 
1967
2062
  // Create the execution state object.
1968
 
  Handle<String> constructor_str = Factory::LookupSymbol(constructor_name);
1969
 
  Handle<Object> constructor(Top::global()->GetPropertyNoExceptionThrown(
1970
 
      *constructor_str));
 
2063
  Handle<String> constructor_str =
 
2064
      isolate_->factory()->LookupSymbol(constructor_name);
 
2065
  Handle<Object> constructor(
 
2066
      isolate_->global()->GetPropertyNoExceptionThrown(*constructor_str));
1971
2067
  ASSERT(constructor->IsJSFunction());
1972
2068
  if (!constructor->IsJSFunction()) {
1973
2069
    *caught_exception = true;
1974
 
    return Factory::undefined_value();
 
2070
    return isolate_->factory()->undefined_value();
1975
2071
  }
1976
2072
  Handle<Object> js_object = Execution::TryCall(
1977
2073
      Handle<JSFunction>::cast(constructor),
1978
 
      Handle<JSObject>(Debug::debug_context()->global()), argc, argv,
1979
 
      caught_exception);
 
2074
      Handle<JSObject>(isolate_->debug()->debug_context()->global()),
 
2075
      argc, argv, caught_exception);
1980
2076
  return js_object;
1981
2077
}
1982
2078
 
1983
2079
 
1984
2080
Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) {
1985
2081
  // Create the execution state object.
1986
 
  Handle<Object> break_id = Factory::NewNumberFromInt(Debug::break_id());
 
2082
  Handle<Object> break_id = isolate_->factory()->NewNumberFromInt(
 
2083
      isolate_->debug()->break_id());
1987
2084
  const int argc = 1;
1988
2085
  Object** argv[argc] = { break_id.location() };
1989
2086
  return MakeJSObject(CStrVector("MakeExecutionState"),
2009
2106
                                            Handle<Object> exception,
2010
2107
                                            bool uncaught,
2011
2108
                                            bool* caught_exception) {
 
2109
  Factory* factory = isolate_->factory();
2012
2110
  // Create the new exception event object.
2013
2111
  const int argc = 3;
2014
2112
  Object** argv[argc] = { exec_state.location(),
2015
2113
                          exception.location(),
2016
 
                          uncaught ? Factory::true_value().location() :
2017
 
                                     Factory::false_value().location()};
 
2114
                          uncaught ? factory->true_value().location() :
 
2115
                                     factory->false_value().location()};
2018
2116
  return MakeJSObject(CStrVector("MakeExceptionEvent"),
2019
2117
                      argc, argv, caught_exception);
2020
2118
}
2033
2131
Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
2034
2132
                                          bool before,
2035
2133
                                          bool* caught_exception) {
 
2134
  Factory* factory = isolate_->factory();
2036
2135
  // Create the compile event object.
2037
2136
  Handle<Object> exec_state = MakeExecutionState(caught_exception);
2038
2137
  Handle<Object> script_wrapper = GetScriptWrapper(script);
2039
2138
  const int argc = 3;
2040
2139
  Object** argv[argc] = { exec_state.location(),
2041
2140
                          script_wrapper.location(),
2042
 
                          before ? Factory::true_value().location() :
2043
 
                                   Factory::false_value().location() };
 
2141
                          before ? factory->true_value().location() :
 
2142
                                   factory->false_value().location() };
2044
2143
 
2045
2144
  return MakeJSObject(CStrVector("MakeCompileEvent"),
2046
2145
                      argc,
2065
2164
 
2066
2165
 
2067
2166
void Debugger::OnException(Handle<Object> exception, bool uncaught) {
2068
 
  HandleScope scope;
 
2167
  HandleScope scope(isolate_);
 
2168
  Debug* debug = isolate_->debug();
2069
2169
 
2070
2170
  // Bail out based on state or if there is no listener for this event
2071
 
  if (Debug::InDebugger()) return;
 
2171
  if (debug->InDebugger()) return;
2072
2172
  if (!Debugger::EventActive(v8::Exception)) return;
2073
2173
 
2074
2174
  // Bail out if exception breaks are not active
2075
2175
  if (uncaught) {
2076
2176
    // Uncaught exceptions are reported by either flags.
2077
 
    if (!(Debug::break_on_uncaught_exception() ||
2078
 
          Debug::break_on_exception())) return;
 
2177
    if (!(debug->break_on_uncaught_exception() ||
 
2178
          debug->break_on_exception())) return;
2079
2179
  } else {
2080
2180
    // Caught exceptions are reported is activated.
2081
 
    if (!Debug::break_on_exception()) return;
 
2181
    if (!debug->break_on_exception()) return;
2082
2182
  }
2083
2183
 
2084
2184
  // Enter the debugger.
2086
2186
  if (debugger.FailedToEnter()) return;
2087
2187
 
2088
2188
  // Clear all current stepping setup.
2089
 
  Debug::ClearStepping();
 
2189
  debug->ClearStepping();
2090
2190
  // Create the event data object.
2091
2191
  bool caught_exception = false;
2092
2192
  Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2108
2208
 
2109
2209
void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
2110
2210
                            bool auto_continue) {
2111
 
  HandleScope scope;
 
2211
  HandleScope scope(isolate_);
2112
2212
 
2113
2213
  // Debugger has already been entered by caller.
2114
 
  ASSERT(Top::context() == *Debug::debug_context());
 
2214
  ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2115
2215
 
2116
2216
  // Bail out if there is no listener for this event
2117
2217
  if (!Debugger::EventActive(v8::Break)) return;
2118
2218
 
2119
2219
  // Debugger must be entered in advance.
2120
 
  ASSERT(Top::context() == *Debug::debug_context());
 
2220
  ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2121
2221
 
2122
2222
  // Create the event data object.
2123
2223
  bool caught_exception = false;
2140
2240
 
2141
2241
 
2142
2242
void Debugger::OnBeforeCompile(Handle<Script> script) {
2143
 
  HandleScope scope;
 
2243
  HandleScope scope(isolate_);
2144
2244
 
2145
2245
  // Bail out based on state or if there is no listener for this event
2146
 
  if (Debug::InDebugger()) return;
 
2246
  if (isolate_->debug()->InDebugger()) return;
2147
2247
  if (compiling_natives()) return;
2148
2248
  if (!EventActive(v8::BeforeCompile)) return;
2149
2249
 
2169
2269
// Handle debugger actions when a new script is compiled.
2170
2270
void Debugger::OnAfterCompile(Handle<Script> script,
2171
2271
                              AfterCompileFlags after_compile_flags) {
2172
 
  HandleScope scope;
 
2272
  HandleScope scope(isolate_);
 
2273
  Debug* debug = isolate_->debug();
2173
2274
 
2174
2275
  // Add the newly compiled script to the script cache.
2175
 
  Debug::AddScriptToScriptCache(script);
 
2276
  debug->AddScriptToScriptCache(script);
2176
2277
 
2177
2278
  // No more to do if not debugging.
2178
2279
  if (!IsDebuggerActive()) return;
2181
2282
  if (compiling_natives()) return;
2182
2283
 
2183
2284
  // Store whether in debugger before entering debugger.
2184
 
  bool in_debugger = Debug::InDebugger();
 
2285
  bool in_debugger = debug->InDebugger();
2185
2286
 
2186
2287
  // Enter the debugger.
2187
2288
  EnterDebugger debugger;
2192
2293
 
2193
2294
  // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
2194
2295
  Handle<String> update_script_break_points_symbol =
2195
 
      Factory::LookupAsciiSymbol("UpdateScriptBreakPoints");
 
2296
      isolate_->factory()->LookupAsciiSymbol("UpdateScriptBreakPoints");
2196
2297
  Handle<Object> update_script_break_points =
2197
 
      Handle<Object>(Debug::debug_context()->global()->
 
2298
      Handle<Object>(debug->debug_context()->global()->
2198
2299
          GetPropertyNoExceptionThrown(*update_script_break_points_symbol));
2199
2300
  if (!update_script_break_points->IsJSFunction()) {
2200
2301
    return;
2209
2310
  bool caught_exception = false;
2210
2311
  const int argc = 1;
2211
2312
  Object** argv[argc] = { reinterpret_cast<Object**>(wrapper.location()) };
2212
 
  Handle<Object> result = Execution::TryCall(
2213
 
      Handle<JSFunction>::cast(update_script_break_points),
2214
 
      Top::builtins(), argc, argv,
 
2313
  Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
 
2314
      Isolate::Current()->js_builtins_object(), argc, argv,
2215
2315
      &caught_exception);
2216
2316
  if (caught_exception) {
2217
2317
    return;
2236
2336
 
2237
2337
 
2238
2338
void Debugger::OnScriptCollected(int id) {
2239
 
  HandleScope scope;
 
2339
  HandleScope scope(isolate_);
2240
2340
 
2241
2341
  // No more to do if not debugging.
2242
2342
  if (!IsDebuggerActive()) return;
2265
2365
void Debugger::ProcessDebugEvent(v8::DebugEvent event,
2266
2366
                                 Handle<JSObject> event_data,
2267
2367
                                 bool auto_continue) {
2268
 
  HandleScope scope;
 
2368
  HandleScope scope(isolate_);
2269
2369
 
2270
2370
  // Clear any pending debug break if this is a real break.
2271
2371
  if (!auto_continue) {
2272
 
    Debug::clear_interrupt_pending(DEBUGBREAK);
 
2372
    isolate_->debug()->clear_interrupt_pending(DEBUGBREAK);
2273
2373
  }
2274
2374
 
2275
2375
  // Create the execution state.
2311
2411
                                 Handle<Object> exec_state,
2312
2412
                                 Handle<Object> event_data,
2313
2413
                                 v8::Debug::ClientData* client_data) {
2314
 
  if (event_listener_->IsProxy()) {
 
2414
  if (event_listener_->IsForeign()) {
2315
2415
    CallCEventCallback(event, exec_state, event_data, client_data);
2316
2416
  } else {
2317
2417
    CallJSEventCallback(event, exec_state, event_data);
2323
2423
                                  Handle<Object> exec_state,
2324
2424
                                  Handle<Object> event_data,
2325
2425
                                  v8::Debug::ClientData* client_data) {
2326
 
  Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_));
 
2426
  Handle<Foreign> callback_obj(Handle<Foreign>::cast(event_listener_));
2327
2427
  v8::Debug::EventCallback2 callback =
2328
 
      FUNCTION_CAST<v8::Debug::EventCallback2>(callback_obj->proxy());
 
2428
      FUNCTION_CAST<v8::Debug::EventCallback2>(callback_obj->address());
2329
2429
  EventDetailsImpl event_details(
2330
2430
      event,
2331
2431
      Handle<JSObject>::cast(exec_state),
2349
2449
                          Handle<Object>::cast(event_data).location(),
2350
2450
                          event_listener_data_.location() };
2351
2451
  bool caught_exception = false;
2352
 
  Execution::TryCall(fun, Top::global(), argc, argv, &caught_exception);
 
2452
  Execution::TryCall(fun, isolate_->global(), argc, argv, &caught_exception);
2353
2453
  // Silently ignore exceptions from debug event listeners.
2354
2454
}
2355
2455
 
2356
2456
 
2357
2457
Handle<Context> Debugger::GetDebugContext() {
2358
 
    never_unload_debugger_ = true;
2359
 
    EnterDebugger debugger;
2360
 
    return Debug::debug_context();
 
2458
  never_unload_debugger_ = true;
 
2459
  EnterDebugger debugger;
 
2460
  return isolate_->debug()->debug_context();
2361
2461
}
2362
2462
 
2363
2463
 
2364
2464
void Debugger::UnloadDebugger() {
 
2465
  Debug* debug = isolate_->debug();
 
2466
 
2365
2467
  // Make sure that there are no breakpoints left.
2366
 
  Debug::ClearAllBreakPoints();
 
2468
  debug->ClearAllBreakPoints();
2367
2469
 
2368
2470
  // Unload the debugger if feasible.
2369
2471
  if (!never_unload_debugger_) {
2370
 
    Debug::Unload();
 
2472
    debug->Unload();
2371
2473
  }
2372
2474
 
2373
2475
  // Clear the flag indicating that the debugger should be unloaded.
2379
2481
                                    Handle<JSObject> exec_state,
2380
2482
                                    Handle<JSObject> event_data,
2381
2483
                                    bool auto_continue) {
2382
 
  HandleScope scope;
 
2484
  HandleScope scope(isolate_);
2383
2485
 
2384
 
  if (!Debug::Load()) return;
 
2486
  if (!isolate_->debug()->Load()) return;
2385
2487
 
2386
2488
  // Process the individual events.
2387
2489
  bool sendEventMessage = false;
2410
2512
  // The debug command interrupt flag might have been set when the command was
2411
2513
  // added. It should be enough to clear the flag only once while we are in the
2412
2514
  // debugger.
2413
 
  ASSERT(Debug::InDebugger());
2414
 
  StackGuard::Continue(DEBUGCOMMAND);
 
2515
  ASSERT(isolate_->debug()->InDebugger());
 
2516
  isolate_->stack_guard()->Continue(DEBUGCOMMAND);
2415
2517
 
2416
2518
  // Notify the debugger that a debug event has occurred unless auto continue is
2417
2519
  // active in which case no event is send.
2474
2576
 
2475
2577
    // Get the command from the queue.
2476
2578
    CommandMessage command = command_queue_.Get();
2477
 
    Logger::DebugTag("Got request from command queue, in interactive loop.");
 
2579
    isolate_->logger()->DebugTag(
 
2580
        "Got request from command queue, in interactive loop.");
2478
2581
    if (!Debugger::IsDebuggerActive()) {
2479
2582
      // Delete command text and user data.
2480
2583
      command.Dispose();
2548
2651
 
2549
2652
void Debugger::SetEventListener(Handle<Object> callback,
2550
2653
                                Handle<Object> data) {
2551
 
  HandleScope scope;
 
2654
  HandleScope scope(isolate_);
 
2655
  GlobalHandles* global_handles = isolate_->global_handles();
2552
2656
 
2553
2657
  // Clear the global handles for the event listener and the event listener data
2554
2658
  // object.
2555
2659
  if (!event_listener_.is_null()) {
2556
 
    GlobalHandles::Destroy(
 
2660
    global_handles->Destroy(
2557
2661
        reinterpret_cast<Object**>(event_listener_.location()));
2558
2662
    event_listener_ = Handle<Object>();
2559
2663
  }
2560
2664
  if (!event_listener_data_.is_null()) {
2561
 
    GlobalHandles::Destroy(
 
2665
    global_handles->Destroy(
2562
2666
        reinterpret_cast<Object**>(event_listener_data_.location()));
2563
2667
    event_listener_data_ = Handle<Object>();
2564
2668
  }
2566
2670
  // If there is a new debug event listener register it together with its data
2567
2671
  // object.
2568
2672
  if (!callback->IsUndefined() && !callback->IsNull()) {
2569
 
    event_listener_ = Handle<Object>::cast(GlobalHandles::Create(*callback));
 
2673
    event_listener_ = Handle<Object>::cast(
 
2674
        global_handles->Create(*callback));
2570
2675
    if (data.is_null()) {
2571
 
      data = Factory::undefined_value();
 
2676
      data = isolate_->factory()->undefined_value();
2572
2677
    }
2573
 
    event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data));
 
2678
    event_listener_data_ = Handle<Object>::cast(
 
2679
        global_handles->Create(*data));
2574
2680
  }
2575
2681
 
2576
2682
  ListenersChanged();
2585
2691
  if (handler == NULL) {
2586
2692
    // Send an empty command to the debugger if in a break to make JavaScript
2587
2693
    // run again if the debugger is closed.
2588
 
    if (Debug::InDebugger()) {
 
2694
    if (isolate_->debug()->InDebugger()) {
2589
2695
      ProcessCommand(Vector<const uint16_t>::empty());
2590
2696
    }
2591
2697
  }
2595
2701
void Debugger::ListenersChanged() {
2596
2702
  if (IsDebuggerActive()) {
2597
2703
    // Disable the compilation cache when the debugger is active.
2598
 
    CompilationCache::Disable();
 
2704
    isolate_->compilation_cache()->Disable();
2599
2705
    debugger_unload_pending_ = false;
2600
2706
  } else {
2601
 
    CompilationCache::Enable();
 
2707
    isolate_->compilation_cache()->Enable();
2602
2708
    // Unload the debugger if event listener and message handler cleared.
2603
2709
    // Schedule this for later, because we may be in non-V8 thread.
2604
2710
    debugger_unload_pending_ = true;
2619
2725
  debug_message_dispatch_handler_ = handler;
2620
2726
 
2621
2727
  if (provide_locker && message_dispatch_helper_thread_ == NULL) {
2622
 
    message_dispatch_helper_thread_ = new MessageDispatchHelperThread;
 
2728
    message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_);
2623
2729
    message_dispatch_helper_thread_->Start();
2624
2730
  }
2625
2731
}
2647
2753
      Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
2648
2754
                       command.length()),
2649
2755
      client_data);
2650
 
  Logger::DebugTag("Put command on command_queue.");
 
2756
  isolate_->logger()->DebugTag("Put command on command_queue.");
2651
2757
  command_queue_.Put(message);
2652
2758
  command_received_->Signal();
2653
2759
 
2654
2760
  // Set the debug command break flag to have the command processed.
2655
 
  if (!Debug::InDebugger()) {
2656
 
    StackGuard::DebugCommand();
 
2761
  if (!isolate_->debug()->InDebugger()) {
 
2762
    isolate_->stack_guard()->DebugCommand();
2657
2763
  }
2658
2764
 
2659
2765
  MessageDispatchHelperThread* dispatch_thread;
2680
2786
  event_command_queue_.Put(message);
2681
2787
 
2682
2788
  // Set the debug command break flag to have the command processed.
2683
 
  if (!Debug::InDebugger()) {
2684
 
    StackGuard::DebugCommand();
 
2789
  if (!isolate_->debug()->InDebugger()) {
 
2790
    isolate_->stack_guard()->DebugCommand();
2685
2791
  }
2686
2792
}
2687
2793
 
2702
2808
  // Enter the debugger.
2703
2809
  EnterDebugger debugger;
2704
2810
  if (debugger.FailedToEnter()) {
2705
 
    return Factory::undefined_value();
 
2811
    return isolate_->factory()->undefined_value();
2706
2812
  }
2707
2813
 
2708
2814
  // Create the execution state.
2709
2815
  bool caught_exception = false;
2710
2816
  Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2711
2817
  if (caught_exception) {
2712
 
    return Factory::undefined_value();
 
2818
    return isolate_->factory()->undefined_value();
2713
2819
  }
2714
2820
 
2715
2821
  static const int kArgc = 2;
2716
2822
  Object** argv[kArgc] = { exec_state.location(), data.location() };
2717
2823
  Handle<Object> result = Execution::Call(
2718
2824
      fun,
2719
 
      Handle<Object>(Debug::debug_context_->global_proxy()),
 
2825
      Handle<Object>(isolate_->debug()->debug_context_->global_proxy()),
2720
2826
      kArgc,
2721
2827
      argv,
2722
2828
      pending_exception);
2731
2837
 
2732
2838
bool Debugger::StartAgent(const char* name, int port,
2733
2839
                          bool wait_for_connection) {
 
2840
  ASSERT(Isolate::Current() == isolate_);
2734
2841
  if (wait_for_connection) {
2735
2842
    // Suspend V8 if it is already running or set V8 to suspend whenever
2736
2843
    // it starts.
2755
2862
 
2756
2863
 
2757
2864
void Debugger::StopAgent() {
 
2865
  ASSERT(Isolate::Current() == isolate_);
2758
2866
  if (agent_ != NULL) {
2759
2867
    agent_->Shutdown();
2760
2868
    agent_->Join();
2765
2873
 
2766
2874
 
2767
2875
void Debugger::WaitForAgent() {
 
2876
  ASSERT(Isolate::Current() == isolate_);
2768
2877
  if (agent_ != NULL)
2769
2878
    agent_->WaitUntilListening();
2770
2879
}
2874
2983
 
2875
2984
 
2876
2985
v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
2877
 
  v8::Handle<v8::Context> context = GetDebugEventContext();
2878
 
  // Top::context() may be NULL when "script collected" event occures.
 
2986
  Isolate* isolate = Isolate::Current();
 
2987
  v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
 
2988
  // Isolate::context() may be NULL when "script collected" event occures.
2879
2989
  ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected);
2880
 
  return GetDebugEventContext();
 
2990
  return context;
2881
2991
}
2882
2992
 
2883
2993
 
2914
3024
 
2915
3025
 
2916
3026
v8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const {
2917
 
  return GetDebugEventContext();
 
3027
  return GetDebugEventContext(Isolate::Current());
2918
3028
}
2919
3029
 
2920
3030
 
3003
3113
}
3004
3114
 
3005
3115
 
3006
 
LockingCommandMessageQueue::LockingCommandMessageQueue(int size)
3007
 
    : queue_(size) {
 
3116
LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
 
3117
    : logger_(logger), queue_(size) {
3008
3118
  lock_ = OS::CreateMutex();
3009
3119
}
3010
3120
 
3023
3133
CommandMessage LockingCommandMessageQueue::Get() {
3024
3134
  ScopedLock sl(lock_);
3025
3135
  CommandMessage result = queue_.Get();
3026
 
  Logger::DebugEvent("Get", result.text());
 
3136
  logger_->DebugEvent("Get", result.text());
3027
3137
  return result;
3028
3138
}
3029
3139
 
3031
3141
void LockingCommandMessageQueue::Put(const CommandMessage& message) {
3032
3142
  ScopedLock sl(lock_);
3033
3143
  queue_.Put(message);
3034
 
  Logger::DebugEvent("Put", message.text());
 
3144
  logger_->DebugEvent("Put", message.text());
3035
3145
}
3036
3146
 
3037
3147
 
3041
3151
}
3042
3152
 
3043
3153
 
3044
 
MessageDispatchHelperThread::MessageDispatchHelperThread()
 
3154
MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate)
3045
3155
    : Thread("v8:MsgDispHelpr"),
3046
3156
      sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
3047
3157
      already_signalled_(false) {
3075
3185
    }
3076
3186
    {
3077
3187
      Locker locker;
3078
 
      Debugger::CallMessageDispatchHandler();
 
3188
      Isolate::Current()->debugger()->CallMessageDispatchHandler();
3079
3189
    }
3080
3190
  }
3081
3191
}