17d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "api.h" 3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "arguments.h" 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "bootstrapper.h" 3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "code-stubs.h" 345c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "codegen.h" 3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "compilation-cache.h" 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "compiler.h" 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "debug.h" 38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "deoptimizer.h" 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "execution.h" 40a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org#include "full-codegen.h" 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "global-handles.h" 4265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#include "ic.h" 4365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#include "ic-inl.h" 44c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "isolate-inl.h" 4534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#include "list.h" 46ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#include "messages.h" 4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "natives.h" 4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "stub-cache.h" 497276f14ca716596e0a0d17539516370c1f453847kasper.lund#include "log.h" 5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 515ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#include "../include/v8-debug.h" 525ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 5371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 5471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 57ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 58ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 59ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgDebug::Debug(Isolate* isolate) 60ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : has_break_points_(false), 61ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org script_cache_(NULL), 62ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org debug_info_list_(NULL), 63ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org disable_break_(false), 64ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break_on_exception_(false), 65ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org break_on_uncaught_exception_(false), 66ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org debug_break_return_(NULL), 67ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org debug_break_slot_(NULL), 68ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_(isolate) { 69ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org memset(registers_, 0, sizeof(JSCallerSavedBuffer)); 70ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 71ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 72ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 73ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgDebug::~Debug() { 74ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 75ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 76ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void PrintLn(v8::Local<v8::Value> value) { 7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v8::Local<v8::String> s = value->ToString(); 7957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ScopedVector<char> data(s->Utf8Length() + 1); 80720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org if (data.start() == NULL) { 8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V8::FatalProcessOutOfMemory("PrintLn"); 8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 8457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org s->WriteUtf8(data.start()); 85720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org PrintF("%s\n", data.start()); 8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 8743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 89e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgstatic Handle<Code> ComputeCallDebugPrepareStepIn(Isolate* isolate, 90e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org int argc, 91e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org Code::Kind kind) { 92394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind); 9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 96ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { 97ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); 98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Isolate::context() may have been NULL when "script collected" event 99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // occured. 100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (context.is_null()) return v8::Local<v8::Context>(); 10146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Handle<Context> native_context(context->native_context()); 10246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org return v8::Utils::ToLocal(native_context); 1039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 1049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info, 10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakLocatorType type) { 10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen debug_info_ = debug_info; 10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen type_ = type; 11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reloc_iterator_ = NULL; 11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reloc_iterator_original_ = NULL; 11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Reset(); // Initialize the rest of the member variables. 11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBreakLocationIterator::~BreakLocationIterator() { 11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(reloc_iterator_ != NULL); 11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(reloc_iterator_original_ != NULL); 11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen delete reloc_iterator_; 12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen delete reloc_iterator_original_; 12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::Next() { 12579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!RinfoDone()); 12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Iterate through reloc info for code and original code stopping at each 12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // breakable code target. 13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool first = break_point_ == -1; 13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!RinfoDone()) { 13243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!first) RinfoNext(); 13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen first = false; 13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (RinfoDone()) return; 13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Whenever a statement position or (plain) position is passed update the 137236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // current value of these. 138236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsPosition(rmode())) { 139236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsStatementPosition(rmode())) { 140c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org statement_position_ = static_cast<int>( 141c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org rinfo()->data() - debug_info_->shared()->start_position()); 14243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 143236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Always update the position as we don't want that to be before the 144236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // statement position. 145c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org position_ = static_cast<int>( 146c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org rinfo()->data() - debug_info_->shared()->start_position()); 14743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(position_ >= 0); 14843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(statement_position_ >= 0); 14943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1512356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org if (IsDebugBreakSlot()) { 1522356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // There is always a possible break point at a debug break slot. 1532356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org break_point_++; 1542356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org return; 1552356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org } else if (RelocInfo::IsCodeTarget(rmode())) { 1562356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Check for breakable code target. Look in the original code as setting 1572356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // break points can cause the code targets in the running (debugged) code 1582356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // to be of a different kind than in the original code. 15943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address target = original_rinfo()->target_address(); 1608bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Code* code = Code::GetCodeFromTargetAddress(target); 161ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org if ((code->is_inline_cache_stub() && 16240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org !code->is_binary_op_stub() && 1639fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org !code->is_compare_ic_stub() && 1649fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org !code->is_to_boolean_ic_stub()) || 165ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org RelocInfo::IsConstructCall(rmode())) { 16643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_point_++; 16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 16843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (code->kind() == Code::STUB) { 170a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (IsDebuggerStatement()) { 171a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org break_point_++; 172a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org return; 173a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (type_ == ALL_BREAK_LOCATIONS) { 17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (Debug::IsBreakStub(code)) { 17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_point_++; 17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(type_ == SOURCE_BREAK_LOCATIONS); 18143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (Debug::IsSourceBreakStub(code)) { 18243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_point_++; 18343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 18543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 18743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 18843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check for break at return. 190236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsJSReturn(rmode())) { 19143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set the positions to the end of the function. 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (debug_info_->shared()->HasSourceCode()) { 19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen position_ = debug_info_->shared()->end_position() - 194e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org debug_info_->shared()->start_position() - 1; 19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen position_ = 0; 19743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen statement_position_ = position_; 19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_point_++; 20043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::Next(int count) { 20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (count > 0) { 20843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen count--; 21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 21143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 21243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2148a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// Find the break point at the supplied address, or the closest one before 2158a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// the address. 21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::FindBreakLocationFromAddress(Address pc) { 21743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Run through all break points to locate the one closest to the address. 21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int closest_break_point = 0; 21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int distance = kMaxInt; 22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!Done()) { 22143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check if this break point is closer that what was previously found. 2228a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (this->pc() <= pc && pc - this->pc() < distance) { 22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen closest_break_point = break_point(); 224c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org distance = static_cast<int>(pc - this->pc()); 22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check whether we can't get any closer. 22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (distance == 0) break; 22743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 22843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Move to the break point found. 23243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Reset(); 23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(closest_break_point); 23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 23543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Find the break point closest to the supplied source position. 23893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.orgvoid BreakLocationIterator::FindBreakLocationFromPosition(int position, 23993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org BreakPositionAlignment alignment) { 24043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Run through all break points to locate the one closest to the source 24143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // position. 24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int closest_break_point = 0; 24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int distance = kMaxInt; 24493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org 24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!Done()) { 24693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org int next_position; 24793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org switch (alignment) { 24893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org case STATEMENT_ALIGNED: 24993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org next_position = this->statement_position(); 25093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org break; 25193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org case BREAK_POSITION_ALIGNED: 25293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org next_position = this->position(); 25393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org break; 25493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org default: 25593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org UNREACHABLE(); 25693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org next_position = this->statement_position(); 25793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org } 25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check if this break point is closer that what was previously found. 25993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org if (position <= next_position && next_position - position < distance) { 26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen closest_break_point = break_point(); 26193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org distance = next_position - position; 26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check whether we can't get any closer. 26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (distance == 0) break; 26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Move to the break point found. 26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Reset(); 27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(closest_break_point); 27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::Reset() { 27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create relocation iterators for the two code objects. 27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (reloc_iterator_ != NULL) delete reloc_iterator_; 27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_; 278e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org reloc_iterator_ = new RelocIterator( 279e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org debug_info_->code(), 280e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)); 281e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org reloc_iterator_original_ = new RelocIterator( 282e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org debug_info_->original_code(), 283e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)); 28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Position at the first break point. 28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_point_ = -1; 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen position_ = 1; 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen statement_position_ = 1; 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::Done() const { 29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return RinfoDone(); 29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) { 29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there is not already a real break point here patch code with debug 30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // break. 30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!HasBreakPoint()) { 30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SetDebugBreak(); 30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 304a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ASSERT(IsDebugBreak() || IsDebuggerStatement()); 30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set the break point information. 30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DebugInfo::SetBreakPoint(debug_info_, code_position(), 30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen position(), statement_position(), 30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_point_object); 30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) { 31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Clear the break point information. 31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object); 31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there are no more break points here remove the debug break. 31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!HasBreakPoint()) { 31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ClearDebugBreak(); 31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!IsDebugBreak()); 31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::SetOneShot() { 324a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Debugger statement always calls debugger. No need to modify it. 325a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (IsDebuggerStatement()) { 326a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org return; 327a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 328a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there is a real break point here no more to do. 33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (HasBreakPoint()) { 33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(IsDebugBreak()); 33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Patch code with debug break. 33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SetDebugBreak(); 33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::ClearOneShot() { 341a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Debugger statement always calls debugger. No need to modify it. 342a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (IsDebuggerStatement()) { 343a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org return; 344a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 345a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there is a real break point here no more to do. 34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (HasBreakPoint()) { 34843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(IsDebugBreak()); 34943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 35043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 35143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Patch code removing debug break. 35343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ClearDebugBreak(); 35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!IsDebugBreak()); 35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::SetDebugBreak() { 359a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Debugger statement always calls debugger. No need to modify it. 360a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (IsDebuggerStatement()) { 361a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org return; 362a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 363a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 36443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there is already a break point here just return. This might happen if 365727e995b7bba3c57fb1e5c156d386ca11894f781v // the same code is flooded with break points twice. Flooding the same 36643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function twice might happen when stepping in a function with an exception 36743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // handler as the handler and the function is the same. 36843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (IsDebugBreak()) { 36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 372236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsJSReturn(rmode())) { 373245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Patch the frame exit code with a break point. 374245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org SetDebugBreakAtReturn(); 3752356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org } else if (IsDebugBreakSlot()) { 3762356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Patch the code in the break slot. 3772356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org SetDebugBreakAtSlot(); 37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 37965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Patch the IC call. 38065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org SetDebugBreakAtIC(); 38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(IsDebugBreak()); 38343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 38443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::ClearDebugBreak() { 387a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Debugger statement always calls debugger. No need to modify it. 388a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (IsDebuggerStatement()) { 389a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org return; 390a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 391a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 392236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsJSReturn(rmode())) { 393245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Restore the frame exit code. 394245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org ClearDebugBreakAtReturn(); 3952356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org } else if (IsDebugBreakSlot()) { 3962356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Restore the code in the break slot. 3972356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org ClearDebugBreakAtSlot(); 39843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 39965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Patch the IC call. 40065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org ClearDebugBreakAtIC(); 40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!IsDebugBreak()); 40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 40543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgbool BreakLocationIterator::IsStepInLocation(Isolate* isolate) { 407e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org if (RelocInfo::IsConstructCall(original_rmode())) { 4081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return true; 4091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (RelocInfo::IsCodeTarget(rmode())) { 4101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HandleScope scope(debug_info_->GetIsolate()); 411e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org Address target = original_rinfo()->target_address(); 4121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); 413594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (target_code->kind() == Code::STUB) { 414594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return target_code->major_key() == CodeStub::CallFunction; 415594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 4161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return target_code->is_call_stub() || target_code->is_keyed_call_stub(); 4171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else { 4181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return false; 4191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 4201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 4211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 4221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 423c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orgvoid BreakLocationIterator::PrepareStepIn(Isolate* isolate) { 424c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org HandleScope scope(isolate); 425381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 426a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Step in can only be prepared if currently positioned on an IC call, 427a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // construct call or CallFunction stub call. 42843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address target = rinfo()->target_address(); 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); 430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (target_code->is_call_stub() || target_code->is_keyed_call_stub()) { 43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Step in through IC call is handled by the runtime system. Therefore make 43243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // sure that the any current IC is cleared and the runtime system is 43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // called. If the executing code has a debug break at the location change 43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the call in the original code as it is the code there that will be 43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // executed in place of the debug break call. 436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Code> stub = ComputeCallDebugPrepareStepIn( 437e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org isolate, target_code->arguments_count(), target_code->kind()); 43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (IsDebugBreak()) { 43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen original_rinfo()->set_target_address(stub->entry()); 44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen rinfo()->set_target_address(stub->entry()); 44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 44343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 444a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef DEBUG 445a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // All the following stuff is needed only for assertion checks so the code 446a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // is wrapped in ifdef. 447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Code> maybe_call_function_stub = target_code; 448a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (IsDebugBreak()) { 449a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Address original_target = original_rinfo()->target_address(); 450a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org maybe_call_function_stub = 451a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Handle<Code>(Code::GetCodeFromTargetAddress(original_target)); 452a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 453a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org bool is_call_function_stub = 454a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org (maybe_call_function_stub->kind() == Code::STUB && 455a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org maybe_call_function_stub->major_key() == CodeStub::CallFunction); 456a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 457e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Step in through construct call requires no changes to the running code. 458e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Step in through getters/setters should already be prepared as well 459e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // because caller of this function (Debug::PrepareStep) is expected to 460e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // flood the top frame's function with one shot breakpoints. 461a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Step in through CallFunction stub should also be prepared by caller of 462a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // this function (Debug::PrepareStep) which should flood target function 463a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // with breakpoints. 464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(RelocInfo::IsConstructCall(rmode()) || 465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com target_code->is_inline_cache_stub() || 466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com is_call_function_stub); 467a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 46843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 46943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 47043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether the break point is at a position which will exit the function. 47343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::IsExit() const { 474236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org return (RelocInfo::IsJSReturn(rmode())); 47543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 47643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::HasBreakPoint() { 47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return debug_info_->HasBreakPoint(code_position()); 48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether there is a debug break at the current position. 48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::IsDebugBreak() { 485236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsJSReturn(rmode())) { 486245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return IsDebugBreakAtReturn(); 4872356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org } else if (IsDebugBreakSlot()) { 4882356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org return IsDebugBreakAtSlot(); 48943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 49043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Debug::IsDebugBreak(rinfo()->target_address()); 49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 49243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 49343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 49443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 49565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtIC() { 49665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Patch the original code with the current address as the current address 49765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // might have changed by the inline caching since the code was copied. 49865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org original_rinfo()->set_target_address(rinfo()->target_address()); 49965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 50065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org RelocInfo::Mode mode = rmode(); 50165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org if (RelocInfo::IsCodeTarget(mode)) { 50265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org Address target = rinfo()->target_address(); 503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); 50465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 50565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Patch the code to invoke the builtin debug break function matching the 50665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // calling convention used by the call site. 507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Code> dbgbrk_code(Debug::FindDebugBreak(target_code, mode)); 50865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org rinfo()->set_target_address(dbgbrk_code->entry()); 50965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org } 51065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org} 51165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 51265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 51365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtIC() { 51465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Patch the code to the original invoke. 51565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org rinfo()->set_target_address(original_rinfo()->target_address()); 51665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org} 51765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 51865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 519a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgbool BreakLocationIterator::IsDebuggerStatement() { 5205c838251403b0be9a882540f1922577abba4c872ager@chromium.org return RelocInfo::DEBUG_BREAK == rmode(); 521a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org} 522a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 523a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 5242356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgbool BreakLocationIterator::IsDebugBreakSlot() { 5252356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org return RelocInfo::DEBUG_BREAK_SLOT == rmode(); 5262356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 5272356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 5282356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 52943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* BreakLocationIterator::BreakPointObjects() { 53043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return debug_info_->GetBreakPointObjects(code_position()); 53143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 53243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 534381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// Clear out all the debug break code. This is ONLY supposed to be used when 535381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// shutting down the debugger as it will leave the break point information in 536381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// DebugInfo even though the code is patched back to the non break point state. 537381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgvoid BreakLocationIterator::ClearAllDebugBreak() { 538381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org while (!Done()) { 539381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org ClearDebugBreak(); 540381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org Next(); 541381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 542381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 543381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 544381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::RinfoDone() const { 54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); 54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return reloc_iterator_->done(); 54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::RinfoNext() { 55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reloc_iterator_->next(); 55343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reloc_iterator_original_->next(); 55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 55543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); 55643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!reloc_iterator_->done()) { 55743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(rmode() == original_rmode()); 55843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 55943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 56043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 56143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 56243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 56343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Threading support. 56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ThreadInit() { 5657be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org thread_local_.break_count_ = 0; 5667be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org thread_local_.break_id_ = 0; 5677be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org thread_local_.break_frame_id_ = StackFrame::NO_ID; 56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.last_step_action_ = StepNone; 569236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 57043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.step_count_ = 0; 57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.last_fp_ = 0; 57234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org thread_local_.queued_step_count_ = 0; 57343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.step_into_fp_ = 0; 574a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org thread_local_.step_out_fp_ = 0; 57543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.after_break_target_ = 0; 576ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // TODO(isolates): frames_are_dropped_? 5777be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org thread_local_.debugger_entry_ = NULL; 578755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org thread_local_.pending_interrupts_ = 0; 5790b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org thread_local_.restarter_frame_function_pointer_ = NULL; 58043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 58143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar* Debug::ArchiveDebug(char* storage) { 58443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char* to = storage; 585e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen to += sizeof(ThreadLocal); 587e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy(to, reinterpret_cast<char*>(®isters_), sizeof(registers_)); 58843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ThreadInit(); 58943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(to <= storage + ArchiveSpacePerThread()); 59043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return storage + ArchiveSpacePerThread(); 59143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 59243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 59343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 59443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar* Debug::RestoreDebug(char* storage) { 59543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char* from = storage; 596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy( 597e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 59843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen from += sizeof(ThreadLocal); 599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy(reinterpret_cast<char*>(®isters_), from, sizeof(registers_)); 60043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(from <= storage + ArchiveSpacePerThread()); 60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return storage + ArchiveSpacePerThread(); 60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 60443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 60543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint Debug::ArchiveSpacePerThread() { 606ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return sizeof(ThreadLocal) + sizeof(JSCallerSavedBuffer); 60743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 60843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 60943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 610ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// Frame structure (conforms InternalFrame structure): 611ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// -- code 612ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// -- SMI maker 613ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// -- function (slot is called "context") 614ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org// -- frame base 615ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgObject** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame, 616ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Handle<Code> code) { 617ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org ASSERT(bottom_js_frame->is_java_script()); 618ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 619ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Address fp = bottom_js_frame->fp(); 620ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 621ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Move function pointer into "context" slot. 622ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Memory::Object_at(fp + StandardFrameConstants::kContextOffset) = 623ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset); 624ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 625ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code; 626ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) = 627ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Smi::FromInt(StackFrame::INTERNAL); 628ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 629ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org return reinterpret_cast<Object**>(&Memory::Object_at( 630ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org fp + StandardFrameConstants::kContextOffset)); 631ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 632ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 633ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgconst int Debug::kFrameDropperFrameSize = 4; 634ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 635ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 63671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid ScriptCache::Add(Handle<Script> script) { 637e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org GlobalHandles* global_handles = isolate_->global_handles(); 63871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Create an entry in the hash map for the script. 6391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int id = script->id()->value(); 64071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org HashMap::Entry* entry = 64171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); 64271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (entry->value != NULL) { 64371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); 64471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org return; 64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 64671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Globalize the script object, make it weak and use the location of the 64771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // global handle as the value in the hash map. 64871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org Handle<Script> script_ = 649ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<Script>::cast( 6507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org (global_handles->Create(*script))); 651d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org global_handles->MakeWeak(reinterpret_cast<Object**>(script_.location()), 652d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org this, 653d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org ScriptCache::HandleWeakScript); 65471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org entry->value = script_.location(); 65543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgHandle<FixedArray> ScriptCache::GetScripts() { 659e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org Factory* factory = isolate_->factory(); 660d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); 66171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org int count = 0; 66271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { 66371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ASSERT(entry->value != NULL); 66471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (entry->value != NULL) { 66571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org instances->set(count, *reinterpret_cast<Script**>(entry->value)); 66671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org count++; 66771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 66871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 66971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org return instances; 67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 67371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid ScriptCache::ProcessCollectedScripts() { 674e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org Debugger* debugger = isolate_->debugger(); 67571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org for (int i = 0; i < collected_scripts_.length(); i++) { 6767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debugger->OnScriptCollected(collected_scripts_[i]); 67771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 67871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org collected_scripts_.Clear(); 67971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 68071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 68171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 68271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid ScriptCache::Clear() { 683e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org GlobalHandles* global_handles = isolate_->global_handles(); 68471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Iterate the script cache to get rid of all the weak handles. 68571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { 68671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ASSERT(entry != NULL); 68771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org Object** location = reinterpret_cast<Object**>(entry->value); 68871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ASSERT((*location)->IsScript()); 6897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org global_handles->ClearWeakness(location); 6907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org global_handles->Destroy(location); 69171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 69271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Clear the content of the hash map. 69371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org HashMap::Clear(); 69471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 69571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 69671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 697d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.orgvoid ScriptCache::HandleWeakScript(v8::Isolate* isolate, 69879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org v8::Persistent<v8::Value>* obj, 699d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org void* data) { 70071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data); 70171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Find the location of the global handle. 70271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org Script** location = 703f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org reinterpret_cast<Script**>(Utils::OpenPersistent(*obj).location()); 70471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ASSERT((*location)->IsScript()); 70571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 70671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Remove the entry from the cache. 7071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int id = (*location)->id()->value(); 70871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org script_cache->Remove(reinterpret_cast<void*>(id), Hash(id)); 70971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org script_cache->collected_scripts_.Add(id); 71071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 71171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Clear the weak handle. 712f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org obj->Reset(); 71343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 71443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 71543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 716f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid Debug::SetUp(bool create_heap_objects) { 71743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ThreadInit(); 71843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (create_heap_objects) { 71943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get code to handle debug break on return. 72043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen debug_break_return_ = 7217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak); 72243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(debug_break_return_->IsCode()); 7232356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Get code to handle debug break in debug break slots. 7242356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org debug_break_slot_ = 7257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->builtins()->builtin(Builtins::kSlot_DebugBreak); 7262356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org ASSERT(debug_break_slot_->IsCode()); 72743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 72843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 72943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 73043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 731d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.orgvoid Debug::HandleWeakDebugInfo(v8::Isolate* isolate, 73279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org v8::Persistent<v8::Value>* obj, 733d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org void* data) { 734d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Debug* debug = reinterpret_cast<Isolate*>(isolate)->debug(); 73571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data); 73669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // We need to clear all breakpoints associated with the function to restore 73769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // original code and avoid patching the code twice later because 73869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // the function will live in the heap until next gc, and can be found by 73978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // Debug::FindSharedFunctionInfoInScript. 74069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 74169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org it.ClearAllDebugBreak(); 742ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org debug->RemoveDebugInfo(node->debug_info()); 74371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#ifdef DEBUG 744ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org node = debug->debug_info_list_; 74571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org while (node != NULL) { 74671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data)); 74771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org node = node->next(); 74871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 74971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#endif 75071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 75171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 75271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 75371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgDebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { 754e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); 75571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Globalize the request debug info object and make it weak. 756ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org debug_info_ = Handle<DebugInfo>::cast( 7577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org (global_handles->Create(debug_info))); 758d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org global_handles->MakeWeak(reinterpret_cast<Object**>(debug_info_.location()), 759d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org this, 760d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Debug::HandleWeakDebugInfo); 76171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 76271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 76371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 76471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgDebugInfoListNode::~DebugInfoListNode() { 765e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org debug_info_->GetIsolate()->global_handles()->Destroy( 766ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org reinterpret_cast<Object**>(debug_info_.location())); 76771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 76871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 76971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 770e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgbool Debug::CompileDebuggerScript(Isolate* isolate, int index) { 7717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Factory* factory = isolate->factory(); 7727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate); 77343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 77444510671e908d0efc639513d81efcd81e7f14240kasper.lund // Bail out if the index is invalid. 77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (index == -1) { 77643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 77743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 77844510671e908d0efc639513d81efcd81e7f14240kasper.lund 77944510671e908d0efc639513d81efcd81e7f14240kasper.lund // Find source and name for the requested script. 780ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<String> source_code = 7817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate->bootstrapper()->NativesSourceLookup(index); 78243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Vector<const char> name = Natives::GetScriptName(index); 7837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Handle<String> script_name = factory->NewStringFromAscii(name); 784355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Handle<Context> context = isolate->native_context(); 78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compile the script. 7875d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org Handle<SharedFunctionInfo> function_info; 7885d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org function_info = Compiler::Compile(source_code, 7895d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org script_name, 790355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 0, 0, 791d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org false, 792355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org context, 793355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org NULL, NULL, 7945d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org Handle<String>::null(), 7955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org NATIVES_CODE); 79643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 79743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Silently ignore stack overflows during compilation. 7985d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org if (function_info.is_null()) { 7997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(isolate->has_pending_exception()); 8007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate->clear_pending_exception(); 80143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 80243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 80343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8045d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org // Execute the shared function in the debugger context. 805c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool caught_exception; 80644510671e908d0efc639513d81efcd81e7f14240kasper.lund Handle<JSFunction> function = 8077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org factory->NewFunctionFromSharedFunctionInfo(function_info, context); 808717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 8097d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org Handle<Object> exception = 81009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Execution::TryCall(function, 81109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object>(context->global_object(), isolate), 81209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org 0, 81309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org NULL, 81409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org &caught_exception); 81544510671e908d0efc639513d81efcd81e7f14240kasper.lund 81644510671e908d0efc639513d81efcd81e7f14240kasper.lund // Check for caught exceptions. 81743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (caught_exception) { 8187d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org ASSERT(!isolate->has_pending_exception()); 8197d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org MessageLocation computed_location; 8207d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org isolate->ComputeLocation(&computed_location); 8219258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org Handle<Object> message = MessageHandler::MakeMessageObject( 822d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org isolate, "error_loading_debugger", &computed_location, 8237d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org Vector<Handle<Object> >::empty(), Handle<String>(), Handle<JSArray>()); 8247d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org ASSERT(!isolate->has_pending_exception()); 82549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org if (!exception.is_null()) { 82649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org isolate->set_pending_exception(*exception); 827e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org MessageHandler::ReportMessage(isolate, NULL, message); 82849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org isolate->clear_pending_exception(); 82949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org } 83043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 83143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 83243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 83344510671e908d0efc639513d81efcd81e7f14240kasper.lund // Mark this script as native and return successfully. 83444510671e908d0efc639513d81efcd81e7f14240kasper.lund Handle<Script> script(Script::cast(function->shared()->script())); 835e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 83643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 83743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 83843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 83943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 84043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::Load() { 84143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return if debugger is already loaded. 842212ac23f8231d169b4aa6737d762099993020826kasper.lund if (IsLoaded()) return true; 84343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Debugger* debugger = isolate_->debugger(); 845ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 84644510671e908d0efc639513d81efcd81e7f14240kasper.lund // Bail out if we're already in the process of compiling the native 84744510671e908d0efc639513d81efcd81e7f14240kasper.lund // JavaScript source code for the debugger. 8487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (debugger->compiling_natives() || 8497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debugger->is_loading_debugger()) 850cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager return false; 8517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debugger->set_loading_debugger(true); 85244510671e908d0efc639513d81efcd81e7f14240kasper.lund 85344510671e908d0efc639513d81efcd81e7f14240kasper.lund // Disable breakpoints and interrupts while compiling and running the 85444510671e908d0efc639513d81efcd81e7f14240kasper.lund // debugger scripts including the context creation code. 855e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org DisableBreak disable(isolate_, true); 8567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org PostponeInterruptsScope postpone(isolate_); 85744510671e908d0efc639513d81efcd81e7f14240kasper.lund 85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the debugger context. 8597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 86044510671e908d0efc639513d81efcd81e7f14240kasper.lund Handle<Context> context = 8617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->bootstrapper()->CreateEnvironment( 862ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<Object>::null(), 863ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org v8::Handle<ObjectTemplate>(), 864ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org NULL); 86544510671e908d0efc639513d81efcd81e7f14240kasper.lund 8667d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // Fail if no context could be created. 8677d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org if (context.is_null()) return false; 8687d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 86944510671e908d0efc639513d81efcd81e7f14240kasper.lund // Use the debugger context. 8707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org SaveContext save(isolate_); 8717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->set_context(*context); 87244510671e908d0efc639513d81efcd81e7f14240kasper.lund 87344510671e908d0efc639513d81efcd81e7f14240kasper.lund // Expose the builtins object in the debugger context. 8744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> key = isolate_->factory()->InternalizeOneByteString( 875a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org STATIC_ASCII_VECTOR("builtins")); 87646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Handle<GlobalObject> global = Handle<GlobalObject>(context->global_object()); 877496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org RETURN_IF_EMPTY_HANDLE_VALUE( 8787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_, 87909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org JSReceiver::SetProperty(global, 88009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org key, 88109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object>(global->builtins(), isolate_), 88209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org NONE, 88309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org kNonStrictMode), 884496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org false); 88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compile the JavaScript for the debugger in the debugger context. 8877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debugger->set_compiling_natives(true); 88844510671e908d0efc639513d81efcd81e7f14240kasper.lund bool caught_exception = 889e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org !CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) || 890e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org !CompileDebuggerScript(isolate_, Natives::GetIndex("debug")); 891ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 892ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org if (FLAG_enable_liveedit) { 893ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org caught_exception = caught_exception || 894e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit")); 895ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 896ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 8977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debugger->set_compiling_natives(false); 89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 899cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager // Make sure we mark the debugger as not loading before we might 900cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager // return. 9017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debugger->set_loading_debugger(false); 902cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager 90344510671e908d0efc639513d81efcd81e7f14240kasper.lund // Check for caught exceptions. 90444510671e908d0efc639513d81efcd81e7f14240kasper.lund if (caught_exception) return false; 90543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 906e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Debugger loaded, create debugger context global handle. 907e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org debug_context_ = Handle<Context>::cast( 908e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate_->global_handles()->Create(*context)); 90971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 91043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 91143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 91343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 91443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::Unload() { 91543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return debugger is not loaded. 91643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!IsLoaded()) { 91743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 91843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 91943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 92071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Clear the script cache. 92171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org DestroyScriptCache(); 92271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Clear debugger context global handle. 924e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate_->global_handles()->Destroy( 925ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org reinterpret_cast<Object**>(debug_context_.location())); 92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen debug_context_ = Handle<Context>(); 92743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 92943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9307be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// Set the flag indicating that preemption happened during debugging. 9317be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid Debug::PreemptionWhileInDebugger() { 9327be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org ASSERT(InDebugger()); 933755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Debug::set_interrupts_pending(PREEMPT); 9347be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 9357be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 9367be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 93743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::Iterate(ObjectVisitor* v) { 93826c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org v->VisitPointer(BitCast<Object**>(&(debug_break_return_))); 93926c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org v->VisitPointer(BitCast<Object**>(&(debug_break_slot_))); 94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 943c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgObject* Debug::Break(Arguments args) { 944c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Heap* heap = isolate_->heap(); 945c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org HandleScope scope(isolate_); 94631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager ASSERT(args.length() == 0); 94743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 948c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED; 949357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 950bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund // Get the top-most JavaScript frame. 95174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org JavaScriptFrameIterator it(isolate_); 952bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund JavaScriptFrame* frame = it.frame(); 953bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund 954bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund // Just continue if breaks are disabled or debugger cannot be loaded. 955c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (disable_break() || !Load()) { 956c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org SetAfterBreakTarget(frame); 957ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return heap->undefined_value(); 95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 96041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Enter the debugger. 961e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org EnterDebugger debugger(isolate_); 96241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org if (debugger.FailedToEnter()) { 963ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return heap->undefined_value(); 96441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org } 96543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 96644510671e908d0efc639513d81efcd81e7f14240kasper.lund // Postpone interrupt during breakpoint processing. 967c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org PostponeInterruptsScope postpone(isolate_); 96843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 96943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the debug info (create it if it does not exist). 97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<SharedFunctionInfo> shared = 971169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Handle<SharedFunctionInfo>(frame->function()->shared()); 97243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<DebugInfo> debug_info = GetDebugInfo(shared); 97343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 97443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Find the break point where execution has stopped. 97543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakLocationIterator break_location_iterator(debug_info, 97643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ALL_BREAK_LOCATIONS); 9778a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // pc points to the instruction after the current one, possibly a break 9788a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // location as well. So the "- 1" to exclude it from the search. 9798a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1); 98043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 98143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check whether step next reached a new statement. 982c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (!StepNextContinue(&break_location_iterator, frame)) { 98343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Decrease steps left if performing multiple steps. 984c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (thread_local_.step_count_ > 0) { 985c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org thread_local_.step_count_--; 98643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 98743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 98943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there is one or more real break points check whether any of these are 99043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // triggered. 99109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> break_points_hit(heap->undefined_value(), isolate_); 99243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (break_location_iterator.HasBreakPoint()) { 99343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> break_point_objects = 99409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_); 995c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org break_points_hit = CheckBreakPoints(break_point_objects); 99643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 99743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 998a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // If step out is active skip everything until the frame where we need to step 999a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // out to is reached, unless real breakpoint is hit. 1000c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (StepOutActive() && frame->fp() != step_out_fp() && 1001a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org break_points_hit->IsUndefined() ) { 1002a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Step count should always be 0 for StepOut. 1003c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(thread_local_.step_count_ == 0); 1004a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } else if (!break_points_hit->IsUndefined() || 1005c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org (thread_local_.last_step_action_ != StepNone && 1006c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org thread_local_.step_count_ == 0)) { 1007a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Notify debugger if a real break point is triggered or if performing 1008a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // single stepping with no more steps to perform. Otherwise do another step. 1009a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 101043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Clear all current stepping setup. 1011c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ClearStepping(); 101243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 101334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (thread_local_.queued_step_count_ > 0) { 101434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Perform queued steps 101534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org int step_count = thread_local_.queued_step_count_; 101634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 101734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Clear queue 101834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org thread_local_.queued_step_count_ = 0; 101934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 1020639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org PrepareStep(StepNext, step_count, StackFrame::NO_ID); 102134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } else { 102234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Notify the debug event listeners. 102334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org isolate_->debugger()->OnDebugBreak(break_points_hit, false); 102434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 1025c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } else if (thread_local_.last_step_action_ != StepNone) { 102643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Hold on to last step action as it is cleared by the call to 102743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // ClearStepping. 1028c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org StepAction step_action = thread_local_.last_step_action_; 1029c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org int step_count = thread_local_.step_count_; 103043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 103134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // If StepNext goes deeper in code, StepOut until original frame 103234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // and keep step count queued up in the meantime. 103334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) { 103434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Count frames until target frame 103534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org int count = 0; 103634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org JavaScriptFrameIterator it(isolate_); 1037212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) { 103834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org count++; 103934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org it.Advance(); 104034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 104134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 104281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Check that we indeed found the frame we are looking for. 104381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_)); 104481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org if (step_count > 1) { 104581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Save old count and action to continue stepping after StepOut. 104681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org thread_local_.queued_step_count_ = step_count - 1; 1047212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } 1048212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 104981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org // Set up for StepOut to reach target frame. 105081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org step_action = StepOut; 105181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org step_count = count; 105234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 105334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Clear all current stepping setup. 1055c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ClearStepping(); 105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set up for the remaining steps. 1058639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org PrepareStep(step_action, step_count, StackFrame::NO_ID); 105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1061c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) { 1062c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org SetAfterBreakTarget(frame); 1063c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } else if (thread_local_.frame_drop_mode_ == 1064ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org FRAME_DROPPED_IN_IC_CALL) { 106569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // We must have been calling IC stub. Do not go there anymore. 1066c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Code* plain_return = isolate_->builtins()->builtin( 1067c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Builtins::kPlainReturn_LiveEdit); 1068c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org thread_local_.after_break_target_ = plain_return->entry(); 1069c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } else if (thread_local_.frame_drop_mode_ == 107069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org FRAME_DROPPED_IN_DEBUG_SLOT_CALL) { 107169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // Debug break slot stub does not return normally, instead it manually 107269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // cleans the stack and jumps. We should patch the jump address. 1073c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Code* plain_return = isolate_->builtins()->builtin( 10747979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Builtins::kFrameDropper_LiveEdit); 1075c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org thread_local_.after_break_target_ = plain_return->entry(); 1076c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } else if (thread_local_.frame_drop_mode_ == 1077ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org FRAME_DROPPED_IN_DIRECT_CALL) { 107869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // Nothing to do, after_break_target is not used here. 10798e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } else if (thread_local_.frame_drop_mode_ == 10808e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org FRAME_DROPPED_IN_RETURN_CALL) { 10818e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org Code* plain_return = isolate_->builtins()->builtin( 10828e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org Builtins::kFrameDropper_LiveEdit); 10838e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org thread_local_.after_break_target_ = plain_return->entry(); 1084357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org } else { 108569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org UNREACHABLE(); 1086357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org } 108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1088ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return heap->undefined_value(); 108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1092c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(Object*, Debug_Break) { 1093c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return isolate->debug()->Break(args); 1094c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org} 1095c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 1096c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check the break point objects for whether one or more are actually 109843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// triggered. This function returns a JSArray with the break point objects 109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// which is triggered. 110043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { 11017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Factory* factory = isolate_->factory(); 11027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11034d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Count the number of break points hit. If there are multiple break points 11044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // they are in a FixedArray. 11054d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org Handle<FixedArray> break_points_hit; 110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int break_points_hit_count = 0; 110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(!break_point_objects->IsUndefined()); 110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (break_point_objects->IsFixedArray()) { 110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<FixedArray> array(FixedArray::cast(*break_point_objects)); 11107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org break_points_hit = factory->NewFixedArray(array->length()); 111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < array->length(); i++) { 111209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> o(array->get(i), isolate_); 111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (CheckBreakPoint(o)) { 11144d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org break_points_hit->set(break_points_hit_count++, *o); 111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 111643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 111743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 11187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org break_points_hit = factory->NewFixedArray(1); 111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (CheckBreakPoint(break_point_objects)) { 11204d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org break_points_hit->set(break_points_hit_count++, *break_point_objects); 112143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 112243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1124d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Return undefined if no break points were triggered. 112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (break_points_hit_count == 0) { 11267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return factory->undefined_value(); 112743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 11284d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Return break points hit as a JSArray. 11297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit); 11304d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org result->set_length(Smi::FromInt(break_points_hit_count)); 11314d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org return result; 113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether a single break point object is triggered. 113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::CheckBreakPoint(Handle<Object> break_point_object) { 11377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Factory* factory = isolate_->factory(); 11387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 1139381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 114043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Ignore check if break point object is not a JSObject. 114143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!break_point_object->IsJSObject()) return true; 114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11434d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Get the function IsBreakPointTriggered (defined in debug-debugger.js). 11444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> is_break_point_triggered_string = 11454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org factory->InternalizeOneByteString( 1146a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org STATIC_ASCII_VECTOR("IsBreakPointTriggered")); 114743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<JSFunction> check_break_point = 114843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<JSFunction>(JSFunction::cast( 114946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org debug_context()->global_object()->GetPropertyNoExceptionThrown( 11504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org *is_break_point_triggered_string))); 115143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the break id as an object. 11537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id()); 115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Call HandleBreakPointx. 1156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool caught_exception; 1157a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { break_id, break_point_object }; 115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> result = Execution::TryCall(check_break_point, 1159a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org isolate_->js_builtins_object(), 1160a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 1161a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argv, 1162a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org &caught_exception); 116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If exception or non boolean result handle as not triggered 116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (caught_exception || !result->IsBoolean()) { 116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return whether the break point is triggered. 1170ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(!result.is_null()); 1171ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return (*result)->IsTrue(); 117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether the function has debug information. 117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) { 117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return !shared->debug_info()->IsUndefined(); 117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1181bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// Return the debug info for this function. EnsureDebugInfo must be called 1182bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// prior to ensure the debug info has been generated for shared. 118343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { 1184bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund ASSERT(HasDebugInfo(shared)); 118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); 118643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgvoid Debug::SetBreakPoint(Handle<JSFunction> function, 11905ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org Handle<Object> break_point_object, 11915ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org int* source_position) { 11927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 1193381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 119434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org PrepareForBreakPoints(); 119534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 11965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Make sure the function is compiled and has set up the debug info. 11975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared(function->shared()); 11985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!EnsureDebugInfo(shared, function)) { 1199bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund // Return if retrieving debug info failed. 1200bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund return; 120143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 120243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1203bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund Handle<DebugInfo> debug_info = GetDebugInfo(shared); 120443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Source positions starts with zero. 1205bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org ASSERT(*source_position >= 0); 120643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Find the break point and change it. 120843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); 120993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED); 121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it.SetBreakPoint(break_point_object); 121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12125ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org *source_position = it.position(); 12135ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // At least one active break point now. 121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(debug_info->GetBreakPointCount() > 0); 121643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgbool Debug::SetBreakPointForScript(Handle<Script> script, 12205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<Object> break_point_object, 122193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org int* source_position, 122293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org BreakPositionAlignment alignment) { 12235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HandleScope scope(isolate_); 12245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 122578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org PrepareForBreakPoints(); 122678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 122778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // Obtain shared function info for the function. 122878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Object* result = FindSharedFunctionInfoInScript(script, *source_position); 12295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (result->IsUndefined()) return false; 12305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 12315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Make sure the function has set up the debug info. 12325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); 12335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { 12345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Return if retrieving debug info failed. 12355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return false; 12365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 12375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 12385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Find position within function. The script position might be before the 12395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // source position of the first function. 12405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int position; 12415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (shared->start_position() > *source_position) { 12425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org position = 0; 12435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 12445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org position = *source_position - shared->start_position(); 12455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 12465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 12475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<DebugInfo> debug_info = GetDebugInfo(shared); 12485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Source positions starts with zero. 12495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(position >= 0); 12505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 12515a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Find the break point and change it. 12525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); 125393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org it.FindBreakLocationFromPosition(position, alignment); 12545a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org it.SetBreakPoint(break_point_object); 12555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 12565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org *source_position = it.position() + shared->start_position(); 12575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 12585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // At least one active break point now. 12595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(debug_info->GetBreakPointCount() > 0); 12605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return true; 12615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org} 12625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 12635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 126443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearBreakPoint(Handle<Object> break_point_object) { 12657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 1266381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 126743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DebugInfoListNode* node = debug_info_list_; 126843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (node != NULL) { 126943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), 127043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_point_object); 127143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!result->IsUndefined()) { 127243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get information in the break point. 127343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakPointInfo* break_point_info = BreakPointInfo::cast(result); 127443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<DebugInfo> debug_info = node->debug_info(); 127543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 127643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Find the break point and clear it. 127743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); 12788a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org it.FindBreakLocationFromAddress(debug_info->code()->entry() + 12798a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org break_point_info->code_position()->value()); 128043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it.ClearBreakPoint(break_point_object); 128143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 128243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there are no more break points left remove the debug info for this 128343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function. 128443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (debug_info->GetBreakPointCount() == 0) { 128543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RemoveDebugInfo(debug_info); 128643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 128743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 128843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 128943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 129043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen node = node->next(); 129143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 129243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 129343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 129443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1295381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgvoid Debug::ClearAllBreakPoints() { 1296381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org DebugInfoListNode* node = debug_info_list_; 1297381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org while (node != NULL) { 1298381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Remove all debug break code. 1299381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 1300381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org it.ClearAllDebugBreak(); 1301381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org node = node->next(); 1302381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1303381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1304381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Remove all debug info. 1305381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org while (debug_info_list_ != NULL) { 1306381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org RemoveDebugInfo(debug_info_list_->debug_info()); 1307381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1308381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1309381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1310381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 13115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgvoid Debug::FloodWithOneShot(Handle<JSFunction> function) { 131234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org PrepareForBreakPoints(); 13135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 13145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Make sure the function is compiled and has set up the debug info. 13155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared(function->shared()); 13165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!EnsureDebugInfo(shared, function)) { 1317bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund // Return if we failed to retrieve the debug info. 1318bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund return; 1319bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund } 132043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 132143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Flood the function with break points. 1322bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); 132343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!it.Done()) { 132443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it.SetOneShot(); 132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it.Next(); 132643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 132843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 132943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13302c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) { 13312c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Handle<FixedArray> new_bindings(function->function_bindings()); 133209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex), 133309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate_); 13342c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 13352c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (!bindee.is_null() && bindee->IsJSFunction() && 13362c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org !JSFunction::cast(*bindee)->IsBuiltin()) { 13375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<JSFunction> bindee_function(JSFunction::cast(*bindee)); 13385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Debug::FloodWithOneShot(bindee_function); 13392c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 13402c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org} 13412c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 13422c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 134343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::FloodHandlerWithOneShot() { 13448bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // Iterate through the JavaScript stack looking for handlers. 13457be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org StackFrame::Id id = break_frame_id(); 13468bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (id == StackFrame::NO_ID) { 13478bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // If there is no JavaScript stack don't do anything. 13488bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org return; 13498bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 135074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) { 135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen JavaScriptFrame* frame = it.frame(); 135243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (frame->HasHandler()) { 135343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Flood the function with the catch block with break points 1354169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org FloodWithOneShot(Handle<JSFunction>(frame->function())); 135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 135743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 135843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 135943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { 136243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (type == BreakUncaughtException) { 136343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_on_uncaught_exception_ = enable; 136443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 136543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_on_exception_ = enable; 136643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 136743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 136843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1370c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgbool Debug::IsBreakOnException(ExceptionBreakType type) { 1371c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org if (type == BreakUncaughtException) { 1372c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org return break_on_uncaught_exception_; 1373c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org } else { 1374c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org return break_on_exception_; 1375c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org } 1376c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org} 1377c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 1378c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 1379639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgvoid Debug::PrepareStep(StepAction step_action, 1380639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org int step_count, 1381639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org StackFrame::Id frame_id) { 13827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 138334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 138434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org PrepareForBreakPoints(); 138534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 138643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(Debug::InDebugger()); 138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Remember this step action and count. 138943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.last_step_action_ = step_action; 1390a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (step_action == StepOut) { 1391a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // For step out target frame will be found on the stack so there is no need 1392a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // to set step counter for it. It's expected to always be 0 for StepOut. 1393a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org thread_local_.step_count_ = 0; 1394a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } else { 1395a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org thread_local_.step_count_ = step_count; 1396a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 139743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 139843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the frame where the execution has stopped and skip the debug frame if 139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // any. The debug frame will only be present if execution was stopped due to 140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // hitting a break point. In other situations (e.g. unhandled exception) the 140143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // debug frame is not present. 14027be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org StackFrame::Id id = break_frame_id(); 14038bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (id == StackFrame::NO_ID) { 14048bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // If there is no JavaScript stack don't do anything. 14058bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org return; 14068bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 1407639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (frame_id != StackFrame::NO_ID) { 1408639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org id = frame_id; 1409639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 141074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org JavaScriptFrameIterator frames_it(isolate_, id); 141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen JavaScriptFrame* frame = frames_it.frame(); 141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // First of all ensure there is one-shot break points in the top handler 141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // if any. 141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FloodHandlerWithOneShot(); 141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the function on the top frame is unresolved perform step out. This will 141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // be the case when calling unknown functions and having the debugger stopped 141943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // in an unhandled exception. 142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!frame->function()->IsJSFunction()) { 142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Step out: Find the calling JavaScript frame and flood it with 142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // breakpoints. 142343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen frames_it.Advance(); 142443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Fill the function to return to with one-shot break points. 1425169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org JSFunction* function = frames_it.frame()->function(); 14265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org FloodWithOneShot(Handle<JSFunction>(function)); 142743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 142843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 142943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 143043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the debug info (create it if it does not exist). 1431169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Handle<JSFunction> function(frame->function()); 14325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared(function->shared()); 14335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!EnsureDebugInfo(shared, function)) { 1434bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund // Return if ensuring debug info failed. 1435bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund return; 1436bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund } 143743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<DebugInfo> debug_info = GetDebugInfo(shared); 143843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Find the break location where execution has stopped. 144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS); 14418a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // pc points to the instruction after the current one, possibly a break 14428a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // location as well. So the "- 1" to exclude it from the search. 14438a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org it.FindBreakLocationFromAddress(frame->pc() - 1); 144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 144543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute whether or not the target is a call target. 1446e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org bool is_load_or_store = false; 1447e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org bool is_inline_cache_stub = false; 1448e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org bool is_at_restarted_function = false; 1449a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Handle<Code> call_function_stub; 1450a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 1451e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (thread_local_.restarter_frame_function_pointer_ == NULL) { 1452e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { 1453e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org bool is_call_target = false; 1454e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Address target = it.rinfo()->target_address(); 1455e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Code* code = Code::GetCodeFromTargetAddress(target); 1456e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (code->is_call_stub() || code->is_keyed_call_stub()) { 1457e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org is_call_target = true; 1458e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org } 1459e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (code->is_inline_cache_stub()) { 1460e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org is_inline_cache_stub = true; 1461e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org is_load_or_store = !is_call_target; 1462e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org } 1463e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 1464e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // Check if target code is CallFunction stub. 1465e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Code* maybe_call_function_stub = code; 1466e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // If there is a breakpoint at this line look at the original code to 1467e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // check if it is a CallFunction stub. 1468e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (it.IsDebugBreak()) { 1469e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Address original_target = it.original_rinfo()->target_address(); 1470e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org maybe_call_function_stub = 1471e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Code::GetCodeFromTargetAddress(original_target); 1472e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org } 1473e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (maybe_call_function_stub->kind() == Code::STUB && 1474e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org maybe_call_function_stub->major_key() == CodeStub::CallFunction) { 1475e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // Save reference to the code as we may need it to find out arguments 1476e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // count for 'step in' later. 1477e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org call_function_stub = Handle<Code>(maybe_call_function_stub); 1478e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org } 1479a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1480e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org } else { 1481e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org is_at_restarted_function = true; 148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 148343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1484727e995b7bba3c57fb1e5c156d386ca11894f781v // If this is the last break code target step out is the only possibility. 148543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (it.IsExit() || step_action == StepOut) { 1486a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (step_action == StepOut) { 1487a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Skip step_count frames starting with the current one. 1488a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org while (step_count-- > 0 && !frames_it.done()) { 1489a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org frames_it.Advance(); 1490a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1491a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } else { 1492a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ASSERT(it.IsExit()); 1493a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org frames_it.Advance(); 1494a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1495a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Skip builtin functions on the stack. 1496169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org while (!frames_it.done() && frames_it.frame()->function()->IsBuiltin()) { 1497a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org frames_it.Advance(); 1498a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 149943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Step out: If there is a JavaScript caller frame, we need to 150043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // flood it with breakpoints. 150143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!frames_it.done()) { 150243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Fill the function to return to with one-shot break points. 1503169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org JSFunction* function = frames_it.frame()->function(); 15045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org FloodWithOneShot(Handle<JSFunction>(function)); 1505a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Set target frame pointer. 1506a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ActivateStepOut(frames_it.frame()); 150743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1508a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) || 1509e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org !call_function_stub.is_null() || is_at_restarted_function) 1510e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org || step_action == StepNext || step_action == StepMin) { 151143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Step next or step min. 151243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 151343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Fill the current function with one-shot break points. 15145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org FloodWithOneShot(function); 151543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 151643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Remember source position and frame to handle step next. 151743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.last_statement_position_ = 151843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen debug_info->code()->SourceStatementPosition(frame->pc()); 15197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org thread_local_.last_fp_ = frame->UnpaddedFP(); 152043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 1521e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // If there's restarter frame on top of the stack, just get the pointer 1522e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // to function which is going to be restarted. 1523e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (is_at_restarted_function) { 1524e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Handle<JSFunction> restarted_function( 1525e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org JSFunction::cast(*thread_local_.restarter_frame_function_pointer_)); 15265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org FloodWithOneShot(restarted_function); 1527e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org } else if (!call_function_stub.is_null()) { 1528e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // If it's CallFunction stub ensure target function is compiled and flood 1529e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // it with one shot breakpoints. 1530e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 1531a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Find out number of arguments from the stub minor key. 1532a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Reverse lookup required as the minor key cannot be retrieved 1533a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // from the code object. 1534a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Handle<Object> obj( 15357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->heap()->code_stubs()->SlowReverseLookup( 153609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org *call_function_stub), 153709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate_); 1538ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(!obj.is_null()); 1539ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(!(*obj)->IsUndefined()); 1540a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ASSERT(obj->IsSmi()); 1541a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Get the STUB key and extract major and minor key. 1542a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org uint32_t key = Smi::cast(*obj)->value(); 1543a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Argc in the stub is the number of arguments passed - not the 1544a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // expected arguments of the called function. 1545b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int call_function_arg_count = 1546b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallFunctionStub::ExtractArgcFromMinorKey( 1547b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CodeStub::MinorKeyFromKey(key)); 1548a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ASSERT(call_function_stub->major_key() == 1549a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org CodeStub::MajorKeyFromKey(key)); 1550a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 1551a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Find target function on the expression stack. 1552b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Expression stack looks like this (top to bottom): 1553a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // argN 1554a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // ... 1555a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // arg0 1556a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Receiver 1557a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Function to call 1558a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org int expressions_count = frame->ComputeExpressionsCount(); 1559a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ASSERT(expressions_count - 2 - call_function_arg_count >= 0); 1560a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Object* fun = frame->GetExpression( 1561a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org expressions_count - 2 - call_function_arg_count); 1562a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (fun->IsJSFunction()) { 1563a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Handle<JSFunction> js_function(JSFunction::cast(fun)); 15642c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (js_function->shared()->bound()) { 15652c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Debug::FloodBoundFunctionWithOneShot(js_function); 15662c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } else if (!js_function->IsBuiltin()) { 15672c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // Don't step into builtins. 1568a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // It will also compile target function if it's not compiled yet. 15695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org FloodWithOneShot(js_function); 1570a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1571a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1572a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 1573a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 157443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Fill the current function with one-shot break points even for step in on 157543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // a call target as the function called might be a native function for 1576e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // which step in will not stop. It also prepares for stepping in 1577e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // getters/setters. 15785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org FloodWithOneShot(function); 157943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1580e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (is_load_or_store) { 1581e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Remember source position and frame to handle step in getter/setter. If 1582e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // there is a custom getter/setter it will be handled in 1583e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Object::Get/SetPropertyWithCallback, otherwise the step action will be 1584e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // propagated on the next Debug::Break. 1585e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org thread_local_.last_statement_position_ = 1586e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org debug_info->code()->SourceStatementPosition(frame->pc()); 15877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org thread_local_.last_fp_ = frame->UnpaddedFP(); 1588e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 1589e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Step in or Step in min 1591c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org it.PrepareStepIn(isolate_); 159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ActivateStepIn(frame); 159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether the current debug break should be reported to the debugger. It 159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// is used to have step next and step in only report break back to the debugger 159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// if on a different frame or in a different statement. In some situations 160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// there will be several break points in the same statement when the code is 1601727e995b7bba3c57fb1e5c156d386ca11894f781v// flooded with one-shot break points. This function helps to perform several 160243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// steps before reporting break back to the debugger. 160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, 160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen JavaScriptFrame* frame) { 160534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // StepNext and StepOut shouldn't bring us deeper in code, so last frame 160634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // shouldn't be a parent of current frame. 160734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (thread_local_.last_step_action_ == StepNext || 160834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org thread_local_.last_step_action_ == StepOut) { 160934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (frame->fp() < thread_local_.last_fp_) return true; 161034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 161134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the step last action was step next or step in make sure that a new 161343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // statement is hit. 161443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (thread_local_.last_step_action_ == StepNext || 161543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.last_step_action_ == StepIn) { 161643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Never continue if returning from function. 161743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (break_location_iterator->IsExit()) return false; 161843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 161943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Continue if we are still on the same frame and in the same statement. 162043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int current_statement_position = 162143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break_location_iterator->code()->SourceStatementPosition(frame->pc()); 16227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return thread_local_.last_fp_ == frame->UnpaddedFP() && 1623236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org thread_local_.last_statement_position_ == current_statement_position; 162443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 162543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // No step next action - don't continue. 162743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 162843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 162943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether the code object at the specified address is a debug break code 163243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object. 163343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::IsDebugBreak(Address addr) { 16348bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Code* code = Code::GetCodeFromTargetAddress(addr); 1635ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK; 163643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 163743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether a code stub with the specified major key is a possible break 164043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// point location when looking for source break locations. 164143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::IsSourceBreakStub(Code* code) { 1642d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org CodeStub::Major major_key = CodeStub::GetMajorKey(code); 164343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return major_key == CodeStub::CallFunction; 164443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether a code stub with the specified major key is a possible break 164843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// location. 164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::IsBreakStub(Code* code) { 1650d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org CodeStub::Major major_key = CodeStub::GetMajorKey(code); 1651e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org return major_key == CodeStub::CallFunction; 165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Find the builtin to use for invoking the debug break 165665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgHandle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) { 1657e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org Isolate* isolate = code->GetIsolate(); 1658fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 165943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Find the builtin debug break function matching the calling convention 166043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // used by the call site. 166165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org if (code->is_inline_cache_stub()) { 1662ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org switch (code->kind()) { 1663ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org case Code::CALL_IC: 16641af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org case Code::KEYED_CALL_IC: 1665fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->stub_cache()->ComputeCallDebugBreak( 1666fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org code->arguments_count(), code->kind()); 1667ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1668ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org case Code::LOAD_IC: 1669fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->builtins()->LoadIC_DebugBreak(); 1670ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1671ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org case Code::STORE_IC: 1672fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->builtins()->StoreIC_DebugBreak(); 1673ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1674ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org case Code::KEYED_LOAD_IC: 1675fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->builtins()->KeyedLoadIC_DebugBreak(); 1676ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1677ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org case Code::KEYED_STORE_IC: 1678fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->builtins()->KeyedStoreIC_DebugBreak(); 1679ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1680f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org case Code::COMPARE_NIL_IC: 1681f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org return isolate->builtins()->CompareNilIC_DebugBreak(); 1682f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 1683ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org default: 1684ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org UNREACHABLE(); 168543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 168643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 168765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org if (RelocInfo::IsConstructCall(mode)) { 1688fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org if (code->has_function_cache()) { 1689fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); 1690fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } else { 1691fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->builtins()->CallConstructStub_DebugBreak(); 1692fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } 169365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org } 169465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org if (code->kind() == Code::STUB) { 1695e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org ASSERT(code->major_key() == CodeStub::CallFunction); 1696fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org if (code->has_function_cache()) { 1697fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->builtins()->CallFunctionStub_Recording_DebugBreak(); 1698fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } else { 1699fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org return isolate->builtins()->CallFunctionStub_DebugBreak(); 1700fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } 170165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org } 170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 170443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Handle<Code>::null(); 170543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 170643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Simple function for returning the source positions for active break points. 170943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debug::GetSourceBreakLocations( 171093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org Handle<SharedFunctionInfo> shared, 171193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org BreakPositionAlignment position_alignment) { 1712e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org Isolate* isolate = shared->GetIsolate(); 17137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Heap* heap = isolate->heap(); 171409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org if (!HasDebugInfo(shared)) { 171509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org return Handle<Object>(heap->undefined_value(), isolate); 171609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org } 171743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<DebugInfo> debug_info = GetDebugInfo(shared); 171843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (debug_info->GetBreakPointCount() == 0) { 171909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org return Handle<Object>(heap->undefined_value(), isolate); 172043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 172143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<FixedArray> locations = 17227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); 172343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int count = 0; 172443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < debug_info->break_points()->length(); i++) { 172543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!debug_info->break_points()->get(i)->IsUndefined()) { 172643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakPointInfo* break_point_info = 172743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakPointInfo::cast(debug_info->break_points()->get(i)); 172843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (break_point_info->GetBreakPointCount() > 0) { 172993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org Smi* position; 173093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org switch (position_alignment) { 173193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org case STATEMENT_ALIGNED: 173293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org position = break_point_info->statement_position(); 173393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org break; 173493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org case BREAK_POSITION_ALIGNED: 173593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org position = break_point_info->source_position(); 173693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org break; 173793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org default: 173893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org UNREACHABLE(); 173993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org position = break_point_info->statement_position(); 174093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org } 174193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org 174293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org locations->set(count++, position); 174343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 174443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 174543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 174643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return locations; 174743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 174843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 174943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17507be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid Debug::NewBreak(StackFrame::Id break_frame_id) { 17517be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org thread_local_.break_frame_id_ = break_frame_id; 17527be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org thread_local_.break_id_ = ++thread_local_.break_count_; 17537be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 17547be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 17557be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 17567be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgvoid Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) { 17577be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org thread_local_.break_frame_id_ = break_frame_id; 17587be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org thread_local_.break_id_ = break_id; 17597be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 17607be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 17617be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 176237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// Handle stepping into a function. 176337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid Debug::HandleStepIn(Handle<JSFunction> function, 1764defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org Handle<Object> holder, 176537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com Address fp, 176637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com bool is_constructor) { 1767c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org Isolate* isolate = function->GetIsolate(); 176837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // If the frame pointer is not supplied by the caller find it. 176937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (fp == 0) { 1770c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org StackFrameIterator it(isolate); 177137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com it.Advance(); 177237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // For constructor functions skip another frame. 177337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com if (is_constructor) { 177437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com ASSERT(it.frame()->is_construct()); 177537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com it.Advance(); 177637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 177737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com fp = it.frame()->fp(); 177837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 177937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 178037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Flood the function with one-shot break points if it is called from where 178137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // step into was requested. 1782ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (fp == step_in_fp()) { 17832c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (function->shared()->bound()) { 17842c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // Handle Function.prototype.bind 17852c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Debug::FloodBoundFunctionWithOneShot(function); 17862c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } else if (!function->IsBuiltin()) { 17872c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // Don't allow step into functions in the native context. 1788acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org if (function->shared()->code() == 1789c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org isolate->builtins()->builtin(Builtins::kFunctionApply) || 1790acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org function->shared()->code() == 1791c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org isolate->builtins()->builtin(Builtins::kFunctionCall)) { 1792acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org // Handle function.apply and function.call separately to flood the 1793acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org // function to be called and not the code for Builtins::FunctionApply or 1794defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org // Builtins::FunctionCall. The receiver of call/apply is the target 1795defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org // function. 1796528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!holder.is_null() && holder->IsJSFunction()) { 17975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder); 1798528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!js_function->IsBuiltin()) { 1799528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Debug::FloodWithOneShot(js_function); 1800528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else if (js_function->shared()->bound()) { 1801528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Handle Function.prototype.bind 1802528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Debug::FloodBoundFunctionWithOneShot(js_function); 1803528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 1804acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org } 1805acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org } else { 18065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Debug::FloodWithOneShot(function); 1807acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org } 180837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 180937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com } 181037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com} 181137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 181237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com 181343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearStepping() { 181443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Clear the various stepping setup. 181543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ClearOneShot(); 181643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ClearStepIn(); 1817a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ClearStepOut(); 181843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ClearStepNext(); 181943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 182043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Clear multiple step counter. 182143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.step_count_ = 0; 182243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 182343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1824e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 182543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Clears all the one-shot break points that are currently set. Normally this 182643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// function is called each time a break point is hit as one shot break points 182743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// are used to support stepping. 182843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearOneShot() { 182943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The current implementation just runs through all the breakpoints. When the 1830727e995b7bba3c57fb1e5c156d386ca11894f781v // last break point for a function is removed that function is automatically 183143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // removed from the list. 183243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 183343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DebugInfoListNode* node = debug_info_list_; 183443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (node != NULL) { 183543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 183643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!it.Done()) { 183743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it.ClearOneShot(); 183843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it.Next(); 183943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 184043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen node = node->next(); 184143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 184243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 184343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 184443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 184543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ActivateStepIn(StackFrame* frame) { 1846a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ASSERT(!StepOutActive()); 18477028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org thread_local_.step_into_fp_ = frame->UnpaddedFP(); 184843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 184943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 185043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 185143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearStepIn() { 185243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.step_into_fp_ = 0; 185343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 185443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 185543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1856a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid Debug::ActivateStepOut(StackFrame* frame) { 1857a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ASSERT(!StepInActive()); 18587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org thread_local_.step_out_fp_ = frame->UnpaddedFP(); 1859a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org} 1860a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 1861a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 1862a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid Debug::ClearStepOut() { 1863a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org thread_local_.step_out_fp_ = 0; 1864a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org} 1865a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 1866a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 186743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearStepNext() { 186843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.last_step_action_ = StepNone; 1869236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 187043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.last_fp_ = 0; 187143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 187243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 187343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1874394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// Helper function to compile full code for debugging. This code will 18757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// have debug break slots and deoptimization information. Deoptimization 18767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// information is required in case that an optimized version of this 18777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// function is still activated on the stack. It will also make sure that 18787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// the full code is compiled with the same flags as the previous version, 18797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// that is flags which can change the code generated. The current method 18807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// of mapping from already compiled full code without debug break slots 18817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// to full code with debug break slots depends on the generated code is 18827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// otherwise exactly the same. 18837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgstatic bool CompileFullCodeForDebugging(Handle<JSFunction> function, 1884394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Code> current_code) { 1885394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!current_code->has_debug_break_slots()); 1886394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 18875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org CompilationInfoWithZone info(function); 1888394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com info.MarkCompilingForDebugging(current_code); 1889394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!info.shared_info()->is_compiled()); 1890394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!info.isolate()->has_pending_exception()); 1891394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1892394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Use compile lazy which will end up compiling the full code in the 1893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // configuration configured above. 1894394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool result = Compiler::CompileLazy(&info); 1895e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org ASSERT(result != info.isolate()->has_pending_exception()); 1896394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com info.isolate()->clear_pending_exception(); 1897394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#if DEBUG 1898394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (result) { 18997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<Code> new_code(function->shared()->code()); 1900394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(new_code->has_debug_break_slots()); 1901394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(current_code->is_compiled_optimizable() == 1902394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com new_code->is_compiled_optimizable()); 1903394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1904394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#endif 1905394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return result; 1906394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1907394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1908394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1909659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgstatic void CollectActiveFunctionsFromThread( 1910659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Isolate* isolate, 1911659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ThreadLocalTop* top, 1912659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org List<Handle<JSFunction> >* active_functions, 1913659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Object* active_code_marker) { 1914659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Find all non-optimized code functions with activation frames 1915659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // on the stack. This includes functions which have optimized 1916659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // activations (including inlined functions) on the stack as the 1917659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // non-optimized code is needed for the lazy deoptimization. 1918659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { 1919659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org JavaScriptFrame* frame = it.frame(); 1920659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (frame->is_optimized()) { 1921ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org List<JSFunction*> functions(FLAG_max_inlining_levels + 1); 1922659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org frame->GetFunctions(&functions); 1923659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org for (int i = 0; i < functions.length(); i++) { 1924659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org JSFunction* function = functions[i]; 1925659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org active_functions->Add(Handle<JSFunction>(function)); 1926659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org function->shared()->code()->set_gc_metadata(active_code_marker); 1927659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 1928659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } else if (frame->function()->IsJSFunction()) { 1929169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org JSFunction* function = frame->function(); 1930659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ASSERT(frame->LookupCode()->kind() == Code::FUNCTION); 1931659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org active_functions->Add(Handle<JSFunction>(function)); 1932659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org function->shared()->code()->set_gc_metadata(active_code_marker); 1933659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 1934659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 1935659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org} 1936659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 1937659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 1938659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgstatic void RedirectActivationsToRecompiledCodeOnThread( 1939659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Isolate* isolate, 1940659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ThreadLocalTop* top) { 1941659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { 1942659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org JavaScriptFrame* frame = it.frame(); 1943659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 1944659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (frame->is_optimized() || !frame->function()->IsJSFunction()) continue; 1945659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 1946169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org JSFunction* function = frame->function(); 1947659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 1948659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ASSERT(frame->LookupCode()->kind() == Code::FUNCTION); 1949659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 1950659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Handle<Code> frame_code(frame->LookupCode()); 1951659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (frame_code->has_debug_break_slots()) continue; 1952659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 1953659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Handle<Code> new_code(function->shared()->code()); 1954659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (new_code->kind() != Code::FUNCTION || 1955659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org !new_code->has_debug_break_slots()) { 1956659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org continue; 1957659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 1958659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 19595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Iterate over the RelocInfo in the original code to compute the sum of the 19605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // constant pools sizes. (See Assembler::CheckConstPool()) 19615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Note that this is only useful for architectures using constant pools. 19625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int constpool_mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL); 19635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int frame_const_pool_size = 0; 19645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org for (RelocIterator it(*frame_code, constpool_mask); !it.done(); it.next()) { 19655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org RelocInfo* info = it.rinfo(); 19665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (info->pc() >= frame->pc()) break; 19675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org frame_const_pool_size += static_cast<int>(info->data()); 19685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 19695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org intptr_t frame_offset = 19705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org frame->pc() - frame_code->instruction_start() - frame_const_pool_size; 19715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 19725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Iterate over the RelocInfo for new code to find the number of bytes 19735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // generated for debug slots and constant pools. 19745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int debug_break_slot_bytes = 0; 19755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int new_code_const_pool_size = 0; 19765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) | 19775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org RelocInfo::ModeMask(RelocInfo::CONST_POOL); 1978659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org for (RelocIterator it(*new_code, mask); !it.done(); it.next()) { 1979659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Check if the pc in the new code with debug break 1980659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // slots is before this slot. 1981659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org RelocInfo* info = it.rinfo(); 19825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org intptr_t new_offset = info->pc() - new_code->instruction_start() - 19835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org new_code_const_pool_size - debug_break_slot_bytes; 19845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (new_offset >= frame_offset) { 1985659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org break; 1986659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 1987659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 19885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (RelocInfo::IsDebugBreakSlot(info->rmode())) { 19895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org debug_break_slot_bytes += Assembler::kDebugBreakSlotLength; 19905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 19915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(RelocInfo::IsConstPool(info->rmode())); 19925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // The size of the constant pool is encoded in the data. 19935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org new_code_const_pool_size += static_cast<int>(info->data()); 19945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 1995659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 19965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 19975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Compute the equivalent pc in the new code. 19985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org byte* new_pc = new_code->instruction_start() + frame_offset + 19995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org debug_break_slot_bytes + new_code_const_pool_size; 20005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 2001659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (FLAG_trace_deopt) { 2002659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org PrintF("Replacing code %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) " 2003659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org "with %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) " 2004659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org "for debugging, " 2005659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org "changing pc from %08" V8PRIxPTR " to %08" V8PRIxPTR "\n", 2006659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org reinterpret_cast<intptr_t>( 2007659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org frame_code->instruction_start()), 2008659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org reinterpret_cast<intptr_t>( 2009659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org frame_code->instruction_start()) + 2010659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org frame_code->instruction_size(), 2011659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org frame_code->instruction_size(), 2012659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org reinterpret_cast<intptr_t>(new_code->instruction_start()), 2013659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org reinterpret_cast<intptr_t>(new_code->instruction_start()) + 2014659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org new_code->instruction_size(), 2015659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org new_code->instruction_size(), 2016659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org reinterpret_cast<intptr_t>(frame->pc()), 20175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org reinterpret_cast<intptr_t>(new_pc)); 2018659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 2019659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2020659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Patch the return address to return into the code with 2021659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // debug break slots. 20225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org frame->set_pc(new_pc); 2023659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 2024659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org} 2025659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2026659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2027659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass ActiveFunctionsCollector : public ThreadVisitor { 2028659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org public: 2029659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org explicit ActiveFunctionsCollector(List<Handle<JSFunction> >* active_functions, 2030659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Object* active_code_marker) 2031659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org : active_functions_(active_functions), 2032659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org active_code_marker_(active_code_marker) { } 2033659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2034659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 2035659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org CollectActiveFunctionsFromThread(isolate, 2036659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org top, 2037659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org active_functions_, 2038659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org active_code_marker_); 2039659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 2040659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2041659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org private: 2042659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org List<Handle<JSFunction> >* active_functions_; 2043659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Object* active_code_marker_; 2044659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}; 2045659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2046659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2047659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass ActiveFunctionsRedirector : public ThreadVisitor { 2048659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org public: 2049659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 2050659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org RedirectActivationsToRecompiledCodeOnThread(isolate, top); 2051659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 2052659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}; 2053659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2054659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 205534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgvoid Debug::PrepareForBreakPoints() { 205634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // If preparing for the first break point make sure to deoptimize all 205734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // functions as debugging does not work with optimized code. 205834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (!has_break_points_) { 20599af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org if (isolate_->concurrent_recompilation_enabled()) { 2060594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org isolate_->optimizing_compiler_thread()->Flush(); 2061594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 2062594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 2063876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org Deoptimizer::DeoptimizeAll(isolate_); 206434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 2065394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Code> lazy_compile = 2066394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Code>(isolate_->builtins()->builtin(Builtins::kLazyCompile)); 2067394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 20685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // There will be at least one break point when we are done. 20695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org has_break_points_ = true; 20705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 2071394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Keep the list of activated functions in a handlified list as it 2072394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // is used both in GC and non-GC code. 2073394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com List<Handle<JSFunction> > active_functions(100); 2074394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2075394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com { 2076394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // We are going to iterate heap to find all functions without 2077394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // debug break slots. 20787c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Heap* heap = isolate_->heap(); 20797c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, 20807c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org "preparing for breakpoints"); 2081394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2082659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Ensure no GC in this scope as we are going to use gc_metadata 2083659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // field in the Code object to mark active functions. 208479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_allocation; 2085394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 20867c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Object* active_code_marker = heap->the_hole_value(); 2087ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org 2088659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org CollectActiveFunctionsFromThread(isolate_, 2089659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org isolate_->thread_local_top(), 2090659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org &active_functions, 2091659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org active_code_marker); 2092659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ActiveFunctionsCollector active_functions_collector(&active_functions, 2093659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org active_code_marker); 2094659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org isolate_->thread_manager()->IterateArchivedThreads( 2095659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org &active_functions_collector); 2096394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2097659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Scan the heap for all non-optimized functions which have no 2098659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // debug break slots and are not active or inlined into an active 2099659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // function and mark them for lazy compilation. 21007c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org HeapIterator iterator(heap); 2101394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HeapObject* obj = NULL; 2102394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com while (((obj = iterator.next()) != NULL)) { 2103394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (obj->IsJSFunction()) { 2104394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSFunction* function = JSFunction::cast(obj); 2105659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org SharedFunctionInfo* shared = function->shared(); 21061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 21071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!shared->allows_lazy_compilation()) continue; 21081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!shared->script()->IsScript()) continue; 2109c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (function->IsBuiltin()) continue; 21101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (shared->code()->gc_metadata() == active_code_marker) continue; 21111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 21121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::Kind kind = function->code()->kind(); 21131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (kind == Code::FUNCTION && 21141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org !function->code()->has_debug_break_slots()) { 2115659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org function->set_code(*lazy_compile); 2116659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org function->shared()->set_code(*lazy_compile); 21171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (kind == Code::BUILTIN && 21184a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org (function->IsInRecompileQueue() || 21191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org function->IsMarkedForLazyRecompilation() || 21209259716434187c932704601f700375e53d865de8rossberg@chromium.org function->IsMarkedForConcurrentRecompilation())) { 21211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Abort in-flight compilation. 21221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code* shared_code = function->shared()->code(); 21231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (shared_code->kind() == Code::FUNCTION && 21241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org shared_code->has_debug_break_slots()) { 21251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org function->set_code(shared_code); 21261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else { 21271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org function->set_code(*lazy_compile); 21281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org function->shared()->set_code(*lazy_compile); 21291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 2130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2131394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 213234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 2133394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2134659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Clear gc_metadata field. 2135659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org for (int i = 0; i < active_functions.length(); i++) { 2136659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Handle<JSFunction> function = active_functions[i]; 2137659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org function->shared()->code()->set_gc_metadata(Smi::FromInt(0)); 2138659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 2139659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 2140394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2141394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Now recompile all functions with activation frames and and 2142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // patch the return address to run in the new compiled code. 2143394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for (int i = 0; i < active_functions.length(); i++) { 2144394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSFunction> function = active_functions[i]; 21457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<SharedFunctionInfo> shared(function->shared()); 2146659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2147659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (function->code()->kind() == Code::FUNCTION && 2148659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org function->code()->has_debug_break_slots()) { 2149659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Nothing to do. Function code already had debug break slots. 2150659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org continue; 2151659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 2152659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If recompilation is not possible just skip it. 2154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (shared->is_toplevel() || 2155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com !shared->allows_lazy_compilation() || 2156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com shared->code()->kind() == Code::BUILTIN) { 2157394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com continue; 2158394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2159394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2160394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Make sure that the shared full code is compiled with debug 2161394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // break slots. 216264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (!shared->code()->has_debug_break_slots()) { 2163394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Try to compile the full code with debug break slots. If it 2164394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // fails just keep the current code. 216564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<Code> current_code(function->shared()->code()); 2166394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com shared->set_code(*lazy_compile); 2167394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool prev_force_debugger_active = 2168394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com isolate_->debugger()->force_debugger_active(); 2169394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com isolate_->debugger()->set_force_debugger_active(true); 217064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(current_code->kind() == Code::FUNCTION); 21717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org CompileFullCodeForDebugging(function, current_code); 2172394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com isolate_->debugger()->set_force_debugger_active( 2173394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com prev_force_debugger_active); 2174394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!shared->is_compiled()) { 2175394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com shared->set_code(*current_code); 2176394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com continue; 2177394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2178394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2179394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2180659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Keep function code in sync with shared function info. 2181659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org function->set_code(shared->code()); 218234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 2183659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2184659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org RedirectActivationsToRecompiledCodeOnThread(isolate_, 2185659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org isolate_->thread_local_top()); 2186659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2187659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ActiveFunctionsRedirector active_functions_redirector; 2188659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org isolate_->thread_manager()->IterateArchivedThreads( 2189659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org &active_functions_redirector); 219034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 219134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 219234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 219334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 219478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgObject* Debug::FindSharedFunctionInfoInScript(Handle<Script> script, 219578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org int position) { 219678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // Iterate the heap looking for SharedFunctionInfo generated from the 219778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // script. The inner most SharedFunctionInfo containing the source position 219878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // for the requested break point is found. 219978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // NOTE: This might require several heap iterations. If the SharedFunctionInfo 220078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // which is found is not compiled it is compiled and the heap is iterated 220178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // again as the compilation might create inner functions from the newly 220278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // compiled function and the actual requested break point might be in one of 220378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // these functions. 220478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // NOTE: The below fix-point iteration depends on all functions that cannot be 220578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // compiled lazily without a context to not be compiled at all. Compilation 220678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // will be triggered at points where we do not need a context. 220778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org bool done = false; 220878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // The current candidate for the source position: 220978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org int target_start_position = RelocInfo::kNoPosition; 221078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Handle<JSFunction> target_function; 221178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Handle<SharedFunctionInfo> target; 22127c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Heap* heap = isolate_->heap(); 221378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org while (!done) { 221478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org { // Extra scope for iterator and no-allocation. 22157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org heap->EnsureHeapIsIterable(); 221679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_alloc_during_heap_iteration; 22177c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org HeapIterator iterator(heap); 221878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org for (HeapObject* obj = iterator.next(); 221978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org obj != NULL; obj = iterator.next()) { 222078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org bool found_next_candidate = false; 222178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Handle<JSFunction> function; 222278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org Handle<SharedFunctionInfo> shared; 222378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (obj->IsJSFunction()) { 222478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org function = Handle<JSFunction>(JSFunction::cast(obj)); 222578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org shared = Handle<SharedFunctionInfo>(function->shared()); 222678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org ASSERT(shared->allows_lazy_compilation() || shared->is_compiled()); 222778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org found_next_candidate = true; 222878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } else if (obj->IsSharedFunctionInfo()) { 222978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj)); 223078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // Skip functions that we cannot compile lazily without a context, 223178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // which is not available here, because there is no closure. 223278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org found_next_candidate = shared->is_compiled() || 223378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org shared->allows_lazy_compilation_without_context(); 223478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 223578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (!found_next_candidate) continue; 223678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (shared->script() == *script) { 223778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // If the SharedFunctionInfo found has the requested script data and 223878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // contains the source position it is a candidate. 223978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org int start_position = shared->function_token_position(); 224078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (start_position == RelocInfo::kNoPosition) { 224178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org start_position = shared->start_position(); 224278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 224378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (start_position <= position && 224478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org position <= shared->end_position()) { 224578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // If there is no candidate or this function is within the current 224678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // candidate this is the new candidate. 224778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (target.is_null()) { 224878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target_start_position = start_position; 224978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target_function = function; 225078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target = shared; 225178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } else { 225278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (target_start_position == start_position && 225378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org shared->end_position() == target->end_position()) { 225478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // If a top-level function contains only one function 225578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // declaration the source for the top-level and the function 225678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // is the same. In that case prefer the non top-level function. 225778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (!shared->is_toplevel()) { 225878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target_start_position = start_position; 225978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target_function = function; 226078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target = shared; 226178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 226278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } else if (target_start_position <= start_position && 226378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org shared->end_position() <= target->end_position()) { 226478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // This containment check includes equality as a function 226578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // inside a top-level function can share either start or end 226678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // position with the top-level function. 226778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target_start_position = start_position; 226878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target_function = function; 226978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org target = shared; 227078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 227178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 227278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 227378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 227478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } // End for loop. 227578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } // End no-allocation scope. 227678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 22777c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (target.is_null()) return heap->undefined_value(); 227878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 227978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // There will be at least one break point when we are done. 228078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org has_break_points_ = true; 228178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 228278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // If the candidate found is compiled we are done. 228378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org done = target->is_compiled(); 228478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (!done) { 228578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // If the candidate is not compiled, compile it to reveal any inner 228678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // functions which might contain the requested source position. This 228778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // will compile all inner functions that cannot be compiled without a 228878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // context, because Compiler::BuildFunctionInfo checks whether the 228978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org // debugger is active. 229078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org if (target_function.is_null()) { 229178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION); 229278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } else { 229378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org JSFunction::CompileLazy(target_function, KEEP_EXCEPTION); 229478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 229578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } 229678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org } // End while loop. 229778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 229878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org return *target; 229978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org} 230078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 230178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org 2302bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// Ensures the debug information is present for shared. 23035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgbool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, 23045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<JSFunction> function) { 2305d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Isolate* isolate = shared->GetIsolate(); 2306d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 2307bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund // Return if we already have the debug info for shared. 230834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (HasDebugInfo(shared)) { 230934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ASSERT(shared->is_compiled()); 231034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return true; 231134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 231243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // There will be at least one break point when we are done. 23145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org has_break_points_ = true; 23155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 23165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Ensure function is compiled. Return false if this failed. 23175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!function.is_null() && 23185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org !JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION)) { 2319394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return false; 2320394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 232143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 232243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the debug info object. 2323d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared); 232443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 232543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Add debug info to the list. 232643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DebugInfoListNode* node = new DebugInfoListNode(*debug_info); 232743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen node->set_next(debug_info_list_); 232843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen debug_info_list_ = node; 232943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2330bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund return true; 233143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 233243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 233343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 233443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { 233543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(debug_info_list_ != NULL); 233643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Run through the debug info objects to find this one and remove it. 233743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DebugInfoListNode* prev = NULL; 233843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DebugInfoListNode* current = debug_info_list_; 233943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (current != NULL) { 234043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (*current->debug_info() == *debug_info) { 234143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Unlink from list. If prev is NULL we are looking at the first element. 234243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (prev == NULL) { 234343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen debug_info_list_ = current->next(); 234443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 234543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen prev->set_next(current->next()); 234643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 23477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org current->debug_info()->shared()->set_debug_info( 23487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->heap()->undefined_value()); 234943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen delete current; 235043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 235143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there are no more debug info objects there are not more break 235243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // points. 235343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen has_break_points_ = debug_info_list_ != NULL; 235443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 235543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 235643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 235743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Move to next in list. 235843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen prev = current; 235943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen current = current->next(); 236043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 236143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 236243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 236343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 236443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 236543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { 23667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 2367381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 236834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org PrepareForBreakPoints(); 236934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 237043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the executing function in which the debug break occurred. 23715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<JSFunction> function(JSFunction::cast(frame->function())); 23725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared(function->shared()); 23735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!EnsureDebugInfo(shared, function)) { 2374bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund // Return if we failed to retrieve the debug info. 2375bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund return; 2376bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund } 237743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<DebugInfo> debug_info = GetDebugInfo(shared); 237843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> code(debug_info->code()); 237943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Code> original_code(debug_info->original_code()); 238043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 238143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the code which is actually executing. 238274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org Handle<Code> frame_code(frame->LookupCode()); 238343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(frame_code.is_identical_to(code)); 238443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 238543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 238643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Find the call address in the running code. This address holds the call to 238743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // either a DebugBreakXXX or to the debug break return entry code if the 238843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // break point is still active after processing the break point. 238989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset; 239043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23912356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Check if the location is at JS exit or debug break slot. 2392a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org bool at_js_return = false; 2393a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org bool break_at_js_return_active = false; 23942356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org bool at_debug_break_slot = false; 239543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RelocIterator it(debug_info->code()); 23962356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org while (!it.done() && !at_js_return && !at_debug_break_slot) { 2397236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { 2398a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org at_js_return = (it.rinfo()->pc() == 2399a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org addr - Assembler::kPatchReturnSequenceAddressOffset); 24009d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence(); 240143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 24022356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) { 24032356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org at_debug_break_slot = (it.rinfo()->pc() == 24042356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org addr - Assembler::kPatchDebugBreakSlotAddressOffset); 24052356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org } 240643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it.next(); 240743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 240843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 240943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Handle the jump to continue execution after break point depending on the 241043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // break location. 2411a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (at_js_return) { 2412a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // If the break point as return is still active jump to the corresponding 2413a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // place in the original code. If not the break point was removed during 2414a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // break point processing. 2415a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if (break_at_js_return_active) { 241643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen addr += original_code->instruction_start() - code->instruction_start(); 241743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 241843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2419911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Move back to where the call instruction sequence started. 2420911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org thread_local_.after_break_target_ = 2421911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org addr - Assembler::kPatchReturnSequenceAddressOffset; 24222356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org } else if (at_debug_break_slot) { 24232356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Address of where the debug break slot starts. 24242356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset; 24252356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 24262356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Continue just after the slot. 24272356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org thread_local_.after_break_target_ = addr + Assembler::kDebugBreakSlotLength; 24282356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org } else if (IsDebugBreak(Assembler::target_address_at(addr))) { 24292356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // We now know that there is still a debug break call at the target address, 24302356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // so the break point is still there and the original code will hold the 24312356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // address to jump to in order to complete the call which is replaced by a 24322356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // call to DebugBreakXXX. 24332356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 24342356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Find the corresponding address in the original code. 24352356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org addr += original_code->instruction_start() - code->instruction_start(); 243643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 243743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Install jump to the call address in the original code. This will be the 243843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // call which was overwritten by the call to DebugBreakXXX. 243943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_local_.after_break_target_ = Assembler::target_address_at(addr); 24402356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org } else { 24412356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // There is no longer a break point present. Don't try to look in the 24422356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // original code as the running code will have the right address. This takes 24432356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // care of the case where the last break point is removed from the function 24442356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // and therefore no "original code" is available. 24452356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org thread_local_.after_break_target_ = Assembler::target_address_at(addr); 244643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 244743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 244843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 244943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24502cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.orgbool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 24517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 24522cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org 24536db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // If there are no break points this cannot be break at return, as 24546db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // the debugger statement and stack guard bebug break cannot be at 24556db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // return. 24566db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (!has_break_points_) { 24576db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org return false; 24586db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 24596db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 246034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org PrepareForBreakPoints(); 246134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 24622cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org // Get the executing function in which the debug break occurred. 24635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<JSFunction> function(JSFunction::cast(frame->function())); 24645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Handle<SharedFunctionInfo> shared(function->shared()); 24655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!EnsureDebugInfo(shared, function)) { 24662cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org // Return if we failed to retrieve the debug info. 24672cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org return false; 24682cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org } 24692cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org Handle<DebugInfo> debug_info = GetDebugInfo(shared); 24702cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org Handle<Code> code(debug_info->code()); 24712cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org#ifdef DEBUG 24722cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org // Get the code which is actually executing. 247374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org Handle<Code> frame_code(frame->LookupCode()); 24742cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org ASSERT(frame_code.is_identical_to(code)); 24752cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org#endif 24762cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org 24772cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org // Find the call address in the running code. 247889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Address addr = frame->pc() - Assembler::kPatchDebugBreakSlotReturnOffset; 24792cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org 24802cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org // Check if the location is at JS return. 24812cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org RelocIterator it(debug_info->code()); 24822cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org while (!it.done()) { 24832cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { 24842cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org return (it.rinfo()->pc() == 24852cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org addr - Assembler::kPatchReturnSequenceAddressOffset); 24862cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org } 24872cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org it.next(); 24882cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org } 24892cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org return false; 24902cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org} 24912cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org 24922cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org 249369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, 2494e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org FrameDropMode mode, 2495e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Object** restarter_frame_function_pointer) { 2496d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org if (mode != CURRENTLY_SET_MODE) { 2497d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org thread_local_.frame_drop_mode_ = mode; 2498d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org } 2499357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org thread_local_.break_frame_id_ = new_break_frame_id; 2500e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org thread_local_.restarter_frame_function_pointer_ = 2501e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org restarter_frame_function_pointer; 2502357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 2503357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 2504357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 2505212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgconst int Debug::FramePaddingLayout::kInitialSize = 1; 2506212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 2507212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 2508212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Any even value bigger than kInitialSize as needed for stack scanning. 2509212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgconst int Debug::FramePaddingLayout::kPaddingValue = kInitialSize + 1; 2510212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 2511212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 251243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::IsDebugGlobal(GlobalObject* global) { 251346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org return IsLoaded() && global == debug_context()->global_object(); 251443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 251543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 251643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid Debug::ClearMirrorCache() { 2518ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org PostponeInterruptsScope postpone(isolate_); 25197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 25207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ASSERT(isolate_->context() == *Debug::debug_context()); 25213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 25223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Clear the mirror cache. 25234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> function_name = isolate_->factory()->InternalizeOneByteString( 2524a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org STATIC_ASCII_VECTOR("ClearMirrorCache")); 252546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Handle<Object> fun( 252609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate_->global_object()->GetPropertyNoExceptionThrown(*function_name), 252709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate_); 25283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ASSERT(fun->IsJSFunction()); 25293291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org bool caught_exception; 2530717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org Execution::TryCall(Handle<JSFunction>::cast(fun), 253146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Handle<JSObject>(Debug::debug_context()->global_object()), 25323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 0, NULL, &caught_exception); 25333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org} 25343291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 25353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 253671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Debug::CreateScriptCache() { 25377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Heap* heap = isolate_->heap(); 25387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 253971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 254071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Perform two GCs to get rid of all unreferenced scripts. The first GC gets 254171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // rid of all the cached script wrappers and the second gets rid of the 2542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // scripts which are no longer referenced. The second also sweeps precisely, 2543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // which saves us doing yet another GC to make the heap iterable. 2544994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache"); 2545994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, 2546994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org "Debug::CreateScriptCache"); 254771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 254871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ASSERT(script_cache_ == NULL); 2549e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org script_cache_ = new ScriptCache(isolate_); 255071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 255171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Scan heap for Script objects. 255271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org int count = 0; 25537c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org HeapIterator iterator(heap); 255479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_allocation; 2555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2556b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 2557152a0b013d7d17f4fe9d04cdce58ec3d6fab2aa5sgjesse@chromium.org if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { 255871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org script_cache_->Add(Handle<Script>(Script::cast(obj))); 255971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org count++; 256071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 256171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 256271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 256371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 256471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 256571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Debug::DestroyScriptCache() { 256671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Get rid of the script cache if it was created. 256771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (script_cache_ != NULL) { 256871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org delete script_cache_; 256971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org script_cache_ = NULL; 257071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 257171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 257271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 257371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 257471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Debug::AddScriptToScriptCache(Handle<Script> script) { 257571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (script_cache_ != NULL) { 257671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org script_cache_->Add(script); 257771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 257871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 257971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 258071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 258171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgHandle<FixedArray> Debug::GetLoadedScripts() { 258271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Create and fill the script cache when the loaded scripts is requested for 258371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // the first time. 258471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (script_cache_ == NULL) { 258571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org CreateScriptCache(); 258671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 258771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 258871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // If the script cache is not active just return an empty array. 258971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ASSERT(script_cache_ != NULL); 259071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (script_cache_ == NULL) { 25917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->factory()->NewFixedArray(0); 259271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 259371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 259471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Perform GC to get unreferenced scripts evicted from the cache before 259571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // returning the content. 2596994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, 2597994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org "Debug::GetLoadedScripts"); 259871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 259971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Get the scripts from the cache. 260071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org return script_cache_->GetScripts(); 260171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 260271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 260371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 260471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Debug::AfterGarbageCollection() { 260571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Generate events for collected scripts. 260671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (script_cache_ != NULL) { 260771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org script_cache_->ProcessCollectedScripts(); 260871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 260971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 261071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 261171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 26126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgDebugger::Debugger(Isolate* isolate) 26137c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org : debugger_access_(isolate->debugger_access()), 2614ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org event_listener_(Handle<Object>()), 2615ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org event_listener_data_(Handle<Object>()), 2616ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org compiling_natives_(false), 2617ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org is_loading_debugger_(false), 2618de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org live_edit_enabled_(true), 2619ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org never_unload_debugger_(false), 2620394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com force_debugger_active_(false), 2621ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org message_handler_(NULL), 2622ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org debugger_unload_pending_(false), 2623ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org host_dispatch_handler_(NULL), 2624ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org debug_message_dispatch_handler_(NULL), 2625ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org message_dispatch_helper_thread_(NULL), 2626e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org host_dispatch_period_(TimeDelta::FromMilliseconds(100)), 2627ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org agent_(NULL), 26286d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org command_queue_(isolate->logger(), kQueueInitialSize), 2629e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org command_received_(0), 26306d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org event_command_queue_(isolate->logger(), kQueueInitialSize), 26316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org isolate_(isolate) { 2632ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 2633ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2634ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2635e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgDebugger::~Debugger() {} 263643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 263743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 263843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, 2639a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org int argc, 2640a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[], 264143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* caught_exception) { 2642ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); 264343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 264443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the execution state object. 26457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Handle<String> constructor_str = 26464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate_->factory()->InternalizeUtf8String(constructor_name); 2647ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<Object> constructor( 264809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate_->global_object()->GetPropertyNoExceptionThrown(*constructor_str), 264909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate_); 265043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(constructor->IsJSFunction()); 265143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!constructor->IsJSFunction()) { 265243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *caught_exception = true; 26537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return isolate_->factory()->undefined_value(); 265443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 265543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> js_object = Execution::TryCall( 265643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<JSFunction>::cast(constructor), 265746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Handle<JSObject>(isolate_->debug()->debug_context()->global_object()), 2658a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argc, 2659a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argv, 2660a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org caught_exception); 266143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return js_object; 266243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 266343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 266443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 266543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debugger::MakeExecutionState(bool* caught_exception) { 266643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the execution state object. 26677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Handle<Object> break_id = isolate_->factory()->NewNumberFromInt( 2668ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->debug()->break_id()); 2669a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { break_id }; 267043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return MakeJSObject(CStrVector("MakeExecutionState"), 2671a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 2672a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argv, 2673a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org caught_exception); 267443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 267543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 267643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 267743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state, 267843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> break_points_hit, 267943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* caught_exception) { 268043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the new break event object. 2681a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { exec_state, break_points_hit }; 268243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return MakeJSObject(CStrVector("MakeBreakEvent"), 2683a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 268443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen argv, 268543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen caught_exception); 268643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 268743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state, 269043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> exception, 269143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool uncaught, 269243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* caught_exception) { 26937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Factory* factory = isolate_->factory(); 269443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the new exception event object. 2695a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { exec_state, 2696a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org exception, 2697a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org factory->ToBoolean(uncaught) }; 269843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return MakeJSObject(CStrVector("MakeExceptionEvent"), 2699a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 2700a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argv, 2701a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org caught_exception); 270243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 270343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 270443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 270543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function, 270643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* caught_exception) { 270743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the new function event object. 2708a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { function }; 270943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return MakeJSObject(CStrVector("MakeNewFunctionEvent"), 2710a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 2711a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argv, 2712a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org caught_exception); 271343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 271443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 271543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 271643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debugger::MakeCompileEvent(Handle<Script> script, 2717245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org bool before, 271843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool* caught_exception) { 27197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Factory* factory = isolate_->factory(); 272043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the compile event object. 272143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> exec_state = MakeExecutionState(caught_exception); 2722245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Handle<Object> script_wrapper = GetScriptWrapper(script); 2723a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { exec_state, 2724a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org script_wrapper, 2725a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org factory->ToBoolean(before) }; 272643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return MakeJSObject(CStrVector("MakeCompileEvent"), 2727a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 272843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen argv, 272943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen caught_exception); 273043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 273143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 273243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 273371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgHandle<Object> Debugger::MakeScriptCollectedEvent(int id, 273471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org bool* caught_exception) { 273571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Create the script collected event object. 273671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org Handle<Object> exec_state = MakeExecutionState(caught_exception); 273709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); 2738a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { exec_state, id_object }; 273971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 274071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org return MakeJSObject(CStrVector("MakeScriptCollectedEvent"), 2741a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 274271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org argv, 274371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org caught_exception); 274471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 274571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 274671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 274743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debugger::OnException(Handle<Object> exception, bool uncaught) { 27487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 27497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Debug* debug = isolate_->debug(); 275043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 275143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out based on state or if there is no listener for this event 27527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (debug->InDebugger()) return; 275343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!Debugger::EventActive(v8::Exception)) return; 275443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 275543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out if exception breaks are not active 275643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (uncaught) { 275743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Uncaught exceptions are reported by either flags. 27587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (!(debug->break_on_uncaught_exception() || 27597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debug->break_on_exception())) return; 276043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 276143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Caught exceptions are reported is activated. 27627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org if (!debug->break_on_exception()) return; 276343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 276443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 276541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Enter the debugger. 2766e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org EnterDebugger debugger(isolate_); 276741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org if (debugger.FailedToEnter()) return; 276843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 276943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Clear all current stepping setup. 27707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debug->ClearStepping(); 277143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the event data object. 277243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool caught_exception = false; 277343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> exec_state = MakeExecutionState(&caught_exception); 277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> event_data; 277543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!caught_exception) { 277643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen event_data = MakeExceptionEvent(exec_state, exception, uncaught, 277743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen &caught_exception); 277843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 277943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out and don't call debugger if exception. 278043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (caught_exception) { 278143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 278243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 278343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27845ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // Process debug event. 27855ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); 278643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return to continue execution from where the exception was thrown. 278743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 278843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 278943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2790bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgvoid Debugger::OnDebugBreak(Handle<Object> break_points_hit, 2791bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org bool auto_continue) { 27927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 279343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2794212ac23f8231d169b4aa6737d762099993020826kasper.lund // Debugger has already been entered by caller. 2795ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); 2796212ac23f8231d169b4aa6737d762099993020826kasper.lund 279743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out if there is no listener for this event 279843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!Debugger::EventActive(v8::Break)) return; 279943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 280043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Debugger must be entered in advance. 28016d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); 280243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 280343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the event data object. 280443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool caught_exception = false; 280543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> exec_state = MakeExecutionState(&caught_exception); 280643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> event_data; 280743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!caught_exception) { 280843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen event_data = MakeBreakEvent(exec_state, break_points_hit, 280943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen &caught_exception); 281043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 281143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out and don't call debugger if exception. 281243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (caught_exception) { 281343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 281443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 281543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // Process debug event. 28175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org ProcessDebugEvent(v8::Break, 28185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject>::cast(event_data), 28195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org auto_continue); 282043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 282143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 282243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 282343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debugger::OnBeforeCompile(Handle<Script> script) { 28247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 282543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 282643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out based on state or if there is no listener for this event 2827ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (isolate_->debug()->InDebugger()) return; 282843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (compiling_natives()) return; 282943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!EventActive(v8::BeforeCompile)) return; 283043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 283141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Enter the debugger. 2832e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org EnterDebugger debugger(isolate_); 283341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org if (debugger.FailedToEnter()) return; 283443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 283543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the event data object. 283643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool caught_exception = false; 2837245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception); 283843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out and don't call debugger if exception. 283943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (caught_exception) { 284043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 284143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 284243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28435ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // Process debug event. 28445ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org ProcessDebugEvent(v8::BeforeCompile, 28455ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject>::cast(event_data), 28465ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org true); 284743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 284843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 284943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 285043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Handle debugger actions when a new script is compiled. 2851ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid Debugger::OnAfterCompile(Handle<Script> script, 2852ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org AfterCompileFlags after_compile_flags) { 28537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 28547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Debug* debug = isolate_->debug(); 2855212ac23f8231d169b4aa6737d762099993020826kasper.lund 285671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Add the newly compiled script to the script cache. 28577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debug->AddScriptToScriptCache(script); 285843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 285943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // No more to do if not debugging. 286071daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org if (!IsDebuggerActive()) return; 286143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 286271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // No compile events while compiling natives. 286371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (compiling_natives()) return; 286471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 2865245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org // Store whether in debugger before entering debugger. 28667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org bool in_debugger = debug->InDebugger(); 2867245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 286841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Enter the debugger. 2869e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org EnterDebugger debugger(isolate_); 287041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org if (debugger.FailedToEnter()) return; 287143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 287243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If debugging there might be script break points registered for this 287343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // script. Make sure that these break points are set. 287443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28755d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). 28764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> update_script_break_points_string = 28774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org isolate_->factory()->InternalizeOneByteString( 2878a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); 287943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> update_script_break_points = 288009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object>( 288109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org debug->debug_context()->global_object()->GetPropertyNoExceptionThrown( 28824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org *update_script_break_points_string), 288309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate_); 288443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!update_script_break_points->IsJSFunction()) { 288543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 288643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 288743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(update_script_break_points->IsJSFunction()); 288843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 288943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Wrap the script object in a proper JS object before passing it 289043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to JavaScript. 289143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<JSValue> wrapper = GetScriptWrapper(script); 289243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 289343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Call UpdateScriptBreakPoints expect no exceptions. 2894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool caught_exception; 2895a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { wrapper }; 2896717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), 2897e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org isolate_->js_builtins_object(), 2898a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 2899a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argv, 2900a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org &caught_exception); 290143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (caught_exception) { 290243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 290343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 290443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out based on state or if there is no listener for this event 2905ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return; 290643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!Debugger::EventActive(v8::AfterCompile)) return; 290743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 290843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the compile state object. 290943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> event_data = MakeCompileEvent(script, 2910245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org false, 291143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen &caught_exception); 291243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out and don't call debugger if exception. 291343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (caught_exception) { 291443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 291543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 29165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // Process debug event. 29175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org ProcessDebugEvent(v8::AfterCompile, 29185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject>::cast(event_data), 29195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org true); 292043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 292143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 292243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 292371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Debugger::OnScriptCollected(int id) { 29247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 292571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 292671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // No more to do if not debugging. 292756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org if (isolate_->debug()->InDebugger()) return; 292871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (!IsDebuggerActive()) return; 292971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (!Debugger::EventActive(v8::ScriptCollected)) return; 293071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 293171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Enter the debugger. 2932e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org EnterDebugger debugger(isolate_); 293371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (debugger.FailedToEnter()) return; 293471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 293571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Create the script collected state object. 293671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org bool caught_exception = false; 293771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org Handle<Object> event_data = MakeScriptCollectedEvent(id, 293871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org &caught_exception); 293971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Bail out and don't call debugger if exception. 294071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (caught_exception) { 294171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org return; 294271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 294371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 294471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Process debug event. 294571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ProcessDebugEvent(v8::ScriptCollected, 294671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org Handle<JSObject>::cast(event_data), 294771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org true); 294871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 294971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 295071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 295143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debugger::ProcessDebugEvent(v8::DebugEvent event, 29525ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> event_data, 2953bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org bool auto_continue) { 29547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 2955381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 2956755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Clear any pending debug break if this is a real break. 2957755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org if (!auto_continue) { 2958ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->debug()->clear_interrupt_pending(DEBUGBREAK); 2959755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org } 2960755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 296143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create the execution state. 296243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool caught_exception = false; 296343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> exec_state = MakeExecutionState(&caught_exception); 296443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (caught_exception) { 296543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 296643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 296741826e77311db718135ef6517b846933dfd275f3ager@chromium.org // First notify the message handler if any. 296841826e77311db718135ef6517b846933dfd275f3ager@chromium.org if (message_handler_ != NULL) { 29695ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org NotifyMessageHandler(event, 29705ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject>::cast(exec_state), 29715ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org event_data, 29725ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org auto_continue); 297343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 297422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com // Notify registered debug event listener. This can be either a C or 297522762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com // a JavaScript function. Don't call event listener for v8::Break 297622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com // here, if it's only a debug command -- they will be processed later. 297722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) { 297822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com CallEventCallback(event, exec_state, event_data, NULL); 297922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com } 298022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com // Process pending debug commands. 298122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com if (event == v8::Break) { 298222762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com while (!event_command_queue_.IsEmpty()) { 298322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com CommandMessage command = event_command_queue_.Get(); 298422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com if (!event_listener_.is_null()) { 298522762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com CallEventCallback(v8::BreakForCommand, 298622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com exec_state, 298722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com event_data, 298822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com command.client_data()); 298922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com } 299022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com command.Dispose(); 299143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 299243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 299343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 299443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 299543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 299622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.comvoid Debugger::CallEventCallback(v8::DebugEvent event, 299722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<Object> exec_state, 299822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<Object> event_data, 299922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com v8::Debug::ClientData* client_data) { 3000ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org if (event_listener_->IsForeign()) { 300122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com CallCEventCallback(event, exec_state, event_data, client_data); 300222762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com } else { 300322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com CallJSEventCallback(event, exec_state, event_data); 300422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com } 300522762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com} 300622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 300722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 300822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.comvoid Debugger::CallCEventCallback(v8::DebugEvent event, 300922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<Object> exec_state, 301022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<Object> event_data, 301122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com v8::Debug::ClientData* client_data) { 3012ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Foreign> callback_obj(Handle<Foreign>::cast(event_listener_)); 301322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com v8::Debug::EventCallback2 callback = 3014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FUNCTION_CAST<v8::Debug::EventCallback2>( 3015c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org callback_obj->foreign_address()); 301622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com EventDetailsImpl event_details( 301722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com event, 301822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<JSObject>::cast(exec_state), 301922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<JSObject>::cast(event_data), 302022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com event_listener_data_, 302122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com client_data); 302222762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com callback(event_details); 302322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com} 302422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 302522762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 302622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.comvoid Debugger::CallJSEventCallback(v8::DebugEvent event, 302722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<Object> exec_state, 302822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<Object> event_data) { 302922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com ASSERT(event_listener_->IsJSFunction()); 303022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); 303122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 303222762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com // Invoke the JavaScript debug event listener. 303309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_), 3034a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org exec_state, 3035a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org event_data, 3036a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org event_listener_data_ }; 3037c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool caught_exception; 3038a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Execution::TryCall(fun, 303946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org isolate_->global_object(), 3040a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 3041a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argv, 3042a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org &caught_exception); 304322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com // Silently ignore exceptions from debug event listeners. 304422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com} 304522762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 304622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 3047c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.orgHandle<Context> Debugger::GetDebugContext() { 3048ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org never_unload_debugger_ = true; 3049e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org EnterDebugger debugger(isolate_); 3050ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return isolate_->debug()->debug_context(); 3051c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org} 3052c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org 3053c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org 305471daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.orgvoid Debugger::UnloadDebugger() { 30557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Debug* debug = isolate_->debug(); 3056ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 305771daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org // Make sure that there are no breakpoints left. 30587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debug->ClearAllBreakPoints(); 305971daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 306071daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org // Unload the debugger if feasible. 306171daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org if (!never_unload_debugger_) { 30627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org debug->Unload(); 306371daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org } 306471daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 306571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Clear the flag indicating that the debugger should be unloaded. 306671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org debugger_unload_pending_ = false; 306771daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org} 306871daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 306971daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 307041826e77311db718135ef6517b846933dfd275f3ager@chromium.orgvoid Debugger::NotifyMessageHandler(v8::DebugEvent event, 30715ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> exec_state, 30725ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> event_data, 3073bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org bool auto_continue) { 3074f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(isolate_); 30757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 3076381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 3077ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (!isolate_->debug()->Load()) return; 307843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 307943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Process the individual events. 30805ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org bool sendEventMessage = false; 308143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (event) { 308243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case v8::Break: 308322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com case v8::BreakForCommand: 30845ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org sendEventMessage = !auto_continue; 308543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 308643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case v8::Exception: 30875ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org sendEventMessage = true; 308843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 308943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case v8::BeforeCompile: 309043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 309143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case v8::AfterCompile: 30925ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org sendEventMessage = true; 309343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 309471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org case v8::ScriptCollected: 309571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org sendEventMessage = true; 309671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org break; 309743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case v8::NewFunction: 309843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 309943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 310043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 310143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 310243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31035ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // The debug command interrupt flag might have been set when the command was 31045ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // added. It should be enough to clear the flag only once while we are in the 31055ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // debugger. 3106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(isolate_->debug()->InDebugger()); 3107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->stack_guard()->Continue(DEBUGCOMMAND); 31085ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 31095ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // Notify the debugger that a debug event has occurred unless auto continue is 31105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // active in which case no event is send. 31115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org if (sendEventMessage) { 31125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org MessageImpl message = MessageImpl::NewEvent( 31135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org event, 31145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org auto_continue, 31155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject>::cast(exec_state), 31165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject>::cast(event_data)); 31175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org InvokeMessageHandler(message); 31185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org } 3119755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 3120755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // If auto continue don't make the event cause a break, but process messages 3121755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // in the queue if any. For script collected events don't even process 3122755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // messages in the queue as the execution state might not be what is expected 3123755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // by the client. 31246ffc2170a4c855ff3bba0f09437d77ec98589ae8ager@chromium.org if ((auto_continue && !HasCommands()) || event == v8::ScriptCollected) { 31255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return; 31265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org } 312743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 312843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v8::TryCatch try_catch; 31299d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 31309d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // DebugCommandProcessor goes here. 31319d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com v8::Local<v8::Object> cmd_processor; 31329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com { 31339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com v8::Local<v8::Object> api_exec_state = 31349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)); 3135f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::Local<v8::String> fun_name = v8::String::NewFromUtf8( 3136f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org isolate, "debugCommandProcessor"); 31379d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com v8::Local<v8::Function> fun = 3138f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org v8::Local<v8::Function>::Cast(api_exec_state->Get(fun_name)); 31399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 314037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org v8::Handle<v8::Boolean> running = v8::Boolean::New(isolate, auto_continue); 31419d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com static const int kArgc = 1; 31429d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com v8::Handle<Value> argv[kArgc] = { running }; 3143f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org cmd_processor = v8::Local<v8::Object>::Cast( 3144f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org fun->Call(api_exec_state, kArgc, argv)); 31459d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (try_catch.HasCaught()) { 31469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com PrintLn(try_catch.Exception()); 31479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return; 31489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 314943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 315043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com bool running = auto_continue; 31529d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 3153bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Process requests from the debugger. 315443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (true) { 3155bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Wait for new command in the queue. 315665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org if (Debugger::host_dispatch_handler_) { 315765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // In case there is a host dispatch - do periodic dispatches. 3158e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org if (!command_received_.WaitFor(host_dispatch_period_)) { 315965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Timout expired, do the dispatch. 316065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org Debugger::host_dispatch_handler_(); 316165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org continue; 316265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org } 316365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org } else { 316465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // In case there is no host dispatch - just wait. 3165e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org command_received_.Wait(); 316665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org } 3167bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 3168bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Get the command from the queue. 31693a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org CommandMessage command = command_queue_.Get(); 31706d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org isolate_->logger()->DebugTag( 31716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org "Got request from command queue, in interactive loop."); 317271daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org if (!Debugger::IsDebuggerActive()) { 317365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Delete command text and user data. 317465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org command.Dispose(); 317543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 317643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 317743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 317841826e77311db718135ef6517b846933dfd275f3ager@chromium.org // Invoke JavaScript to process the debug request. 317943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v8::Local<v8::String> fun_name; 318043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v8::Local<v8::Function> fun; 3181a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org v8::Local<v8::Value> request; 318243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v8::TryCatch try_catch; 3183f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org fun_name = v8::String::NewFromUtf8(isolate, "processDebugRequest"); 3184f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org fun = v8::Local<v8::Function>::Cast(cmd_processor->Get(fun_name)); 318565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 3186f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org request = v8::String::NewFromTwoByte(isolate, command.text().start(), 3187f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org v8::String::kNormalString, 3188f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org command.text().length()); 3189a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const int kArgc = 1; 3190a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org v8::Handle<Value> argv[kArgc] = { request }; 3191a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv); 319243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3193a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Get the response. 3194a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org v8::Local<v8::String> response; 319543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!try_catch.HasCaught()) { 3196a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Get response string. 3197a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!response_val->IsUndefined()) { 3198f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org response = v8::Local<v8::String>::Cast(response_val); 3199a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } else { 3200f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org response = v8::String::NewFromUtf8(isolate, ""); 3201a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 320243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 320343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Log the JSON request/response. 320443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_trace_debug_json) { 3205a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org PrintLn(request); 3206a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org PrintLn(response); 320743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 320843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 320943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the running state. 3210f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org fun_name = v8::String::NewFromUtf8(isolate, "isRunning"); 3211f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org fun = v8::Local<v8::Function>::Cast(cmd_processor->Get(fun_name)); 3212a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const int kArgc = 1; 3213a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org v8::Handle<Value> argv[kArgc] = { response }; 3214a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv); 3215a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (!try_catch.HasCaught()) { 3216a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org running = running_val->ToBoolean()->Value(); 321743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 321843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 321943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // In case of failure the result text is the exception text. 3220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org response = try_catch.Exception()->ToString(); 322143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 322243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 322343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the result. 32245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org MessageImpl message = MessageImpl::NewResponse( 32255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org event, 32265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org running, 32275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject>::cast(exec_state), 32285ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject>::cast(event_data), 32295ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<String>(Utils::OpenHandle(*response)), 32305ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org command.client_data()); 32315ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org InvokeMessageHandler(message); 32325ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org command.Dispose(); 323343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3234bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Return from debug event processing if either the VM is put into the 3235f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // running state (through a continue command) or auto continue is active 3236bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // and there are no more commands queued. 32379d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (running && !HasCommands()) { 323843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 323943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 324043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 324143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 324243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 324343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 324441826e77311db718135ef6517b846933dfd275f3ager@chromium.orgvoid Debugger::SetEventListener(Handle<Object> callback, 324541826e77311db718135ef6517b846933dfd275f3ager@chromium.org Handle<Object> data) { 32467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org HandleScope scope(isolate_); 32477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org GlobalHandles* global_handles = isolate_->global_handles(); 324841826e77311db718135ef6517b846933dfd275f3ager@chromium.org 324941826e77311db718135ef6517b846933dfd275f3ager@chromium.org // Clear the global handles for the event listener and the event listener data 325041826e77311db718135ef6517b846933dfd275f3ager@chromium.org // object. 325141826e77311db718135ef6517b846933dfd275f3ager@chromium.org if (!event_listener_.is_null()) { 32527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org global_handles->Destroy( 325341826e77311db718135ef6517b846933dfd275f3ager@chromium.org reinterpret_cast<Object**>(event_listener_.location())); 325441826e77311db718135ef6517b846933dfd275f3ager@chromium.org event_listener_ = Handle<Object>(); 325541826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 325641826e77311db718135ef6517b846933dfd275f3ager@chromium.org if (!event_listener_data_.is_null()) { 32577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org global_handles->Destroy( 325841826e77311db718135ef6517b846933dfd275f3ager@chromium.org reinterpret_cast<Object**>(event_listener_data_.location())); 325941826e77311db718135ef6517b846933dfd275f3ager@chromium.org event_listener_data_ = Handle<Object>(); 326041826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 326141826e77311db718135ef6517b846933dfd275f3ager@chromium.org 326241826e77311db718135ef6517b846933dfd275f3ager@chromium.org // If there is a new debug event listener register it together with its data 326341826e77311db718135ef6517b846933dfd275f3ager@chromium.org // object. 326441826e77311db718135ef6517b846933dfd275f3ager@chromium.org if (!callback->IsUndefined() && !callback->IsNull()) { 3265ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org event_listener_ = Handle<Object>::cast( 32667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org global_handles->Create(*callback)); 326741826e77311db718135ef6517b846933dfd275f3ager@chromium.org if (data.is_null()) { 32687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org data = isolate_->factory()->undefined_value(); 326941826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 3270ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org event_listener_data_ = Handle<Object>::cast( 32717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org global_handles->Create(*data)); 327241826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 327341826e77311db718135ef6517b846933dfd275f3ager@chromium.org 327471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ListenersChanged(); 327541826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 327641826e77311db718135ef6517b846933dfd275f3ager@chromium.org 327741826e77311db718135ef6517b846933dfd275f3ager@chromium.org 32785ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgvoid Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { 3279dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<RecursiveMutex> with(debugger_access_); 328071daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 328141826e77311db718135ef6517b846933dfd275f3ager@chromium.org message_handler_ = handler; 328271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org ListenersChanged(); 32833a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org if (handler == NULL) { 328471daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org // Send an empty command to the debugger if in a break to make JavaScript 328571daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org // run again if the debugger is closed. 3286ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (isolate_->debug()->InDebugger()) { 328771daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org ProcessCommand(Vector<const uint16_t>::empty()); 328871daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org } 328941826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 329041826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 329141826e77311db718135ef6517b846933dfd275f3ager@chromium.org 329241826e77311db718135ef6517b846933dfd275f3ager@chromium.org 329371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Debugger::ListenersChanged() { 329471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org if (IsDebuggerActive()) { 329571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Disable the compilation cache when the debugger is active. 32967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->compilation_cache()->Disable(); 3297b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org debugger_unload_pending_ = false; 329871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } else { 32997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate_->compilation_cache()->Enable(); 330071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Unload the debugger if event listener and message handler cleared. 3301b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Schedule this for later, because we may be in non-V8 thread. 3302b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org debugger_unload_pending_ = true; 330371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org } 330471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 330571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 330671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 330765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, 3308e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org TimeDelta period) { 330941826e77311db718135ef6517b846933dfd275f3ager@chromium.org host_dispatch_handler_ = handler; 3310e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org host_dispatch_period_ = period; 331141826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 331241826e77311db718135ef6517b846933dfd275f3ager@chromium.org 331341826e77311db718135ef6517b846933dfd275f3ager@chromium.org 3314c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Debugger::SetDebugMessageDispatchHandler( 3315b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { 3316dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&dispatch_handler_access_); 3317c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org debug_message_dispatch_handler_ = handler; 3318b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3319b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (provide_locker && message_dispatch_helper_thread_ == NULL) { 3320ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_); 3321b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org message_dispatch_helper_thread_->Start(); 3322b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3323c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 3324c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 3325c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 332641826e77311db718135ef6517b846933dfd275f3ager@chromium.org// Calls the registered debug message handler. This callback is part of the 33275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// public API. 33285ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgvoid Debugger::InvokeMessageHandler(MessageImpl message) { 3329dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<RecursiveMutex> with(debugger_access_); 333071daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 333141826e77311db718135ef6517b846933dfd275f3ager@chromium.org if (message_handler_ != NULL) { 33325ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org message_handler_(message); 333341826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 333441826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 333541826e77311db718135ef6517b846933dfd275f3ager@chromium.org 333641826e77311db718135ef6517b846933dfd275f3ager@chromium.org 33377276f14ca716596e0a0d17539516370c1f453847kasper.lund// Puts a command coming from the public API on the queue. Creates 33387276f14ca716596e0a0d17539516370c1f453847kasper.lund// a copy of the command string managed by the debugger. Up to this 33397276f14ca716596e0a0d17539516370c1f453847kasper.lund// point, the command data was managed by the API client. Called 33403a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// by the API client thread. 334165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid Debugger::ProcessCommand(Vector<const uint16_t> command, 334265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org v8::Debug::ClientData* client_data) { 334365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Need to cast away const. 33443a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org CommandMessage message = CommandMessage::New( 334541826e77311db718135ef6517b846933dfd275f3ager@chromium.org Vector<uint16_t>(const_cast<uint16_t*>(command.start()), 334665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org command.length()), 334765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org client_data); 33486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org isolate_->logger()->DebugTag("Put command on command_queue."); 334965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org command_queue_.Put(message); 3350e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org command_received_.Signal(); 33513afc15871025a4736634052bd1ff4b4bb2fc2e4fsgjesse@chromium.org 33523afc15871025a4736634052bd1ff4b4bb2fc2e4fsgjesse@chromium.org // Set the debug command break flag to have the command processed. 3353ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (!isolate_->debug()->InDebugger()) { 3354ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->stack_guard()->DebugCommand(); 3355bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 3356c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 3357b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org MessageDispatchHelperThread* dispatch_thread; 3358b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 3359dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&dispatch_handler_access_); 3360b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org dispatch_thread = message_dispatch_helper_thread_; 3361b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3362b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3363b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (dispatch_thread == NULL) { 3364b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallMessageDispatchHandler(); 3365b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 3366b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org dispatch_thread->Schedule(); 3367c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org } 336843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 336943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 337043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 337141826e77311db718135ef6517b846933dfd275f3ager@chromium.orgbool Debugger::HasCommands() { 337241826e77311db718135ef6517b846933dfd275f3ager@chromium.org return !command_queue_.IsEmpty(); 337341826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 337441826e77311db718135ef6517b846933dfd275f3ager@chromium.org 337541826e77311db718135ef6517b846933dfd275f3ager@chromium.org 337622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.comvoid Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { 337722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); 337822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com event_command_queue_.Put(message); 337922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 338022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com // Set the debug command break flag to have the command processed. 3381ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (!isolate_->debug()->InDebugger()) { 3382ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->stack_guard()->DebugCommand(); 338322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com } 338422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com} 338522762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 338622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 338771daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.orgbool Debugger::IsDebuggerActive() { 3388dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<RecursiveMutex> with(debugger_access_); 338971daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 3390394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return message_handler_ != NULL || 3391394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com !event_listener_.is_null() || 3392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com force_debugger_active_; 339341826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 339441826e77311db718135ef6517b846933dfd275f3ager@chromium.org 339541826e77311db718135ef6517b846933dfd275f3ager@chromium.org 339641826e77311db718135ef6517b846933dfd275f3ager@chromium.orgHandle<Object> Debugger::Call(Handle<JSFunction> fun, 339741826e77311db718135ef6517b846933dfd275f3ager@chromium.org Handle<Object> data, 339841826e77311db718135ef6517b846933dfd275f3ager@chromium.org bool* pending_exception) { 339971daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org // When calling functions in the debugger prevent it from beeing unloaded. 340071daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org Debugger::never_unload_debugger_ = true; 340171daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 340241826e77311db718135ef6517b846933dfd275f3ager@chromium.org // Enter the debugger. 3403e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org EnterDebugger debugger(isolate_); 3404df7a284a293865a5fa9390be2e8f82ba3ac8598asgjesse@chromium.org if (debugger.FailedToEnter()) { 34057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return isolate_->factory()->undefined_value(); 340641826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 340741826e77311db718135ef6517b846933dfd275f3ager@chromium.org 340841826e77311db718135ef6517b846933dfd275f3ager@chromium.org // Create the execution state. 340941826e77311db718135ef6517b846933dfd275f3ager@chromium.org bool caught_exception = false; 341041826e77311db718135ef6517b846933dfd275f3ager@chromium.org Handle<Object> exec_state = MakeExecutionState(&caught_exception); 341141826e77311db718135ef6517b846933dfd275f3ager@chromium.org if (caught_exception) { 34127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return isolate_->factory()->undefined_value(); 341341826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 341441826e77311db718135ef6517b846933dfd275f3ager@chromium.org 3415a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<Object> argv[] = { exec_state, data }; 3416df7a284a293865a5fa9390be2e8f82ba3ac8598asgjesse@chromium.org Handle<Object> result = Execution::Call( 34172c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org isolate_, 3418df7a284a293865a5fa9390be2e8f82ba3ac8598asgjesse@chromium.org fun, 341909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object>(isolate_->debug()->debug_context_->global_proxy(), 342009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate_), 3421a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ARRAY_SIZE(argv), 3422df7a284a293865a5fa9390be2e8f82ba3ac8598asgjesse@chromium.org argv, 3423df7a284a293865a5fa9390be2e8f82ba3ac8598asgjesse@chromium.org pending_exception); 342441826e77311db718135ef6517b846933dfd275f3ager@chromium.org return result; 342541826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 342641826e77311db718135ef6517b846933dfd275f3ager@chromium.org 342741826e77311db718135ef6517b846933dfd275f3ager@chromium.org 34280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgstatic void StubMessageHandler2(const v8::Debug::Message& message) { 34290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Simply ignore message. 34300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 34310c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 34320c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 34330c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgbool Debugger::StartAgent(const char* name, int port, 34340c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org bool wait_for_connection) { 34350c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (wait_for_connection) { 34360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Suspend V8 if it is already running or set V8 to suspend whenever 34370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // it starts. 34380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Provide stub message handler; V8 auto-continues each suspend 34390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // when there is no message handler; we doesn't need it. 34400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Once become suspended, V8 will stay so indefinitely long, until remote 34410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // debugger connects and issues "continue" command. 34420c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Debugger::message_handler_ = StubMessageHandler2; 34430c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org v8::Debug::DebugBreak(); 34440c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 34450c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 34463d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org if (agent_ == NULL) { 34473d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org agent_ = new DebuggerAgent(isolate_, name, port); 34483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org agent_->Start(); 34497276f14ca716596e0a0d17539516370c1f453847kasper.lund } 34503d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org return true; 345141826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 345241826e77311db718135ef6517b846933dfd275f3ager@chromium.org 345341826e77311db718135ef6517b846933dfd275f3ager@chromium.org 345441826e77311db718135ef6517b846933dfd275f3ager@chromium.orgvoid Debugger::StopAgent() { 345541826e77311db718135ef6517b846933dfd275f3ager@chromium.org if (agent_ != NULL) { 345641826e77311db718135ef6517b846933dfd275f3ager@chromium.org agent_->Shutdown(); 345741826e77311db718135ef6517b846933dfd275f3ager@chromium.org agent_->Join(); 345841826e77311db718135ef6517b846933dfd275f3ager@chromium.org delete agent_; 345941826e77311db718135ef6517b846933dfd275f3ager@chromium.org agent_ = NULL; 346041826e77311db718135ef6517b846933dfd275f3ager@chromium.org } 346141826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 346241826e77311db718135ef6517b846933dfd275f3ager@chromium.org 346341826e77311db718135ef6517b846933dfd275f3ager@chromium.org 3464c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgvoid Debugger::WaitForAgent() { 3465c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (agent_ != NULL) 3466c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org agent_->WaitUntilListening(); 3467c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 3468c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 3469b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3470b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Debugger::CallMessageDispatchHandler() { 3471b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org v8::Debug::DebugMessageDispatchHandler handler; 3472b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 3473dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&dispatch_handler_access_); 3474b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org handler = Debugger::debug_message_dispatch_handler_; 3475b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3476b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (handler != NULL) { 3477b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org handler(); 3478b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3479b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 3480b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3481b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3482e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgEnterDebugger::EnterDebugger(Isolate* isolate) 3483e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org : isolate_(isolate), 3484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com prev_(isolate_->debug()->debugger_entry()), 3485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com it_(isolate_), 3486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com has_js_frames_(!it_.done()), 3487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com save_(isolate_) { 3488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Debug* debug = isolate_->debug(); 3489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(prev_ != NULL || !debug->is_interrupt_pending(PREEMPT)); 3490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(prev_ != NULL || !debug->is_interrupt_pending(DEBUGBREAK)); 3491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Link recursive debugger entry. 3493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->set_debugger_entry(this); 3494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store the previous break id and frame id. 3496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break_id_ = debug->break_id(); 3497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break_frame_id_ = debug->break_frame_id(); 3498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Create the new break info. If there is no JavaScript frames there is no 3500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // break frame id. 3501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (has_js_frames_) { 3502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->NewBreak(it_.frame()->id()); 3503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->NewBreak(StackFrame::NO_ID); 3505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Make sure that debugger is loaded and enter the debugger context. 3508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com load_failed_ = !debug->Load(); 3509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!load_failed_) { 3510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // NOTE the member variable save which saves the previous context before 3511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // this change. 3512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate_->set_context(*debug->debug_context()); 3513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comEnterDebugger::~EnterDebugger() { 3518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Debug* debug = isolate_->debug(); 3519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Restore to the previous break state. 3521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->SetBreak(break_frame_id_, break_id_); 3522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for leaving the debugger. 35247d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org if (!load_failed_ && prev_ == NULL) { 3525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clear mirror cache when leaving the debugger. Skip this if there is a 3526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // pending exception as clearing the mirror cache calls back into 3527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // JavaScript. This can happen if the v8::Debug::Call is used in which 3528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // case the exception should end up in the calling code. 3529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!isolate_->has_pending_exception()) { 3530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Try to avoid any pending debug break breaking in the clear mirror 3531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // cache JavaScript code. 3532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (isolate_->stack_guard()->IsDebugBreak()) { 3533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->set_interrupts_pending(DEBUGBREAK); 3534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate_->stack_guard()->Continue(DEBUGBREAK); 3535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->ClearMirrorCache(); 3537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Request preemption and debug break when leaving the last debugger entry 3540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // if any of these where recorded while debugging. 3541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (debug->is_interrupt_pending(PREEMPT)) { 3542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // This re-scheduling of preemption is to avoid starvation in some 3543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // debugging scenarios. 3544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->clear_interrupt_pending(PREEMPT); 3545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate_->stack_guard()->Preempt(); 3546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (debug->is_interrupt_pending(DEBUGBREAK)) { 3548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->clear_interrupt_pending(DEBUGBREAK); 3549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate_->stack_guard()->DebugBreak(); 3550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If there are commands in the queue when leaving the debugger request 3553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // that these commands are processed. 3554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (isolate_->debugger()->HasCommands()) { 3555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate_->stack_guard()->DebugCommand(); 3556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If leaving the debugger with the debugger no longer active unload it. 3559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!isolate_->debugger()->IsDebuggerActive()) { 3560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate_->debugger()->UnloadDebugger(); 3561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leaving this debugger entry. 3565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com debug->set_debugger_entry(prev_); 3566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 35695ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgMessageImpl MessageImpl::NewEvent(DebugEvent event, 35705ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org bool running, 35715ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> exec_state, 35725ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> event_data) { 35735ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org MessageImpl message(true, event, running, 35745ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org exec_state, event_data, Handle<String>(), NULL); 35755ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return message; 35765ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 35775ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 35785ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 35795ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgMessageImpl MessageImpl::NewResponse(DebugEvent event, 35805ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org bool running, 35815ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> exec_state, 35825ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> event_data, 35835ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<String> response_json, 35845ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org v8::Debug::ClientData* client_data) { 35855ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org MessageImpl message(false, event, running, 35865ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org exec_state, event_data, response_json, client_data); 35875ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return message; 35885ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 35895ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 35905ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 35915ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgMessageImpl::MessageImpl(bool is_event, 35925ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org DebugEvent event, 35935ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org bool running, 35945ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> exec_state, 35955ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<JSObject> event_data, 35965ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<String> response_json, 35975ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org v8::Debug::ClientData* client_data) 35985ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org : is_event_(is_event), 35995ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org event_(event), 36005ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org running_(running), 36015ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org exec_state_(exec_state), 36025ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org event_data_(event_data), 36035ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org response_json_(response_json), 36045ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org client_data_(client_data) {} 36055ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36065ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36075ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgbool MessageImpl::IsEvent() const { 36085ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return is_event_; 36095ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgbool MessageImpl::IsResponse() const { 36135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return !is_event_; 36145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgDebugEvent MessageImpl::GetEvent() const { 36185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return event_; 36195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36205ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgbool MessageImpl::WillStartRunning() const { 36235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return running_; 36245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Handle<v8::Object> MessageImpl::GetExecutionState() const { 36285ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return v8::Utils::ToLocal(exec_state_); 36295ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36305ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36315ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 3632c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgv8::Isolate* MessageImpl::GetIsolate() const { 3633c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); 3634c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3635c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3636c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 36375ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Handle<v8::Object> MessageImpl::GetEventData() const { 36385ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return v8::Utils::ToLocal(event_data_); 36395ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36405ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36415ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36425ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Handle<v8::String> MessageImpl::GetJSON() const { 3643ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org v8::EscapableHandleScope scope( 36442bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org reinterpret_cast<v8::Isolate*>(event_data_->GetIsolate())); 36455ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36465ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org if (IsEvent()) { 36475ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org // Call toJSONProtocol on the debug event object. 36485ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<Object> fun = GetProperty(event_data_, "toJSONProtocol"); 36495ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org if (!fun->IsJSFunction()) { 36505ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return v8::Handle<v8::String>(); 36515ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org } 36525ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org bool caught_exception; 36535ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org Handle<Object> json = Execution::TryCall(Handle<JSFunction>::cast(fun), 36545ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org event_data_, 36555ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 0, NULL, &caught_exception); 36565ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org if (caught_exception || !json->IsString()) { 36575ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return v8::Handle<v8::String>(); 36585ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org } 3659ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json))); 36605ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org } else { 36615ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return v8::Utils::ToLocal(response_json_); 36625ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org } 36635ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36645ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36655ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36665ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Handle<v8::Context> MessageImpl::GetEventContext() const { 3667e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org Isolate* isolate = event_data_->GetIsolate(); 3668ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org v8::Handle<v8::Context> context = GetDebugEventContext(isolate); 3669ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Isolate::context() may be NULL when "script collected" event occures. 36709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected); 3671717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org return context; 36725ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36735ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36745ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36755ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Debug::ClientData* MessageImpl::GetClientData() const { 36765ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return client_data_; 36775ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org} 36785ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36795ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 36809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comEventDetailsImpl::EventDetailsImpl(DebugEvent event, 36819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Handle<JSObject> exec_state, 36829dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Handle<JSObject> event_data, 368322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com Handle<Object> callback_data, 368422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com v8::Debug::ClientData* client_data) 36859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com : event_(event), 36869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com exec_state_(exec_state), 36879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com event_data_(event_data), 368822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com callback_data_(callback_data), 368922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com client_data_(client_data) {} 36909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36919dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36929dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comDebugEvent EventDetailsImpl::GetEvent() const { 36939dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com return event_; 36949dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 36959dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comv8::Handle<v8::Object> EventDetailsImpl::GetExecutionState() const { 36989dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com return v8::Utils::ToLocal(exec_state_); 36999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 37009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 37019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 37029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comv8::Handle<v8::Object> EventDetailsImpl::GetEventData() const { 37039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com return v8::Utils::ToLocal(event_data_); 37049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 37059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 37069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 37079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comv8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const { 3708e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org return GetDebugEventContext(exec_state_->GetIsolate()); 37099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 37109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 37119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 37129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comv8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const { 37139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com return v8::Utils::ToLocal(callback_data_); 37149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 37159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 37169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 371722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.comv8::Debug::ClientData* EventDetailsImpl::GetClientData() const { 371822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com return client_data_; 371922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com} 372022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 372122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com 37223a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()), 37233a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org client_data_(NULL) { 372441826e77311db718135ef6517b846933dfd275f3ager@chromium.org} 372541826e77311db718135ef6517b846933dfd275f3ager@chromium.org 372641826e77311db718135ef6517b846933dfd275f3ager@chromium.org 37273a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage::CommandMessage(const Vector<uint16_t>& text, 37283a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org v8::Debug::ClientData* data) 372965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org : text_(text), 373065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org client_data_(data) { 373165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org} 373265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 373365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 37343a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage::~CommandMessage() { 373565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org} 373665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 373765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 37383a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid CommandMessage::Dispose() { 373965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org text_.Dispose(); 374065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org delete client_data_; 374165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org client_data_ = NULL; 374265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org} 374365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 374465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 37453a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage CommandMessage::New(const Vector<uint16_t>& command, 37463a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org v8::Debug::ClientData* data) { 37473a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org return CommandMessage(command.Clone(), data); 374865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org} 374965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 375065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org 37513a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0), 37523a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org size_(size) { 37533a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org messages_ = NewArray<CommandMessage>(size); 37547276f14ca716596e0a0d17539516370c1f453847kasper.lund} 37557276f14ca716596e0a0d17539516370c1f453847kasper.lund 37567276f14ca716596e0a0d17539516370c1f453847kasper.lund 37573a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessageQueue::~CommandMessageQueue() { 375865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org while (!IsEmpty()) { 37593a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org CommandMessage m = Get(); 376065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org m.Dispose(); 376165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org } 37627276f14ca716596e0a0d17539516370c1f453847kasper.lund DeleteArray(messages_); 37637276f14ca716596e0a0d17539516370c1f453847kasper.lund} 37647276f14ca716596e0a0d17539516370c1f453847kasper.lund 37657276f14ca716596e0a0d17539516370c1f453847kasper.lund 37663a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage CommandMessageQueue::Get() { 37677276f14ca716596e0a0d17539516370c1f453847kasper.lund ASSERT(!IsEmpty()); 37687276f14ca716596e0a0d17539516370c1f453847kasper.lund int result = start_; 37697276f14ca716596e0a0d17539516370c1f453847kasper.lund start_ = (start_ + 1) % size_; 37707276f14ca716596e0a0d17539516370c1f453847kasper.lund return messages_[result]; 37717276f14ca716596e0a0d17539516370c1f453847kasper.lund} 37727276f14ca716596e0a0d17539516370c1f453847kasper.lund 37737276f14ca716596e0a0d17539516370c1f453847kasper.lund 37743a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid CommandMessageQueue::Put(const CommandMessage& message) { 37757276f14ca716596e0a0d17539516370c1f453847kasper.lund if ((end_ + 1) % size_ == start_) { 37767276f14ca716596e0a0d17539516370c1f453847kasper.lund Expand(); 37777276f14ca716596e0a0d17539516370c1f453847kasper.lund } 37787276f14ca716596e0a0d17539516370c1f453847kasper.lund messages_[end_] = message; 37797276f14ca716596e0a0d17539516370c1f453847kasper.lund end_ = (end_ + 1) % size_; 37807276f14ca716596e0a0d17539516370c1f453847kasper.lund} 37817276f14ca716596e0a0d17539516370c1f453847kasper.lund 37827276f14ca716596e0a0d17539516370c1f453847kasper.lund 37833a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid CommandMessageQueue::Expand() { 37843a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org CommandMessageQueue new_queue(size_ * 2); 37857276f14ca716596e0a0d17539516370c1f453847kasper.lund while (!IsEmpty()) { 37867276f14ca716596e0a0d17539516370c1f453847kasper.lund new_queue.Put(Get()); 378743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 37883a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org CommandMessage* array_to_free = messages_; 37897276f14ca716596e0a0d17539516370c1f453847kasper.lund *this = new_queue; 37907276f14ca716596e0a0d17539516370c1f453847kasper.lund new_queue.messages_ = array_to_free; 379165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org // Make the new_queue empty so that it doesn't call Dispose on any messages. 379265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org new_queue.start_ = new_queue.end_; 37937276f14ca716596e0a0d17539516370c1f453847kasper.lund // Automatic destructor called on new_queue, freeing array_to_free. 37947276f14ca716596e0a0d17539516370c1f453847kasper.lund} 37957276f14ca716596e0a0d17539516370c1f453847kasper.lund 37967276f14ca716596e0a0d17539516370c1f453847kasper.lund 37976d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgLockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size) 3798dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org : logger_(logger), queue_(size) {} 37997276f14ca716596e0a0d17539516370c1f453847kasper.lund 38007276f14ca716596e0a0d17539516370c1f453847kasper.lund 38013a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgbool LockingCommandMessageQueue::IsEmpty() const { 3802dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&mutex_); 38037276f14ca716596e0a0d17539516370c1f453847kasper.lund return queue_.IsEmpty(); 380443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 380543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38067276f14ca716596e0a0d17539516370c1f453847kasper.lund 38073a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage LockingCommandMessageQueue::Get() { 3808dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&mutex_); 38093a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org CommandMessage result = queue_.Get(); 38106d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org logger_->DebugEvent("Get", result.text()); 38117276f14ca716596e0a0d17539516370c1f453847kasper.lund return result; 38127276f14ca716596e0a0d17539516370c1f453847kasper.lund} 38137276f14ca716596e0a0d17539516370c1f453847kasper.lund 38147276f14ca716596e0a0d17539516370c1f453847kasper.lund 38153a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid LockingCommandMessageQueue::Put(const CommandMessage& message) { 3816dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&mutex_); 38177276f14ca716596e0a0d17539516370c1f453847kasper.lund queue_.Put(message); 38186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org logger_->DebugEvent("Put", message.text()); 38197276f14ca716596e0a0d17539516370c1f453847kasper.lund} 38207276f14ca716596e0a0d17539516370c1f453847kasper.lund 38217276f14ca716596e0a0d17539516370c1f453847kasper.lund 38223a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid LockingCommandMessageQueue::Clear() { 3823dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&mutex_); 38247276f14ca716596e0a0d17539516370c1f453847kasper.lund queue_.Clear(); 38257276f14ca716596e0a0d17539516370c1f453847kasper.lund} 38267276f14ca716596e0a0d17539516370c1f453847kasper.lund 3827b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3828ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) 38296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org : Thread("v8:MsgDispHelpr"), 3830e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org isolate_(isolate), sem_(0), 3831dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org already_signalled_(false) { 3832b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 3833b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3834b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3835b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MessageDispatchHelperThread::Schedule() { 3836b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 3837dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&mutex_); 3838b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (already_signalled_) { 3839b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return; 3840b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3841b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org already_signalled_ = true; 3842b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3843e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org sem_.Signal(); 3844b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 3845b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3846b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3847b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MessageDispatchHelperThread::Run() { 3848b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org while (true) { 3849e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org sem_.Wait(); 3850b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 3851dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(&mutex_); 3852b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org already_signalled_ = false; 3853b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3854b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 3855f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); 3856f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org isolate_->debugger()->CallMessageDispatchHandler(); 3857b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3858b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3859b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 3860b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 386165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif // ENABLE_DEBUGGER_SUPPORT 38627276f14ca716596e0a0d17539516370c1f453847kasper.lund 386343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 3864