Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include "v8.h"
     29 
     30 #include "api.h"
     31 #include "arguments.h"
     32 #include "bootstrapper.h"
     33 #include "code-stubs.h"
     34 #include "codegen.h"
     35 #include "compilation-cache.h"
     36 #include "compiler.h"
     37 #include "debug.h"
     38 #include "deoptimizer.h"
     39 #include "execution.h"
     40 #include "global-handles.h"
     41 #include "ic.h"
     42 #include "ic-inl.h"
     43 #include "messages.h"
     44 #include "natives.h"
     45 #include "stub-cache.h"
     46 #include "log.h"
     47 
     48 #include "../include/v8-debug.h"
     49 
     50 namespace v8 {
     51 namespace internal {
     52 
     53 #ifdef ENABLE_DEBUGGER_SUPPORT
     54 
     55 
     56 Debug::Debug(Isolate* isolate)
     57     : has_break_points_(false),
     58       script_cache_(NULL),
     59       debug_info_list_(NULL),
     60       disable_break_(false),
     61       break_on_exception_(false),
     62       break_on_uncaught_exception_(false),
     63       debug_break_return_(NULL),
     64       debug_break_slot_(NULL),
     65       isolate_(isolate) {
     66   memset(registers_, 0, sizeof(JSCallerSavedBuffer));
     67 }
     68 
     69 
     70 Debug::~Debug() {
     71 }
     72 
     73 
     74 static void PrintLn(v8::Local<v8::Value> value) {
     75   v8::Local<v8::String> s = value->ToString();
     76   ScopedVector<char> data(s->Length() + 1);
     77   if (data.start() == NULL) {
     78     V8::FatalProcessOutOfMemory("PrintLn");
     79     return;
     80   }
     81   s->WriteAscii(data.start());
     82   PrintF("%s\n", data.start());
     83 }
     84 
     85 
     86 static Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind) {
     87   Isolate* isolate = Isolate::Current();
     88   CALL_HEAP_FUNCTION(
     89       isolate,
     90       isolate->stub_cache()->ComputeCallDebugBreak(argc, kind),
     91       Code);
     92 }
     93 
     94 
     95 static Handle<Code> ComputeCallDebugPrepareStepIn(int argc,  Code::Kind kind) {
     96   Isolate* isolate = Isolate::Current();
     97   CALL_HEAP_FUNCTION(
     98       isolate,
     99       isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind),
    100       Code);
    101 }
    102 
    103 
    104 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
    105   Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
    106   // Isolate::context() may have been NULL when "script collected" event
    107   // occured.
    108   if (context.is_null()) return v8::Local<v8::Context>();
    109   Handle<Context> global_context(context->global_context());
    110   return v8::Utils::ToLocal(global_context);
    111 }
    112 
    113 
    114 BreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info,
    115                                              BreakLocatorType type) {
    116   debug_info_ = debug_info;
    117   type_ = type;
    118   reloc_iterator_ = NULL;
    119   reloc_iterator_original_ = NULL;
    120   Reset();  // Initialize the rest of the member variables.
    121 }
    122 
    123 
    124 BreakLocationIterator::~BreakLocationIterator() {
    125   ASSERT(reloc_iterator_ != NULL);
    126   ASSERT(reloc_iterator_original_ != NULL);
    127   delete reloc_iterator_;
    128   delete reloc_iterator_original_;
    129 }
    130 
    131 
    132 void BreakLocationIterator::Next() {
    133   AssertNoAllocation nogc;
    134   ASSERT(!RinfoDone());
    135 
    136   // Iterate through reloc info for code and original code stopping at each
    137   // breakable code target.
    138   bool first = break_point_ == -1;
    139   while (!RinfoDone()) {
    140     if (!first) RinfoNext();
    141     first = false;
    142     if (RinfoDone()) return;
    143 
    144     // Whenever a statement position or (plain) position is passed update the
    145     // current value of these.
    146     if (RelocInfo::IsPosition(rmode())) {
    147       if (RelocInfo::IsStatementPosition(rmode())) {
    148         statement_position_ = static_cast<int>(
    149             rinfo()->data() - debug_info_->shared()->start_position());
    150       }
    151       // Always update the position as we don't want that to be before the
    152       // statement position.
    153       position_ = static_cast<int>(
    154           rinfo()->data() - debug_info_->shared()->start_position());
    155       ASSERT(position_ >= 0);
    156       ASSERT(statement_position_ >= 0);
    157     }
    158 
    159     if (IsDebugBreakSlot()) {
    160       // There is always a possible break point at a debug break slot.
    161       break_point_++;
    162       return;
    163     } else if (RelocInfo::IsCodeTarget(rmode())) {
    164       // Check for breakable code target. Look in the original code as setting
    165       // break points can cause the code targets in the running (debugged) code
    166       // to be of a different kind than in the original code.
    167       Address target = original_rinfo()->target_address();
    168       Code* code = Code::GetCodeFromTargetAddress(target);
    169       if ((code->is_inline_cache_stub() &&
    170            !code->is_type_recording_binary_op_stub() &&
    171            !code->is_compare_ic_stub()) ||
    172           RelocInfo::IsConstructCall(rmode())) {
    173         break_point_++;
    174         return;
    175       }
    176       if (code->kind() == Code::STUB) {
    177         if (IsDebuggerStatement()) {
    178           break_point_++;
    179           return;
    180         }
    181         if (type_ == ALL_BREAK_LOCATIONS) {
    182           if (Debug::IsBreakStub(code)) {
    183             break_point_++;
    184             return;
    185           }
    186         } else {
    187           ASSERT(type_ == SOURCE_BREAK_LOCATIONS);
    188           if (Debug::IsSourceBreakStub(code)) {
    189             break_point_++;
    190             return;
    191           }
    192         }
    193       }
    194     }
    195 
    196     // Check for break at return.
    197     if (RelocInfo::IsJSReturn(rmode())) {
    198       // Set the positions to the end of the function.
    199       if (debug_info_->shared()->HasSourceCode()) {
    200         position_ = debug_info_->shared()->end_position() -
    201                     debug_info_->shared()->start_position() - 1;
    202       } else {
    203         position_ = 0;
    204       }
    205       statement_position_ = position_;
    206       break_point_++;
    207       return;
    208     }
    209   }
    210 }
    211 
    212 
    213 void BreakLocationIterator::Next(int count) {
    214   while (count > 0) {
    215     Next();
    216     count--;
    217   }
    218 }
    219 
    220 
    221 // Find the break point closest to the supplied address.
    222 void BreakLocationIterator::FindBreakLocationFromAddress(Address pc) {
    223   // Run through all break points to locate the one closest to the address.
    224   int closest_break_point = 0;
    225   int distance = kMaxInt;
    226   while (!Done()) {
    227     // Check if this break point is closer that what was previously found.
    228     if (this->pc() < pc && pc - this->pc() < distance) {
    229       closest_break_point = break_point();
    230       distance = static_cast<int>(pc - this->pc());
    231       // Check whether we can't get any closer.
    232       if (distance == 0) break;
    233     }
    234     Next();
    235   }
    236 
    237   // Move to the break point found.
    238   Reset();
    239   Next(closest_break_point);
    240 }
    241 
    242 
    243 // Find the break point closest to the supplied source position.
    244 void BreakLocationIterator::FindBreakLocationFromPosition(int position) {
    245   // Run through all break points to locate the one closest to the source
    246   // position.
    247   int closest_break_point = 0;
    248   int distance = kMaxInt;
    249   while (!Done()) {
    250     // Check if this break point is closer that what was previously found.
    251     if (position <= statement_position() &&
    252         statement_position() - position < distance) {
    253       closest_break_point = break_point();
    254       distance = statement_position() - position;
    255       // Check whether we can't get any closer.
    256       if (distance == 0) break;
    257     }
    258     Next();
    259   }
    260 
    261   // Move to the break point found.
    262   Reset();
    263   Next(closest_break_point);
    264 }
    265 
    266 
    267 void BreakLocationIterator::Reset() {
    268   // Create relocation iterators for the two code objects.
    269   if (reloc_iterator_ != NULL) delete reloc_iterator_;
    270   if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_;
    271   reloc_iterator_ = new RelocIterator(debug_info_->code());
    272   reloc_iterator_original_ = new RelocIterator(debug_info_->original_code());
    273 
    274   // Position at the first break point.
    275   break_point_ = -1;
    276   position_ = 1;
    277   statement_position_ = 1;
    278   Next();
    279 }
    280 
    281 
    282 bool BreakLocationIterator::Done() const {
    283   return RinfoDone();
    284 }
    285 
    286 
    287 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
    288   // If there is not already a real break point here patch code with debug
    289   // break.
    290   if (!HasBreakPoint()) {
    291     SetDebugBreak();
    292   }
    293   ASSERT(IsDebugBreak() || IsDebuggerStatement());
    294   // Set the break point information.
    295   DebugInfo::SetBreakPoint(debug_info_, code_position(),
    296                            position(), statement_position(),
    297                            break_point_object);
    298 }
    299 
    300 
    301 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
    302   // Clear the break point information.
    303   DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
    304   // If there are no more break points here remove the debug break.
    305   if (!HasBreakPoint()) {
    306     ClearDebugBreak();
    307     ASSERT(!IsDebugBreak());
    308   }
    309 }
    310 
    311 
    312 void BreakLocationIterator::SetOneShot() {
    313   // Debugger statement always calls debugger. No need to modify it.
    314   if (IsDebuggerStatement()) {
    315     return;
    316   }
    317 
    318   // If there is a real break point here no more to do.
    319   if (HasBreakPoint()) {
    320     ASSERT(IsDebugBreak());
    321     return;
    322   }
    323 
    324   // Patch code with debug break.
    325   SetDebugBreak();
    326 }
    327 
    328 
    329 void BreakLocationIterator::ClearOneShot() {
    330   // Debugger statement always calls debugger. No need to modify it.
    331   if (IsDebuggerStatement()) {
    332     return;
    333   }
    334 
    335   // If there is a real break point here no more to do.
    336   if (HasBreakPoint()) {
    337     ASSERT(IsDebugBreak());
    338     return;
    339   }
    340 
    341   // Patch code removing debug break.
    342   ClearDebugBreak();
    343   ASSERT(!IsDebugBreak());
    344 }
    345 
    346 
    347 void BreakLocationIterator::SetDebugBreak() {
    348   // Debugger statement always calls debugger. No need to modify it.
    349   if (IsDebuggerStatement()) {
    350     return;
    351   }
    352 
    353   // If there is already a break point here just return. This might happen if
    354   // the same code is flooded with break points twice. Flooding the same
    355   // function twice might happen when stepping in a function with an exception
    356   // handler as the handler and the function is the same.
    357   if (IsDebugBreak()) {
    358     return;
    359   }
    360 
    361   if (RelocInfo::IsJSReturn(rmode())) {
    362     // Patch the frame exit code with a break point.
    363     SetDebugBreakAtReturn();
    364   } else if (IsDebugBreakSlot()) {
    365     // Patch the code in the break slot.
    366     SetDebugBreakAtSlot();
    367   } else {
    368     // Patch the IC call.
    369     SetDebugBreakAtIC();
    370   }
    371   ASSERT(IsDebugBreak());
    372 }
    373 
    374 
    375 void BreakLocationIterator::ClearDebugBreak() {
    376   // Debugger statement always calls debugger. No need to modify it.
    377   if (IsDebuggerStatement()) {
    378     return;
    379   }
    380 
    381   if (RelocInfo::IsJSReturn(rmode())) {
    382     // Restore the frame exit code.
    383     ClearDebugBreakAtReturn();
    384   } else if (IsDebugBreakSlot()) {
    385     // Restore the code in the break slot.
    386     ClearDebugBreakAtSlot();
    387   } else {
    388     // Patch the IC call.
    389     ClearDebugBreakAtIC();
    390   }
    391   ASSERT(!IsDebugBreak());
    392 }
    393 
    394 
    395 void BreakLocationIterator::PrepareStepIn() {
    396   HandleScope scope;
    397 
    398   // Step in can only be prepared if currently positioned on an IC call,
    399   // construct call or CallFunction stub call.
    400   Address target = rinfo()->target_address();
    401   Handle<Code> code(Code::GetCodeFromTargetAddress(target));
    402   if (code->is_call_stub() || code->is_keyed_call_stub()) {
    403     // Step in through IC call is handled by the runtime system. Therefore make
    404     // sure that the any current IC is cleared and the runtime system is
    405     // called. If the executing code has a debug break at the location change
    406     // the call in the original code as it is the code there that will be
    407     // executed in place of the debug break call.
    408     Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count(),
    409                                                       code->kind());
    410     if (IsDebugBreak()) {
    411       original_rinfo()->set_target_address(stub->entry());
    412     } else {
    413       rinfo()->set_target_address(stub->entry());
    414     }
    415   } else {
    416 #ifdef DEBUG
    417     // All the following stuff is needed only for assertion checks so the code
    418     // is wrapped in ifdef.
    419     Handle<Code> maybe_call_function_stub = code;
    420     if (IsDebugBreak()) {
    421       Address original_target = original_rinfo()->target_address();
    422       maybe_call_function_stub =
    423           Handle<Code>(Code::GetCodeFromTargetAddress(original_target));
    424     }
    425     bool is_call_function_stub =
    426         (maybe_call_function_stub->kind() == Code::STUB &&
    427          maybe_call_function_stub->major_key() == CodeStub::CallFunction);
    428 
    429     // Step in through construct call requires no changes to the running code.
    430     // Step in through getters/setters should already be prepared as well
    431     // because caller of this function (Debug::PrepareStep) is expected to
    432     // flood the top frame's function with one shot breakpoints.
    433     // Step in through CallFunction stub should also be prepared by caller of
    434     // this function (Debug::PrepareStep) which should flood target function
    435     // with breakpoints.
    436     ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub()
    437            || is_call_function_stub);
    438 #endif
    439   }
    440 }
    441 
    442 
    443 // Check whether the break point is at a position which will exit the function.
    444 bool BreakLocationIterator::IsExit() const {
    445   return (RelocInfo::IsJSReturn(rmode()));
    446 }
    447 
    448 
    449 bool BreakLocationIterator::HasBreakPoint() {
    450   return debug_info_->HasBreakPoint(code_position());
    451 }
    452 
    453 
    454 // Check whether there is a debug break at the current position.
    455 bool BreakLocationIterator::IsDebugBreak() {
    456   if (RelocInfo::IsJSReturn(rmode())) {
    457     return IsDebugBreakAtReturn();
    458   } else if (IsDebugBreakSlot()) {
    459     return IsDebugBreakAtSlot();
    460   } else {
    461     return Debug::IsDebugBreak(rinfo()->target_address());
    462   }
    463 }
    464 
    465 
    466 void BreakLocationIterator::SetDebugBreakAtIC() {
    467   // Patch the original code with the current address as the current address
    468   // might have changed by the inline caching since the code was copied.
    469   original_rinfo()->set_target_address(rinfo()->target_address());
    470 
    471   RelocInfo::Mode mode = rmode();
    472   if (RelocInfo::IsCodeTarget(mode)) {
    473     Address target = rinfo()->target_address();
    474     Handle<Code> code(Code::GetCodeFromTargetAddress(target));
    475 
    476     // Patch the code to invoke the builtin debug break function matching the
    477     // calling convention used by the call site.
    478     Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode));
    479     rinfo()->set_target_address(dbgbrk_code->entry());
    480 
    481     // For stubs that refer back to an inlined version clear the cached map for
    482     // the inlined case to always go through the IC. As long as the break point
    483     // is set the patching performed by the runtime system will take place in
    484     // the code copy and will therefore have no effect on the running code
    485     // keeping it from using the inlined code.
    486     if (code->is_keyed_load_stub()) {
    487       KeyedLoadIC::ClearInlinedVersion(pc());
    488     } else if (code->is_keyed_store_stub()) {
    489       KeyedStoreIC::ClearInlinedVersion(pc());
    490     } else if (code->is_load_stub()) {
    491       LoadIC::ClearInlinedVersion(pc());
    492     } else if (code->is_store_stub()) {
    493       StoreIC::ClearInlinedVersion(pc());
    494     }
    495   }
    496 }
    497 
    498 
    499 void BreakLocationIterator::ClearDebugBreakAtIC() {
    500   // Patch the code to the original invoke.
    501   rinfo()->set_target_address(original_rinfo()->target_address());
    502 
    503   RelocInfo::Mode mode = rmode();
    504   if (RelocInfo::IsCodeTarget(mode)) {
    505     AssertNoAllocation nogc;
    506     Address target = original_rinfo()->target_address();
    507     Code* code = Code::GetCodeFromTargetAddress(target);
    508 
    509     // Restore the inlined version of keyed stores to get back to the
    510     // fast case.  We need to patch back the keyed store because no
    511     // patching happens when running normally.  For keyed loads, the
    512     // map check will get patched back when running normally after ICs
    513     // have been cleared at GC.
    514     if (code->is_keyed_store_stub()) KeyedStoreIC::RestoreInlinedVersion(pc());
    515   }
    516 }
    517 
    518 
    519 bool BreakLocationIterator::IsDebuggerStatement() {
    520   return RelocInfo::DEBUG_BREAK == rmode();
    521 }
    522 
    523 
    524 bool BreakLocationIterator::IsDebugBreakSlot() {
    525   return RelocInfo::DEBUG_BREAK_SLOT == rmode();
    526 }
    527 
    528 
    529 Object* BreakLocationIterator::BreakPointObjects() {
    530   return debug_info_->GetBreakPointObjects(code_position());
    531 }
    532 
    533 
    534 // Clear out all the debug break code. This is ONLY supposed to be used when
    535 // shutting down the debugger as it will leave the break point information in
    536 // DebugInfo even though the code is patched back to the non break point state.
    537 void BreakLocationIterator::ClearAllDebugBreak() {
    538   while (!Done()) {
    539     ClearDebugBreak();
    540     Next();
    541   }
    542 }
    543 
    544 
    545 bool BreakLocationIterator::RinfoDone() const {
    546   ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
    547   return reloc_iterator_->done();
    548 }
    549 
    550 
    551 void BreakLocationIterator::RinfoNext() {
    552   reloc_iterator_->next();
    553   reloc_iterator_original_->next();
    554 #ifdef DEBUG
    555   ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
    556   if (!reloc_iterator_->done()) {
    557     ASSERT(rmode() == original_rmode());
    558   }
    559 #endif
    560 }
    561 
    562 
    563 // Threading support.
    564 void Debug::ThreadInit() {
    565   thread_local_.break_count_ = 0;
    566   thread_local_.break_id_ = 0;
    567   thread_local_.break_frame_id_ = StackFrame::NO_ID;
    568   thread_local_.last_step_action_ = StepNone;
    569   thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
    570   thread_local_.step_count_ = 0;
    571   thread_local_.last_fp_ = 0;
    572   thread_local_.step_into_fp_ = 0;
    573   thread_local_.step_out_fp_ = 0;
    574   thread_local_.after_break_target_ = 0;
    575   // TODO(isolates): frames_are_dropped_?
    576   thread_local_.debugger_entry_ = NULL;
    577   thread_local_.pending_interrupts_ = 0;
    578   thread_local_.restarter_frame_function_pointer_ = NULL;
    579 }
    580 
    581 
    582 char* Debug::ArchiveDebug(char* storage) {
    583   char* to = storage;
    584   memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
    585   to += sizeof(ThreadLocal);
    586   memcpy(to, reinterpret_cast<char*>(&registers_), sizeof(registers_));
    587   ThreadInit();
    588   ASSERT(to <= storage + ArchiveSpacePerThread());
    589   return storage + ArchiveSpacePerThread();
    590 }
    591 
    592 
    593 char* Debug::RestoreDebug(char* storage) {
    594   char* from = storage;
    595   memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
    596   from += sizeof(ThreadLocal);
    597   memcpy(reinterpret_cast<char*>(&registers_), from, sizeof(registers_));
    598   ASSERT(from <= storage + ArchiveSpacePerThread());
    599   return storage + ArchiveSpacePerThread();
    600 }
    601 
    602 
    603 int Debug::ArchiveSpacePerThread() {
    604   return sizeof(ThreadLocal) + sizeof(JSCallerSavedBuffer);
    605 }
    606 
    607 
    608 // Frame structure (conforms InternalFrame structure):
    609 //   -- code
    610 //   -- SMI maker
    611 //   -- function (slot is called "context")
    612 //   -- frame base
    613 Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
    614                                        Handle<Code> code) {
    615   ASSERT(bottom_js_frame->is_java_script());
    616 
    617   Address fp = bottom_js_frame->fp();
    618 
    619   // Move function pointer into "context" slot.
    620   Memory::Object_at(fp + StandardFrameConstants::kContextOffset) =
    621       Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset);
    622 
    623   Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code;
    624   Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) =
    625       Smi::FromInt(StackFrame::INTERNAL);
    626 
    627   return reinterpret_cast<Object**>(&Memory::Object_at(
    628       fp + StandardFrameConstants::kContextOffset));
    629 }
    630 
    631 const int Debug::kFrameDropperFrameSize = 4;
    632 
    633 
    634 void ScriptCache::Add(Handle<Script> script) {
    635   GlobalHandles* global_handles = Isolate::Current()->global_handles();
    636   // Create an entry in the hash map for the script.
    637   int id = Smi::cast(script->id())->value();
    638   HashMap::Entry* entry =
    639       HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
    640   if (entry->value != NULL) {
    641     ASSERT(*script == *reinterpret_cast<Script**>(entry->value));
    642     return;
    643   }
    644 
    645   // Globalize the script object, make it weak and use the location of the
    646   // global handle as the value in the hash map.
    647   Handle<Script> script_ =
    648       Handle<Script>::cast(
    649           (global_handles->Create(*script)));
    650   global_handles->MakeWeak(
    651       reinterpret_cast<Object**>(script_.location()),
    652       this,
    653       ScriptCache::HandleWeakScript);
    654   entry->value = script_.location();
    655 }
    656 
    657 
    658 Handle<FixedArray> ScriptCache::GetScripts() {
    659   Handle<FixedArray> instances = FACTORY->NewFixedArray(occupancy());
    660   int count = 0;
    661   for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
    662     ASSERT(entry->value != NULL);
    663     if (entry->value != NULL) {
    664       instances->set(count, *reinterpret_cast<Script**>(entry->value));
    665       count++;
    666     }
    667   }
    668   return instances;
    669 }
    670 
    671 
    672 void ScriptCache::ProcessCollectedScripts() {
    673   Debugger* debugger = Isolate::Current()->debugger();
    674   for (int i = 0; i < collected_scripts_.length(); i++) {
    675     debugger->OnScriptCollected(collected_scripts_[i]);
    676   }
    677   collected_scripts_.Clear();
    678 }
    679 
    680 
    681 void ScriptCache::Clear() {
    682   GlobalHandles* global_handles = Isolate::Current()->global_handles();
    683   // Iterate the script cache to get rid of all the weak handles.
    684   for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
    685     ASSERT(entry != NULL);
    686     Object** location = reinterpret_cast<Object**>(entry->value);
    687     ASSERT((*location)->IsScript());
    688     global_handles->ClearWeakness(location);
    689     global_handles->Destroy(location);
    690   }
    691   // Clear the content of the hash map.
    692   HashMap::Clear();
    693 }
    694 
    695 
    696 void ScriptCache::HandleWeakScript(v8::Persistent<v8::Value> obj, void* data) {
    697   ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data);
    698   // Find the location of the global handle.
    699   Script** location =
    700       reinterpret_cast<Script**>(Utils::OpenHandle(*obj).location());
    701   ASSERT((*location)->IsScript());
    702 
    703   // Remove the entry from the cache.
    704   int id = Smi::cast((*location)->id())->value();
    705   script_cache->Remove(reinterpret_cast<void*>(id), Hash(id));
    706   script_cache->collected_scripts_.Add(id);
    707 
    708   // Clear the weak handle.
    709   obj.Dispose();
    710   obj.Clear();
    711 }
    712 
    713 
    714 void Debug::Setup(bool create_heap_objects) {
    715   ThreadInit();
    716   if (create_heap_objects) {
    717     // Get code to handle debug break on return.
    718     debug_break_return_ =
    719         isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak);
    720     ASSERT(debug_break_return_->IsCode());
    721     // Get code to handle debug break in debug break slots.
    722     debug_break_slot_ =
    723         isolate_->builtins()->builtin(Builtins::kSlot_DebugBreak);
    724     ASSERT(debug_break_slot_->IsCode());
    725   }
    726 }
    727 
    728 
    729 void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) {
    730   Debug* debug = Isolate::Current()->debug();
    731   DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data);
    732   // We need to clear all breakpoints associated with the function to restore
    733   // original code and avoid patching the code twice later because
    734   // the function will live in the heap until next gc, and can be found by
    735   // Runtime::FindSharedFunctionInfoInScript.
    736   BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
    737   it.ClearAllDebugBreak();
    738   debug->RemoveDebugInfo(node->debug_info());
    739 #ifdef DEBUG
    740   node = debug->debug_info_list_;
    741   while (node != NULL) {
    742     ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data));
    743     node = node->next();
    744   }
    745 #endif
    746 }
    747 
    748 
    749 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
    750   GlobalHandles* global_handles = Isolate::Current()->global_handles();
    751   // Globalize the request debug info object and make it weak.
    752   debug_info_ = Handle<DebugInfo>::cast(
    753       (global_handles->Create(debug_info)));
    754   global_handles->MakeWeak(
    755       reinterpret_cast<Object**>(debug_info_.location()),
    756       this,
    757       Debug::HandleWeakDebugInfo);
    758 }
    759 
    760 
    761 DebugInfoListNode::~DebugInfoListNode() {
    762   Isolate::Current()->global_handles()->Destroy(
    763       reinterpret_cast<Object**>(debug_info_.location()));
    764 }
    765 
    766 
    767 bool Debug::CompileDebuggerScript(int index) {
    768   Isolate* isolate = Isolate::Current();
    769   Factory* factory = isolate->factory();
    770   HandleScope scope(isolate);
    771 
    772   // Bail out if the index is invalid.
    773   if (index == -1) {
    774     return false;
    775   }
    776 
    777   // Find source and name for the requested script.
    778   Handle<String> source_code =
    779       isolate->bootstrapper()->NativesSourceLookup(index);
    780   Vector<const char> name = Natives::GetScriptName(index);
    781   Handle<String> script_name = factory->NewStringFromAscii(name);
    782 
    783   // Compile the script.
    784   Handle<SharedFunctionInfo> function_info;
    785   function_info = Compiler::Compile(source_code,
    786                                     script_name,
    787                                     0, 0, NULL, NULL,
    788                                     Handle<String>::null(),
    789                                     NATIVES_CODE);
    790 
    791   // Silently ignore stack overflows during compilation.
    792   if (function_info.is_null()) {
    793     ASSERT(isolate->has_pending_exception());
    794     isolate->clear_pending_exception();
    795     return false;
    796   }
    797 
    798   // Execute the shared function in the debugger context.
    799   Handle<Context> context = isolate->global_context();
    800   bool caught_exception = false;
    801   Handle<JSFunction> function =
    802       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
    803   Handle<Object> result =
    804       Execution::TryCall(function, Handle<Object>(context->global()),
    805                          0, NULL, &caught_exception);
    806 
    807   // Check for caught exceptions.
    808   if (caught_exception) {
    809     Handle<Object> message = MessageHandler::MakeMessageObject(
    810         "error_loading_debugger", NULL, Vector<Handle<Object> >::empty(),
    811         Handle<String>(), Handle<JSArray>());
    812     MessageHandler::ReportMessage(Isolate::Current(), NULL, message);
    813     return false;
    814   }
    815 
    816   // Mark this script as native and return successfully.
    817   Handle<Script> script(Script::cast(function->shared()->script()));
    818   script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
    819   return true;
    820 }
    821 
    822 
    823 bool Debug::Load() {
    824   // Return if debugger is already loaded.
    825   if (IsLoaded()) return true;
    826 
    827   ASSERT(Isolate::Current() == isolate_);
    828   Debugger* debugger = isolate_->debugger();
    829 
    830   // Bail out if we're already in the process of compiling the native
    831   // JavaScript source code for the debugger.
    832   if (debugger->compiling_natives() ||
    833       debugger->is_loading_debugger())
    834     return false;
    835   debugger->set_loading_debugger(true);
    836 
    837   // Disable breakpoints and interrupts while compiling and running the
    838   // debugger scripts including the context creation code.
    839   DisableBreak disable(true);
    840   PostponeInterruptsScope postpone(isolate_);
    841 
    842   // Create the debugger context.
    843   HandleScope scope(isolate_);
    844   Handle<Context> context =
    845       isolate_->bootstrapper()->CreateEnvironment(
    846           Handle<Object>::null(),
    847           v8::Handle<ObjectTemplate>(),
    848           NULL);
    849 
    850   // Use the debugger context.
    851   SaveContext save(isolate_);
    852   isolate_->set_context(*context);
    853 
    854   // Expose the builtins object in the debugger context.
    855   Handle<String> key = isolate_->factory()->LookupAsciiSymbol("builtins");
    856   Handle<GlobalObject> global = Handle<GlobalObject>(context->global());
    857   RETURN_IF_EMPTY_HANDLE_VALUE(
    858       isolate_,
    859       SetProperty(global, key, Handle<Object>(global->builtins()),
    860                   NONE, kNonStrictMode),
    861       false);
    862 
    863   // Compile the JavaScript for the debugger in the debugger context.
    864   debugger->set_compiling_natives(true);
    865   bool caught_exception =
    866       !CompileDebuggerScript(Natives::GetIndex("mirror")) ||
    867       !CompileDebuggerScript(Natives::GetIndex("debug"));
    868 
    869   if (FLAG_enable_liveedit) {
    870     caught_exception = caught_exception ||
    871         !CompileDebuggerScript(Natives::GetIndex("liveedit"));
    872   }
    873 
    874   debugger->set_compiling_natives(false);
    875 
    876   // Make sure we mark the debugger as not loading before we might
    877   // return.
    878   debugger->set_loading_debugger(false);
    879 
    880   // Check for caught exceptions.
    881   if (caught_exception) return false;
    882 
    883   // Debugger loaded.
    884   debug_context_ = context;
    885 
    886   return true;
    887 }
    888 
    889 
    890 void Debug::Unload() {
    891   // Return debugger is not loaded.
    892   if (!IsLoaded()) {
    893     return;
    894   }
    895 
    896   // Clear the script cache.
    897   DestroyScriptCache();
    898 
    899   // Clear debugger context global handle.
    900   Isolate::Current()->global_handles()->Destroy(
    901       reinterpret_cast<Object**>(debug_context_.location()));
    902   debug_context_ = Handle<Context>();
    903 }
    904 
    905 
    906 // Set the flag indicating that preemption happened during debugging.
    907 void Debug::PreemptionWhileInDebugger() {
    908   ASSERT(InDebugger());
    909   Debug::set_interrupts_pending(PREEMPT);
    910 }
    911 
    912 
    913 void Debug::Iterate(ObjectVisitor* v) {
    914   v->VisitPointer(BitCast<Object**>(&(debug_break_return_)));
    915   v->VisitPointer(BitCast<Object**>(&(debug_break_slot_)));
    916 }
    917 
    918 
    919 Object* Debug::Break(Arguments args) {
    920   Heap* heap = isolate_->heap();
    921   HandleScope scope(isolate_);
    922   ASSERT(args.length() == 0);
    923 
    924   thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED;
    925 
    926   // Get the top-most JavaScript frame.
    927   JavaScriptFrameIterator it(isolate_);
    928   JavaScriptFrame* frame = it.frame();
    929 
    930   // Just continue if breaks are disabled or debugger cannot be loaded.
    931   if (disable_break() || !Load()) {
    932     SetAfterBreakTarget(frame);
    933     return heap->undefined_value();
    934   }
    935 
    936   // Enter the debugger.
    937   EnterDebugger debugger;
    938   if (debugger.FailedToEnter()) {
    939     return heap->undefined_value();
    940   }
    941 
    942   // Postpone interrupt during breakpoint processing.
    943   PostponeInterruptsScope postpone(isolate_);
    944 
    945   // Get the debug info (create it if it does not exist).
    946   Handle<SharedFunctionInfo> shared =
    947       Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
    948   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
    949 
    950   // Find the break point where execution has stopped.
    951   BreakLocationIterator break_location_iterator(debug_info,
    952                                                 ALL_BREAK_LOCATIONS);
    953   break_location_iterator.FindBreakLocationFromAddress(frame->pc());
    954 
    955   // Check whether step next reached a new statement.
    956   if (!StepNextContinue(&break_location_iterator, frame)) {
    957     // Decrease steps left if performing multiple steps.
    958     if (thread_local_.step_count_ > 0) {
    959       thread_local_.step_count_--;
    960     }
    961   }
    962 
    963   // If there is one or more real break points check whether any of these are
    964   // triggered.
    965   Handle<Object> break_points_hit(heap->undefined_value());
    966   if (break_location_iterator.HasBreakPoint()) {
    967     Handle<Object> break_point_objects =
    968         Handle<Object>(break_location_iterator.BreakPointObjects());
    969     break_points_hit = CheckBreakPoints(break_point_objects);
    970   }
    971 
    972   // If step out is active skip everything until the frame where we need to step
    973   // out to is reached, unless real breakpoint is hit.
    974   if (StepOutActive() && frame->fp() != step_out_fp() &&
    975       break_points_hit->IsUndefined() ) {
    976       // Step count should always be 0 for StepOut.
    977       ASSERT(thread_local_.step_count_ == 0);
    978   } else if (!break_points_hit->IsUndefined() ||
    979              (thread_local_.last_step_action_ != StepNone &&
    980               thread_local_.step_count_ == 0)) {
    981     // Notify debugger if a real break point is triggered or if performing
    982     // single stepping with no more steps to perform. Otherwise do another step.
    983 
    984     // Clear all current stepping setup.
    985     ClearStepping();
    986 
    987     // Notify the debug event listeners.
    988     isolate_->debugger()->OnDebugBreak(break_points_hit, false);
    989   } else if (thread_local_.last_step_action_ != StepNone) {
    990     // Hold on to last step action as it is cleared by the call to
    991     // ClearStepping.
    992     StepAction step_action = thread_local_.last_step_action_;
    993     int step_count = thread_local_.step_count_;
    994 
    995     // Clear all current stepping setup.
    996     ClearStepping();
    997 
    998     // Set up for the remaining steps.
    999     PrepareStep(step_action, step_count);
   1000   }
   1001 
   1002   if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) {
   1003     SetAfterBreakTarget(frame);
   1004   } else if (thread_local_.frame_drop_mode_ ==
   1005       FRAME_DROPPED_IN_IC_CALL) {
   1006     // We must have been calling IC stub. Do not go there anymore.
   1007     Code* plain_return = isolate_->builtins()->builtin(
   1008         Builtins::kPlainReturn_LiveEdit);
   1009     thread_local_.after_break_target_ = plain_return->entry();
   1010   } else if (thread_local_.frame_drop_mode_ ==
   1011       FRAME_DROPPED_IN_DEBUG_SLOT_CALL) {
   1012     // Debug break slot stub does not return normally, instead it manually
   1013     // cleans the stack and jumps. We should patch the jump address.
   1014     Code* plain_return = isolate_->builtins()->builtin(
   1015         Builtins::kFrameDropper_LiveEdit);
   1016     thread_local_.after_break_target_ = plain_return->entry();
   1017   } else if (thread_local_.frame_drop_mode_ ==
   1018       FRAME_DROPPED_IN_DIRECT_CALL) {
   1019     // Nothing to do, after_break_target is not used here.
   1020   } else {
   1021     UNREACHABLE();
   1022   }
   1023 
   1024   return heap->undefined_value();
   1025 }
   1026 
   1027 
   1028 RUNTIME_FUNCTION(Object*, Debug_Break) {
   1029   return isolate->debug()->Break(args);
   1030 }
   1031 
   1032 
   1033 // Check the break point objects for whether one or more are actually
   1034 // triggered. This function returns a JSArray with the break point objects
   1035 // which is triggered.
   1036 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
   1037   Factory* factory = isolate_->factory();
   1038 
   1039   // Count the number of break points hit. If there are multiple break points
   1040   // they are in a FixedArray.
   1041   Handle<FixedArray> break_points_hit;
   1042   int break_points_hit_count = 0;
   1043   ASSERT(!break_point_objects->IsUndefined());
   1044   if (break_point_objects->IsFixedArray()) {
   1045     Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
   1046     break_points_hit = factory->NewFixedArray(array->length());
   1047     for (int i = 0; i < array->length(); i++) {
   1048       Handle<Object> o(array->get(i));
   1049       if (CheckBreakPoint(o)) {
   1050         break_points_hit->set(break_points_hit_count++, *o);
   1051       }
   1052     }
   1053   } else {
   1054     break_points_hit = factory->NewFixedArray(1);
   1055     if (CheckBreakPoint(break_point_objects)) {
   1056       break_points_hit->set(break_points_hit_count++, *break_point_objects);
   1057     }
   1058   }
   1059 
   1060   // Return undefined if no break points were triggered.
   1061   if (break_points_hit_count == 0) {
   1062     return factory->undefined_value();
   1063   }
   1064   // Return break points hit as a JSArray.
   1065   Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
   1066   result->set_length(Smi::FromInt(break_points_hit_count));
   1067   return result;
   1068 }
   1069 
   1070 
   1071 // Check whether a single break point object is triggered.
   1072 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
   1073   ASSERT(Isolate::Current() == isolate_);
   1074   Factory* factory = isolate_->factory();
   1075   HandleScope scope(isolate_);
   1076 
   1077   // Ignore check if break point object is not a JSObject.
   1078   if (!break_point_object->IsJSObject()) return true;
   1079 
   1080   // Get the function IsBreakPointTriggered (defined in debug-debugger.js).
   1081   Handle<String> is_break_point_triggered_symbol =
   1082       factory->LookupAsciiSymbol("IsBreakPointTriggered");
   1083   Handle<JSFunction> check_break_point =
   1084     Handle<JSFunction>(JSFunction::cast(
   1085         debug_context()->global()->GetPropertyNoExceptionThrown(
   1086             *is_break_point_triggered_symbol)));
   1087 
   1088   // Get the break id as an object.
   1089   Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
   1090 
   1091   // Call HandleBreakPointx.
   1092   bool caught_exception = false;
   1093   const int argc = 2;
   1094   Object** argv[argc] = {
   1095     break_id.location(),
   1096     reinterpret_cast<Object**>(break_point_object.location())
   1097   };
   1098   Handle<Object> result = Execution::TryCall(check_break_point,
   1099       isolate_->js_builtins_object(), argc, argv, &caught_exception);
   1100 
   1101   // If exception or non boolean result handle as not triggered
   1102   if (caught_exception || !result->IsBoolean()) {
   1103     return false;
   1104   }
   1105 
   1106   // Return whether the break point is triggered.
   1107   ASSERT(!result.is_null());
   1108   return (*result)->IsTrue();
   1109 }
   1110 
   1111 
   1112 // Check whether the function has debug information.
   1113 bool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) {
   1114   return !shared->debug_info()->IsUndefined();
   1115 }
   1116 
   1117 
   1118 // Return the debug info for this function. EnsureDebugInfo must be called
   1119 // prior to ensure the debug info has been generated for shared.
   1120 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) {
   1121   ASSERT(HasDebugInfo(shared));
   1122   return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info()));
   1123 }
   1124 
   1125 
   1126 void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared,
   1127                           Handle<Object> break_point_object,
   1128                           int* source_position) {
   1129   HandleScope scope(isolate_);
   1130 
   1131   if (!EnsureDebugInfo(shared)) {
   1132     // Return if retrieving debug info failed.
   1133     return;
   1134   }
   1135 
   1136   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
   1137   // Source positions starts with zero.
   1138   ASSERT(source_position >= 0);
   1139 
   1140   // Find the break point and change it.
   1141   BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
   1142   it.FindBreakLocationFromPosition(*source_position);
   1143   it.SetBreakPoint(break_point_object);
   1144 
   1145   *source_position = it.position();
   1146 
   1147   // At least one active break point now.
   1148   ASSERT(debug_info->GetBreakPointCount() > 0);
   1149 }
   1150 
   1151 
   1152 void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
   1153   HandleScope scope(isolate_);
   1154 
   1155   DebugInfoListNode* node = debug_info_list_;
   1156   while (node != NULL) {
   1157     Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),
   1158                                                    break_point_object);
   1159     if (!result->IsUndefined()) {
   1160       // Get information in the break point.
   1161       BreakPointInfo* break_point_info = BreakPointInfo::cast(result);
   1162       Handle<DebugInfo> debug_info = node->debug_info();
   1163       Handle<SharedFunctionInfo> shared(debug_info->shared());
   1164       int source_position =  break_point_info->statement_position()->value();
   1165 
   1166       // Source positions starts with zero.
   1167       ASSERT(source_position >= 0);
   1168 
   1169       // Find the break point and clear it.
   1170       BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
   1171       it.FindBreakLocationFromPosition(source_position);
   1172       it.ClearBreakPoint(break_point_object);
   1173 
   1174       // If there are no more break points left remove the debug info for this
   1175       // function.
   1176       if (debug_info->GetBreakPointCount() == 0) {
   1177         RemoveDebugInfo(debug_info);
   1178       }
   1179 
   1180       return;
   1181     }
   1182     node = node->next();
   1183   }
   1184 }
   1185 
   1186 
   1187 void Debug::ClearAllBreakPoints() {
   1188   DebugInfoListNode* node = debug_info_list_;
   1189   while (node != NULL) {
   1190     // Remove all debug break code.
   1191     BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
   1192     it.ClearAllDebugBreak();
   1193     node = node->next();
   1194   }
   1195 
   1196   // Remove all debug info.
   1197   while (debug_info_list_ != NULL) {
   1198     RemoveDebugInfo(debug_info_list_->debug_info());
   1199   }
   1200 }
   1201 
   1202 
   1203 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
   1204   // Make sure the function has setup the debug info.
   1205   if (!EnsureDebugInfo(shared)) {
   1206     // Return if we failed to retrieve the debug info.
   1207     return;
   1208   }
   1209 
   1210   // Flood the function with break points.
   1211   BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS);
   1212   while (!it.Done()) {
   1213     it.SetOneShot();
   1214     it.Next();
   1215   }
   1216 }
   1217 
   1218 
   1219 void Debug::FloodHandlerWithOneShot() {
   1220   // Iterate through the JavaScript stack looking for handlers.
   1221   StackFrame::Id id = break_frame_id();
   1222   if (id == StackFrame::NO_ID) {
   1223     // If there is no JavaScript stack don't do anything.
   1224     return;
   1225   }
   1226   for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
   1227     JavaScriptFrame* frame = it.frame();
   1228     if (frame->HasHandler()) {
   1229       Handle<SharedFunctionInfo> shared =
   1230           Handle<SharedFunctionInfo>(
   1231               JSFunction::cast(frame->function())->shared());
   1232       // Flood the function with the catch block with break points
   1233       FloodWithOneShot(shared);
   1234       return;
   1235     }
   1236   }
   1237 }
   1238 
   1239 
   1240 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
   1241   if (type == BreakUncaughtException) {
   1242     break_on_uncaught_exception_ = enable;
   1243   } else {
   1244     break_on_exception_ = enable;
   1245   }
   1246 }
   1247 
   1248 
   1249 bool Debug::IsBreakOnException(ExceptionBreakType type) {
   1250   if (type == BreakUncaughtException) {
   1251     return break_on_uncaught_exception_;
   1252   } else {
   1253     return break_on_exception_;
   1254   }
   1255 }
   1256 
   1257 
   1258 void Debug::PrepareStep(StepAction step_action, int step_count) {
   1259   ASSERT(Isolate::Current() == isolate_);
   1260   HandleScope scope(isolate_);
   1261   ASSERT(Debug::InDebugger());
   1262 
   1263   // Remember this step action and count.
   1264   thread_local_.last_step_action_ = step_action;
   1265   if (step_action == StepOut) {
   1266     // For step out target frame will be found on the stack so there is no need
   1267     // to set step counter for it. It's expected to always be 0 for StepOut.
   1268     thread_local_.step_count_ = 0;
   1269   } else {
   1270     thread_local_.step_count_ = step_count;
   1271   }
   1272 
   1273   // Get the frame where the execution has stopped and skip the debug frame if
   1274   // any. The debug frame will only be present if execution was stopped due to
   1275   // hitting a break point. In other situations (e.g. unhandled exception) the
   1276   // debug frame is not present.
   1277   StackFrame::Id id = break_frame_id();
   1278   if (id == StackFrame::NO_ID) {
   1279     // If there is no JavaScript stack don't do anything.
   1280     return;
   1281   }
   1282   JavaScriptFrameIterator frames_it(isolate_, id);
   1283   JavaScriptFrame* frame = frames_it.frame();
   1284 
   1285   // First of all ensure there is one-shot break points in the top handler
   1286   // if any.
   1287   FloodHandlerWithOneShot();
   1288 
   1289   // If the function on the top frame is unresolved perform step out. This will
   1290   // be the case when calling unknown functions and having the debugger stopped
   1291   // in an unhandled exception.
   1292   if (!frame->function()->IsJSFunction()) {
   1293     // Step out: Find the calling JavaScript frame and flood it with
   1294     // breakpoints.
   1295     frames_it.Advance();
   1296     // Fill the function to return to with one-shot break points.
   1297     JSFunction* function = JSFunction::cast(frames_it.frame()->function());
   1298     FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
   1299     return;
   1300   }
   1301 
   1302   // Get the debug info (create it if it does not exist).
   1303   Handle<SharedFunctionInfo> shared =
   1304       Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
   1305   if (!EnsureDebugInfo(shared)) {
   1306     // Return if ensuring debug info failed.
   1307     return;
   1308   }
   1309   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
   1310 
   1311   // Find the break location where execution has stopped.
   1312   BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS);
   1313   it.FindBreakLocationFromAddress(frame->pc());
   1314 
   1315   // Compute whether or not the target is a call target.
   1316   bool is_load_or_store = false;
   1317   bool is_inline_cache_stub = false;
   1318   bool is_at_restarted_function = false;
   1319   Handle<Code> call_function_stub;
   1320 
   1321   if (thread_local_.restarter_frame_function_pointer_ == NULL) {
   1322     if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
   1323       bool is_call_target = false;
   1324       Address target = it.rinfo()->target_address();
   1325       Code* code = Code::GetCodeFromTargetAddress(target);
   1326       if (code->is_call_stub() || code->is_keyed_call_stub()) {
   1327         is_call_target = true;
   1328       }
   1329       if (code->is_inline_cache_stub()) {
   1330         is_inline_cache_stub = true;
   1331         is_load_or_store = !is_call_target;
   1332       }
   1333 
   1334       // Check if target code is CallFunction stub.
   1335       Code* maybe_call_function_stub = code;
   1336       // If there is a breakpoint at this line look at the original code to
   1337       // check if it is a CallFunction stub.
   1338       if (it.IsDebugBreak()) {
   1339         Address original_target = it.original_rinfo()->target_address();
   1340         maybe_call_function_stub =
   1341             Code::GetCodeFromTargetAddress(original_target);
   1342       }
   1343       if (maybe_call_function_stub->kind() == Code::STUB &&
   1344           maybe_call_function_stub->major_key() == CodeStub::CallFunction) {
   1345         // Save reference to the code as we may need it to find out arguments
   1346         // count for 'step in' later.
   1347         call_function_stub = Handle<Code>(maybe_call_function_stub);
   1348       }
   1349     }
   1350   } else {
   1351     is_at_restarted_function = true;
   1352   }
   1353 
   1354   // If this is the last break code target step out is the only possibility.
   1355   if (it.IsExit() || step_action == StepOut) {
   1356     if (step_action == StepOut) {
   1357       // Skip step_count frames starting with the current one.
   1358       while (step_count-- > 0 && !frames_it.done()) {
   1359         frames_it.Advance();
   1360       }
   1361     } else {
   1362       ASSERT(it.IsExit());
   1363       frames_it.Advance();
   1364     }
   1365     // Skip builtin functions on the stack.
   1366     while (!frames_it.done() &&
   1367            JSFunction::cast(frames_it.frame()->function())->IsBuiltin()) {
   1368       frames_it.Advance();
   1369     }
   1370     // Step out: If there is a JavaScript caller frame, we need to
   1371     // flood it with breakpoints.
   1372     if (!frames_it.done()) {
   1373       // Fill the function to return to with one-shot break points.
   1374       JSFunction* function = JSFunction::cast(frames_it.frame()->function());
   1375       FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
   1376       // Set target frame pointer.
   1377       ActivateStepOut(frames_it.frame());
   1378     }
   1379   } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
   1380                !call_function_stub.is_null() || is_at_restarted_function)
   1381              || step_action == StepNext || step_action == StepMin) {
   1382     // Step next or step min.
   1383 
   1384     // Fill the current function with one-shot break points.
   1385     FloodWithOneShot(shared);
   1386 
   1387     // Remember source position and frame to handle step next.
   1388     thread_local_.last_statement_position_ =
   1389         debug_info->code()->SourceStatementPosition(frame->pc());
   1390     thread_local_.last_fp_ = frame->fp();
   1391   } else {
   1392     // If there's restarter frame on top of the stack, just get the pointer
   1393     // to function which is going to be restarted.
   1394     if (is_at_restarted_function) {
   1395       Handle<JSFunction> restarted_function(
   1396           JSFunction::cast(*thread_local_.restarter_frame_function_pointer_));
   1397       Handle<SharedFunctionInfo> restarted_shared(
   1398           restarted_function->shared());
   1399       FloodWithOneShot(restarted_shared);
   1400     } else if (!call_function_stub.is_null()) {
   1401       // If it's CallFunction stub ensure target function is compiled and flood
   1402       // it with one shot breakpoints.
   1403 
   1404       // Find out number of arguments from the stub minor key.
   1405       // Reverse lookup required as the minor key cannot be retrieved
   1406       // from the code object.
   1407       Handle<Object> obj(
   1408           isolate_->heap()->code_stubs()->SlowReverseLookup(
   1409               *call_function_stub));
   1410       ASSERT(!obj.is_null());
   1411       ASSERT(!(*obj)->IsUndefined());
   1412       ASSERT(obj->IsSmi());
   1413       // Get the STUB key and extract major and minor key.
   1414       uint32_t key = Smi::cast(*obj)->value();
   1415       // Argc in the stub is the number of arguments passed - not the
   1416       // expected arguments of the called function.
   1417       int call_function_arg_count =
   1418           CallFunctionStub::ExtractArgcFromMinorKey(
   1419               CodeStub::MinorKeyFromKey(key));
   1420       ASSERT(call_function_stub->major_key() ==
   1421              CodeStub::MajorKeyFromKey(key));
   1422 
   1423       // Find target function on the expression stack.
   1424       // Expression stack looks like this (top to bottom):
   1425       // argN
   1426       // ...
   1427       // arg0
   1428       // Receiver
   1429       // Function to call
   1430       int expressions_count = frame->ComputeExpressionsCount();
   1431       ASSERT(expressions_count - 2 - call_function_arg_count >= 0);
   1432       Object* fun = frame->GetExpression(
   1433           expressions_count - 2 - call_function_arg_count);
   1434       if (fun->IsJSFunction()) {
   1435         Handle<JSFunction> js_function(JSFunction::cast(fun));
   1436         // Don't step into builtins.
   1437         if (!js_function->IsBuiltin()) {
   1438           // It will also compile target function if it's not compiled yet.
   1439           FloodWithOneShot(Handle<SharedFunctionInfo>(js_function->shared()));
   1440         }
   1441       }
   1442     }
   1443 
   1444     // Fill the current function with one-shot break points even for step in on
   1445     // a call target as the function called might be a native function for
   1446     // which step in will not stop. It also prepares for stepping in
   1447     // getters/setters.
   1448     FloodWithOneShot(shared);
   1449 
   1450     if (is_load_or_store) {
   1451       // Remember source position and frame to handle step in getter/setter. If
   1452       // there is a custom getter/setter it will be handled in
   1453       // Object::Get/SetPropertyWithCallback, otherwise the step action will be
   1454       // propagated on the next Debug::Break.
   1455       thread_local_.last_statement_position_ =
   1456           debug_info->code()->SourceStatementPosition(frame->pc());
   1457       thread_local_.last_fp_ = frame->fp();
   1458     }
   1459 
   1460     // Step in or Step in min
   1461     it.PrepareStepIn();
   1462     ActivateStepIn(frame);
   1463   }
   1464 }
   1465 
   1466 
   1467 // Check whether the current debug break should be reported to the debugger. It
   1468 // is used to have step next and step in only report break back to the debugger
   1469 // if on a different frame or in a different statement. In some situations
   1470 // there will be several break points in the same statement when the code is
   1471 // flooded with one-shot break points. This function helps to perform several
   1472 // steps before reporting break back to the debugger.
   1473 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
   1474                              JavaScriptFrame* frame) {
   1475   // If the step last action was step next or step in make sure that a new
   1476   // statement is hit.
   1477   if (thread_local_.last_step_action_ == StepNext ||
   1478       thread_local_.last_step_action_ == StepIn) {
   1479     // Never continue if returning from function.
   1480     if (break_location_iterator->IsExit()) return false;
   1481 
   1482     // Continue if we are still on the same frame and in the same statement.
   1483     int current_statement_position =
   1484         break_location_iterator->code()->SourceStatementPosition(frame->pc());
   1485     return thread_local_.last_fp_ == frame->fp() &&
   1486         thread_local_.last_statement_position_ == current_statement_position;
   1487   }
   1488 
   1489   // No step next action - don't continue.
   1490   return false;
   1491 }
   1492 
   1493 
   1494 // Check whether the code object at the specified address is a debug break code
   1495 // object.
   1496 bool Debug::IsDebugBreak(Address addr) {
   1497   Code* code = Code::GetCodeFromTargetAddress(addr);
   1498   return code->ic_state() == DEBUG_BREAK;
   1499 }
   1500 
   1501 
   1502 // Check whether a code stub with the specified major key is a possible break
   1503 // point location when looking for source break locations.
   1504 bool Debug::IsSourceBreakStub(Code* code) {
   1505   CodeStub::Major major_key = CodeStub::GetMajorKey(code);
   1506   return major_key == CodeStub::CallFunction;
   1507 }
   1508 
   1509 
   1510 // Check whether a code stub with the specified major key is a possible break
   1511 // location.
   1512 bool Debug::IsBreakStub(Code* code) {
   1513   CodeStub::Major major_key = CodeStub::GetMajorKey(code);
   1514   return major_key == CodeStub::CallFunction;
   1515 }
   1516 
   1517 
   1518 // Find the builtin to use for invoking the debug break
   1519 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
   1520   // Find the builtin debug break function matching the calling convention
   1521   // used by the call site.
   1522   if (code->is_inline_cache_stub()) {
   1523     switch (code->kind()) {
   1524       case Code::CALL_IC:
   1525       case Code::KEYED_CALL_IC:
   1526         return ComputeCallDebugBreak(code->arguments_count(), code->kind());
   1527 
   1528       case Code::LOAD_IC:
   1529         return Isolate::Current()->builtins()->LoadIC_DebugBreak();
   1530 
   1531       case Code::STORE_IC:
   1532         return Isolate::Current()->builtins()->StoreIC_DebugBreak();
   1533 
   1534       case Code::KEYED_LOAD_IC:
   1535         return Isolate::Current()->builtins()->KeyedLoadIC_DebugBreak();
   1536 
   1537       case Code::KEYED_STORE_IC:
   1538         return Isolate::Current()->builtins()->KeyedStoreIC_DebugBreak();
   1539 
   1540       default:
   1541         UNREACHABLE();
   1542     }
   1543   }
   1544   if (RelocInfo::IsConstructCall(mode)) {
   1545     Handle<Code> result =
   1546         Isolate::Current()->builtins()->ConstructCall_DebugBreak();
   1547     return result;
   1548   }
   1549   if (code->kind() == Code::STUB) {
   1550     ASSERT(code->major_key() == CodeStub::CallFunction);
   1551     Handle<Code> result =
   1552         Isolate::Current()->builtins()->StubNoRegisters_DebugBreak();
   1553     return result;
   1554   }
   1555 
   1556   UNREACHABLE();
   1557   return Handle<Code>::null();
   1558 }
   1559 
   1560 
   1561 // Simple function for returning the source positions for active break points.
   1562 Handle<Object> Debug::GetSourceBreakLocations(
   1563     Handle<SharedFunctionInfo> shared) {
   1564   Isolate* isolate = Isolate::Current();
   1565   Heap* heap = isolate->heap();
   1566   if (!HasDebugInfo(shared)) return Handle<Object>(heap->undefined_value());
   1567   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
   1568   if (debug_info->GetBreakPointCount() == 0) {
   1569     return Handle<Object>(heap->undefined_value());
   1570   }
   1571   Handle<FixedArray> locations =
   1572       isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
   1573   int count = 0;
   1574   for (int i = 0; i < debug_info->break_points()->length(); i++) {
   1575     if (!debug_info->break_points()->get(i)->IsUndefined()) {
   1576       BreakPointInfo* break_point_info =
   1577           BreakPointInfo::cast(debug_info->break_points()->get(i));
   1578       if (break_point_info->GetBreakPointCount() > 0) {
   1579         locations->set(count++, break_point_info->statement_position());
   1580       }
   1581     }
   1582   }
   1583   return locations;
   1584 }
   1585 
   1586 
   1587 void Debug::NewBreak(StackFrame::Id break_frame_id) {
   1588   thread_local_.break_frame_id_ = break_frame_id;
   1589   thread_local_.break_id_ = ++thread_local_.break_count_;
   1590 }
   1591 
   1592 
   1593 void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) {
   1594   thread_local_.break_frame_id_ = break_frame_id;
   1595   thread_local_.break_id_ = break_id;
   1596 }
   1597 
   1598 
   1599 // Handle stepping into a function.
   1600 void Debug::HandleStepIn(Handle<JSFunction> function,
   1601                          Handle<Object> holder,
   1602                          Address fp,
   1603                          bool is_constructor) {
   1604   // If the frame pointer is not supplied by the caller find it.
   1605   if (fp == 0) {
   1606     StackFrameIterator it;
   1607     it.Advance();
   1608     // For constructor functions skip another frame.
   1609     if (is_constructor) {
   1610       ASSERT(it.frame()->is_construct());
   1611       it.Advance();
   1612     }
   1613     fp = it.frame()->fp();
   1614   }
   1615 
   1616   // Flood the function with one-shot break points if it is called from where
   1617   // step into was requested.
   1618   if (fp == step_in_fp()) {
   1619     // Don't allow step into functions in the native context.
   1620     if (!function->IsBuiltin()) {
   1621       if (function->shared()->code() ==
   1622           Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) ||
   1623           function->shared()->code() ==
   1624           Isolate::Current()->builtins()->builtin(Builtins::kFunctionCall)) {
   1625         // Handle function.apply and function.call separately to flood the
   1626         // function to be called and not the code for Builtins::FunctionApply or
   1627         // Builtins::FunctionCall. The receiver of call/apply is the target
   1628         // function.
   1629         if (!holder.is_null() && holder->IsJSFunction() &&
   1630             !JSFunction::cast(*holder)->IsBuiltin()) {
   1631           Handle<SharedFunctionInfo> shared_info(
   1632               JSFunction::cast(*holder)->shared());
   1633           Debug::FloodWithOneShot(shared_info);
   1634         }
   1635       } else {
   1636         Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
   1637       }
   1638     }
   1639   }
   1640 }
   1641 
   1642 
   1643 void Debug::ClearStepping() {
   1644   // Clear the various stepping setup.
   1645   ClearOneShot();
   1646   ClearStepIn();
   1647   ClearStepOut();
   1648   ClearStepNext();
   1649 
   1650   // Clear multiple step counter.
   1651   thread_local_.step_count_ = 0;
   1652 }
   1653 
   1654 // Clears all the one-shot break points that are currently set. Normally this
   1655 // function is called each time a break point is hit as one shot break points
   1656 // are used to support stepping.
   1657 void Debug::ClearOneShot() {
   1658   // The current implementation just runs through all the breakpoints. When the
   1659   // last break point for a function is removed that function is automatically
   1660   // removed from the list.
   1661 
   1662   DebugInfoListNode* node = debug_info_list_;
   1663   while (node != NULL) {
   1664     BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
   1665     while (!it.Done()) {
   1666       it.ClearOneShot();
   1667       it.Next();
   1668     }
   1669     node = node->next();
   1670   }
   1671 }
   1672 
   1673 
   1674 void Debug::ActivateStepIn(StackFrame* frame) {
   1675   ASSERT(!StepOutActive());
   1676   thread_local_.step_into_fp_ = frame->fp();
   1677 }
   1678 
   1679 
   1680 void Debug::ClearStepIn() {
   1681   thread_local_.step_into_fp_ = 0;
   1682 }
   1683 
   1684 
   1685 void Debug::ActivateStepOut(StackFrame* frame) {
   1686   ASSERT(!StepInActive());
   1687   thread_local_.step_out_fp_ = frame->fp();
   1688 }
   1689 
   1690 
   1691 void Debug::ClearStepOut() {
   1692   thread_local_.step_out_fp_ = 0;
   1693 }
   1694 
   1695 
   1696 void Debug::ClearStepNext() {
   1697   thread_local_.last_step_action_ = StepNone;
   1698   thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
   1699   thread_local_.last_fp_ = 0;
   1700 }
   1701 
   1702 
   1703 // Ensures the debug information is present for shared.
   1704 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
   1705   // Return if we already have the debug info for shared.
   1706   if (HasDebugInfo(shared)) return true;
   1707 
   1708   // Ensure shared in compiled. Return false if this failed.
   1709   if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
   1710 
   1711   // If preparing for the first break point make sure to deoptimize all
   1712   // functions as debugging does not work with optimized code.
   1713   if (!has_break_points_) {
   1714     Deoptimizer::DeoptimizeAll();
   1715   }
   1716 
   1717   // Create the debug info object.
   1718   Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared);
   1719 
   1720   // Add debug info to the list.
   1721   DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
   1722   node->set_next(debug_info_list_);
   1723   debug_info_list_ = node;
   1724 
   1725   // Now there is at least one break point.
   1726   has_break_points_ = true;
   1727 
   1728   return true;
   1729 }
   1730 
   1731 
   1732 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
   1733   ASSERT(debug_info_list_ != NULL);
   1734   // Run through the debug info objects to find this one and remove it.
   1735   DebugInfoListNode* prev = NULL;
   1736   DebugInfoListNode* current = debug_info_list_;
   1737   while (current != NULL) {
   1738     if (*current->debug_info() == *debug_info) {
   1739       // Unlink from list. If prev is NULL we are looking at the first element.
   1740       if (prev == NULL) {
   1741         debug_info_list_ = current->next();
   1742       } else {
   1743         prev->set_next(current->next());
   1744       }
   1745       current->debug_info()->shared()->set_debug_info(
   1746               isolate_->heap()->undefined_value());
   1747       delete current;
   1748 
   1749       // If there are no more debug info objects there are not more break
   1750       // points.
   1751       has_break_points_ = debug_info_list_ != NULL;
   1752 
   1753       return;
   1754     }
   1755     // Move to next in list.
   1756     prev = current;
   1757     current = current->next();
   1758   }
   1759   UNREACHABLE();
   1760 }
   1761 
   1762 
   1763 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
   1764   ASSERT(Isolate::Current() == isolate_);
   1765   HandleScope scope(isolate_);
   1766 
   1767   // Get the executing function in which the debug break occurred.
   1768   Handle<SharedFunctionInfo> shared =
   1769       Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
   1770   if (!EnsureDebugInfo(shared)) {
   1771     // Return if we failed to retrieve the debug info.
   1772     return;
   1773   }
   1774   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
   1775   Handle<Code> code(debug_info->code());
   1776   Handle<Code> original_code(debug_info->original_code());
   1777 #ifdef DEBUG
   1778   // Get the code which is actually executing.
   1779   Handle<Code> frame_code(frame->LookupCode());
   1780   ASSERT(frame_code.is_identical_to(code));
   1781 #endif
   1782 
   1783   // Find the call address in the running code. This address holds the call to
   1784   // either a DebugBreakXXX or to the debug break return entry code if the
   1785   // break point is still active after processing the break point.
   1786   Address addr = frame->pc() - Assembler::kCallTargetAddressOffset;
   1787 
   1788   // Check if the location is at JS exit or debug break slot.
   1789   bool at_js_return = false;
   1790   bool break_at_js_return_active = false;
   1791   bool at_debug_break_slot = false;
   1792   RelocIterator it(debug_info->code());
   1793   while (!it.done() && !at_js_return && !at_debug_break_slot) {
   1794     if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
   1795       at_js_return = (it.rinfo()->pc() ==
   1796           addr - Assembler::kPatchReturnSequenceAddressOffset);
   1797       break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence();
   1798     }
   1799     if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) {
   1800       at_debug_break_slot = (it.rinfo()->pc() ==
   1801           addr - Assembler::kPatchDebugBreakSlotAddressOffset);
   1802     }
   1803     it.next();
   1804   }
   1805 
   1806   // Handle the jump to continue execution after break point depending on the
   1807   // break location.
   1808   if (at_js_return) {
   1809     // If the break point as return is still active jump to the corresponding
   1810     // place in the original code. If not the break point was removed during
   1811     // break point processing.
   1812     if (break_at_js_return_active) {
   1813       addr +=  original_code->instruction_start() - code->instruction_start();
   1814     }
   1815 
   1816     // Move back to where the call instruction sequence started.
   1817     thread_local_.after_break_target_ =
   1818         addr - Assembler::kPatchReturnSequenceAddressOffset;
   1819   } else if (at_debug_break_slot) {
   1820     // Address of where the debug break slot starts.
   1821     addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset;
   1822 
   1823     // Continue just after the slot.
   1824     thread_local_.after_break_target_ = addr + Assembler::kDebugBreakSlotLength;
   1825   } else if (IsDebugBreak(Assembler::target_address_at(addr))) {
   1826     // We now know that there is still a debug break call at the target address,
   1827     // so the break point is still there and the original code will hold the
   1828     // address to jump to in order to complete the call which is replaced by a
   1829     // call to DebugBreakXXX.
   1830 
   1831     // Find the corresponding address in the original code.
   1832     addr += original_code->instruction_start() - code->instruction_start();
   1833 
   1834     // Install jump to the call address in the original code. This will be the
   1835     // call which was overwritten by the call to DebugBreakXXX.
   1836     thread_local_.after_break_target_ = Assembler::target_address_at(addr);
   1837   } else {
   1838     // There is no longer a break point present. Don't try to look in the
   1839     // original code as the running code will have the right address. This takes
   1840     // care of the case where the last break point is removed from the function
   1841     // and therefore no "original code" is available.
   1842     thread_local_.after_break_target_ = Assembler::target_address_at(addr);
   1843   }
   1844 }
   1845 
   1846 
   1847 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
   1848   HandleScope scope(isolate_);
   1849 
   1850   // Get the executing function in which the debug break occurred.
   1851   Handle<SharedFunctionInfo> shared =
   1852       Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
   1853   if (!EnsureDebugInfo(shared)) {
   1854     // Return if we failed to retrieve the debug info.
   1855     return false;
   1856   }
   1857   Handle<DebugInfo> debug_info = GetDebugInfo(shared);
   1858   Handle<Code> code(debug_info->code());
   1859 #ifdef DEBUG
   1860   // Get the code which is actually executing.
   1861   Handle<Code> frame_code(frame->LookupCode());
   1862   ASSERT(frame_code.is_identical_to(code));
   1863 #endif
   1864 
   1865   // Find the call address in the running code.
   1866   Address addr = frame->pc() - Assembler::kCallTargetAddressOffset;
   1867 
   1868   // Check if the location is at JS return.
   1869   RelocIterator it(debug_info->code());
   1870   while (!it.done()) {
   1871     if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
   1872       return (it.rinfo()->pc() ==
   1873           addr - Assembler::kPatchReturnSequenceAddressOffset);
   1874     }
   1875     it.next();
   1876   }
   1877   return false;
   1878 }
   1879 
   1880 
   1881 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
   1882                                   FrameDropMode mode,
   1883                                   Object** restarter_frame_function_pointer) {
   1884   thread_local_.frame_drop_mode_ = mode;
   1885   thread_local_.break_frame_id_ = new_break_frame_id;
   1886   thread_local_.restarter_frame_function_pointer_ =
   1887       restarter_frame_function_pointer;
   1888 }
   1889 
   1890 
   1891 bool Debug::IsDebugGlobal(GlobalObject* global) {
   1892   return IsLoaded() && global == debug_context()->global();
   1893 }
   1894 
   1895 
   1896 void Debug::ClearMirrorCache() {
   1897   ASSERT(Isolate::Current() == isolate_);
   1898   PostponeInterruptsScope postpone(isolate_);
   1899   HandleScope scope(isolate_);
   1900   ASSERT(isolate_->context() == *Debug::debug_context());
   1901 
   1902   // Clear the mirror cache.
   1903   Handle<String> function_name =
   1904       isolate_->factory()->LookupSymbol(CStrVector("ClearMirrorCache"));
   1905   Handle<Object> fun(Isolate::Current()->global()->GetPropertyNoExceptionThrown(
   1906       *function_name));
   1907   ASSERT(fun->IsJSFunction());
   1908   bool caught_exception;
   1909   Handle<Object> js_object = Execution::TryCall(
   1910       Handle<JSFunction>::cast(fun),
   1911       Handle<JSObject>(Debug::debug_context()->global()),
   1912       0, NULL, &caught_exception);
   1913 }
   1914 
   1915 
   1916 void Debug::CreateScriptCache() {
   1917   ASSERT(Isolate::Current() == isolate_);
   1918   Heap* heap = isolate_->heap();
   1919   HandleScope scope(isolate_);
   1920 
   1921   // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
   1922   // rid of all the cached script wrappers and the second gets rid of the
   1923   // scripts which are no longer referenced.
   1924   heap->CollectAllGarbage(false);
   1925   heap->CollectAllGarbage(false);
   1926 
   1927   ASSERT(script_cache_ == NULL);
   1928   script_cache_ = new ScriptCache();
   1929 
   1930   // Scan heap for Script objects.
   1931   int count = 0;
   1932   HeapIterator iterator;
   1933   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
   1934     if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
   1935       script_cache_->Add(Handle<Script>(Script::cast(obj)));
   1936       count++;
   1937     }
   1938   }
   1939 }
   1940 
   1941 
   1942 void Debug::DestroyScriptCache() {
   1943   // Get rid of the script cache if it was created.
   1944   if (script_cache_ != NULL) {
   1945     delete script_cache_;
   1946     script_cache_ = NULL;
   1947   }
   1948 }
   1949 
   1950 
   1951 void Debug::AddScriptToScriptCache(Handle<Script> script) {
   1952   if (script_cache_ != NULL) {
   1953     script_cache_->Add(script);
   1954   }
   1955 }
   1956 
   1957 
   1958 Handle<FixedArray> Debug::GetLoadedScripts() {
   1959   ASSERT(Isolate::Current() == isolate_);
   1960   // Create and fill the script cache when the loaded scripts is requested for
   1961   // the first time.
   1962   if (script_cache_ == NULL) {
   1963     CreateScriptCache();
   1964   }
   1965 
   1966   // If the script cache is not active just return an empty array.
   1967   ASSERT(script_cache_ != NULL);
   1968   if (script_cache_ == NULL) {
   1969     isolate_->factory()->NewFixedArray(0);
   1970   }
   1971 
   1972   // Perform GC to get unreferenced scripts evicted from the cache before
   1973   // returning the content.
   1974   isolate_->heap()->CollectAllGarbage(false);
   1975 
   1976   // Get the scripts from the cache.
   1977   return script_cache_->GetScripts();
   1978 }
   1979 
   1980 
   1981 void Debug::AfterGarbageCollection() {
   1982   // Generate events for collected scripts.
   1983   if (script_cache_ != NULL) {
   1984     script_cache_->ProcessCollectedScripts();
   1985   }
   1986 }
   1987 
   1988 
   1989 Debugger::Debugger(Isolate* isolate)
   1990     : debugger_access_(isolate->debugger_access()),
   1991       event_listener_(Handle<Object>()),
   1992       event_listener_data_(Handle<Object>()),
   1993       compiling_natives_(false),
   1994       is_loading_debugger_(false),
   1995       never_unload_debugger_(false),
   1996       message_handler_(NULL),
   1997       debugger_unload_pending_(false),
   1998       host_dispatch_handler_(NULL),
   1999       dispatch_handler_access_(OS::CreateMutex()),
   2000       debug_message_dispatch_handler_(NULL),
   2001       message_dispatch_helper_thread_(NULL),
   2002       host_dispatch_micros_(100 * 1000),
   2003       agent_(NULL),
   2004       command_queue_(kQueueInitialSize),
   2005       command_received_(OS::CreateSemaphore(0)),
   2006       event_command_queue_(kQueueInitialSize),
   2007       isolate_(isolate) {
   2008 }
   2009 
   2010 
   2011 Debugger::~Debugger() {
   2012   delete dispatch_handler_access_;
   2013   dispatch_handler_access_ = 0;
   2014   delete command_received_;
   2015   command_received_ = 0;
   2016 }
   2017 
   2018 
   2019 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
   2020                                       int argc, Object*** argv,
   2021                                       bool* caught_exception) {
   2022   ASSERT(Isolate::Current() == isolate_);
   2023   ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
   2024 
   2025   // Create the execution state object.
   2026   Handle<String> constructor_str =
   2027       isolate_->factory()->LookupSymbol(constructor_name);
   2028   Handle<Object> constructor(
   2029       isolate_->global()->GetPropertyNoExceptionThrown(*constructor_str));
   2030   ASSERT(constructor->IsJSFunction());
   2031   if (!constructor->IsJSFunction()) {
   2032     *caught_exception = true;
   2033     return isolate_->factory()->undefined_value();
   2034   }
   2035   Handle<Object> js_object = Execution::TryCall(
   2036       Handle<JSFunction>::cast(constructor),
   2037       Handle<JSObject>(isolate_->debug()->debug_context()->global()),
   2038       argc, argv, caught_exception);
   2039   return js_object;
   2040 }
   2041 
   2042 
   2043 Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) {
   2044   ASSERT(Isolate::Current() == isolate_);
   2045   // Create the execution state object.
   2046   Handle<Object> break_id = isolate_->factory()->NewNumberFromInt(
   2047       isolate_->debug()->break_id());
   2048   const int argc = 1;
   2049   Object** argv[argc] = { break_id.location() };
   2050   return MakeJSObject(CStrVector("MakeExecutionState"),
   2051                       argc, argv, caught_exception);
   2052 }
   2053 
   2054 
   2055 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state,
   2056                                         Handle<Object> break_points_hit,
   2057                                         bool* caught_exception) {
   2058   ASSERT(Isolate::Current() == isolate_);
   2059   // Create the new break event object.
   2060   const int argc = 2;
   2061   Object** argv[argc] = { exec_state.location(),
   2062                           break_points_hit.location() };
   2063   return MakeJSObject(CStrVector("MakeBreakEvent"),
   2064                       argc,
   2065                       argv,
   2066                       caught_exception);
   2067 }
   2068 
   2069 
   2070 Handle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state,
   2071                                             Handle<Object> exception,
   2072                                             bool uncaught,
   2073                                             bool* caught_exception) {
   2074   ASSERT(Isolate::Current() == isolate_);
   2075   Factory* factory = isolate_->factory();
   2076   // Create the new exception event object.
   2077   const int argc = 3;
   2078   Object** argv[argc] = { exec_state.location(),
   2079                           exception.location(),
   2080                           uncaught ? factory->true_value().location() :
   2081                                      factory->false_value().location()};
   2082   return MakeJSObject(CStrVector("MakeExceptionEvent"),
   2083                       argc, argv, caught_exception);
   2084 }
   2085 
   2086 
   2087 Handle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function,
   2088                                               bool* caught_exception) {
   2089   ASSERT(Isolate::Current() == isolate_);
   2090   // Create the new function event object.
   2091   const int argc = 1;
   2092   Object** argv[argc] = { function.location() };
   2093   return MakeJSObject(CStrVector("MakeNewFunctionEvent"),
   2094                       argc, argv, caught_exception);
   2095 }
   2096 
   2097 
   2098 Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
   2099                                           bool before,
   2100                                           bool* caught_exception) {
   2101   ASSERT(Isolate::Current() == isolate_);
   2102   Factory* factory = isolate_->factory();
   2103   // Create the compile event object.
   2104   Handle<Object> exec_state = MakeExecutionState(caught_exception);
   2105   Handle<Object> script_wrapper = GetScriptWrapper(script);
   2106   const int argc = 3;
   2107   Object** argv[argc] = { exec_state.location(),
   2108                           script_wrapper.location(),
   2109                           before ? factory->true_value().location() :
   2110                                    factory->false_value().location() };
   2111 
   2112   return MakeJSObject(CStrVector("MakeCompileEvent"),
   2113                       argc,
   2114                       argv,
   2115                       caught_exception);
   2116 }
   2117 
   2118 
   2119 Handle<Object> Debugger::MakeScriptCollectedEvent(int id,
   2120                                                   bool* caught_exception) {
   2121   ASSERT(Isolate::Current() == isolate_);
   2122   // Create the script collected event object.
   2123   Handle<Object> exec_state = MakeExecutionState(caught_exception);
   2124   Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id));
   2125   const int argc = 2;
   2126   Object** argv[argc] = { exec_state.location(), id_object.location() };
   2127 
   2128   return MakeJSObject(CStrVector("MakeScriptCollectedEvent"),
   2129                       argc,
   2130                       argv,
   2131                       caught_exception);
   2132 }
   2133 
   2134 
   2135 void Debugger::OnException(Handle<Object> exception, bool uncaught) {
   2136   ASSERT(Isolate::Current() == isolate_);
   2137   HandleScope scope(isolate_);
   2138   Debug* debug = isolate_->debug();
   2139 
   2140   // Bail out based on state or if there is no listener for this event
   2141   if (debug->InDebugger()) return;
   2142   if (!Debugger::EventActive(v8::Exception)) return;
   2143 
   2144   // Bail out if exception breaks are not active
   2145   if (uncaught) {
   2146     // Uncaught exceptions are reported by either flags.
   2147     if (!(debug->break_on_uncaught_exception() ||
   2148           debug->break_on_exception())) return;
   2149   } else {
   2150     // Caught exceptions are reported is activated.
   2151     if (!debug->break_on_exception()) return;
   2152   }
   2153 
   2154   // Enter the debugger.
   2155   EnterDebugger debugger;
   2156   if (debugger.FailedToEnter()) return;
   2157 
   2158   // Clear all current stepping setup.
   2159   debug->ClearStepping();
   2160   // Create the event data object.
   2161   bool caught_exception = false;
   2162   Handle<Object> exec_state = MakeExecutionState(&caught_exception);
   2163   Handle<Object> event_data;
   2164   if (!caught_exception) {
   2165     event_data = MakeExceptionEvent(exec_state, exception, uncaught,
   2166                                     &caught_exception);
   2167   }
   2168   // Bail out and don't call debugger if exception.
   2169   if (caught_exception) {
   2170     return;
   2171   }
   2172 
   2173   // Process debug event.
   2174   ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
   2175   // Return to continue execution from where the exception was thrown.
   2176 }
   2177 
   2178 
   2179 void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
   2180                             bool auto_continue) {
   2181   ASSERT(Isolate::Current() == isolate_);
   2182   HandleScope scope(isolate_);
   2183 
   2184   // Debugger has already been entered by caller.
   2185   ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
   2186 
   2187   // Bail out if there is no listener for this event
   2188   if (!Debugger::EventActive(v8::Break)) return;
   2189 
   2190   // Debugger must be entered in advance.
   2191   ASSERT(Isolate::Current()->context() == *isolate_->debug()->debug_context());
   2192 
   2193   // Create the event data object.
   2194   bool caught_exception = false;
   2195   Handle<Object> exec_state = MakeExecutionState(&caught_exception);
   2196   Handle<Object> event_data;
   2197   if (!caught_exception) {
   2198     event_data = MakeBreakEvent(exec_state, break_points_hit,
   2199                                 &caught_exception);
   2200   }
   2201   // Bail out and don't call debugger if exception.
   2202   if (caught_exception) {
   2203     return;
   2204   }
   2205 
   2206   // Process debug event.
   2207   ProcessDebugEvent(v8::Break,
   2208                     Handle<JSObject>::cast(event_data),
   2209                     auto_continue);
   2210 }
   2211 
   2212 
   2213 void Debugger::OnBeforeCompile(Handle<Script> script) {
   2214   ASSERT(Isolate::Current() == isolate_);
   2215   HandleScope scope(isolate_);
   2216 
   2217   // Bail out based on state or if there is no listener for this event
   2218   if (isolate_->debug()->InDebugger()) return;
   2219   if (compiling_natives()) return;
   2220   if (!EventActive(v8::BeforeCompile)) return;
   2221 
   2222   // Enter the debugger.
   2223   EnterDebugger debugger;
   2224   if (debugger.FailedToEnter()) return;
   2225 
   2226   // Create the event data object.
   2227   bool caught_exception = false;
   2228   Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception);
   2229   // Bail out and don't call debugger if exception.
   2230   if (caught_exception) {
   2231     return;
   2232   }
   2233 
   2234   // Process debug event.
   2235   ProcessDebugEvent(v8::BeforeCompile,
   2236                     Handle<JSObject>::cast(event_data),
   2237                     true);
   2238 }
   2239 
   2240 
   2241 // Handle debugger actions when a new script is compiled.
   2242 void Debugger::OnAfterCompile(Handle<Script> script,
   2243                               AfterCompileFlags after_compile_flags) {
   2244   ASSERT(Isolate::Current() == isolate_);
   2245   HandleScope scope(isolate_);
   2246   Debug* debug = isolate_->debug();
   2247 
   2248   // Add the newly compiled script to the script cache.
   2249   debug->AddScriptToScriptCache(script);
   2250 
   2251   // No more to do if not debugging.
   2252   if (!IsDebuggerActive()) return;
   2253 
   2254   // No compile events while compiling natives.
   2255   if (compiling_natives()) return;
   2256 
   2257   // Store whether in debugger before entering debugger.
   2258   bool in_debugger = debug->InDebugger();
   2259 
   2260   // Enter the debugger.
   2261   EnterDebugger debugger;
   2262   if (debugger.FailedToEnter()) return;
   2263 
   2264   // If debugging there might be script break points registered for this
   2265   // script. Make sure that these break points are set.
   2266 
   2267   // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
   2268   Handle<String> update_script_break_points_symbol =
   2269       isolate_->factory()->LookupAsciiSymbol("UpdateScriptBreakPoints");
   2270   Handle<Object> update_script_break_points =
   2271       Handle<Object>(debug->debug_context()->global()->
   2272           GetPropertyNoExceptionThrown(*update_script_break_points_symbol));
   2273   if (!update_script_break_points->IsJSFunction()) {
   2274     return;
   2275   }
   2276   ASSERT(update_script_break_points->IsJSFunction());
   2277 
   2278   // Wrap the script object in a proper JS object before passing it
   2279   // to JavaScript.
   2280   Handle<JSValue> wrapper = GetScriptWrapper(script);
   2281 
   2282   // Call UpdateScriptBreakPoints expect no exceptions.
   2283   bool caught_exception = false;
   2284   const int argc = 1;
   2285   Object** argv[argc] = { reinterpret_cast<Object**>(wrapper.location()) };
   2286   Handle<Object> result = Execution::TryCall(
   2287       Handle<JSFunction>::cast(update_script_break_points),
   2288       Isolate::Current()->js_builtins_object(), argc, argv,
   2289       &caught_exception);
   2290   if (caught_exception) {
   2291     return;
   2292   }
   2293   // Bail out based on state or if there is no listener for this event
   2294   if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return;
   2295   if (!Debugger::EventActive(v8::AfterCompile)) return;
   2296 
   2297   // Create the compile state object.
   2298   Handle<Object> event_data = MakeCompileEvent(script,
   2299                                                false,
   2300                                                &caught_exception);
   2301   // Bail out and don't call debugger if exception.
   2302   if (caught_exception) {
   2303     return;
   2304   }
   2305   // Process debug event.
   2306   ProcessDebugEvent(v8::AfterCompile,
   2307                     Handle<JSObject>::cast(event_data),
   2308                     true);
   2309 }
   2310 
   2311 
   2312 void Debugger::OnScriptCollected(int id) {
   2313   ASSERT(Isolate::Current() == isolate_);
   2314   HandleScope scope(isolate_);
   2315 
   2316   // No more to do if not debugging.
   2317   if (!IsDebuggerActive()) return;
   2318   if (!Debugger::EventActive(v8::ScriptCollected)) return;
   2319 
   2320   // Enter the debugger.
   2321   EnterDebugger debugger;
   2322   if (debugger.FailedToEnter()) return;
   2323 
   2324   // Create the script collected state object.
   2325   bool caught_exception = false;
   2326   Handle<Object> event_data = MakeScriptCollectedEvent(id,
   2327                                                        &caught_exception);
   2328   // Bail out and don't call debugger if exception.
   2329   if (caught_exception) {
   2330     return;
   2331   }
   2332 
   2333   // Process debug event.
   2334   ProcessDebugEvent(v8::ScriptCollected,
   2335                     Handle<JSObject>::cast(event_data),
   2336                     true);
   2337 }
   2338 
   2339 
   2340 void Debugger::ProcessDebugEvent(v8::DebugEvent event,
   2341                                  Handle<JSObject> event_data,
   2342                                  bool auto_continue) {
   2343   ASSERT(Isolate::Current() == isolate_);
   2344   HandleScope scope(isolate_);
   2345 
   2346   // Clear any pending debug break if this is a real break.
   2347   if (!auto_continue) {
   2348     isolate_->debug()->clear_interrupt_pending(DEBUGBREAK);
   2349   }
   2350 
   2351   // Create the execution state.
   2352   bool caught_exception = false;
   2353   Handle<Object> exec_state = MakeExecutionState(&caught_exception);
   2354   if (caught_exception) {
   2355     return;
   2356   }
   2357   // First notify the message handler if any.
   2358   if (message_handler_ != NULL) {
   2359     NotifyMessageHandler(event,
   2360                          Handle<JSObject>::cast(exec_state),
   2361                          event_data,
   2362                          auto_continue);
   2363   }
   2364   // Notify registered debug event listener. This can be either a C or
   2365   // a JavaScript function. Don't call event listener for v8::Break
   2366   // here, if it's only a debug command -- they will be processed later.
   2367   if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
   2368     CallEventCallback(event, exec_state, event_data, NULL);
   2369   }
   2370   // Process pending debug commands.
   2371   if (event == v8::Break) {
   2372     while (!event_command_queue_.IsEmpty()) {
   2373       CommandMessage command = event_command_queue_.Get();
   2374       if (!event_listener_.is_null()) {
   2375         CallEventCallback(v8::BreakForCommand,
   2376                           exec_state,
   2377                           event_data,
   2378                           command.client_data());
   2379       }
   2380       command.Dispose();
   2381     }
   2382   }
   2383 }
   2384 
   2385 
   2386 void Debugger::CallEventCallback(v8::DebugEvent event,
   2387                                  Handle<Object> exec_state,
   2388                                  Handle<Object> event_data,
   2389                                  v8::Debug::ClientData* client_data) {
   2390   if (event_listener_->IsProxy()) {
   2391     CallCEventCallback(event, exec_state, event_data, client_data);
   2392   } else {
   2393     CallJSEventCallback(event, exec_state, event_data);
   2394   }
   2395 }
   2396 
   2397 
   2398 void Debugger::CallCEventCallback(v8::DebugEvent event,
   2399                                   Handle<Object> exec_state,
   2400                                   Handle<Object> event_data,
   2401                                   v8::Debug::ClientData* client_data) {
   2402   Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_));
   2403   v8::Debug::EventCallback2 callback =
   2404       FUNCTION_CAST<v8::Debug::EventCallback2>(callback_obj->proxy());
   2405   EventDetailsImpl event_details(
   2406       event,
   2407       Handle<JSObject>::cast(exec_state),
   2408       Handle<JSObject>::cast(event_data),
   2409       event_listener_data_,
   2410       client_data);
   2411   callback(event_details);
   2412 }
   2413 
   2414 
   2415 void Debugger::CallJSEventCallback(v8::DebugEvent event,
   2416                                    Handle<Object> exec_state,
   2417                                    Handle<Object> event_data) {
   2418   ASSERT(event_listener_->IsJSFunction());
   2419   ASSERT(Isolate::Current() == isolate_);
   2420   Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
   2421 
   2422   // Invoke the JavaScript debug event listener.
   2423   const int argc = 4;
   2424   Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(),
   2425                           exec_state.location(),
   2426                           Handle<Object>::cast(event_data).location(),
   2427                           event_listener_data_.location() };
   2428   bool caught_exception = false;
   2429   Execution::TryCall(fun, isolate_->global(), argc, argv, &caught_exception);
   2430   // Silently ignore exceptions from debug event listeners.
   2431 }
   2432 
   2433 
   2434 Handle<Context> Debugger::GetDebugContext() {
   2435   ASSERT(Isolate::Current() == isolate_);
   2436   never_unload_debugger_ = true;
   2437   EnterDebugger debugger;
   2438   return isolate_->debug()->debug_context();
   2439 }
   2440 
   2441 
   2442 void Debugger::UnloadDebugger() {
   2443   ASSERT(Isolate::Current() == isolate_);
   2444   Debug* debug = isolate_->debug();
   2445 
   2446   // Make sure that there are no breakpoints left.
   2447   debug->ClearAllBreakPoints();
   2448 
   2449   // Unload the debugger if feasible.
   2450   if (!never_unload_debugger_) {
   2451     debug->Unload();
   2452   }
   2453 
   2454   // Clear the flag indicating that the debugger should be unloaded.
   2455   debugger_unload_pending_ = false;
   2456 }
   2457 
   2458 
   2459 void Debugger::NotifyMessageHandler(v8::DebugEvent event,
   2460                                     Handle<JSObject> exec_state,
   2461                                     Handle<JSObject> event_data,
   2462                                     bool auto_continue) {
   2463   ASSERT(Isolate::Current() == isolate_);
   2464   HandleScope scope(isolate_);
   2465 
   2466   if (!isolate_->debug()->Load()) return;
   2467 
   2468   // Process the individual events.
   2469   bool sendEventMessage = false;
   2470   switch (event) {
   2471     case v8::Break:
   2472     case v8::BreakForCommand:
   2473       sendEventMessage = !auto_continue;
   2474       break;
   2475     case v8::Exception:
   2476       sendEventMessage = true;
   2477       break;
   2478     case v8::BeforeCompile:
   2479       break;
   2480     case v8::AfterCompile:
   2481       sendEventMessage = true;
   2482       break;
   2483     case v8::ScriptCollected:
   2484       sendEventMessage = true;
   2485       break;
   2486     case v8::NewFunction:
   2487       break;
   2488     default:
   2489       UNREACHABLE();
   2490   }
   2491 
   2492   // The debug command interrupt flag might have been set when the command was
   2493   // added. It should be enough to clear the flag only once while we are in the
   2494   // debugger.
   2495   ASSERT(isolate_->debug()->InDebugger());
   2496   isolate_->stack_guard()->Continue(DEBUGCOMMAND);
   2497 
   2498   // Notify the debugger that a debug event has occurred unless auto continue is
   2499   // active in which case no event is send.
   2500   if (sendEventMessage) {
   2501     MessageImpl message = MessageImpl::NewEvent(
   2502         event,
   2503         auto_continue,
   2504         Handle<JSObject>::cast(exec_state),
   2505         Handle<JSObject>::cast(event_data));
   2506     InvokeMessageHandler(message);
   2507   }
   2508 
   2509   // If auto continue don't make the event cause a break, but process messages
   2510   // in the queue if any. For script collected events don't even process
   2511   // messages in the queue as the execution state might not be what is expected
   2512   // by the client.
   2513   if ((auto_continue && !HasCommands()) || event == v8::ScriptCollected) {
   2514     return;
   2515   }
   2516 
   2517   v8::TryCatch try_catch;
   2518 
   2519   // DebugCommandProcessor goes here.
   2520   v8::Local<v8::Object> cmd_processor;
   2521   {
   2522     v8::Local<v8::Object> api_exec_state =
   2523         v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state));
   2524     v8::Local<v8::String> fun_name =
   2525         v8::String::New("debugCommandProcessor");
   2526     v8::Local<v8::Function> fun =
   2527         v8::Function::Cast(*api_exec_state->Get(fun_name));
   2528 
   2529     v8::Handle<v8::Boolean> running =
   2530         auto_continue ? v8::True() : v8::False();
   2531     static const int kArgc = 1;
   2532     v8::Handle<Value> argv[kArgc] = { running };
   2533     cmd_processor = v8::Object::Cast(*fun->Call(api_exec_state, kArgc, argv));
   2534     if (try_catch.HasCaught()) {
   2535       PrintLn(try_catch.Exception());
   2536       return;
   2537     }
   2538   }
   2539 
   2540   bool running = auto_continue;
   2541 
   2542   // Process requests from the debugger.
   2543   while (true) {
   2544     // Wait for new command in the queue.
   2545     if (Debugger::host_dispatch_handler_) {
   2546       // In case there is a host dispatch - do periodic dispatches.
   2547       if (!command_received_->Wait(host_dispatch_micros_)) {
   2548         // Timout expired, do the dispatch.
   2549         Debugger::host_dispatch_handler_();
   2550         continue;
   2551       }
   2552     } else {
   2553       // In case there is no host dispatch - just wait.
   2554       command_received_->Wait();
   2555     }
   2556 
   2557     // Get the command from the queue.
   2558     CommandMessage command = command_queue_.Get();
   2559     LOGGER->DebugTag("Got request from command queue, in interactive loop.");
   2560     if (!Debugger::IsDebuggerActive()) {
   2561       // Delete command text and user data.
   2562       command.Dispose();
   2563       return;
   2564     }
   2565 
   2566     // Invoke JavaScript to process the debug request.
   2567     v8::Local<v8::String> fun_name;
   2568     v8::Local<v8::Function> fun;
   2569     v8::Local<v8::Value> request;
   2570     v8::TryCatch try_catch;
   2571     fun_name = v8::String::New("processDebugRequest");
   2572     fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
   2573 
   2574     request = v8::String::New(command.text().start(),
   2575                               command.text().length());
   2576     static const int kArgc = 1;
   2577     v8::Handle<Value> argv[kArgc] = { request };
   2578     v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv);
   2579 
   2580     // Get the response.
   2581     v8::Local<v8::String> response;
   2582     if (!try_catch.HasCaught()) {
   2583       // Get response string.
   2584       if (!response_val->IsUndefined()) {
   2585         response = v8::String::Cast(*response_val);
   2586       } else {
   2587         response = v8::String::New("");
   2588       }
   2589 
   2590       // Log the JSON request/response.
   2591       if (FLAG_trace_debug_json) {
   2592         PrintLn(request);
   2593         PrintLn(response);
   2594       }
   2595 
   2596       // Get the running state.
   2597       fun_name = v8::String::New("isRunning");
   2598       fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
   2599       static const int kArgc = 1;
   2600       v8::Handle<Value> argv[kArgc] = { response };
   2601       v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv);
   2602       if (!try_catch.HasCaught()) {
   2603         running = running_val->ToBoolean()->Value();
   2604       }
   2605     } else {
   2606       // In case of failure the result text is the exception text.
   2607       response = try_catch.Exception()->ToString();
   2608     }
   2609 
   2610     // Return the result.
   2611     MessageImpl message = MessageImpl::NewResponse(
   2612         event,
   2613         running,
   2614         Handle<JSObject>::cast(exec_state),
   2615         Handle<JSObject>::cast(event_data),
   2616         Handle<String>(Utils::OpenHandle(*response)),
   2617         command.client_data());
   2618     InvokeMessageHandler(message);
   2619     command.Dispose();
   2620 
   2621     // Return from debug event processing if either the VM is put into the
   2622     // runnning state (through a continue command) or auto continue is active
   2623     // and there are no more commands queued.
   2624     if (running && !HasCommands()) {
   2625       return;
   2626     }
   2627   }
   2628 }
   2629 
   2630 
   2631 void Debugger::SetEventListener(Handle<Object> callback,
   2632                                 Handle<Object> data) {
   2633   ASSERT(Isolate::Current() == isolate_);
   2634   HandleScope scope(isolate_);
   2635   GlobalHandles* global_handles = isolate_->global_handles();
   2636 
   2637   // Clear the global handles for the event listener and the event listener data
   2638   // object.
   2639   if (!event_listener_.is_null()) {
   2640     global_handles->Destroy(
   2641         reinterpret_cast<Object**>(event_listener_.location()));
   2642     event_listener_ = Handle<Object>();
   2643   }
   2644   if (!event_listener_data_.is_null()) {
   2645     global_handles->Destroy(
   2646         reinterpret_cast<Object**>(event_listener_data_.location()));
   2647     event_listener_data_ = Handle<Object>();
   2648   }
   2649 
   2650   // If there is a new debug event listener register it together with its data
   2651   // object.
   2652   if (!callback->IsUndefined() && !callback->IsNull()) {
   2653     event_listener_ = Handle<Object>::cast(
   2654         global_handles->Create(*callback));
   2655     if (data.is_null()) {
   2656       data = isolate_->factory()->undefined_value();
   2657     }
   2658     event_listener_data_ = Handle<Object>::cast(
   2659         global_handles->Create(*data));
   2660   }
   2661 
   2662   ListenersChanged();
   2663 }
   2664 
   2665 
   2666 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) {
   2667   ASSERT(Isolate::Current() == isolate_);
   2668   ScopedLock with(debugger_access_);
   2669 
   2670   message_handler_ = handler;
   2671   ListenersChanged();
   2672   if (handler == NULL) {
   2673     // Send an empty command to the debugger if in a break to make JavaScript
   2674     // run again if the debugger is closed.
   2675     if (isolate_->debug()->InDebugger()) {
   2676       ProcessCommand(Vector<const uint16_t>::empty());
   2677     }
   2678   }
   2679 }
   2680 
   2681 
   2682 void Debugger::ListenersChanged() {
   2683   ASSERT(Isolate::Current() == isolate_);
   2684   if (IsDebuggerActive()) {
   2685     // Disable the compilation cache when the debugger is active.
   2686     isolate_->compilation_cache()->Disable();
   2687     debugger_unload_pending_ = false;
   2688   } else {
   2689     isolate_->compilation_cache()->Enable();
   2690     // Unload the debugger if event listener and message handler cleared.
   2691     // Schedule this for later, because we may be in non-V8 thread.
   2692     debugger_unload_pending_ = true;
   2693   }
   2694 }
   2695 
   2696 
   2697 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
   2698                                       int period) {
   2699   ASSERT(Isolate::Current() == isolate_);
   2700   host_dispatch_handler_ = handler;
   2701   host_dispatch_micros_ = period * 1000;
   2702 }
   2703 
   2704 
   2705 void Debugger::SetDebugMessageDispatchHandler(
   2706     v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) {
   2707   ASSERT(Isolate::Current() == isolate_);
   2708   ScopedLock with(dispatch_handler_access_);
   2709   debug_message_dispatch_handler_ = handler;
   2710 
   2711   if (provide_locker && message_dispatch_helper_thread_ == NULL) {
   2712     message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_);
   2713     message_dispatch_helper_thread_->Start();
   2714   }
   2715 }
   2716 
   2717 
   2718 // Calls the registered debug message handler. This callback is part of the
   2719 // public API.
   2720 void Debugger::InvokeMessageHandler(MessageImpl message) {
   2721   ASSERT(Isolate::Current() == isolate_);
   2722   ScopedLock with(debugger_access_);
   2723 
   2724   if (message_handler_ != NULL) {
   2725     message_handler_(message);
   2726   }
   2727 }
   2728 
   2729 
   2730 // Puts a command coming from the public API on the queue.  Creates
   2731 // a copy of the command string managed by the debugger.  Up to this
   2732 // point, the command data was managed by the API client.  Called
   2733 // by the API client thread.
   2734 void Debugger::ProcessCommand(Vector<const uint16_t> command,
   2735                               v8::Debug::ClientData* client_data) {
   2736   ASSERT(Isolate::Current() == isolate_);
   2737   // Need to cast away const.
   2738   CommandMessage message = CommandMessage::New(
   2739       Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
   2740                        command.length()),
   2741       client_data);
   2742   LOGGER->DebugTag("Put command on command_queue.");
   2743   command_queue_.Put(message);
   2744   command_received_->Signal();
   2745 
   2746   // Set the debug command break flag to have the command processed.
   2747   if (!isolate_->debug()->InDebugger()) {
   2748     isolate_->stack_guard()->DebugCommand();
   2749   }
   2750 
   2751   MessageDispatchHelperThread* dispatch_thread;
   2752   {
   2753     ScopedLock with(dispatch_handler_access_);
   2754     dispatch_thread = message_dispatch_helper_thread_;
   2755   }
   2756 
   2757   if (dispatch_thread == NULL) {
   2758     CallMessageDispatchHandler();
   2759   } else {
   2760     dispatch_thread->Schedule();
   2761   }
   2762 }
   2763 
   2764 
   2765 bool Debugger::HasCommands() {
   2766   ASSERT(Isolate::Current() == isolate_);
   2767   return !command_queue_.IsEmpty();
   2768 }
   2769 
   2770 
   2771 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
   2772   ASSERT(Isolate::Current() == isolate_);
   2773   CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
   2774   event_command_queue_.Put(message);
   2775 
   2776   // Set the debug command break flag to have the command processed.
   2777   if (!isolate_->debug()->InDebugger()) {
   2778     isolate_->stack_guard()->DebugCommand();
   2779   }
   2780 }
   2781 
   2782 
   2783 bool Debugger::IsDebuggerActive() {
   2784   ASSERT(Isolate::Current() == isolate_);
   2785   ScopedLock with(debugger_access_);
   2786 
   2787   return message_handler_ != NULL || !event_listener_.is_null();
   2788 }
   2789 
   2790 
   2791 Handle<Object> Debugger::Call(Handle<JSFunction> fun,
   2792                               Handle<Object> data,
   2793                               bool* pending_exception) {
   2794   ASSERT(Isolate::Current() == isolate_);
   2795   // When calling functions in the debugger prevent it from beeing unloaded.
   2796   Debugger::never_unload_debugger_ = true;
   2797 
   2798   // Enter the debugger.
   2799   EnterDebugger debugger;
   2800   if (debugger.FailedToEnter()) {
   2801     return isolate_->factory()->undefined_value();
   2802   }
   2803 
   2804   // Create the execution state.
   2805   bool caught_exception = false;
   2806   Handle<Object> exec_state = MakeExecutionState(&caught_exception);
   2807   if (caught_exception) {
   2808     return isolate_->factory()->undefined_value();
   2809   }
   2810 
   2811   static const int kArgc = 2;
   2812   Object** argv[kArgc] = { exec_state.location(), data.location() };
   2813   Handle<Object> result = Execution::Call(
   2814       fun,
   2815       Handle<Object>(isolate_->debug()->debug_context_->global_proxy()),
   2816       kArgc,
   2817       argv,
   2818       pending_exception);
   2819   return result;
   2820 }
   2821 
   2822 
   2823 static void StubMessageHandler2(const v8::Debug::Message& message) {
   2824   // Simply ignore message.
   2825 }
   2826 
   2827 
   2828 bool Debugger::StartAgent(const char* name, int port,
   2829                           bool wait_for_connection) {
   2830   ASSERT(Isolate::Current() == isolate_);
   2831   if (wait_for_connection) {
   2832     // Suspend V8 if it is already running or set V8 to suspend whenever
   2833     // it starts.
   2834     // Provide stub message handler; V8 auto-continues each suspend
   2835     // when there is no message handler; we doesn't need it.
   2836     // Once become suspended, V8 will stay so indefinitely long, until remote
   2837     // debugger connects and issues "continue" command.
   2838     Debugger::message_handler_ = StubMessageHandler2;
   2839     v8::Debug::DebugBreak();
   2840   }
   2841 
   2842   if (Socket::Setup()) {
   2843     if (agent_ == NULL) {
   2844       agent_ = new DebuggerAgent(isolate_, name, port);
   2845       agent_->Start();
   2846     }
   2847     return true;
   2848   }
   2849 
   2850   return false;
   2851 }
   2852 
   2853 
   2854 void Debugger::StopAgent() {
   2855   ASSERT(Isolate::Current() == isolate_);
   2856   if (agent_ != NULL) {
   2857     agent_->Shutdown();
   2858     agent_->Join();
   2859     delete agent_;
   2860     agent_ = NULL;
   2861   }
   2862 }
   2863 
   2864 
   2865 void Debugger::WaitForAgent() {
   2866   ASSERT(Isolate::Current() == isolate_);
   2867   if (agent_ != NULL)
   2868     agent_->WaitUntilListening();
   2869 }
   2870 
   2871 
   2872 void Debugger::CallMessageDispatchHandler() {
   2873   ASSERT(Isolate::Current() == isolate_);
   2874   v8::Debug::DebugMessageDispatchHandler handler;
   2875   {
   2876     ScopedLock with(dispatch_handler_access_);
   2877     handler = Debugger::debug_message_dispatch_handler_;
   2878   }
   2879   if (handler != NULL) {
   2880     handler();
   2881   }
   2882 }
   2883 
   2884 
   2885 MessageImpl MessageImpl::NewEvent(DebugEvent event,
   2886                                   bool running,
   2887                                   Handle<JSObject> exec_state,
   2888                                   Handle<JSObject> event_data) {
   2889   MessageImpl message(true, event, running,
   2890                       exec_state, event_data, Handle<String>(), NULL);
   2891   return message;
   2892 }
   2893 
   2894 
   2895 MessageImpl MessageImpl::NewResponse(DebugEvent event,
   2896                                      bool running,
   2897                                      Handle<JSObject> exec_state,
   2898                                      Handle<JSObject> event_data,
   2899                                      Handle<String> response_json,
   2900                                      v8::Debug::ClientData* client_data) {
   2901   MessageImpl message(false, event, running,
   2902                       exec_state, event_data, response_json, client_data);
   2903   return message;
   2904 }
   2905 
   2906 
   2907 MessageImpl::MessageImpl(bool is_event,
   2908                          DebugEvent event,
   2909                          bool running,
   2910                          Handle<JSObject> exec_state,
   2911                          Handle<JSObject> event_data,
   2912                          Handle<String> response_json,
   2913                          v8::Debug::ClientData* client_data)
   2914     : is_event_(is_event),
   2915       event_(event),
   2916       running_(running),
   2917       exec_state_(exec_state),
   2918       event_data_(event_data),
   2919       response_json_(response_json),
   2920       client_data_(client_data) {}
   2921 
   2922 
   2923 bool MessageImpl::IsEvent() const {
   2924   return is_event_;
   2925 }
   2926 
   2927 
   2928 bool MessageImpl::IsResponse() const {
   2929   return !is_event_;
   2930 }
   2931 
   2932 
   2933 DebugEvent MessageImpl::GetEvent() const {
   2934   return event_;
   2935 }
   2936 
   2937 
   2938 bool MessageImpl::WillStartRunning() const {
   2939   return running_;
   2940 }
   2941 
   2942 
   2943 v8::Handle<v8::Object> MessageImpl::GetExecutionState() const {
   2944   return v8::Utils::ToLocal(exec_state_);
   2945 }
   2946 
   2947 
   2948 v8::Handle<v8::Object> MessageImpl::GetEventData() const {
   2949   return v8::Utils::ToLocal(event_data_);
   2950 }
   2951 
   2952 
   2953 v8::Handle<v8::String> MessageImpl::GetJSON() const {
   2954   v8::HandleScope scope;
   2955 
   2956   if (IsEvent()) {
   2957     // Call toJSONProtocol on the debug event object.
   2958     Handle<Object> fun = GetProperty(event_data_, "toJSONProtocol");
   2959     if (!fun->IsJSFunction()) {
   2960       return v8::Handle<v8::String>();
   2961     }
   2962     bool caught_exception;
   2963     Handle<Object> json = Execution::TryCall(Handle<JSFunction>::cast(fun),
   2964                                              event_data_,
   2965                                              0, NULL, &caught_exception);
   2966     if (caught_exception || !json->IsString()) {
   2967       return v8::Handle<v8::String>();
   2968     }
   2969     return scope.Close(v8::Utils::ToLocal(Handle<String>::cast(json)));
   2970   } else {
   2971     return v8::Utils::ToLocal(response_json_);
   2972   }
   2973 }
   2974 
   2975 
   2976 v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
   2977   Isolate* isolate = Isolate::Current();
   2978   v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
   2979   // Isolate::context() may be NULL when "script collected" event occures.
   2980   ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected);
   2981   return GetDebugEventContext(isolate);
   2982 }
   2983 
   2984 
   2985 v8::Debug::ClientData* MessageImpl::GetClientData() const {
   2986   return client_data_;
   2987 }
   2988 
   2989 
   2990 EventDetailsImpl::EventDetailsImpl(DebugEvent event,
   2991                                    Handle<JSObject> exec_state,
   2992                                    Handle<JSObject> event_data,
   2993                                    Handle<Object> callback_data,
   2994                                    v8::Debug::ClientData* client_data)
   2995     : event_(event),
   2996       exec_state_(exec_state),
   2997       event_data_(event_data),
   2998       callback_data_(callback_data),
   2999       client_data_(client_data) {}
   3000 
   3001 
   3002 DebugEvent EventDetailsImpl::GetEvent() const {
   3003   return event_;
   3004 }
   3005 
   3006 
   3007 v8::Handle<v8::Object> EventDetailsImpl::GetExecutionState() const {
   3008   return v8::Utils::ToLocal(exec_state_);
   3009 }
   3010 
   3011 
   3012 v8::Handle<v8::Object> EventDetailsImpl::GetEventData() const {
   3013   return v8::Utils::ToLocal(event_data_);
   3014 }
   3015 
   3016 
   3017 v8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const {
   3018   return GetDebugEventContext(Isolate::Current());
   3019 }
   3020 
   3021 
   3022 v8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const {
   3023   return v8::Utils::ToLocal(callback_data_);
   3024 }
   3025 
   3026 
   3027 v8::Debug::ClientData* EventDetailsImpl::GetClientData() const {
   3028   return client_data_;
   3029 }
   3030 
   3031 
   3032 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
   3033                                    client_data_(NULL) {
   3034 }
   3035 
   3036 
   3037 CommandMessage::CommandMessage(const Vector<uint16_t>& text,
   3038                                v8::Debug::ClientData* data)
   3039     : text_(text),
   3040       client_data_(data) {
   3041 }
   3042 
   3043 
   3044 CommandMessage::~CommandMessage() {
   3045 }
   3046 
   3047 
   3048 void CommandMessage::Dispose() {
   3049   text_.Dispose();
   3050   delete client_data_;
   3051   client_data_ = NULL;
   3052 }
   3053 
   3054 
   3055 CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
   3056                                    v8::Debug::ClientData* data) {
   3057   return CommandMessage(command.Clone(), data);
   3058 }
   3059 
   3060 
   3061 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
   3062                                                      size_(size) {
   3063   messages_ = NewArray<CommandMessage>(size);
   3064 }
   3065 
   3066 
   3067 CommandMessageQueue::~CommandMessageQueue() {
   3068   while (!IsEmpty()) {
   3069     CommandMessage m = Get();
   3070     m.Dispose();
   3071   }
   3072   DeleteArray(messages_);
   3073 }
   3074 
   3075 
   3076 CommandMessage CommandMessageQueue::Get() {
   3077   ASSERT(!IsEmpty());
   3078   int result = start_;
   3079   start_ = (start_ + 1) % size_;
   3080   return messages_[result];
   3081 }
   3082 
   3083 
   3084 void CommandMessageQueue::Put(const CommandMessage& message) {
   3085   if ((end_ + 1) % size_ == start_) {
   3086     Expand();
   3087   }
   3088   messages_[end_] = message;
   3089   end_ = (end_ + 1) % size_;
   3090 }
   3091 
   3092 
   3093 void CommandMessageQueue::Expand() {
   3094   CommandMessageQueue new_queue(size_ * 2);
   3095   while (!IsEmpty()) {
   3096     new_queue.Put(Get());
   3097   }
   3098   CommandMessage* array_to_free = messages_;
   3099   *this = new_queue;
   3100   new_queue.messages_ = array_to_free;
   3101   // Make the new_queue empty so that it doesn't call Dispose on any messages.
   3102   new_queue.start_ = new_queue.end_;
   3103   // Automatic destructor called on new_queue, freeing array_to_free.
   3104 }
   3105 
   3106 
   3107 LockingCommandMessageQueue::LockingCommandMessageQueue(int size)
   3108     : queue_(size) {
   3109   lock_ = OS::CreateMutex();
   3110 }
   3111 
   3112 
   3113 LockingCommandMessageQueue::~LockingCommandMessageQueue() {
   3114   delete lock_;
   3115 }
   3116 
   3117 
   3118 bool LockingCommandMessageQueue::IsEmpty() const {
   3119   ScopedLock sl(lock_);
   3120   return queue_.IsEmpty();
   3121 }
   3122 
   3123 
   3124 CommandMessage LockingCommandMessageQueue::Get() {
   3125   ScopedLock sl(lock_);
   3126   CommandMessage result = queue_.Get();
   3127   LOGGER->DebugEvent("Get", result.text());
   3128   return result;
   3129 }
   3130 
   3131 
   3132 void LockingCommandMessageQueue::Put(const CommandMessage& message) {
   3133   ScopedLock sl(lock_);
   3134   queue_.Put(message);
   3135   LOGGER->DebugEvent("Put", message.text());
   3136 }
   3137 
   3138 
   3139 void LockingCommandMessageQueue::Clear() {
   3140   ScopedLock sl(lock_);
   3141   queue_.Clear();
   3142 }
   3143 
   3144 
   3145 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate)
   3146     : Thread(isolate, "v8:MsgDispHelpr"),
   3147       sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
   3148       already_signalled_(false) {
   3149 }
   3150 
   3151 
   3152 MessageDispatchHelperThread::~MessageDispatchHelperThread() {
   3153   delete mutex_;
   3154   delete sem_;
   3155 }
   3156 
   3157 
   3158 void MessageDispatchHelperThread::Schedule() {
   3159   {
   3160     ScopedLock lock(mutex_);
   3161     if (already_signalled_) {
   3162       return;
   3163     }
   3164     already_signalled_ = true;
   3165   }
   3166   sem_->Signal();
   3167 }
   3168 
   3169 
   3170 void MessageDispatchHelperThread::Run() {
   3171   while (true) {
   3172     sem_->Wait();
   3173     {
   3174       ScopedLock lock(mutex_);
   3175       already_signalled_ = false;
   3176     }
   3177     {
   3178       Locker locker;
   3179       Isolate::Current()->debugger()->CallMessageDispatchHandler();
   3180     }
   3181   }
   3182 }
   3183 
   3184 #endif  // ENABLE_DEBUGGER_SUPPORT
   3185 
   3186 } }  // namespace v8::internal
   3187