1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arguments.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bootstrapper.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "code-stubs.h" 34402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "codegen.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compilation-cache.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compiler.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h" 38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "execution.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "global-handles.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ic.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ic-inl.h" 436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "messages.h" 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "natives.h" 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "stub-cache.h" 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "log.h" 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "../include/v8-debug.h" 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDebug::Debug(Isolate* isolate) 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block : has_break_points_(false), 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block script_cache_(NULL), 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug_info_list_(NULL), 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block disable_break_(false), 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block break_on_exception_(false), 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block break_on_uncaught_exception_(false), 6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug_break_return_(NULL), 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug_break_slot_(NULL), 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_(isolate) { 6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block memset(registers_, 0, sizeof(JSCallerSavedBuffer)); 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDebug::~Debug() { 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void PrintLn(v8::Local<v8::Value> value) { 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> s = value->ToString(); 7625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen ScopedVector<char> data(s->Length() + 1); 7725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (data.start() == NULL) { 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::FatalProcessOutOfMemory("PrintLn"); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 8125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen s->WriteAscii(data.start()); 8225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen PrintF("%s\n", data.start()); 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochstatic Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind) { 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CALL_HEAP_FUNCTION( 8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate, 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stub_cache()->ComputeCallDebugBreak(argc, kind), 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind) { 9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CALL_HEAP_FUNCTION( 9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate, 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind), 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code); 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); 10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Isolate::context() may have been NULL when "script collected" event 10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // occured. 10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (context.is_null()) return v8::Local<v8::Context>(); 109f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Handle<Context> global_context(context->global_context()); 110f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return v8::Utils::ToLocal(global_context); 111f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 112f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 113f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info, 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakLocatorType type) { 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_info_ = debug_info; 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block type_ = type; 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_iterator_ = NULL; 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_iterator_original_ = NULL; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(); // Initialize the rest of the member variables. 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBreakLocationIterator::~BreakLocationIterator() { 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reloc_iterator_ != NULL); 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reloc_iterator_original_ != NULL); 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete reloc_iterator_; 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete reloc_iterator_original_; 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::Next() { 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AssertNoAllocation nogc; 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!RinfoDone()); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate through reloc info for code and original code stopping at each 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // breakable code target. 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool first = break_point_ == -1; 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!RinfoDone()) { 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!first) RinfoNext(); 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block first = false; 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RinfoDone()) return; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Whenever a statement position or (plain) position is passed update the 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // current value of these. 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsPosition(rmode())) { 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsStatementPosition(rmode())) { 148d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block statement_position_ = static_cast<int>( 149d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block rinfo()->data() - debug_info_->shared()->start_position()); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Always update the position as we don't want that to be before the 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // statement position. 153d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block position_ = static_cast<int>( 154d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block rinfo()->data() - debug_info_->shared()->start_position()); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(position_ >= 0); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(statement_position_ >= 0); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (IsDebugBreakSlot()) { 1607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // There is always a possible break point at a debug break slot. 1617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_++; 1627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return; 1637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (RelocInfo::IsCodeTarget(rmode())) { 1647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check for breakable code target. Look in the original code as setting 1657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // break points can cause the code targets in the running (debugged) code 1667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // to be of a different kind than in the original code. 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address target = original_rinfo()->target_address(); 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* code = Code::GetCodeFromTargetAddress(target); 1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if ((code->is_inline_cache_stub() && 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch !code->is_type_recording_binary_op_stub() && 171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch !code->is_compare_ic_stub()) || 1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block RelocInfo::IsConstructCall(rmode())) { 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_++; 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (code->kind() == Code::STUB) { 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebuggerStatement()) { 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_++; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (type_ == ALL_BREAK_LOCATIONS) { 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debug::IsBreakStub(code)) { 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_++; 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(type_ == SOURCE_BREAK_LOCATIONS); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debug::IsSourceBreakStub(code)) { 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_++; 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check for break at return. 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsJSReturn(rmode())) { 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the positions to the end of the function. 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debug_info_->shared()->HasSourceCode()) { 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block position_ = debug_info_->shared()->end_position() - 201bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch debug_info_->shared()->start_position() - 1; 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block position_ = 0; 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block statement_position_ = position_; 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_++; 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::Next(int count) { 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (count > 0) { 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block count--; 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Find the break point closest to the supplied address. 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::FindBreakLocationFromAddress(Address pc) { 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run through all break points to locate the one closest to the address. 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int closest_break_point = 0; 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int distance = kMaxInt; 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!Done()) { 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this break point is closer that what was previously found. 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (this->pc() < pc && pc - this->pc() < distance) { 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block closest_break_point = break_point(); 230d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block distance = static_cast<int>(pc - this->pc()); 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether we can't get any closer. 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (distance == 0) break; 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move to the break point found. 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(closest_break_point); 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Find the break point closest to the supplied source position. 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::FindBreakLocationFromPosition(int position) { 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run through all break points to locate the one closest to the source 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // position. 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int closest_break_point = 0; 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int distance = kMaxInt; 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!Done()) { 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this break point is closer that what was previously found. 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (position <= statement_position() && 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block statement_position() - position < distance) { 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block closest_break_point = break_point(); 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block distance = statement_position() - position; 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether we can't get any closer. 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (distance == 0) break; 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move to the break point found. 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(); 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(closest_break_point); 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::Reset() { 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create relocation iterators for the two code objects. 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (reloc_iterator_ != NULL) delete reloc_iterator_; 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_; 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_iterator_ = new RelocIterator(debug_info_->code()); 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_iterator_original_ = new RelocIterator(debug_info_->original_code()); 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Position at the first break point. 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_ = -1; 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block position_ = 1; 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block statement_position_ = 1; 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool BreakLocationIterator::Done() const { 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return RinfoDone(); 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) { 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is not already a real break point here patch code with debug 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // break. 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!HasBreakPoint()) { 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetDebugBreak(); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsDebugBreak() || IsDebuggerStatement()); 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the break point information. 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfo::SetBreakPoint(debug_info_, code_position(), 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block position(), statement_position(), 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_object); 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) { 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the break point information. 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object); 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there are no more break points here remove the debug break. 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!HasBreakPoint()) { 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearDebugBreak(); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!IsDebugBreak()); 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::SetOneShot() { 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger statement always calls debugger. No need to modify it. 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebuggerStatement()) { 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is a real break point here no more to do. 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (HasBreakPoint()) { 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsDebugBreak()); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch code with debug break. 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetDebugBreak(); 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::ClearOneShot() { 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger statement always calls debugger. No need to modify it. 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebuggerStatement()) { 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is a real break point here no more to do. 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (HasBreakPoint()) { 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsDebugBreak()); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch code removing debug break. 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearDebugBreak(); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!IsDebugBreak()); 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::SetDebugBreak() { 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger statement always calls debugger. No need to modify it. 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebuggerStatement()) { 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is already a break point here just return. This might happen if 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the same code is flooded with break points twice. Flooding the same 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function twice might happen when stepping in a function with an exception 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler as the handler and the function is the same. 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebugBreak()) { 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsJSReturn(rmode())) { 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the frame exit code with a break point. 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetDebugBreakAtReturn(); 3647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (IsDebugBreakSlot()) { 3657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Patch the code in the break slot. 3667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetDebugBreakAtSlot(); 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the IC call. 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetDebugBreakAtIC(); 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsDebugBreak()); 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::ClearDebugBreak() { 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger statement always calls debugger. No need to modify it. 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebuggerStatement()) { 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsJSReturn(rmode())) { 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Restore the frame exit code. 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearDebugBreakAtReturn(); 3847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (IsDebugBreakSlot()) { 3857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Restore the code in the break slot. 3867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ClearDebugBreakAtSlot(); 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the IC call. 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearDebugBreakAtIC(); 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!IsDebugBreak()); 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::PrepareStepIn() { 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step in can only be prepared if currently positioned on an IC call, 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // construct call or CallFunction stub call. 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address target = rinfo()->target_address(); 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code(Code::GetCodeFromTargetAddress(target)); 4027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (code->is_call_stub() || code->is_keyed_call_stub()) { 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step in through IC call is handled by the runtime system. Therefore make 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sure that the any current IC is cleared and the runtime system is 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // called. If the executing code has a debug break at the location change 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the call in the original code as it is the code there that will be 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // executed in place of the debug break call. 4087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count(), 4097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch code->kind()); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebugBreak()) { 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block original_rinfo()->set_target_address(stub->entry()); 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rinfo()->set_target_address(stub->entry()); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All the following stuff is needed only for assertion checks so the code 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is wrapped in ifdef. 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> maybe_call_function_stub = code; 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebugBreak()) { 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address original_target = original_rinfo()->target_address(); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block maybe_call_function_stub = 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code>(Code::GetCodeFromTargetAddress(original_target)); 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_call_function_stub = 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (maybe_call_function_stub->kind() == Code::STUB && 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block maybe_call_function_stub->major_key() == CodeStub::CallFunction); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step in through construct call requires no changes to the running code. 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step in through getters/setters should already be prepared as well 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // because caller of this function (Debug::PrepareStep) is expected to 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // flood the top frame's function with one shot breakpoints. 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step in through CallFunction stub should also be prepared by caller of 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // this function (Debug::PrepareStep) which should flood target function 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // with breakpoints. 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub() 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block || is_call_function_stub); 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check whether the break point is at a position which will exit the function. 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool BreakLocationIterator::IsExit() const { 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (RelocInfo::IsJSReturn(rmode())); 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool BreakLocationIterator::HasBreakPoint() { 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return debug_info_->HasBreakPoint(code_position()); 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check whether there is a debug break at the current position. 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool BreakLocationIterator::IsDebugBreak() { 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsJSReturn(rmode())) { 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return IsDebugBreakAtReturn(); 4587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (IsDebugBreakSlot()) { 4597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return IsDebugBreakAtSlot(); 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Debug::IsDebugBreak(rinfo()->target_address()); 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::SetDebugBreakAtIC() { 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the original code with the current address as the current address 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // might have changed by the inline caching since the code was copied. 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block original_rinfo()->set_target_address(rinfo()->target_address()); 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode mode = rmode(); 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsCodeTarget(mode)) { 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address target = rinfo()->target_address(); 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code(Code::GetCodeFromTargetAddress(target)); 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code to invoke the builtin debug break function matching the 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // calling convention used by the call site. 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode)); 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rinfo()->set_target_address(dbgbrk_code->entry()); 480053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 481053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // For stubs that refer back to an inlined version clear the cached map for 482053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // the inlined case to always go through the IC. As long as the break point 483053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // is set the patching performed by the runtime system will take place in 484053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // the code copy and will therefore have no effect on the running code 485053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // keeping it from using the inlined code. 486053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block if (code->is_keyed_load_stub()) { 487053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block KeyedLoadIC::ClearInlinedVersion(pc()); 488053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block } else if (code->is_keyed_store_stub()) { 489053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block KeyedStoreIC::ClearInlinedVersion(pc()); 490053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block } else if (code->is_load_stub()) { 491053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block LoadIC::ClearInlinedVersion(pc()); 492053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block } else if (code->is_store_stub()) { 493053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block StoreIC::ClearInlinedVersion(pc()); 494053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block } 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::ClearDebugBreakAtIC() { 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code to the original invoke. 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rinfo()->set_target_address(original_rinfo()->target_address()); 502053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 503053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block RelocInfo::Mode mode = rmode(); 504053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block if (RelocInfo::IsCodeTarget(mode)) { 505053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block AssertNoAllocation nogc; 506053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block Address target = original_rinfo()->target_address(); 507053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block Code* code = Code::GetCodeFromTargetAddress(target); 508053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 509053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // Restore the inlined version of keyed stores to get back to the 510053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // fast case. We need to patch back the keyed store because no 511053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // patching happens when running normally. For keyed loads, the 512053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // map check will get patched back when running normally after ICs 513053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // have been cleared at GC. 514053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block if (code->is_keyed_store_stub()) KeyedStoreIC::RestoreInlinedVersion(pc()); 515053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block } 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool BreakLocationIterator::IsDebuggerStatement() { 520402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return RelocInfo::DEBUG_BREAK == rmode(); 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool BreakLocationIterator::IsDebugBreakSlot() { 5257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return RelocInfo::DEBUG_BREAK_SLOT == rmode(); 5267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* BreakLocationIterator::BreakPointObjects() { 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return debug_info_->GetBreakPointObjects(code_position()); 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Clear out all the debug break code. This is ONLY supposed to be used when 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// shutting down the debugger as it will leave the break point information in 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DebugInfo even though the code is patched back to the non break point state. 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::ClearAllDebugBreak() { 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!Done()) { 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearDebugBreak(); 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool BreakLocationIterator::RinfoDone() const { 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reloc_iterator_->done(); 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::RinfoNext() { 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_iterator_->next(); 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reloc_iterator_original_->next(); 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!reloc_iterator_->done()) { 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(rmode() == original_rmode()); 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Threading support. 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ThreadInit() { 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.break_count_ = 0; 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.break_id_ = 0; 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.break_frame_id_ = StackFrame::NO_ID; 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_step_action_ = StepNone; 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_count_ = 0; 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_fp_ = 0; 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_into_fp_ = 0; 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_out_fp_ = 0; 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.after_break_target_ = 0; 57544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // TODO(isolates): frames_are_dropped_? 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.debugger_entry_ = NULL; 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.pending_interrupts_ = 0; 578756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick thread_local_.restarter_frame_function_pointer_ = NULL; 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* Debug::ArchiveDebug(char* storage) { 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* to = storage; 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block to += sizeof(ThreadLocal); 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(to, reinterpret_cast<char*>(®isters_), sizeof(registers_)); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadInit(); 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(to <= storage + ArchiveSpacePerThread()); 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return storage + ArchiveSpacePerThread(); 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* Debug::RestoreDebug(char* storage) { 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* from = storage; 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block from += sizeof(ThreadLocal); 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(reinterpret_cast<char*>(®isters_), from, sizeof(registers_)); 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(from <= storage + ArchiveSpacePerThread()); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return storage + ArchiveSpacePerThread(); 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Debug::ArchiveSpacePerThread() { 60444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return sizeof(ThreadLocal) + sizeof(JSCallerSavedBuffer); 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 608756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// Frame structure (conforms InternalFrame structure): 609756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// -- code 610756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// -- SMI maker 611756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// -- function (slot is called "context") 612756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// -- frame base 613756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickObject** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame, 614756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Handle<Code> code) { 615756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ASSERT(bottom_js_frame->is_java_script()); 616756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 617756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Address fp = bottom_js_frame->fp(); 618756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 619756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Move function pointer into "context" slot. 620756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Memory::Object_at(fp + StandardFrameConstants::kContextOffset) = 621756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset); 622756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 623756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code; 624756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) = 625756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Smi::FromInt(StackFrame::INTERNAL); 626756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 627756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return reinterpret_cast<Object**>(&Memory::Object_at( 628756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick fp + StandardFrameConstants::kContextOffset)); 629756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 630756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 631756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickconst int Debug::kFrameDropperFrameSize = 4; 632756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 633756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ScriptCache::Add(Handle<Script> script) { 63544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GlobalHandles* global_handles = Isolate::Current()->global_handles(); 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create an entry in the hash map for the script. 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int id = Smi::cast(script->id())->value(); 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HashMap::Entry* entry = 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (entry->value != NULL) { 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Globalize the script object, make it weak and use the location of the 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // global handle as the value in the hash map. 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Script> script_ = 64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Script>::cast( 64944f0eee88ff00398ff7f715fab053374d808c90dSteve Block (global_handles->Create(*script))); 65044f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak( 65144f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<Object**>(script_.location()), 65244f0eee88ff00398ff7f715fab053374d808c90dSteve Block this, 65344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ScriptCache::HandleWeakScript); 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block entry->value = script_.location(); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> ScriptCache::GetScripts() { 65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> instances = FACTORY->NewFixedArray(occupancy()); 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = 0; 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(entry->value != NULL); 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (entry->value != NULL) { 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block instances->set(count, *reinterpret_cast<Script**>(entry->value)); 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block count++; 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return instances; 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ScriptCache::ProcessCollectedScripts() { 67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debugger* debugger = Isolate::Current()->debugger(); 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < collected_scripts_.length(); i++) { 67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->OnScriptCollected(collected_scripts_[i]); 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block collected_scripts_.Clear(); 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ScriptCache::Clear() { 68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GlobalHandles* global_handles = Isolate::Current()->global_handles(); 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate the script cache to get rid of all the weak handles. 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(entry != NULL); 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** location = reinterpret_cast<Object**>(entry->value); 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((*location)->IsScript()); 68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->ClearWeakness(location); 68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy(location); 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the content of the hash map. 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HashMap::Clear(); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ScriptCache::HandleWeakScript(v8::Persistent<v8::Value> obj, void* data) { 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data); 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the location of the global handle. 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Script** location = 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<Script**>(Utils::OpenHandle(*obj).location()); 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((*location)->IsScript()); 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the entry from the cache. 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int id = Smi::cast((*location)->id())->value(); 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_cache->Remove(reinterpret_cast<void*>(id), Hash(id)); 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_cache->collected_scripts_.Add(id); 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the weak handle. 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj.Dispose(); 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj.Clear(); 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::Setup(bool create_heap_objects) { 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadInit(); 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (create_heap_objects) { 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get code to handle debug break on return. 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_break_return_ = 71944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak); 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(debug_break_return_->IsCode()); 7217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get code to handle debug break in debug break slots. 7227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch debug_break_slot_ = 72344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->builtins()->builtin(Builtins::kSlot_DebugBreak); 7247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT(debug_break_slot_->IsCode()); 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) { 73044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debug* debug = Isolate::Current()->debug(); 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data); 7328defd9ff6930b4e24729971a61cf7469daf119beSteve Block // We need to clear all breakpoints associated with the function to restore 7338defd9ff6930b4e24729971a61cf7469daf119beSteve Block // original code and avoid patching the code twice later because 7348defd9ff6930b4e24729971a61cf7469daf119beSteve Block // the function will live in the heap until next gc, and can be found by 7358defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Runtime::FindSharedFunctionInfoInScript. 7368defd9ff6930b4e24729971a61cf7469daf119beSteve Block BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 7378defd9ff6930b4e24729971a61cf7469daf119beSteve Block it.ClearAllDebugBreak(); 73844f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->RemoveDebugInfo(node->debug_info()); 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 74044f0eee88ff00398ff7f715fab053374d808c90dSteve Block node = debug->debug_info_list_; 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (node != NULL) { 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data)); 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node = node->next(); 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockDebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { 75044f0eee88ff00398ff7f715fab053374d808c90dSteve Block GlobalHandles* global_handles = Isolate::Current()->global_handles(); 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Globalize the request debug info object and make it weak. 75244f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug_info_ = Handle<DebugInfo>::cast( 75344f0eee88ff00398ff7f715fab053374d808c90dSteve Block (global_handles->Create(debug_info))); 75444f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak( 75544f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<Object**>(debug_info_.location()), 75644f0eee88ff00398ff7f715fab053374d808c90dSteve Block this, 75744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debug::HandleWeakDebugInfo); 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockDebugInfoListNode::~DebugInfoListNode() { 76244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->global_handles()->Destroy( 76344f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<Object**>(debug_info_.location())); 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::CompileDebuggerScript(int index) { 76844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 76944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory = isolate->factory(); 77044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate); 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out if the index is invalid. 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (index == -1) { 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find source and name for the requested script. 77844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> source_code = 77944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->bootstrapper()->NativesSourceLookup(index); 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const char> name = Natives::GetScriptName(index); 78144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> script_name = factory->NewStringFromAscii(name); 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script. 7846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function_info; 7856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info = Compiler::Compile(source_code, 7866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block script_name, 7876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 0, 0, NULL, NULL, 7886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String>::null(), 7896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block NATIVES_CODE); 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Silently ignore stack overflows during compilation. 7926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (function_info.is_null()) { 79344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate->has_pending_exception()); 79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->clear_pending_exception(); 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Execute the shared function in the debugger context. 79944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Context> context = isolate->global_context(); 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> function = 80244f0eee88ff00398ff7f715fab053374d808c90dSteve Block factory->NewFunctionFromSharedFunctionInfo(function_info, context); 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execution::TryCall(function, Handle<Object>(context->global()), 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, NULL, &caught_exception); 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check for caught exceptions. 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> message = MessageHandler::MakeMessageObject( 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "error_loading_debugger", NULL, Vector<Handle<Object> >::empty(), 8113bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<String>(), Handle<JSArray>()); 8128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MessageHandler::ReportMessage(Isolate::Current(), NULL, message); 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark this script as native and return successfully. 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Script> script(Script::cast(function->shared()->script())); 8186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::Load() { 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return if debugger is already loaded. 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsLoaded()) return true; 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 82844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debugger* debugger = isolate_->debugger(); 82944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out if we're already in the process of compiling the native 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // JavaScript source code for the debugger. 83244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (debugger->compiling_natives() || 83344f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->is_loading_debugger()) 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 83544f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->set_loading_debugger(true); 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Disable breakpoints and interrupts while compiling and running the 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // debugger scripts including the context creation code. 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DisableBreak disable(true); 84044f0eee88ff00398ff7f715fab053374d808c90dSteve Block PostponeInterruptsScope postpone(isolate_); 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the debugger context. 84344f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Context> context = 84544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->bootstrapper()->CreateEnvironment( 84644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object>::null(), 84744f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::Handle<ObjectTemplate>(), 84844f0eee88ff00398ff7f715fab053374d808c90dSteve Block NULL); 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use the debugger context. 85144f0eee88ff00398ff7f715fab053374d808c90dSteve Block SaveContext save(isolate_); 85244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->set_context(*context); 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Expose the builtins object in the debugger context. 85544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> key = isolate_->factory()->LookupAsciiSymbol("builtins"); 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<GlobalObject> global = Handle<GlobalObject>(context->global()); 8571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block RETURN_IF_EMPTY_HANDLE_VALUE( 85844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_, 859e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetProperty(global, key, Handle<Object>(global->builtins()), 860e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, kNonStrictMode), 8611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block false); 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the JavaScript for the debugger in the debugger context. 86444f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->set_compiling_natives(true); 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !CompileDebuggerScript(Natives::GetIndex("mirror")) || 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !CompileDebuggerScript(Natives::GetIndex("debug")); 8686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (FLAG_enable_liveedit) { 8706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block caught_exception = caught_exception || 8716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block !CompileDebuggerScript(Natives::GetIndex("liveedit")); 8726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 8736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 87444f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->set_compiling_natives(false); 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure we mark the debugger as not loading before we might 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // return. 87844f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->set_loading_debugger(false); 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check for caught exceptions. 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) return false; 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger loaded. 884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch debug_context_ = context; 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::Unload() { 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return debugger is not loaded. 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsLoaded()) { 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the script cache. 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DestroyScriptCache(); 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear debugger context global handle. 90044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->global_handles()->Destroy( 90144f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<Object**>(debug_context_.location())); 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_context_ = Handle<Context>(); 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set the flag indicating that preemption happened during debugging. 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::PreemptionWhileInDebugger() { 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(InDebugger()); 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debug::set_interrupts_pending(PREEMPT); 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::Iterate(ObjectVisitor* v) { 914756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v->VisitPointer(BitCast<Object**>(&(debug_break_return_))); 915756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v->VisitPointer(BitCast<Object**>(&(debug_break_slot_))); 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9198b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochObject* Debug::Break(Arguments args) { 9208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Heap* heap = isolate_->heap(); 9218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HandleScope scope(isolate_); 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(args.length() == 0); 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED; 9256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the top-most JavaScript frame. 9278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch JavaScriptFrameIterator it(isolate_); 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrame* frame = it.frame(); 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Just continue if breaks are disabled or debugger cannot be loaded. 9318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (disable_break() || !Load()) { 9328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SetAfterBreakTarget(frame); 93344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return heap->undefined_value(); 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debugger.FailedToEnter()) { 93944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return heap->undefined_value(); 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Postpone interrupt during breakpoint processing. 9438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch PostponeInterruptsScope postpone(isolate_); 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the debug info (create it if it does not exist). 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo> shared = 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<DebugInfo> debug_info = GetDebugInfo(shared); 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the break point where execution has stopped. 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakLocationIterator break_location_iterator(debug_info, 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ALL_BREAK_LOCATIONS); 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_location_iterator.FindBreakLocationFromAddress(frame->pc()); 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether step next reached a new statement. 9568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (!StepNextContinue(&break_location_iterator, frame)) { 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Decrease steps left if performing multiple steps. 9588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (thread_local_.step_count_ > 0) { 9598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch thread_local_.step_count_--; 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is one or more real break points check whether any of these are 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // triggered. 96544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> break_points_hit(heap->undefined_value()); 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_location_iterator.HasBreakPoint()) { 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> break_point_objects = 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>(break_location_iterator.BreakPointObjects()); 9698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch break_points_hit = CheckBreakPoints(break_point_objects); 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If step out is active skip everything until the frame where we need to step 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // out to is reached, unless real breakpoint is hit. 9748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (StepOutActive() && frame->fp() != step_out_fp() && 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_points_hit->IsUndefined() ) { 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step count should always be 0 for StepOut. 9778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(thread_local_.step_count_ == 0); 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (!break_points_hit->IsUndefined() || 9798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch (thread_local_.last_step_action_ != StepNone && 9808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch thread_local_.step_count_ == 0)) { 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify debugger if a real break point is triggered or if performing 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // single stepping with no more steps to perform. Otherwise do another step. 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear all current stepping setup. 9858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ClearStepping(); 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify the debug event listeners. 9888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate_->debugger()->OnDebugBreak(break_points_hit, false); 9898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if (thread_local_.last_step_action_ != StepNone) { 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Hold on to last step action as it is cleared by the call to 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ClearStepping. 9928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StepAction step_action = thread_local_.last_step_action_; 9938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int step_count = thread_local_.step_count_; 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear all current stepping setup. 9968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ClearStepping(); 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set up for the remaining steps. 9998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch PrepareStep(step_action, step_count); 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) { 10038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SetAfterBreakTarget(frame); 10048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if (thread_local_.frame_drop_mode_ == 100544f0eee88ff00398ff7f715fab053374d808c90dSteve Block FRAME_DROPPED_IN_IC_CALL) { 10068defd9ff6930b4e24729971a61cf7469daf119beSteve Block // We must have been calling IC stub. Do not go there anymore. 10078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Code* plain_return = isolate_->builtins()->builtin( 10088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Builtins::kPlainReturn_LiveEdit); 10098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch thread_local_.after_break_target_ = plain_return->entry(); 10108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if (thread_local_.frame_drop_mode_ == 10118defd9ff6930b4e24729971a61cf7469daf119beSteve Block FRAME_DROPPED_IN_DEBUG_SLOT_CALL) { 10128defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Debug break slot stub does not return normally, instead it manually 10138defd9ff6930b4e24729971a61cf7469daf119beSteve Block // cleans the stack and jumps. We should patch the jump address. 10148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Code* plain_return = isolate_->builtins()->builtin( 101544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kFrameDropper_LiveEdit); 10168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch thread_local_.after_break_target_ = plain_return->entry(); 10178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if (thread_local_.frame_drop_mode_ == 101844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FRAME_DROPPED_IN_DIRECT_CALL) { 10198defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Nothing to do, after_break_target is not used here. 10206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 10218defd9ff6930b4e24729971a61cf7469daf119beSteve Block UNREACHABLE(); 10226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return heap->undefined_value(); 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10288b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(Object*, Debug_Break) { 10298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return isolate->debug()->Break(args); 10308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 10318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 10328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check the break point objects for whether one or more are actually 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// triggered. This function returns a JSArray with the break point objects 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// which is triggered. 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { 103744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory = isolate_->factory(); 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Count the number of break points hit. If there are multiple break points 104044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // they are in a FixedArray. 104144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> break_points_hit; 104244f0eee88ff00398ff7f715fab053374d808c90dSteve Block int break_points_hit_count = 0; 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!break_point_objects->IsUndefined()); 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_point_objects->IsFixedArray()) { 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> array(FixedArray::cast(*break_point_objects)); 104644f0eee88ff00398ff7f715fab053374d808c90dSteve Block break_points_hit = factory->NewFixedArray(array->length()); 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < array->length(); i++) { 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> o(array->get(i)); 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (CheckBreakPoint(o)) { 105044f0eee88ff00398ff7f715fab053374d808c90dSteve Block break_points_hit->set(break_points_hit_count++, *o); 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 105444f0eee88ff00398ff7f715fab053374d808c90dSteve Block break_points_hit = factory->NewFixedArray(1); 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (CheckBreakPoint(break_point_objects)) { 105644f0eee88ff00398ff7f715fab053374d808c90dSteve Block break_points_hit->set(break_points_hit_count++, *break_point_objects); 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Return undefined if no break points were triggered. 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_points_hit_count == 0) { 106244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return factory->undefined_value(); 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 106444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Return break points hit as a JSArray. 106544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit); 106644f0eee88ff00398ff7f715fab053374d808c90dSteve Block result->set_length(Smi::FromInt(break_points_hit_count)); 106744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return result; 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check whether a single break point object is triggered. 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::CheckBreakPoint(Handle<Object> break_point_object) { 107344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 107444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory = isolate_->factory(); 107544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Ignore check if break point object is not a JSObject. 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!break_point_object->IsJSObject()) return true; 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 108044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Get the function IsBreakPointTriggered (defined in debug-debugger.js). 10810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Handle<String> is_break_point_triggered_symbol = 108244f0eee88ff00398ff7f715fab053374d808c90dSteve Block factory->LookupAsciiSymbol("IsBreakPointTriggered"); 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> check_break_point = 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction>(JSFunction::cast( 10855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck debug_context()->global()->GetPropertyNoExceptionThrown( 10860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *is_break_point_triggered_symbol))); 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the break id as an object. 108944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id()); 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call HandleBreakPointx. 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 2; 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[argc] = { 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_id.location(), 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<Object**>(break_point_object.location()) 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = Execution::TryCall(check_break_point, 109944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->js_builtins_object(), argc, argv, &caught_exception); 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If exception or non boolean result handle as not triggered 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception || !result->IsBoolean()) { 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return whether the break point is triggered. 110744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!result.is_null()); 110844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return (*result)->IsTrue(); 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check whether the function has debug information. 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) { 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !shared->debug_info()->IsUndefined(); 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Return the debug info for this function. EnsureDebugInfo must be called 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// prior to ensure the debug info has been generated for shared. 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(HasDebugInfo(shared)); 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, 11279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen Handle<Object> break_point_object, 11289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen int* source_position) { 112944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!EnsureDebugInfo(shared)) { 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return if retrieving debug info failed. 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<DebugInfo> debug_info = GetDebugInfo(shared); 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Source positions starts with zero. 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(source_position >= 0); 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the break point and change it. 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); 11429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen it.FindBreakLocationFromPosition(*source_position); 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.SetBreakPoint(break_point_object); 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11459dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen *source_position = it.position(); 11469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // At least one active break point now. 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(debug_info->GetBreakPointCount() > 0); 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ClearBreakPoint(Handle<Object> break_point_object) { 115344f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* node = debug_info_list_; 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (node != NULL) { 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_object); 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!result->IsUndefined()) { 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get information in the break point. 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakPointInfo* break_point_info = BreakPointInfo::cast(result); 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<DebugInfo> debug_info = node->debug_info(); 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo> shared(debug_info->shared()); 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int source_position = break_point_info->statement_position()->value(); 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Source positions starts with zero. 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(source_position >= 0); 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the break point and clear it. 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.FindBreakLocationFromPosition(source_position); 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.ClearBreakPoint(break_point_object); 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there are no more break points left remove the debug info for this 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function. 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debug_info->GetBreakPointCount() == 0) { 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RemoveDebugInfo(debug_info); 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node = node->next(); 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ClearAllBreakPoints() { 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* node = debug_info_list_; 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (node != NULL) { 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove all debug break code. 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.ClearAllDebugBreak(); 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node = node->next(); 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove all debug info. 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (debug_info_list_ != NULL) { 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RemoveDebugInfo(debug_info_list_->debug_info()); 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { 1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure the function has setup the debug info. 1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!EnsureDebugInfo(shared)) { 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return if we failed to retrieve the debug info. 1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Flood the function with break points. 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!it.Done()) { 1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.SetOneShot(); 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.Next(); 1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::FloodHandlerWithOneShot() { 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate through the JavaScript stack looking for handlers. 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::Id id = break_frame_id(); 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (id == StackFrame::NO_ID) { 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is no JavaScript stack don't do anything. 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 12268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) { 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrame* frame = it.frame(); 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (frame->HasHandler()) { 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo> shared = 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo>( 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction::cast(frame->function())->shared()); 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Flood the function with the catch block with break points 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FloodWithOneShot(shared); 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (type == BreakUncaughtException) { 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_on_uncaught_exception_ = enable; 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_on_exception_ = enable; 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12490d5e116f6aee03185f237311a943491bb079a768Kristian Monsenbool Debug::IsBreakOnException(ExceptionBreakType type) { 12500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (type == BreakUncaughtException) { 12510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return break_on_uncaught_exception_; 12520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 12530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return break_on_exception_; 12540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 12550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 12560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 12570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::PrepareStep(StepAction step_action, int step_count) { 125944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 126044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Debug::InDebugger()); 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remember this step action and count. 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_step_action_ = step_action; 1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (step_action == StepOut) { 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For step out target frame will be found on the stack so there is no need 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to set step counter for it. It's expected to always be 0 for StepOut. 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_count_ = 0; 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_count_ = step_count; 1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the frame where the execution has stopped and skip the debug frame if 1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // any. The debug frame will only be present if execution was stopped due to 1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // hitting a break point. In other situations (e.g. unhandled exception) the 1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // debug frame is not present. 1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::Id id = break_frame_id(); 1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (id == StackFrame::NO_ID) { 1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is no JavaScript stack don't do anything. 1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 12828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch JavaScriptFrameIterator frames_it(isolate_, id); 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrame* frame = frames_it.frame(); 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // First of all ensure there is one-shot break points in the top handler 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // if any. 1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FloodHandlerWithOneShot(); 1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the function on the top frame is unresolved perform step out. This will 1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // be the case when calling unknown functions and having the debugger stopped 1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in an unhandled exception. 1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame->function()->IsJSFunction()) { 1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step out: Find the calling JavaScript frame and flood it with 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // breakpoints. 1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frames_it.Advance(); 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill the function to return to with one-shot break points. 1297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* function = JSFunction::cast(frames_it.frame()->function()); 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the debug info (create it if it does not exist). 1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo> shared = 1304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); 1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!EnsureDebugInfo(shared)) { 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return if ensuring debug info failed. 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<DebugInfo> debug_info = GetDebugInfo(shared); 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the break location where execution has stopped. 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); 1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.FindBreakLocationFromAddress(frame->pc()); 1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute whether or not the target is a call target. 1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_load_or_store = false; 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_inline_cache_stub = false; 1318bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch bool is_at_restarted_function = false; 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> call_function_stub; 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1321bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (thread_local_.restarter_frame_function_pointer_ == NULL) { 1322bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { 1323bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch bool is_call_target = false; 1324bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Address target = it.rinfo()->target_address(); 1325bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Code* code = Code::GetCodeFromTargetAddress(target); 1326bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (code->is_call_stub() || code->is_keyed_call_stub()) { 1327bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch is_call_target = true; 1328bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1329bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (code->is_inline_cache_stub()) { 1330bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch is_inline_cache_stub = true; 1331bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch is_load_or_store = !is_call_target; 1332bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1333bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 1334bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Check if target code is CallFunction stub. 1335bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Code* maybe_call_function_stub = code; 1336bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // If there is a breakpoint at this line look at the original code to 1337bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // check if it is a CallFunction stub. 1338bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (it.IsDebugBreak()) { 1339bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Address original_target = it.original_rinfo()->target_address(); 1340bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch maybe_call_function_stub = 1341bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Code::GetCodeFromTargetAddress(original_target); 1342bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1343bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (maybe_call_function_stub->kind() == Code::STUB && 1344bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch maybe_call_function_stub->major_key() == CodeStub::CallFunction) { 1345bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Save reference to the code as we may need it to find out arguments 1346bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // count for 'step in' later. 1347bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch call_function_stub = Handle<Code>(maybe_call_function_stub); 1348bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1350bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } else { 1351bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch is_at_restarted_function = true; 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If this is the last break code target step out is the only possibility. 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (it.IsExit() || step_action == StepOut) { 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (step_action == StepOut) { 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip step_count frames starting with the current one. 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (step_count-- > 0 && !frames_it.done()) { 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frames_it.Advance(); 1360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(it.IsExit()); 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frames_it.Advance(); 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip builtin functions on the stack. 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!frames_it.done() && 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction::cast(frames_it.frame()->function())->IsBuiltin()) { 1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frames_it.Advance(); 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step out: If there is a JavaScript caller frame, we need to 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // flood it with breakpoints. 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frames_it.done()) { 1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill the function to return to with one-shot break points. 1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* function = JSFunction::cast(frames_it.frame()->function()); 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set target frame pointer. 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ActivateStepOut(frames_it.frame()); 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) || 1380bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch !call_function_stub.is_null() || is_at_restarted_function) 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block || step_action == StepNext || step_action == StepMin) { 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step next or step min. 1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill the current function with one-shot break points. 1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FloodWithOneShot(shared); 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remember source position and frame to handle step next. 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_statement_position_ = 1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_info->code()->SourceStatementPosition(frame->pc()); 1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_fp_ = frame->fp(); 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1392bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // If there's restarter frame on top of the stack, just get the pointer 1393bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // to function which is going to be restarted. 1394bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (is_at_restarted_function) { 1395bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Handle<JSFunction> restarted_function( 1396bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch JSFunction::cast(*thread_local_.restarter_frame_function_pointer_)); 1397bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Handle<SharedFunctionInfo> restarted_shared( 1398bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch restarted_function->shared()); 1399bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch FloodWithOneShot(restarted_shared); 1400bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } else if (!call_function_stub.is_null()) { 1401bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // If it's CallFunction stub ensure target function is compiled and flood 1402bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // it with one shot breakpoints. 1403bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find out number of arguments from the stub minor key. 1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reverse lookup required as the minor key cannot be retrieved 1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // from the code object. 1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> obj( 140844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->code_stubs()->SlowReverseLookup( 140944f0eee88ff00398ff7f715fab053374d808c90dSteve Block *call_function_stub)); 141044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!obj.is_null()); 141144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!(*obj)->IsUndefined()); 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(obj->IsSmi()); 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the STUB key and extract major and minor key. 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t key = Smi::cast(*obj)->value(); 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Argc in the stub is the number of arguments passed - not the 1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // expected arguments of the called function. 1417e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int call_function_arg_count = 1418e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CallFunctionStub::ExtractArgcFromMinorKey( 1419e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CodeStub::MinorKeyFromKey(key)); 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(call_function_stub->major_key() == 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeStub::MajorKeyFromKey(key)); 1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find target function on the expression stack. 1424e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Expression stack looks like this (top to bottom): 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // argN 1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ... 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // arg0 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Receiver 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Function to call 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int expressions_count = frame->ComputeExpressionsCount(); 1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(expressions_count - 2 - call_function_arg_count >= 0); 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* fun = frame->GetExpression( 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expressions_count - 2 - call_function_arg_count); 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (fun->IsJSFunction()) { 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> js_function(JSFunction::cast(fun)); 1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't step into builtins. 1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!js_function->IsBuiltin()) { 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // It will also compile target function if it's not compiled yet. 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FloodWithOneShot(Handle<SharedFunctionInfo>(js_function->shared())); 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill the current function with one-shot break points even for step in on 1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a call target as the function called might be a native function for 1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // which step in will not stop. It also prepares for stepping in 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // getters/setters. 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FloodWithOneShot(shared); 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_load_or_store) { 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remember source position and frame to handle step in getter/setter. If 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // there is a custom getter/setter it will be handled in 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Object::Get/SetPropertyWithCallback, otherwise the step action will be 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // propagated on the next Debug::Break. 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_statement_position_ = 1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_info->code()->SourceStatementPosition(frame->pc()); 1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_fp_ = frame->fp(); 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step in or Step in min 1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.PrepareStepIn(); 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ActivateStepIn(frame); 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check whether the current debug break should be reported to the debugger. It 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// is used to have step next and step in only report break back to the debugger 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// if on a different frame or in a different statement. In some situations 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// there will be several break points in the same statement when the code is 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// flooded with one-shot break points. This function helps to perform several 1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// steps before reporting break back to the debugger. 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrame* frame) { 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the step last action was step next or step in make sure that a new 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // statement is hit. 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (thread_local_.last_step_action_ == StepNext || 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_step_action_ == StepIn) { 1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Never continue if returning from function. 1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_location_iterator->IsExit()) return false; 1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Continue if we are still on the same frame and in the same statement. 1483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int current_statement_position = 1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_location_iterator->code()->SourceStatementPosition(frame->pc()); 1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.last_fp_ == frame->fp() && 1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_statement_position_ == current_statement_position; 1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No step next action - don't continue. 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check whether the code object at the specified address is a debug break code 1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// object. 1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::IsDebugBreak(Address addr) { 1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* code = Code::GetCodeFromTargetAddress(addr); 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code->ic_state() == DEBUG_BREAK; 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check whether a code stub with the specified major key is a possible break 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// point location when looking for source break locations. 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::IsSourceBreakStub(Code* code) { 150580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CodeStub::Major major_key = CodeStub::GetMajorKey(code); 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return major_key == CodeStub::CallFunction; 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check whether a code stub with the specified major key is a possible break 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// location. 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::IsBreakStub(Code* code) { 151380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CodeStub::Major major_key = CodeStub::GetMajorKey(code); 15143e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu return major_key == CodeStub::CallFunction; 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Find the builtin to use for invoking the debug break 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) { 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the builtin debug break function matching the calling convention 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // used by the call site. 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (code->is_inline_cache_stub()) { 15236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block switch (code->kind()) { 15246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block case Code::CALL_IC: 15257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch case Code::KEYED_CALL_IC: 15267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return ComputeCallDebugBreak(code->arguments_count(), code->kind()); 15276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block case Code::LOAD_IC: 152944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->LoadIC_DebugBreak(); 15306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block case Code::STORE_IC: 153244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->StoreIC_DebugBreak(); 15336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block case Code::KEYED_LOAD_IC: 153544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->KeyedLoadIC_DebugBreak(); 15366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block case Code::KEYED_STORE_IC: 153844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->KeyedStoreIC_DebugBreak(); 15396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block default: 15416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block UNREACHABLE(); 1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsConstructCall(mode)) { 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> result = 154644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->builtins()->ConstructCall_DebugBreak(); 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (code->kind() == Code::STUB) { 15503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu ASSERT(code->major_key() == CodeStub::CallFunction); 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> result = 155244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->builtins()->StubNoRegisters_DebugBreak(); 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<Code>::null(); 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Simple function for returning the source positions for active break points. 1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debug::GetSourceBreakLocations( 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo> shared) { 156444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 156544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap = isolate->heap(); 156644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!HasDebugInfo(shared)) return Handle<Object>(heap->undefined_value()); 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<DebugInfo> debug_info = GetDebugInfo(shared); 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debug_info->GetBreakPointCount() == 0) { 156944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Handle<Object>(heap->undefined_value()); 1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> locations = 157244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); 1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = 0; 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < debug_info->break_points()->length(); i++) { 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!debug_info->break_points()->get(i)->IsUndefined()) { 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakPointInfo* break_point_info = 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakPointInfo::cast(debug_info->break_points()->get(i)); 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_point_info->GetBreakPointCount() > 0) { 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block locations->set(count++, break_point_info->statement_position()); 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return locations; 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::NewBreak(StackFrame::Id break_frame_id) { 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.break_frame_id_ = break_frame_id; 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.break_id_ = ++thread_local_.break_count_; 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) { 1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.break_frame_id_ = break_frame_id; 1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.break_id_ = break_id; 1596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Handle stepping into a function. 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::HandleStepIn(Handle<JSFunction> function, 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> holder, 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp, 1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_constructor) { 1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the frame pointer is not supplied by the caller find it. 1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (fp == 0) { 1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator it; 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.Advance(); 1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For constructor functions skip another frame. 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_constructor) { 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(it.frame()->is_construct()); 1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.Advance(); 1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fp = it.frame()->fp(); 1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Flood the function with one-shot break points if it is called from where 1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // step into was requested. 161844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (fp == step_in_fp()) { 1619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't allow step into functions in the native context. 1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!function->IsBuiltin()) { 1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (function->shared()->code() == 162244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) || 1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block function->shared()->code() == 162444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->builtins()->builtin(Builtins::kFunctionCall)) { 1625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Handle function.apply and function.call separately to flood the 1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function to be called and not the code for Builtins::FunctionApply or 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Builtins::FunctionCall. The receiver of call/apply is the target 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function. 1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!holder.is_null() && holder->IsJSFunction() && 1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !JSFunction::cast(*holder)->IsBuiltin()) { 1631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo> shared_info( 1632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction::cast(*holder)->shared()); 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debug::FloodWithOneShot(shared_info); 1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared())); 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ClearStepping() { 1644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the various stepping setup. 1645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearOneShot(); 1646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearStepIn(); 1647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearStepOut(); 1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearStepNext(); 1649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear multiple step counter. 1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_count_ = 0; 1652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Clears all the one-shot break points that are currently set. Normally this 1655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function is called each time a break point is hit as one shot break points 1656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are used to support stepping. 1657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ClearOneShot() { 1658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The current implementation just runs through all the breakpoints. When the 1659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // last break point for a function is removed that function is automatically 1660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // removed from the list. 1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* node = debug_info_list_; 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (node != NULL) { 1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!it.Done()) { 1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.ClearOneShot(); 1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.Next(); 1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node = node->next(); 1670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ActivateStepIn(StackFrame* frame) { 1675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!StepOutActive()); 1676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_into_fp_ = frame->fp(); 1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ClearStepIn() { 1681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_into_fp_ = 0; 1682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ActivateStepOut(StackFrame* frame) { 1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!StepInActive()); 1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_out_fp_ = frame->fp(); 1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ClearStepOut() { 1692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.step_out_fp_ = 0; 1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ClearStepNext() { 1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_step_action_ = StepNone; 1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.last_fp_ = 0; 1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Ensures the debug information is present for shared. 1704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { 1705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return if we already have the debug info for shared. 1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (HasDebugInfo(shared)) return true; 1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Ensure shared in compiled. Return false if this failed. 17094515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; 1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // If preparing for the first break point make sure to deoptimize all 1712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // functions as debugging does not work with optimized code. 1713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!has_break_points_) { 1714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Deoptimizer::DeoptimizeAll(); 1715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the debug info object. 171844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); 1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add debug info to the list. 1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* node = new DebugInfoListNode(*debug_info); 1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node->set_next(debug_info_list_); 1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_info_list_ = node; 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Now there is at least one break point. 1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block has_break_points_ = true; 1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { 1733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(debug_info_list_ != NULL); 1734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run through the debug info objects to find this one and remove it. 1735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* prev = NULL; 1736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* current = debug_info_list_; 1737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (current != NULL) { 1738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*current->debug_info() == *debug_info) { 1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unlink from list. If prev is NULL we are looking at the first element. 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (prev == NULL) { 1741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_info_list_ = current->next(); 1742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block prev->set_next(current->next()); 1744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 174544f0eee88ff00398ff7f715fab053374d808c90dSteve Block current->debug_info()->shared()->set_debug_info( 174644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->undefined_value()); 1747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete current; 1748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there are no more debug info objects there are not more break 1750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // points. 1751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block has_break_points_ = debug_info_list_ != NULL; 1752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move to next in list. 1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block prev = current; 1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current = current->next(); 1758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 1760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { 176444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 176544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 1766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the executing function in which the debug break occurred. 1768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo> shared = 1769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); 1770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!EnsureDebugInfo(shared)) { 1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return if we failed to retrieve the debug info. 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<DebugInfo> debug_info = GetDebugInfo(shared); 1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code(debug_info->code()); 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> original_code(debug_info->original_code()); 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the code which is actually executing. 17798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Code> frame_code(frame->LookupCode()); 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame_code.is_identical_to(code)); 1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the call address in the running code. This address holds the call to 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // either a DebugBreakXXX or to the debug break return entry code if the 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // break point is still active after processing the break point. 1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address addr = frame->pc() - Assembler::kCallTargetAddressOffset; 1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if the location is at JS exit or debug break slot. 1789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool at_js_return = false; 1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool break_at_js_return_active = false; 17917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch bool at_debug_break_slot = false; 1792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocIterator it(debug_info->code()); 17937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch while (!it.done() && !at_js_return && !at_debug_break_slot) { 1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block at_js_return = (it.rinfo()->pc() == 1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block addr - Assembler::kPatchReturnSequenceAddressOffset); 17973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence(); 1798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 17997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) { 18007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch at_debug_break_slot = (it.rinfo()->pc() == 18017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch addr - Assembler::kPatchDebugBreakSlotAddressOffset); 18027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.next(); 1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Handle the jump to continue execution after break point depending on the 1807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // break location. 1808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (at_js_return) { 1809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the break point as return is still active jump to the corresponding 1810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // place in the original code. If not the break point was removed during 1811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // break point processing. 1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_at_js_return_active) { 1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block addr += original_code->instruction_start() - code->instruction_start(); 1814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move back to where the call instruction sequence started. 1817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.after_break_target_ = 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block addr - Assembler::kPatchReturnSequenceAddressOffset; 18197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (at_debug_break_slot) { 18207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Address of where the debug break slot starts. 18217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset; 18227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 18237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Continue just after the slot. 18247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch thread_local_.after_break_target_ = addr + Assembler::kDebugBreakSlotLength; 18257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (IsDebugBreak(Assembler::target_address_at(addr))) { 18267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // We now know that there is still a debug break call at the target address, 18277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // so the break point is still there and the original code will hold the 18287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // address to jump to in order to complete the call which is replaced by a 18297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // call to DebugBreakXXX. 18307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 18317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Find the corresponding address in the original code. 18327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch addr += original_code->instruction_start() - code->instruction_start(); 1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Install jump to the call address in the original code. This will be the 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // call which was overwritten by the call to DebugBreakXXX. 1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.after_break_target_ = Assembler::target_address_at(addr); 18377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 18387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // There is no longer a break point present. Don't try to look in the 18397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // original code as the running code will have the right address. This takes 18407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // care of the case where the last break point is removed from the function 18417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // and therefore no "original code" is available. 18427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch thread_local_.after_break_target_ = Assembler::target_address_at(addr); 1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 184844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 18497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 18507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get the executing function in which the debug break occurred. 18517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Handle<SharedFunctionInfo> shared = 18527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); 18537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (!EnsureDebugInfo(shared)) { 18547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Return if we failed to retrieve the debug info. 18557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return false; 18567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 18577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Handle<DebugInfo> debug_info = GetDebugInfo(shared); 18587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Handle<Code> code(debug_info->code()); 18597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef DEBUG 18607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get the code which is actually executing. 18618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Code> frame_code(frame->LookupCode()); 18627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT(frame_code.is_identical_to(code)); 18637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 18647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 18657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Find the call address in the running code. 18667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Address addr = frame->pc() - Assembler::kCallTargetAddressOffset; 18677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 18687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if the location is at JS return. 18697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch RelocIterator it(debug_info->code()); 18707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch while (!it.done()) { 18717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { 18727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return (it.rinfo()->pc() == 18737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch addr - Assembler::kPatchReturnSequenceAddressOffset); 18747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 18757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch it.next(); 18767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 18777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return false; 18787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 18797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 18807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 18818defd9ff6930b4e24729971a61cf7469daf119beSteve Blockvoid Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, 1882bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch FrameDropMode mode, 1883bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Object** restarter_frame_function_pointer) { 18848defd9ff6930b4e24729971a61cf7469daf119beSteve Block thread_local_.frame_drop_mode_ = mode; 18856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block thread_local_.break_frame_id_ = new_break_frame_id; 1886bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch thread_local_.restarter_frame_function_pointer_ = 1887bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch restarter_frame_function_pointer; 18886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 18896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 18906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::IsDebugGlobal(GlobalObject* global) { 189244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return IsLoaded() && global == debug_context()->global(); 1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::ClearMirrorCache() { 189744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 189844f0eee88ff00398ff7f715fab053374d808c90dSteve Block PostponeInterruptsScope postpone(isolate_); 189944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 190044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate_->context() == *Debug::debug_context()); 1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the mirror cache. 1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> function_name = 190444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->factory()->LookupSymbol(CStrVector("ClearMirrorCache")); 190544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> fun(Isolate::Current()->global()->GetPropertyNoExceptionThrown( 19065913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck *function_name)); 1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(fun->IsJSFunction()); 1908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception; 1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> js_object = Execution::TryCall( 1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction>::cast(fun), 1911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>(Debug::debug_context()->global()), 1912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, NULL, &caught_exception); 1913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::CreateScriptCache() { 191744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 191844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap = isolate_->heap(); 191944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform two GCs to get rid of all unreferenced scripts. The first GC gets 1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // rid of all the cached script wrappers and the second gets rid of the 19233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // scripts which are no longer referenced. 192444f0eee88ff00398ff7f715fab053374d808c90dSteve Block heap->CollectAllGarbage(false); 192544f0eee88ff00398ff7f715fab053374d808c90dSteve Block heap->CollectAllGarbage(false); 1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(script_cache_ == NULL); 1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_cache_ = new ScriptCache(); 1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scan heap for Script objects. 1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = 0; 1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapIterator iterator; 1933d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 19343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { 1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_cache_->Add(Handle<Script>(Script::cast(obj))); 1936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block count++; 1937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::DestroyScriptCache() { 1943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the script cache if it was created. 1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script_cache_ != NULL) { 1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete script_cache_; 1946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_cache_ = NULL; 1947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::AddScriptToScriptCache(Handle<Script> script) { 1952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script_cache_ != NULL) { 1953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_cache_->Add(script); 1954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> Debug::GetLoadedScripts() { 195944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create and fill the script cache when the loaded scripts is requested for 1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the first time. 1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script_cache_ == NULL) { 1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CreateScriptCache(); 1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the script cache is not active just return an empty array. 1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(script_cache_ != NULL); 1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script_cache_ == NULL) { 196944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->factory()->NewFixedArray(0); 1970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform GC to get unreferenced scripts evicted from the cache before 1973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // returning the content. 197444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->CollectAllGarbage(false); 1975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the scripts from the cache. 1977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return script_cache_->GetScripts(); 1978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::AfterGarbageCollection() { 1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generate events for collected scripts. 1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (script_cache_ != NULL) { 1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_cache_->ProcessCollectedScripts(); 1985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19896d7cb000ed533f52d745e60663019ff891bb19a8Ben MurdochDebugger::Debugger(Isolate* isolate) 19906d7cb000ed533f52d745e60663019ff891bb19a8Ben Murdoch : debugger_access_(isolate->debugger_access()), 199144f0eee88ff00398ff7f715fab053374d808c90dSteve Block event_listener_(Handle<Object>()), 199244f0eee88ff00398ff7f715fab053374d808c90dSteve Block event_listener_data_(Handle<Object>()), 199344f0eee88ff00398ff7f715fab053374d808c90dSteve Block compiling_natives_(false), 199444f0eee88ff00398ff7f715fab053374d808c90dSteve Block is_loading_debugger_(false), 199544f0eee88ff00398ff7f715fab053374d808c90dSteve Block never_unload_debugger_(false), 199644f0eee88ff00398ff7f715fab053374d808c90dSteve Block message_handler_(NULL), 199744f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger_unload_pending_(false), 199844f0eee88ff00398ff7f715fab053374d808c90dSteve Block host_dispatch_handler_(NULL), 199944f0eee88ff00398ff7f715fab053374d808c90dSteve Block dispatch_handler_access_(OS::CreateMutex()), 200044f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug_message_dispatch_handler_(NULL), 200144f0eee88ff00398ff7f715fab053374d808c90dSteve Block message_dispatch_helper_thread_(NULL), 200244f0eee88ff00398ff7f715fab053374d808c90dSteve Block host_dispatch_micros_(100 * 1000), 200344f0eee88ff00398ff7f715fab053374d808c90dSteve Block agent_(NULL), 200444f0eee88ff00398ff7f715fab053374d808c90dSteve Block command_queue_(kQueueInitialSize), 200544f0eee88ff00398ff7f715fab053374d808c90dSteve Block command_received_(OS::CreateSemaphore(0)), 20066d7cb000ed533f52d745e60663019ff891bb19a8Ben Murdoch event_command_queue_(kQueueInitialSize), 20076d7cb000ed533f52d745e60663019ff891bb19a8Ben Murdoch isolate_(isolate) { 200844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 200944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 201044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 201144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDebugger::~Debugger() { 201244f0eee88ff00398ff7f715fab053374d808c90dSteve Block delete dispatch_handler_access_; 201344f0eee88ff00398ff7f715fab053374d808c90dSteve Block dispatch_handler_access_ = 0; 201444f0eee88ff00398ff7f715fab053374d808c90dSteve Block delete command_received_; 201544f0eee88ff00398ff7f715fab053374d808c90dSteve Block command_received_ = 0; 201644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 2017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, 2020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, Object*** argv, 2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 202244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 202344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); 2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the execution state object. 202644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<String> constructor_str = 202744f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->factory()->LookupSymbol(constructor_name); 202844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> constructor( 202944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->global()->GetPropertyNoExceptionThrown(*constructor_str)); 2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(constructor->IsJSFunction()); 2031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!constructor->IsJSFunction()) { 2032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *caught_exception = true; 203344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate_->factory()->undefined_value(); 2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> js_object = Execution::TryCall( 2036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction>::cast(constructor), 203744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject>(isolate_->debug()->debug_context()->global()), 203844f0eee88ff00398ff7f715fab053374d808c90dSteve Block argc, argv, caught_exception); 2039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return js_object; 2040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debugger::MakeExecutionState(bool* caught_exception) { 204444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the execution state object. 204644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> break_id = isolate_->factory()->NewNumberFromInt( 204744f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->debug()->break_id()); 2048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[argc] = { break_id.location() }; 2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MakeJSObject(CStrVector("MakeExecutionState"), 2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv, caught_exception); 2052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state, 2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> break_points_hit, 2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 205844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the new break event object. 2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 2; 2061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[argc] = { exec_state.location(), 2062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_points_hit.location() }; 2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MakeJSObject(CStrVector("MakeBreakEvent"), 2064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, 2065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argv, 2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught_exception); 2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state, 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> exception, 2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool uncaught, 2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 207444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 207544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory = isolate_->factory(); 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the new exception event object. 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 3; 2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[argc] = { exec_state.location(), 2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception.location(), 208044f0eee88ff00398ff7f715fab053374d808c90dSteve Block uncaught ? factory->true_value().location() : 208144f0eee88ff00398ff7f715fab053374d808c90dSteve Block factory->false_value().location()}; 2082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MakeJSObject(CStrVector("MakeExceptionEvent"), 2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv, caught_exception); 2084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function, 2088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 208944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the new function event object. 2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[argc] = { function.location() }; 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MakeJSObject(CStrVector("MakeNewFunctionEvent"), 2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv, caught_exception); 2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debugger::MakeCompileEvent(Handle<Script> script, 2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool before, 2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 210144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 210244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Factory* factory = isolate_->factory(); 2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the compile event object. 2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> exec_state = MakeExecutionState(caught_exception); 2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> script_wrapper = GetScriptWrapper(script); 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 3; 2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[argc] = { exec_state.location(), 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_wrapper.location(), 210944f0eee88ff00398ff7f715fab053374d808c90dSteve Block before ? factory->true_value().location() : 211044f0eee88ff00398ff7f715fab053374d808c90dSteve Block factory->false_value().location() }; 2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MakeJSObject(CStrVector("MakeCompileEvent"), 2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, 2114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argv, 2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught_exception); 2116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debugger::MakeScriptCollectedEvent(int id, 2120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 212144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the script collected event object. 2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> exec_state = MakeExecutionState(caught_exception); 2124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id)); 2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 2; 2126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[argc] = { exec_state.location(), id_object.location() }; 2127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MakeJSObject(CStrVector("MakeScriptCollectedEvent"), 2129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, 2130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argv, 2131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught_exception); 2132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::OnException(Handle<Object> exception, bool uncaught) { 213644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 213744f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 213844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debug* debug = isolate_->debug(); 2139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out based on state or if there is no listener for this event 214144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (debug->InDebugger()) return; 2142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Debugger::EventActive(v8::Exception)) return; 2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out if exception breaks are not active 2145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (uncaught) { 2146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Uncaught exceptions are reported by either flags. 214744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!(debug->break_on_uncaught_exception() || 214844f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->break_on_exception())) return; 2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Caught exceptions are reported is activated. 215144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!debug->break_on_exception()) return; 2152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. 2155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 2156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debugger.FailedToEnter()) return; 2157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear all current stepping setup. 215944f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->ClearStepping(); 2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the event data object. 2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 2162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> exec_state = MakeExecutionState(&caught_exception); 2163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> event_data; 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!caught_exception) { 2165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_data = MakeExceptionEvent(exec_state, exception, uncaught, 2166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out and don't call debugger if exception. 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Process debug event. 2174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); 2175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return to continue execution from where the exception was thrown. 2176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::OnDebugBreak(Handle<Object> break_points_hit, 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool auto_continue) { 218144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 218244f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger has already been entered by caller. 218544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out if there is no listener for this event 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Debugger::EventActive(v8::Break)) return; 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Debugger must be entered in advance. 219144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current()->context() == *isolate_->debug()->debug_context()); 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the event data object. 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> exec_state = MakeExecutionState(&caught_exception); 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> event_data; 2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!caught_exception) { 2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_data = MakeBreakEvent(exec_state, break_points_hit, 2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out and don't call debugger if exception. 2202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Process debug event. 2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ProcessDebugEvent(v8::Break, 2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(event_data), 2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block auto_continue); 2210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::OnBeforeCompile(Handle<Script> script) { 221444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 221544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out based on state or if there is no listener for this event 221844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate_->debug()->InDebugger()) return; 2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (compiling_natives()) return; 2220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!EventActive(v8::BeforeCompile)) return; 2221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. 2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 2224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debugger.FailedToEnter()) return; 2225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the event data object. 2227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 2228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception); 2229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out and don't call debugger if exception. 2230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 2231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Process debug event. 2235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ProcessDebugEvent(v8::BeforeCompile, 2236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(event_data), 2237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block true); 2238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Handle debugger actions when a new script is compiled. 22426ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Debugger::OnAfterCompile(Handle<Script> script, 22436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block AfterCompileFlags after_compile_flags) { 224444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 224544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 224644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debug* debug = isolate_->debug(); 2247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add the newly compiled script to the script cache. 224944f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->AddScriptToScriptCache(script); 2250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No more to do if not debugging. 2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsDebuggerActive()) return; 2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No compile events while compiling natives. 2255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (compiling_natives()) return; 2256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Store whether in debugger before entering debugger. 225844f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool in_debugger = debug->InDebugger(); 2259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. 2261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 2262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debugger.FailedToEnter()) return; 2263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If debugging there might be script break points registered for this 2265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // script. Make sure that these break points are set. 2266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). 22680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Handle<String> update_script_break_points_symbol = 226944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->factory()->LookupAsciiSymbol("UpdateScriptBreakPoints"); 2270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> update_script_break_points = 227144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object>(debug->debug_context()->global()-> 22725913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck GetPropertyNoExceptionThrown(*update_script_break_points_symbol)); 2273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!update_script_break_points->IsJSFunction()) { 2274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(update_script_break_points->IsJSFunction()); 2277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Wrap the script object in a proper JS object before passing it 2279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to JavaScript. 2280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSValue> wrapper = GetScriptWrapper(script); 2281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call UpdateScriptBreakPoints expect no exceptions. 2283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 2284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 2285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[argc] = { reinterpret_cast<Object**>(wrapper.location()) }; 2286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = Execution::TryCall( 2287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction>::cast(update_script_break_points), 228844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->js_builtins_object(), argc, argv, 2289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 2290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 2291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out based on state or if there is no listener for this event 22946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return; 2295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Debugger::EventActive(v8::AfterCompile)) return; 2296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the compile state object. 2298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> event_data = MakeCompileEvent(script, 2299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block false, 2300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 2301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out and don't call debugger if exception. 2302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 2303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Process debug event. 2306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ProcessDebugEvent(v8::AfterCompile, 2307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(event_data), 2308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block true); 2309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::OnScriptCollected(int id) { 231344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 231444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 2315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No more to do if not debugging. 2317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IsDebuggerActive()) return; 2318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Debugger::EventActive(v8::ScriptCollected)) return; 2319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. 2321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 2322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debugger.FailedToEnter()) return; 2323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the script collected state object. 2325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 2326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> event_data = MakeScriptCollectedEvent(id, 2327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 2328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Bail out and don't call debugger if exception. 2329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 2330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Process debug event. 2334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ProcessDebugEvent(v8::ScriptCollected, 2335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(event_data), 2336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block true); 2337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::ProcessDebugEvent(v8::DebugEvent event, 2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> event_data, 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool auto_continue) { 234344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 234444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 2345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear any pending debug break if this is a real break. 2347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!auto_continue) { 234844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->debug()->clear_interrupt_pending(DEBUGBREAK); 2349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the execution state. 2352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 2353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> exec_state = MakeExecutionState(&caught_exception); 2354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 2355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // First notify the message handler if any. 2358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message_handler_ != NULL) { 2359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NotifyMessageHandler(event, 2360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(exec_state), 2361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_data, 2362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block auto_continue); 2363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 23643bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Notify registered debug event listener. This can be either a C or 23653bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // a JavaScript function. Don't call event listener for v8::Break 23663bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // here, if it's only a debug command -- they will be processed later. 23673bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) { 23683bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CallEventCallback(event, exec_state, event_data, NULL); 23693bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 23703bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Process pending debug commands. 23713bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (event == v8::Break) { 23723bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch while (!event_command_queue_.IsEmpty()) { 23733bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CommandMessage command = event_command_queue_.Get(); 23743bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (!event_listener_.is_null()) { 23753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CallEventCallback(v8::BreakForCommand, 23763bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch exec_state, 23773bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch event_data, 23783bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch command.client_data()); 23793bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 23803bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch command.Dispose(); 2381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23863bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochvoid Debugger::CallEventCallback(v8::DebugEvent event, 23873bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Object> exec_state, 23883bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Object> event_data, 23893bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::ClientData* client_data) { 23903bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (event_listener_->IsProxy()) { 23913bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CallCEventCallback(event, exec_state, event_data, client_data); 23923bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } else { 23933bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CallJSEventCallback(event, exec_state, event_data); 23943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 23953bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 23963bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 23973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 23983bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochvoid Debugger::CallCEventCallback(v8::DebugEvent event, 23993bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Object> exec_state, 24003bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Object> event_data, 24013bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::ClientData* client_data) { 24023bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_)); 24033bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::EventCallback2 callback = 24043bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch FUNCTION_CAST<v8::Debug::EventCallback2>(callback_obj->proxy()); 24053bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch EventDetailsImpl event_details( 24063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch event, 24073bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<JSObject>::cast(exec_state), 24083bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<JSObject>::cast(event_data), 24093bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch event_listener_data_, 24103bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch client_data); 24113bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch callback(event_details); 24123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 24133bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 24143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 24153bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochvoid Debugger::CallJSEventCallback(v8::DebugEvent event, 24163bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Object> exec_state, 24173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Object> event_data) { 24183bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch ASSERT(event_listener_->IsJSFunction()); 241944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 24203bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); 24213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 24223bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Invoke the JavaScript debug event listener. 24233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const int argc = 4; 24243bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), 24253bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch exec_state.location(), 24263bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Object>::cast(event_data).location(), 24273bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch event_listener_data_.location() }; 24283bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch bool caught_exception = false; 242944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Execution::TryCall(fun, isolate_->global(), argc, argv, &caught_exception); 24303bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Silently ignore exceptions from debug event listeners. 24313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 24323bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 24333bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 24346ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<Context> Debugger::GetDebugContext() { 243544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 243644f0eee88ff00398ff7f715fab053374d808c90dSteve Block never_unload_debugger_ = true; 243744f0eee88ff00398ff7f715fab053374d808c90dSteve Block EnterDebugger debugger; 243844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate_->debug()->debug_context(); 24396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 24406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 24416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::UnloadDebugger() { 244344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 244444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debug* debug = isolate_->debug(); 244544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that there are no breakpoints left. 244744f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->ClearAllBreakPoints(); 2448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unload the debugger if feasible. 2450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!never_unload_debugger_) { 245144f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->Unload(); 2452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the flag indicating that the debugger should be unloaded. 2455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugger_unload_pending_ = false; 2456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::NotifyMessageHandler(v8::DebugEvent event, 2460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> exec_state, 2461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> event_data, 2462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool auto_continue) { 246344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 246444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 2465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 246644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!isolate_->debug()->Load()) return; 2467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Process the individual events. 2469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool sendEventMessage = false; 2470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (event) { 2471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case v8::Break: 24723bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch case v8::BreakForCommand: 2473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sendEventMessage = !auto_continue; 2474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 2475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case v8::Exception: 2476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sendEventMessage = true; 2477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 2478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case v8::BeforeCompile: 2479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 2480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case v8::AfterCompile: 2481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sendEventMessage = true; 2482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 2483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case v8::ScriptCollected: 2484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sendEventMessage = true; 2485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 2486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case v8::NewFunction: 2487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 2488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 2489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 2490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The debug command interrupt flag might have been set when the command was 2493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // added. It should be enough to clear the flag only once while we are in the 2494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // debugger. 249544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate_->debug()->InDebugger()); 249644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->stack_guard()->Continue(DEBUGCOMMAND); 2497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify the debugger that a debug event has occurred unless auto continue is 2499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // active in which case no event is send. 2500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (sendEventMessage) { 2501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageImpl message = MessageImpl::NewEvent( 2502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event, 2503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block auto_continue, 2504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(exec_state), 2505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(event_data)); 2506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InvokeMessageHandler(message); 2507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If auto continue don't make the event cause a break, but process messages 2510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the queue if any. For script collected events don't even process 2511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // messages in the queue as the execution state might not be what is expected 2512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the client. 2513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((auto_continue && !HasCommands()) || event == v8::ScriptCollected) { 2514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch try_catch; 25183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 25193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // DebugCommandProcessor goes here. 25203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::Local<v8::Object> cmd_processor; 25213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 25223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::Local<v8::Object> api_exec_state = 25233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)); 25243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::Local<v8::String> fun_name = 25253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::String::New("debugCommandProcessor"); 25263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::Local<v8::Function> fun = 25273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::Function::Cast(*api_exec_state->Get(fun_name)); 25283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 25293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::Handle<v8::Boolean> running = 25303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block auto_continue ? v8::True() : v8::False(); 25313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static const int kArgc = 1; 25323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::Handle<Value> argv[kArgc] = { running }; 25333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cmd_processor = v8::Object::Cast(*fun->Call(api_exec_state, kArgc, argv)); 25343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (try_catch.HasCaught()) { 25353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block PrintLn(try_catch.Exception()); 25363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return; 25373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 25403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool running = auto_continue; 25413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Process requests from the debugger. 2543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 2544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Wait for new command in the queue. 2545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debugger::host_dispatch_handler_) { 2546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // In case there is a host dispatch - do periodic dispatches. 2547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!command_received_->Wait(host_dispatch_micros_)) { 2548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Timout expired, do the dispatch. 2549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debugger::host_dispatch_handler_(); 2550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 2551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // In case there is no host dispatch - just wait. 2554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command_received_->Wait(); 2555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the command from the queue. 2558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CommandMessage command = command_queue_.Get(); 255944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->DebugTag("Got request from command queue, in interactive loop."); 2560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Debugger::IsDebuggerActive()) { 2561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Delete command text and user data. 2562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command.Dispose(); 2563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Invoke JavaScript to process the debug request. 2567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> fun_name; 2568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> fun; 2569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Value> request; 2570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch try_catch; 2571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fun_name = v8::String::New("processDebugRequest"); 2572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); 2573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block request = v8::String::New(command.text().start(), 2575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command.text().length()); 2576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kArgc = 1; 2577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<Value> argv[kArgc] = { request }; 2578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv); 2579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the response. 2581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> response; 2582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!try_catch.HasCaught()) { 2583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get response string. 2584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!response_val->IsUndefined()) { 2585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block response = v8::String::Cast(*response_val); 2586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block response = v8::String::New(""); 2588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Log the JSON request/response. 2591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_trace_debug_json) { 2592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintLn(request); 2593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintLn(response); 2594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the running state. 2597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fun_name = v8::String::New("isRunning"); 2598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); 2599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kArgc = 1; 2600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<Value> argv[kArgc] = { response }; 2601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv); 2602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!try_catch.HasCaught()) { 2603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block running = running_val->ToBoolean()->Value(); 2604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // In case of failure the result text is the exception text. 2607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block response = try_catch.Exception()->ToString(); 2608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the result. 2611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageImpl message = MessageImpl::NewResponse( 2612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event, 2613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block running, 2614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(exec_state), 2615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject>::cast(event_data), 2616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String>(Utils::OpenHandle(*response)), 2617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command.client_data()); 2618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InvokeMessageHandler(message); 2619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command.Dispose(); 2620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return from debug event processing if either the VM is put into the 2622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // runnning state (through a continue command) or auto continue is active 2623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and there are no more commands queued. 26243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (running && !HasCommands()) { 2625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 2626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::SetEventListener(Handle<Object> callback, 2632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> data) { 263344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 263444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 263544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GlobalHandles* global_handles = isolate_->global_handles(); 2636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the global handles for the event listener and the event listener data 2638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object. 2639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!event_listener_.is_null()) { 264044f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy( 2641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<Object**>(event_listener_.location())); 2642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_listener_ = Handle<Object>(); 2643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!event_listener_data_.is_null()) { 264544f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Destroy( 2646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<Object**>(event_listener_data_.location())); 2647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_listener_data_ = Handle<Object>(); 2648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is a new debug event listener register it together with its data 2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object. 2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!callback->IsUndefined() && !callback->IsNull()) { 265344f0eee88ff00398ff7f715fab053374d808c90dSteve Block event_listener_ = Handle<Object>::cast( 265444f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Create(*callback)); 2655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (data.is_null()) { 265644f0eee88ff00398ff7f715fab053374d808c90dSteve Block data = isolate_->factory()->undefined_value(); 2657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 265844f0eee88ff00398ff7f715fab053374d808c90dSteve Block event_listener_data_ = Handle<Object>::cast( 265944f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Create(*data)); 2660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ListenersChanged(); 2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { 266744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScopedLock with(debugger_access_); 2669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_ = handler; 2671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ListenersChanged(); 2672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (handler == NULL) { 2673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Send an empty command to the debugger if in a break to make JavaScript 2674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // run again if the debugger is closed. 267544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate_->debug()->InDebugger()) { 2676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ProcessCommand(Vector<const uint16_t>::empty()); 2677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::ListenersChanged() { 268344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDebuggerActive()) { 2685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Disable the compilation cache when the debugger is active. 268644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->compilation_cache()->Disable(); 2687e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke debugger_unload_pending_ = false; 2688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 268944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->compilation_cache()->Enable(); 2690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unload the debugger if event listener and message handler cleared. 2691e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Schedule this for later, because we may be in non-V8 thread. 2692e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke debugger_unload_pending_ = true; 2693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, 2698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int period) { 269944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_handler_ = handler; 2701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_micros_ = period * 1000; 2702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2705d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Debugger::SetDebugMessageDispatchHandler( 2706e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { 270744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2708e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ScopedLock with(dispatch_handler_access_); 2709d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_handler_ = handler; 2710e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2711e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (provide_locker && message_dispatch_helper_thread_ == NULL) { 271244f0eee88ff00398ff7f715fab053374d808c90dSteve Block message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_); 2713e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke message_dispatch_helper_thread_->Start(); 2714e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2715d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 2716d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 2717d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 2718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Calls the registered debug message handler. This callback is part of the 2719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// public API. 2720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::InvokeMessageHandler(MessageImpl message) { 272144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScopedLock with(debugger_access_); 2723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message_handler_ != NULL) { 2725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_(message); 2726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Puts a command coming from the public API on the queue. Creates 2731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a copy of the command string managed by the debugger. Up to this 2732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// point, the command data was managed by the API client. Called 2733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// by the API client thread. 2734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::ProcessCommand(Vector<const uint16_t> command, 2735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::ClientData* client_data) { 273644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Need to cast away const. 2738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CommandMessage message = CommandMessage::New( 2739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<uint16_t>(const_cast<uint16_t*>(command.start()), 2740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command.length()), 2741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client_data); 274244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->DebugTag("Put command on command_queue."); 2743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command_queue_.Put(message); 2744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command_received_->Signal(); 2745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug command break flag to have the command processed. 274744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!isolate_->debug()->InDebugger()) { 274844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->stack_guard()->DebugCommand(); 2749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2750d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 2751e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke MessageDispatchHelperThread* dispatch_thread; 2752e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 2753e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ScopedLock with(dispatch_handler_access_); 2754e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke dispatch_thread = message_dispatch_helper_thread_; 2755e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2756e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2757e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (dispatch_thread == NULL) { 2758e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CallMessageDispatchHandler(); 2759e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 2760e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke dispatch_thread->Schedule(); 2761d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 2762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debugger::HasCommands() { 276644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !command_queue_.IsEmpty(); 2768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27713bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochvoid Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { 277244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 27733bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); 27743bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch event_command_queue_.Put(message); 27753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 27763bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Set the debug command break flag to have the command processed. 277744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!isolate_->debug()->InDebugger()) { 277844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->stack_guard()->DebugCommand(); 27793bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 27803bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 27813bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 27823bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 2783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debugger::IsDebuggerActive() { 278444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScopedLock with(debugger_access_); 2786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return message_handler_ != NULL || !event_listener_.is_null(); 2788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Debugger::Call(Handle<JSFunction> fun, 2792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> data, 2793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* pending_exception) { 279444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When calling functions in the debugger prevent it from beeing unloaded. 2796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debugger::never_unload_debugger_ = true; 2797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. 2799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 28006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (debugger.FailedToEnter()) { 280144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate_->factory()->undefined_value(); 2802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the execution state. 2805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 2806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> exec_state = MakeExecutionState(&caught_exception); 2807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 280844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate_->factory()->undefined_value(); 2809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kArgc = 2; 2812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** argv[kArgc] = { exec_state.location(), data.location() }; 28136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> result = Execution::Call( 28146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block fun, 281544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object>(isolate_->debug()->debug_context_->global_proxy()), 28166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kArgc, 28176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block argv, 28186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block pending_exception); 2819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 2820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2823e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic void StubMessageHandler2(const v8::Debug::Message& message) { 2824e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Simply ignore message. 2825e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2826e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2827e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2828e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkebool Debugger::StartAgent(const char* name, int port, 2829e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool wait_for_connection) { 283044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2831e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (wait_for_connection) { 2832e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Suspend V8 if it is already running or set V8 to suspend whenever 2833e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // it starts. 2834e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Provide stub message handler; V8 auto-continues each suspend 2835e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // when there is no message handler; we doesn't need it. 2836e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Once become suspended, V8 will stay so indefinitely long, until remote 2837e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // debugger connects and issues "continue" command. 2838e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Debugger::message_handler_ = StubMessageHandler2; 2839e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::DebugBreak(); 2840e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2841e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Socket::Setup()) { 2843086aeeaae12517475c22695a200be45495516549Ben Murdoch if (agent_ == NULL) { 284444f0eee88ff00398ff7f715fab053374d808c90dSteve Block agent_ = new DebuggerAgent(isolate_, name, port); 2845086aeeaae12517475c22695a200be45495516549Ben Murdoch agent_->Start(); 2846086aeeaae12517475c22695a200be45495516549Ben Murdoch } 2847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 2848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 2851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::StopAgent() { 285544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (agent_ != NULL) { 2857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block agent_->Shutdown(); 2858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block agent_->Join(); 2859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete agent_; 2860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block agent_ = NULL; 2861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debugger::WaitForAgent() { 286644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (agent_ != NULL) 2868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block agent_->WaitUntilListening(); 2869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2871e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2872e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Debugger::CallMessageDispatchHandler() { 287344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(Isolate::Current() == isolate_); 2874e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::DebugMessageDispatchHandler handler; 2875e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 2876e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ScopedLock with(dispatch_handler_access_); 2877e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke handler = Debugger::debug_message_dispatch_handler_; 2878e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2879e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (handler != NULL) { 2880e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke handler(); 2881e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2882e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2883e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2884e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMessageImpl MessageImpl::NewEvent(DebugEvent event, 2886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool running, 2887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> exec_state, 2888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> event_data) { 2889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageImpl message(true, event, running, 2890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exec_state, event_data, Handle<String>(), NULL); 2891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return message; 2892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMessageImpl MessageImpl::NewResponse(DebugEvent event, 2896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool running, 2897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> exec_state, 2898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> event_data, 2899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> response_json, 2900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::ClientData* client_data) { 2901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageImpl message(false, event, running, 2902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exec_state, event_data, response_json, client_data); 2903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return message; 2904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMessageImpl::MessageImpl(bool is_event, 2908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEvent event, 2909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool running, 2910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> exec_state, 2911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> event_data, 2912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> response_json, 2913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::ClientData* client_data) 2914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : is_event_(is_event), 2915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_(event), 2916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block running_(running), 2917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exec_state_(exec_state), 2918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_data_(event_data), 2919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block response_json_(response_json), 2920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client_data_(client_data) {} 2921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool MessageImpl::IsEvent() const { 2924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return is_event_; 2925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool MessageImpl::IsResponse() const { 2929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !is_event_; 2930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockDebugEvent MessageImpl::GetEvent() const { 2934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return event_; 2935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool MessageImpl::WillStartRunning() const { 2939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return running_; 2940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Object> MessageImpl::GetExecutionState() const { 2944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Utils::ToLocal(exec_state_); 2945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Object> MessageImpl::GetEventData() const { 2949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Utils::ToLocal(event_data_); 2950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::String> MessageImpl::GetJSON() const { 2954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsEvent()) { 2957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call toJSONProtocol on the debug event object. 2958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> fun = GetProperty(event_data_, "toJSONProtocol"); 2959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!fun->IsJSFunction()) { 2960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Handle<v8::String>(); 2961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception; 2963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> json = Execution::TryCall(Handle<JSFunction>::cast(fun), 2964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block event_data_, 2965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, NULL, &caught_exception); 2966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception || !json->IsString()) { 2967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Handle<v8::String>(); 2968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return scope.Close(v8::Utils::ToLocal(Handle<String>::cast(json))); 2970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Utils::ToLocal(response_json_); 2972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Context> MessageImpl::GetEventContext() const { 297744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 297844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::Handle<v8::Context> context = GetDebugEventContext(isolate); 297944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Isolate::context() may be NULL when "script collected" event occures. 2980f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected); 298144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return GetDebugEventContext(isolate); 2982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Debug::ClientData* MessageImpl::GetClientData() const { 2986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return client_data_; 2987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2990f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeEventDetailsImpl::EventDetailsImpl(DebugEvent event, 2991f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Handle<JSObject> exec_state, 2992f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Handle<JSObject> event_data, 29933bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<Object> callback_data, 29943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::ClientData* client_data) 2995f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke : event_(event), 2996f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke exec_state_(exec_state), 2997f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke event_data_(event_data), 29983bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch callback_data_(callback_data), 29993bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch client_data_(client_data) {} 3000f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3001f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3002f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeDebugEvent EventDetailsImpl::GetEvent() const { 3003f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return event_; 3004f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 3005f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3006f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3007f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkev8::Handle<v8::Object> EventDetailsImpl::GetExecutionState() const { 3008f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return v8::Utils::ToLocal(exec_state_); 3009f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 3010f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3011f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3012f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkev8::Handle<v8::Object> EventDetailsImpl::GetEventData() const { 3013f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return v8::Utils::ToLocal(event_data_); 3014f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 3015f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3016f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3017f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkev8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const { 301844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return GetDebugEventContext(Isolate::Current()); 3019f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 3020f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3021f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3022f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkev8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const { 3023f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return v8::Utils::ToLocal(callback_data_); 3024f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 3025f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 3026f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 30273bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochv8::Debug::ClientData* EventDetailsImpl::GetClientData() const { 30283bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch return client_data_; 30293bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 30303bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 30313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 3032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()), 3033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client_data_(NULL) { 3034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCommandMessage::CommandMessage(const Vector<uint16_t>& text, 3038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::ClientData* data) 3039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : text_(text), 3040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client_data_(data) { 3041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCommandMessage::~CommandMessage() { 3045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CommandMessage::Dispose() { 3049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block text_.Dispose(); 3050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete client_data_; 3051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client_data_ = NULL; 3052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCommandMessage CommandMessage::New(const Vector<uint16_t>& command, 3056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::ClientData* data) { 3057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CommandMessage(command.Clone(), data); 3058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0), 3062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block size_(size) { 3063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block messages_ = NewArray<CommandMessage>(size); 3064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCommandMessageQueue::~CommandMessageQueue() { 3068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!IsEmpty()) { 3069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CommandMessage m = Get(); 3070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Dispose(); 3071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(messages_); 3073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCommandMessage CommandMessageQueue::Get() { 3077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!IsEmpty()); 3078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int result = start_; 3079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_ = (start_ + 1) % size_; 3080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return messages_[result]; 3081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CommandMessageQueue::Put(const CommandMessage& message) { 3085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((end_ + 1) % size_ == start_) { 3086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Expand(); 3087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block messages_[end_] = message; 3089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end_ = (end_ + 1) % size_; 3090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CommandMessageQueue::Expand() { 3094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CommandMessageQueue new_queue(size_ * 2); 3095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!IsEmpty()) { 3096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new_queue.Put(Get()); 3097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CommandMessage* array_to_free = messages_; 3099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *this = new_queue; 3100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new_queue.messages_ = array_to_free; 3101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make the new_queue empty so that it doesn't call Dispose on any messages. 3102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new_queue.start_ = new_queue.end_; 3103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Automatic destructor called on new_queue, freeing array_to_free. 3104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLockingCommandMessageQueue::LockingCommandMessageQueue(int size) 3108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : queue_(size) { 3109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lock_ = OS::CreateMutex(); 3110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLockingCommandMessageQueue::~LockingCommandMessageQueue() { 3114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete lock_; 3115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool LockingCommandMessageQueue::IsEmpty() const { 3119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScopedLock sl(lock_); 3120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return queue_.IsEmpty(); 3121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCommandMessage LockingCommandMessageQueue::Get() { 3125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScopedLock sl(lock_); 3126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CommandMessage result = queue_.Get(); 312744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->DebugEvent("Get", result.text()); 3128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 3129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LockingCommandMessageQueue::Put(const CommandMessage& message) { 3133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScopedLock sl(lock_); 3134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue_.Put(message); 313544f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOGGER->DebugEvent("Put", message.text()); 3136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LockingCommandMessageQueue::Clear() { 3140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScopedLock sl(lock_); 3141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue_.Clear(); 3142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3144e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 314544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockMessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) 314644f0eee88ff00398ff7f715fab053374d808c90dSteve Block : Thread(isolate, "v8:MsgDispHelpr"), 31479fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()), 3148e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke already_signalled_(false) { 3149e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 3150e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3151e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3152e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeMessageDispatchHelperThread::~MessageDispatchHelperThread() { 3153e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke delete mutex_; 3154e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke delete sem_; 3155e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 3156e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3157e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3158e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MessageDispatchHelperThread::Schedule() { 3159e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 3160e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ScopedLock lock(mutex_); 3161e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (already_signalled_) { 3162e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return; 3163e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3164e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke already_signalled_ = true; 3165e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3166e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke sem_->Signal(); 3167e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 3168e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3169e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3170e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MessageDispatchHelperThread::Run() { 3171e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke while (true) { 3172e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke sem_->Wait(); 3173e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 3174e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ScopedLock lock(mutex_); 3175e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke already_signalled_ = false; 3176e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3177e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 3178e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Locker locker; 317944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->debugger()->CallMessageDispatchHandler(); 3180e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3181e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3182e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 3183e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // ENABLE_DEBUGGER_SUPPORT 3185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 3187