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