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();
91
isolate->stub_cache()->ComputeCallDebugBreak(argc, kind),
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);
100
isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind),
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>();
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
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);
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());
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());
474
487
void BreakLocationIterator::ClearDebugBreakAtIC() {
475
488
// Patch the code to the original invoke.
476
489
rinfo()->set_target_address(original_rinfo()->target_address());
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);
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());
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;
561
JSCallerSavedBuffer Debug::registers_;
562
Debug::ThreadLocal Debug::thread_local_;
565
557
char* Debug::ArchiveDebug(char* storage) {
566
558
char* to = storage;
567
559
memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
614
606
const int Debug::kFrameDropperFrameSize = 4;
620
// Default break enabled.
621
bool Debug::disable_break_ = false;
623
// Default call debugger on uncaught exception.
624
bool Debug::break_on_exception_ = false;
625
bool Debug::break_on_uncaught_exception_ = false;
627
Handle<Context> Debug::debug_context_ = Handle<Context>();
628
Code* Debug::debug_break_return_ = NULL;
629
Code* Debug::debug_break_slot_ = NULL;
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()),
628
ScriptCache::HandleWeakScript);
648
629
entry->value = script_.location();
652
633
Handle<FixedArray> ScriptCache::GetScripts() {
653
Handle<FixedArray> instances = Factory::NewFixedArray(occupancy());
634
Handle<FixedArray> instances = FACTORY->NewFixedArray(occupancy());
655
636
for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
656
637
ASSERT(entry->value != NULL);
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]);
670
652
collected_scripts_.Clear();
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);
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());
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
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()),
732
Debug::HandleWeakDebugInfo);
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()));
753
742
bool Debug::CompileDebuggerScript(int index) {
743
Isolate* isolate = Isolate::Current();
744
Factory* factory = isolate->factory();
745
HandleScope scope(isolate);
756
747
// Bail out if the index is invalid.
757
748
if (index == -1) {
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);
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,
772
762
0, 0, NULL, NULL,
773
763
Handle<String>::null(),
775
FLAG_allow_natives_syntax = allow_natives_syntax;
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();
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);
779
Execution::TryCall(function, Handle<Object>(context->global()),
780
0, NULL, &caught_exception);
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);
810
799
// Return if debugger is already loaded.
811
800
if (IsLoaded()) return true;
802
Debugger* debugger = isolate_->debugger();
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())
817
Debugger::set_loading_debugger(true);
809
debugger->set_loading_debugger(true);
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_);
824
816
// Create the debugger context.
817
HandleScope scope(isolate_);
826
818
Handle<Context> context =
827
Bootstrapper::CreateEnvironment(Handle<Object>::null(),
828
v8::Handle<ObjectTemplate>(),
819
isolate_->bootstrapper()->CreateEnvironment(
821
Handle<Object>::null(),
822
v8::Handle<ObjectTemplate>(),
831
825
// Use the debugger context.
833
Top::set_context(*context);
826
SaveContext save(isolate_);
827
isolate_->set_context(*context);
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(
839
834
SetProperty(global, key, Handle<Object>(global->builtins()),
840
835
NONE, kNonStrictMode),
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"));
898
894
Object* Debug::Break(Arguments args) {
895
Heap* heap = isolate_->heap();
896
HandleScope scope(isolate_);
900
897
ASSERT(args.length() == 0);
902
899
thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED;
904
901
// Get the top-most JavaScript frame.
905
JavaScriptFrameIterator it;
902
JavaScriptFrameIterator it(isolate_);
906
903
JavaScriptFrame* frame = it.frame();
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();
914
911
// Enter the debugger.
915
912
EnterDebugger debugger;
916
913
if (debugger.FailedToEnter()) {
917
return Heap::undefined_value();
914
return heap->undefined_value();
920
917
// Postpone interrupt during breakpoint processing.
921
PostponeInterruptsScope postpone;
918
PostponeInterruptsScope postpone(isolate_);
923
920
// Get the debug info (create it if it does not exist).
924
921
Handle<SharedFunctionInfo> shared =
962
959
// Clear all current stepping setup.
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_;
967
thread_local_.queued_step_count_ = 0;
969
PrepareStep(StepNext, step_count);
971
// Notify the debug event listeners.
972
isolate_->debugger()->OnDebugBreak(break_points_hit, false);
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_;
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
985
JavaScriptFrameIterator it(isolate_);
986
while (!it.done() && it.frame()->fp() != thread_local_.last_fp_) {
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
996
thread_local_.queued_step_count_ = step_count - 1;
999
// Set up for StepOut to reach target frame
1000
step_action = StepOut;
973
1005
// Clear all current stepping setup.
974
1006
ClearStepping();
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();
998
return Heap::undefined_value();
1039
return heap->undefined_value();
1043
RUNTIME_FUNCTION(Object*, Debug_Break) {
1044
return isolate->debug()->Break(args);
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();
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);
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);
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);
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();
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));
1035
1086
// Check whether a single break point object is triggered.
1036
1087
bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
1088
Factory* factory = isolate_->factory();
1089
HandleScope scope(isolate_);
1039
1091
// Ignore check if break point object is not a JSObject.
1040
1092
if (!break_point_object->IsJSObject()) return true;
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)));
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());
1053
1105
// Call HandleBreakPointx.
1054
1106
bool caught_exception = false;
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());
1530
1597
Handle<FixedArray> locations =
1531
Factory::NewFixedArray(debug_info->GetBreakPointCount());
1598
isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1533
1600
for (int i = 0; i < debug_info->break_points()->length(); i++) {
1534
1601
if (!debug_info->break_points()->get(i)->IsUndefined()) {
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
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();
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());
1667
1746
// Ensure shared in compiled. Return false if this failed.
1668
1747
if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
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();
1676
1749
// Create the debug info object.
1677
Handle<DebugInfo> debug_info = Factory::NewDebugInfo(shared);
1750
Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared);
1679
1752
// Add debug info to the list.
1680
1753
DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
1848
1933
bool Debug::IsDebugGlobal(GlobalObject* global) {
1849
return IsLoaded() && global == Debug::debug_context()->global();
1934
return IsLoaded() && global == debug_context()->global();
1853
1938
void Debug::ClearMirrorCache() {
1854
PostponeInterruptsScope postpone;
1856
ASSERT(Top::context() == *Debug::debug_context());
1939
PostponeInterruptsScope postpone(isolate_);
1940
HandleScope scope(isolate_);
1941
ASSERT(isolate_->context() == *Debug::debug_context());
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);
1872
1956
void Debug::CreateScriptCache() {
1957
Heap* heap = isolate_->heap();
1958
HandleScope scope(isolate_);
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);
1881
1966
ASSERT(script_cache_ == NULL);
1882
1967
script_cache_ = new ScriptCache();
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),
2042
command_queue_(isolate->logger(), kQueueInitialSize),
2043
command_received_(OS::CreateSemaphore(0)),
2044
event_command_queue_(isolate->logger(), kQueueInitialSize),
2049
Debugger::~Debugger() {
2050
delete dispatch_handler_access_;
2051
dispatch_handler_access_ = 0;
2052
delete command_received_;
2053
command_received_ = 0;
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());
1967
2062
// Create the execution state object.
1968
Handle<String> constructor_str = Factory::LookupSymbol(constructor_name);
1969
Handle<Object> constructor(Top::global()->GetPropertyNoExceptionThrown(
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();
1976
2072
Handle<Object> js_object = Execution::TryCall(
1977
2073
Handle<JSFunction>::cast(constructor),
1978
Handle<JSObject>(Debug::debug_context()->global()), argc, argv,
2074
Handle<JSObject>(isolate_->debug()->debug_context()->global()),
2075
argc, argv, caught_exception);
1980
2076
return js_object;
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,
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);
2033
2131
Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
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() };
2045
2144
return MakeJSObject(CStrVector("MakeCompileEvent"),
2067
2166
void Debugger::OnException(Handle<Object> exception, bool uncaught) {
2167
HandleScope scope(isolate_);
2168
Debug* debug = isolate_->debug();
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;
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;
2080
2180
// Caught exceptions are reported is activated.
2081
if (!Debug::break_on_exception()) return;
2181
if (!debug->break_on_exception()) return;
2084
2184
// Enter the debugger.
2109
2209
void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
2110
2210
bool auto_continue) {
2211
HandleScope scope(isolate_);
2113
2213
// Debugger has already been entered by caller.
2114
ASSERT(Top::context() == *Debug::debug_context());
2214
ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2116
2216
// Bail out if there is no listener for this event
2117
2217
if (!Debugger::EventActive(v8::Break)) return;
2119
2219
// Debugger must be entered in advance.
2120
ASSERT(Top::context() == *Debug::debug_context());
2220
ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2122
2222
// Create the event data object.
2123
2223
bool caught_exception = false;
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.
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();
2364
2464
void Debugger::UnloadDebugger() {
2465
Debug* debug = isolate_->debug();
2365
2467
// Make sure that there are no breakpoints left.
2366
Debug::ClearAllBreakPoints();
2468
debug->ClearAllBreakPoints();
2368
2470
// Unload the debugger if feasible.
2369
2471
if (!never_unload_debugger_) {
2373
2475
// Clear the flag indicating that the debugger should be unloaded.
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();
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();
2715
2821
static const int kArgc = 2;
2716
2822
Object** argv[kArgc] = { exec_state.location(), data.location() };
2717
2823
Handle<Object> result = Execution::Call(
2719
Handle<Object>(Debug::debug_context_->global_proxy()),
2825
Handle<Object>(isolate_->debug()->debug_context_->global_proxy()),
2722
2828
pending_exception);