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*>(&registers_), 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*>(&registers_), 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