| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 Handle<DebugInfo> debug_info() { return debug_info_; } | 199 Handle<DebugInfo> debug_info() { return debug_info_; } |
| 200 | 200 |
| 201 private: | 201 private: |
| 202 // Global (weak) handle to the debug info object. | 202 // Global (weak) handle to the debug info object. |
| 203 Handle<DebugInfo> debug_info_; | 203 Handle<DebugInfo> debug_info_; |
| 204 | 204 |
| 205 // Next pointer for linked list. | 205 // Next pointer for linked list. |
| 206 DebugInfoListNode* next_; | 206 DebugInfoListNode* next_; |
| 207 }; | 207 }; |
| 208 | 208 |
| 209 class DebugData { |
| 210 public: |
| 211 // List of active debug info objects. public for tests |
| 212 DebugInfoListNode* debug_info_list_; |
| 213 private: |
| 214 // Global handle to debug context where all the debugger JavaScript code is |
| 215 // loaded. |
| 216 Handle<Context> debug_context_; |
| 217 |
| 218 // Boolean state indicating whether any break points are set. |
| 219 bool has_break_points_; |
| 220 |
| 221 // Cache of all scripts in the heap. |
| 222 ScriptCache* script_cache_; |
| 223 |
| 224 bool disable_break_; |
| 225 bool break_on_exception_; |
| 226 bool break_on_uncaught_exception_; |
| 227 |
| 228 // Per-thread data. |
| 229 class ThreadLocal { |
| 230 public: |
| 231 // Counter for generating next break id. |
| 232 int break_count_; |
| 233 |
| 234 // Current break id. |
| 235 int break_id_; |
| 236 |
| 237 // Frame id for the frame of the current break. |
| 238 StackFrame::Id break_frame_id_; |
| 239 |
| 240 // Step action for last step performed. |
| 241 StepAction last_step_action_; |
| 242 |
| 243 // Source statement position from last step next action. |
| 244 int last_statement_position_; |
| 245 |
| 246 // Number of steps left to perform before debug event. |
| 247 int step_count_; |
| 248 |
| 249 // Frame pointer from last step next action. |
| 250 Address last_fp_; |
| 251 |
| 252 // Frame pointer for frame from which step in was performed. |
| 253 Address step_into_fp_; |
| 254 |
| 255 // Frame pointer for the frame where debugger should be called when current |
| 256 // step out action is completed. |
| 257 Address step_out_fp_; |
| 258 |
| 259 // Storage location for jump when exiting debug break calls. |
| 260 Address after_break_target_; |
| 261 |
| 262 // Top debugger entry. |
| 263 EnterDebugger* debugger_entry_; |
| 264 |
| 265 // Pending interrupts scheduled while debugging. |
| 266 int pending_interrupts_; |
| 267 }; |
| 268 |
| 269 // Storage location for registers when handling debug break calls |
| 270 JSCallerSavedBuffer registers_; |
| 271 ThreadLocal thread_local_; |
| 272 |
| 273 // Code to call for handling debug break on return. |
| 274 Code* debug_break_return_; |
| 275 |
| 276 friend class Debug; |
| 277 friend class V8Context; |
| 278 |
| 279 DebugData(); |
| 280 DISALLOW_COPY_AND_ASSIGN(DebugData); |
| 281 }; |
| 209 | 282 |
| 210 // This class contains the debugger support. The main purpose is to handle | 283 // This class contains the debugger support. The main purpose is to handle |
| 211 // setting break points in the code. | 284 // setting break points in the code. |
| 212 // | 285 // |
| 213 // This class controls the debug info for all functions which currently have | 286 // This class controls the debug info for all functions which currently have |
| 214 // active breakpoints in them. This debug info is held in the heap root object | 287 // active breakpoints in them. This debug info is held in the heap root object |
| 215 // debug_info which is a FixedArray. Each entry in this list is of class | 288 // debug_info which is a FixedArray. Each entry in this list is of class |
| 216 // DebugInfo. | 289 // DebugInfo. |
| 217 class Debug { | 290 class Debug { |
| 218 public: | 291 public: |
| 219 static void Setup(bool create_heap_objects); | 292 static void Setup(bool create_heap_objects); |
| 220 static bool Load(); | 293 static bool Load(); |
| 221 static void Unload(); | 294 static void Unload(); |
| 222 static bool IsLoaded() { return !debug_context_.is_null(); } | 295 static bool IsLoaded() { |
| 223 static bool InDebugger() { return thread_local_.debugger_entry_ != NULL; } | 296 return !v8_context()->debug_data_.debug_context_.is_null(); |
| 297 } |
| 298 static bool InDebugger() { |
| 299 return v8_context()->debug_data_.thread_local_.debugger_entry_ != NULL; |
| 300 } |
| 224 static void PreemptionWhileInDebugger(); | 301 static void PreemptionWhileInDebugger(); |
| 225 static void Iterate(ObjectVisitor* v); | 302 static void Iterate(ObjectVisitor* v); |
| 226 | 303 |
| 227 static Object* Break(Arguments args); | 304 static Object* Break(Arguments args); |
| 228 static void SetBreakPoint(Handle<SharedFunctionInfo> shared, | 305 static void SetBreakPoint(Handle<SharedFunctionInfo> shared, |
| 229 int source_position, | 306 int source_position, |
| 230 Handle<Object> break_point_object); | 307 Handle<Object> break_point_object); |
| 231 static void ClearBreakPoint(Handle<Object> break_point_object); | 308 static void ClearBreakPoint(Handle<Object> break_point_object); |
| 232 static void ClearAllBreakPoints(); | 309 static void ClearAllBreakPoints(); |
| 233 static void FloodWithOneShot(Handle<SharedFunctionInfo> shared); | 310 static void FloodWithOneShot(Handle<SharedFunctionInfo> shared); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 254 static bool IsSourceBreakStub(Code* code); | 331 static bool IsSourceBreakStub(Code* code); |
| 255 static bool IsBreakStub(Code* code); | 332 static bool IsBreakStub(Code* code); |
| 256 | 333 |
| 257 // Find the builtin to use for invoking the debug break | 334 // Find the builtin to use for invoking the debug break |
| 258 static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode); | 335 static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode); |
| 259 | 336 |
| 260 static Handle<Object> GetSourceBreakLocations( | 337 static Handle<Object> GetSourceBreakLocations( |
| 261 Handle<SharedFunctionInfo> shared); | 338 Handle<SharedFunctionInfo> shared); |
| 262 | 339 |
| 263 // Getter for the debug_context. | 340 // Getter for the debug_context. |
| 264 inline static Handle<Context> debug_context() { return debug_context_; } | 341 inline static Handle<Context> debug_context() { |
| 342 return v8_context()->debug_data_.debug_context_; |
| 343 } |
| 265 | 344 |
| 266 // Check whether a global object is the debug global object. | 345 // Check whether a global object is the debug global object. |
| 267 static bool IsDebugGlobal(GlobalObject* global); | 346 static bool IsDebugGlobal(GlobalObject* global); |
| 268 | 347 |
| 269 // Fast check to see if any break points are active. | 348 // Fast check to see if any break points are active. |
| 270 inline static bool has_break_points() { return has_break_points_; } | 349 inline static bool has_break_points() { |
| 350 return v8_context()->debug_data_.has_break_points_; |
| 351 } |
| 271 | 352 |
| 272 static void NewBreak(StackFrame::Id break_frame_id); | 353 static void NewBreak(StackFrame::Id break_frame_id); |
| 273 static void SetBreak(StackFrame::Id break_frame_id, int break_id); | 354 static void SetBreak(StackFrame::Id break_frame_id, int break_id); |
| 274 static StackFrame::Id break_frame_id() { | 355 static StackFrame::Id break_frame_id() { |
| 275 return thread_local_.break_frame_id_; | 356 return v8_context()->debug_data_.thread_local_.break_frame_id_; |
| 276 } | 357 } |
| 277 static int break_id() { return thread_local_.break_id_; } | 358 static int break_id() { |
| 359 return v8_context()->debug_data_.thread_local_.break_id_; |
| 360 } |
| 278 | 361 |
| 279 static bool StepInActive() { return thread_local_.step_into_fp_ != 0; } | 362 static bool StepInActive() { |
| 363 return v8_context()->debug_data_.thread_local_.step_into_fp_ != 0; |
| 364 } |
| 280 static void HandleStepIn(Handle<JSFunction> function, | 365 static void HandleStepIn(Handle<JSFunction> function, |
| 281 Handle<Object> holder, | 366 Handle<Object> holder, |
| 282 Address fp, | 367 Address fp, |
| 283 bool is_constructor); | 368 bool is_constructor); |
| 284 static Address step_in_fp() { return thread_local_.step_into_fp_; } | 369 static Address step_in_fp() { |
| 285 static Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; } | 370 return v8_context()->debug_data_.thread_local_.step_into_fp_; |
| 371 } |
| 372 static Address* step_in_fp_addr() { |
| 373 return &v8_context()->debug_data_.thread_local_.step_into_fp_; |
| 374 } |
| 286 | 375 |
| 287 static bool StepOutActive() { return thread_local_.step_out_fp_ != 0; } | 376 static bool StepOutActive() { |
| 288 static Address step_out_fp() { return thread_local_.step_out_fp_; } | 377 return v8_context()->debug_data_.thread_local_.step_out_fp_ != 0; |
| 378 } |
| 379 static Address step_out_fp() { |
| 380 return v8_context()->debug_data_.thread_local_.step_out_fp_; |
| 381 } |
| 289 | 382 |
| 290 static EnterDebugger* debugger_entry() { | 383 static EnterDebugger* debugger_entry() { |
| 291 return thread_local_.debugger_entry_; | 384 return v8_context()->debug_data_.thread_local_.debugger_entry_; |
| 292 } | 385 } |
| 293 static void set_debugger_entry(EnterDebugger* entry) { | 386 static void set_debugger_entry(EnterDebugger* entry) { |
| 294 thread_local_.debugger_entry_ = entry; | 387 v8_context()->debug_data_.thread_local_.debugger_entry_ = entry; |
| 295 } | 388 } |
| 296 | 389 |
| 297 // Check whether any of the specified interrupts are pending. | 390 // Check whether any of the specified interrupts are pending. |
| 298 static bool is_interrupt_pending(InterruptFlag what) { | 391 static bool is_interrupt_pending(InterruptFlag what) { |
| 299 return (thread_local_.pending_interrupts_ & what) != 0; | 392 return (v8_context()->debug_data_.thread_local_.pending_interrupts_ & |
| 393 what) != 0; |
| 300 } | 394 } |
| 301 | 395 |
| 302 // Set specified interrupts as pending. | 396 // Set specified interrupts as pending. |
| 303 static void set_interrupts_pending(InterruptFlag what) { | 397 static void set_interrupts_pending(InterruptFlag what) { |
| 304 thread_local_.pending_interrupts_ |= what; | 398 v8_context()->debug_data_.thread_local_.pending_interrupts_ |= what; |
| 305 } | 399 } |
| 306 | 400 |
| 307 // Clear specified interrupts from pending. | 401 // Clear specified interrupts from pending. |
| 308 static void clear_interrupt_pending(InterruptFlag what) { | 402 static void clear_interrupt_pending(InterruptFlag what) { |
| 309 thread_local_.pending_interrupts_ &= ~static_cast<int>(what); | 403 v8_context()->debug_data_.thread_local_.pending_interrupts_ &= |
| 404 ~static_cast<int>(what); |
| 310 } | 405 } |
| 311 | 406 |
| 312 // Getter and setter for the disable break state. | 407 // Getter and setter for the disable break state. |
| 313 static bool disable_break() { return disable_break_; } | 408 static bool disable_break() { |
| 409 return v8_context()->debug_data_.disable_break_; |
| 410 } |
| 314 static void set_disable_break(bool disable_break) { | 411 static void set_disable_break(bool disable_break) { |
| 315 disable_break_ = disable_break; | 412 v8_context()->debug_data_.disable_break_ = disable_break; |
| 316 } | 413 } |
| 317 | 414 |
| 318 // Getters for the current exception break state. | 415 // Getters for the current exception break state. |
| 319 static bool break_on_exception() { return break_on_exception_; } | 416 static bool break_on_exception() { |
| 417 return v8_context()->debug_data_.break_on_exception_; |
| 418 } |
| 320 static bool break_on_uncaught_exception() { | 419 static bool break_on_uncaught_exception() { |
| 321 return break_on_uncaught_exception_; | 420 return v8_context()->debug_data_.break_on_uncaught_exception_; |
| 322 } | 421 } |
| 323 | 422 |
| 324 enum AddressId { | 423 enum AddressId { |
| 325 k_after_break_target_address, | 424 k_after_break_target_address, |
| 326 k_debug_break_return_address, | 425 k_debug_break_return_address, |
| 327 k_register_address | 426 k_register_address |
| 328 }; | 427 }; |
| 329 | 428 |
| 330 // Support for setting the address to jump to when returning from break point. | 429 // Support for setting the address to jump to when returning from break point. |
| 331 static Address* after_break_target_address() { | 430 static Address* after_break_target_address() { |
| 332 return reinterpret_cast<Address*>(&thread_local_.after_break_target_); | 431 return reinterpret_cast<Address*>( |
| 432 &v8_context()->debug_data_.thread_local_.after_break_target_); |
| 333 } | 433 } |
| 334 | 434 |
| 335 // Support for saving/restoring registers when handling debug break calls. | 435 // Support for saving/restoring registers when handling debug break calls. |
| 336 static Object** register_address(int r) { | 436 static Object** register_address(int r) { |
| 337 return ®isters_[r]; | 437 return &v8_context()->debug_data_.registers_[r]; |
| 338 } | 438 } |
| 339 | 439 |
| 340 // Access to the debug break on return code. | 440 // Access to the debug break on return code. |
| 341 static Code* debug_break_return() { return debug_break_return_; } | 441 static Code* debug_break_return() { |
| 442 return v8_context()->debug_data_.debug_break_return_; |
| 443 } |
| 342 static Code** debug_break_return_address() { | 444 static Code** debug_break_return_address() { |
| 343 return &debug_break_return_; | 445 return &v8_context()->debug_data_.debug_break_return_; |
| 344 } | 446 } |
| 345 | 447 |
| 346 static const int kEstimatedNofDebugInfoEntries = 16; | 448 static const int kEstimatedNofDebugInfoEntries = 16; |
| 347 static const int kEstimatedNofBreakPointsInFunction = 16; | 449 static const int kEstimatedNofBreakPointsInFunction = 16; |
| 348 | 450 |
| 349 static void HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data); | 451 static void HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data); |
| 350 | 452 |
| 351 friend class Debugger; | 453 friend class Debugger; |
| 352 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc | 454 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc |
| 353 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc | 455 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 static void ActivateStepOut(StackFrame* frame); | 492 static void ActivateStepOut(StackFrame* frame); |
| 391 static void ClearStepOut(); | 493 static void ClearStepOut(); |
| 392 static void ClearStepNext(); | 494 static void ClearStepNext(); |
| 393 // Returns whether the compile succeeded. | 495 // Returns whether the compile succeeded. |
| 394 static bool EnsureCompiled(Handle<SharedFunctionInfo> shared); | 496 static bool EnsureCompiled(Handle<SharedFunctionInfo> shared); |
| 395 static void RemoveDebugInfo(Handle<DebugInfo> debug_info); | 497 static void RemoveDebugInfo(Handle<DebugInfo> debug_info); |
| 396 static void SetAfterBreakTarget(JavaScriptFrame* frame); | 498 static void SetAfterBreakTarget(JavaScriptFrame* frame); |
| 397 static Handle<Object> CheckBreakPoints(Handle<Object> break_point); | 499 static Handle<Object> CheckBreakPoints(Handle<Object> break_point); |
| 398 static bool CheckBreakPoint(Handle<Object> break_point_object); | 500 static bool CheckBreakPoint(Handle<Object> break_point_object); |
| 399 | 501 |
| 400 // Global handle to debug context where all the debugger JavaScript code is | 502 typedef DebugData::ThreadLocal ThreadLocal; |
| 401 // loaded. | |
| 402 static Handle<Context> debug_context_; | |
| 403 | |
| 404 // Boolean state indicating whether any break points are set. | |
| 405 static bool has_break_points_; | |
| 406 | |
| 407 // Cache of all scripts in the heap. | |
| 408 static ScriptCache* script_cache_; | |
| 409 | |
| 410 // List of active debug info objects. | |
| 411 static DebugInfoListNode* debug_info_list_; | |
| 412 | |
| 413 static bool disable_break_; | |
| 414 static bool break_on_exception_; | |
| 415 static bool break_on_uncaught_exception_; | |
| 416 | |
| 417 // Per-thread data. | |
| 418 class ThreadLocal { | |
| 419 public: | |
| 420 // Counter for generating next break id. | |
| 421 int break_count_; | |
| 422 | |
| 423 // Current break id. | |
| 424 int break_id_; | |
| 425 | |
| 426 // Frame id for the frame of the current break. | |
| 427 StackFrame::Id break_frame_id_; | |
| 428 | |
| 429 // Step action for last step performed. | |
| 430 StepAction last_step_action_; | |
| 431 | |
| 432 // Source statement position from last step next action. | |
| 433 int last_statement_position_; | |
| 434 | |
| 435 // Number of steps left to perform before debug event. | |
| 436 int step_count_; | |
| 437 | |
| 438 // Frame pointer from last step next action. | |
| 439 Address last_fp_; | |
| 440 | |
| 441 // Frame pointer for frame from which step in was performed. | |
| 442 Address step_into_fp_; | |
| 443 | |
| 444 // Frame pointer for the frame where debugger should be called when current | |
| 445 // step out action is completed. | |
| 446 Address step_out_fp_; | |
| 447 | |
| 448 // Storage location for jump when exiting debug break calls. | |
| 449 Address after_break_target_; | |
| 450 | |
| 451 // Top debugger entry. | |
| 452 EnterDebugger* debugger_entry_; | |
| 453 | |
| 454 // Pending interrupts scheduled while debugging. | |
| 455 int pending_interrupts_; | |
| 456 }; | |
| 457 | |
| 458 // Storage location for registers when handling debug break calls | |
| 459 static JSCallerSavedBuffer registers_; | |
| 460 static ThreadLocal thread_local_; | |
| 461 static void ThreadInit(); | 503 static void ThreadInit(); |
| 462 | 504 |
| 463 // Code to call for handling debug break on return. | |
| 464 static Code* debug_break_return_; | |
| 465 | |
| 466 DISALLOW_COPY_AND_ASSIGN(Debug); | 505 DISALLOW_COPY_AND_ASSIGN(Debug); |
| 467 }; | 506 }; |
| 468 | 507 |
| 469 | 508 |
| 470 // Message delivered to the message handler callback. This is either a debugger | 509 // Message delivered to the message handler callback. This is either a debugger |
| 471 // event or the response to a command. | 510 // event or the response to a command. |
| 472 class MessageImpl: public v8::Debug::Message { | 511 class MessageImpl: public v8::Debug::Message { |
| 473 public: | 512 public: |
| 474 // Create a message object for a debug event. | 513 // Create a message object for a debug event. |
| 475 static MessageImpl NewEvent(DebugEvent event, | 514 static MessageImpl NewEvent(DebugEvent event, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 bool IsEmpty() const; | 609 bool IsEmpty() const; |
| 571 CommandMessage Get(); | 610 CommandMessage Get(); |
| 572 void Put(const CommandMessage& message); | 611 void Put(const CommandMessage& message); |
| 573 void Clear(); | 612 void Clear(); |
| 574 private: | 613 private: |
| 575 CommandMessageQueue queue_; | 614 CommandMessageQueue queue_; |
| 576 Mutex* lock_; | 615 Mutex* lock_; |
| 577 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); | 616 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); |
| 578 }; | 617 }; |
| 579 | 618 |
| 619 class DebuggerData { |
| 620 Mutex* debugger_access_; // Mutex guarding debugger variables. |
| 621 Handle<Object> event_listener_; // Global handle to listener. |
| 622 Handle<Object> event_listener_data_; |
| 623 bool compiling_natives_; // Are we compiling natives? |
| 624 bool is_loading_debugger_; // Are we loading the debugger? |
| 625 bool never_unload_debugger_; // Can we unload the debugger? |
| 626 v8::Debug::MessageHandler2 message_handler_; |
| 627 bool debugger_unload_pending_; // Was message handler cleared? |
| 628 v8::Debug::HostDispatchHandler host_dispatch_handler_; |
| 629 v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_; |
| 630 int host_dispatch_micros_; |
| 631 |
| 632 DebuggerAgent* agent_; |
| 633 |
| 634 LockingCommandMessageQueue command_queue_; |
| 635 Semaphore* command_received_; // Signaled for each command received. |
| 636 static const int kQueueInitialSize = 4; |
| 637 |
| 638 friend class Debugger; |
| 639 friend class V8Context; |
| 640 DebuggerData(); |
| 641 DISALLOW_COPY_AND_ASSIGN(DebuggerData); |
| 642 }; |
| 580 | 643 |
| 581 class Debugger { | 644 class Debugger { |
| 582 public: | 645 public: |
| 583 static void DebugRequest(const uint16_t* json_request, int length); | 646 static void DebugRequest(const uint16_t* json_request, int length); |
| 584 | 647 |
| 585 static Handle<Object> MakeJSObject(Vector<const char> constructor_name, | 648 static Handle<Object> MakeJSObject(Vector<const char> constructor_name, |
| 586 int argc, Object*** argv, | 649 int argc, Object*** argv, |
| 587 bool* caught_exception); | 650 bool* caught_exception); |
| 588 static Handle<Object> MakeExecutionState(bool* caught_exception); | 651 static Handle<Object> MakeExecutionState(bool* caught_exception); |
| 589 static Handle<Object> MakeBreakEvent(Handle<Object> exec_state, | 652 static Handle<Object> MakeBreakEvent(Handle<Object> exec_state, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 static void StopAgent(); | 705 static void StopAgent(); |
| 643 | 706 |
| 644 // Blocks until the agent has started listening for connections | 707 // Blocks until the agent has started listening for connections |
| 645 static void WaitForAgent(); | 708 static void WaitForAgent(); |
| 646 | 709 |
| 647 // Unload the debugger if possible. Only called when no debugger is currently | 710 // Unload the debugger if possible. Only called when no debugger is currently |
| 648 // active. | 711 // active. |
| 649 static void UnloadDebugger(); | 712 static void UnloadDebugger(); |
| 650 | 713 |
| 651 inline static bool EventActive(v8::DebugEvent event) { | 714 inline static bool EventActive(v8::DebugEvent event) { |
| 652 ScopedLock with(debugger_access_); | 715 DebuggerData& data = v8_context()->debugger_data_; |
| 716 ScopedLock with(data.debugger_access_); |
| 653 | 717 |
| 654 // Check whether the message handler was been cleared. | 718 // Check whether the message handler was been cleared. |
| 655 if (debugger_unload_pending_) { | 719 if (data.debugger_unload_pending_) { |
| 656 UnloadDebugger(); | 720 UnloadDebugger(); |
| 657 } | 721 } |
| 658 | 722 |
| 659 // Currently argument event is not used. | 723 // Currently argument event is not used. |
| 660 return !compiling_natives_ && Debugger::IsDebuggerActive(); | 724 return !data.compiling_natives_ && Debugger::IsDebuggerActive(); |
| 661 } | 725 } |
| 662 | 726 |
| 663 static void set_compiling_natives(bool compiling_natives) { | 727 static void set_compiling_natives(bool compiling_natives) { |
| 664 Debugger::compiling_natives_ = compiling_natives; | 728 v8_context()->debugger_data_.compiling_natives_ = compiling_natives; |
| 665 } | 729 } |
| 666 static bool compiling_natives() { return Debugger::compiling_natives_; } | 730 static bool compiling_natives() { |
| 667 static void set_loading_debugger(bool v) { is_loading_debugger_ = v; } | 731 return v8_context()->debugger_data_.compiling_natives_; |
| 668 static bool is_loading_debugger() { return Debugger::is_loading_debugger_; } | 732 } |
| 733 static void set_loading_debugger(bool v) { |
| 734 v8_context()->debugger_data_.is_loading_debugger_ = v; |
| 735 } |
| 736 static bool is_loading_debugger() { |
| 737 return v8_context()->debugger_data_.is_loading_debugger_; |
| 738 } |
| 669 | 739 |
| 670 private: | 740 private: |
| 671 static bool IsDebuggerActive(); | 741 static bool IsDebuggerActive(); |
| 672 static void ListenersChanged(); | 742 static void ListenersChanged(); |
| 673 | 743 |
| 674 static Mutex* debugger_access_; // Mutex guarding debugger variables. | |
| 675 static Handle<Object> event_listener_; // Global handle to listener. | |
| 676 static Handle<Object> event_listener_data_; | |
| 677 static bool compiling_natives_; // Are we compiling natives? | |
| 678 static bool is_loading_debugger_; // Are we loading the debugger? | |
| 679 static bool never_unload_debugger_; // Can we unload the debugger? | |
| 680 static v8::Debug::MessageHandler2 message_handler_; | |
| 681 static bool debugger_unload_pending_; // Was message handler cleared? | |
| 682 static v8::Debug::HostDispatchHandler host_dispatch_handler_; | |
| 683 static v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_; | |
| 684 static int host_dispatch_micros_; | |
| 685 | |
| 686 static DebuggerAgent* agent_; | |
| 687 | |
| 688 static const int kQueueInitialSize = 4; | |
| 689 static LockingCommandMessageQueue command_queue_; | |
| 690 static Semaphore* command_received_; // Signaled for each command received. | |
| 691 | |
| 692 friend class EnterDebugger; | 744 friend class EnterDebugger; |
| 693 }; | 745 }; |
| 694 | 746 |
| 695 | 747 |
| 696 // This class is used for entering the debugger. Create an instance in the stack | 748 // This class is used for entering the debugger. Create an instance in the stack |
| 697 // to enter the debugger. This will set the current break state, make sure the | 749 // to enter the debugger. This will set the current break state, make sure the |
| 698 // debugger is loaded and switch to the debugger context. If the debugger for | 750 // debugger is loaded and switch to the debugger context. If the debugger for |
| 699 // some reason could not be entered FailedToEnter will return true. | 751 // some reason could not be entered FailedToEnter will return true. |
| 700 class EnterDebugger BASE_EMBEDDED { | 752 class EnterDebugger BASE_EMBEDDED { |
| 701 public: | 753 public: |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 Debug::AddressId id_; | 908 Debug::AddressId id_; |
| 857 int reg_; | 909 int reg_; |
| 858 }; | 910 }; |
| 859 | 911 |
| 860 | 912 |
| 861 } } // namespace v8::internal | 913 } } // namespace v8::internal |
| 862 | 914 |
| 863 #endif // ENABLE_DEBUGGER_SUPPORT | 915 #endif // ENABLE_DEBUGGER_SUPPORT |
| 864 | 916 |
| 865 #endif // V8_DEBUG_H_ | 917 #endif // V8_DEBUG_H_ |
| OLD | NEW |