17d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h"
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arguments.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compilation-cache.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h"
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/execution.h"
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/full-codegen.h"
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/global-handles.h"
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h"
20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/list.h"
214b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/log.h"
22196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/messages.h"
23196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/natives.h"
24196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
25196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "include/v8-debug.h"
265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
2771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
2871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgDebug::Debug(Isolate* isolate)
31d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    : debug_context_(Handle<Context>()),
32d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      event_listener_(Handle<Object>()),
33d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      event_listener_data_(Handle<Object>()),
34d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      message_handler_(NULL),
35d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      command_received_(0),
36d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      command_queue_(isolate->logger(), kQueueInitialSize),
37d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      event_command_queue_(isolate->logger(), kQueueInitialSize),
38d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      is_active_(false),
398d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      is_suppressed_(false),
40d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      live_edit_enabled_(true),  // TODO(yangguo): set to false by default.
41d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      has_break_points_(false),
428d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      break_disabled_(false),
43ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      break_on_exception_(false),
44ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      break_on_uncaught_exception_(false),
45d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      script_cache_(NULL),
46d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      debug_info_list_(NULL),
47ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate_(isolate) {
48af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  ThreadInit();
49ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
50ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
51ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
52ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
53ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
54ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Isolate::context() may have been NULL when "script collected" event
55ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // occured.
56ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (context.is_null()) return v8::Local<v8::Context>();
5746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Context> native_context(context->native_context());
5846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return v8::Utils::ToLocal(native_context);
599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
619dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info,
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                             BreakLocatorType type) {
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  debug_info_ = debug_info;
6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  type_ = type;
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reloc_iterator_ = NULL;
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reloc_iterator_original_ = NULL;
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Reset();  // Initialize the rest of the member variables.
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenBreakLocationIterator::~BreakLocationIterator() {
73e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(reloc_iterator_ != NULL);
74e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(reloc_iterator_original_ != NULL);
7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  delete reloc_iterator_;
7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  delete reloc_iterator_original_;
7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org// Check whether a code stub with the specified major key is a possible break
818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org// point location when looking for source break locations.
828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgstatic bool IsSourceBreakStub(Code* code) {
838d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  CodeStub::Major major_key = CodeStub::GetMajorKey(code);
848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  return major_key == CodeStub::CallFunction;
858d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
868d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
878d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
888d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org// Check whether a code stub with the specified major key is a possible break
898d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org// location.
908d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgstatic bool IsBreakStub(Code* code) {
918d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  CodeStub::Major major_key = CodeStub::GetMajorKey(code);
928d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  return major_key == CodeStub::CallFunction;
938d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
948d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
958d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::Next() {
9779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
98e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!RinfoDone());
9943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate through reloc info for code and original code stopping at each
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // breakable code target.
10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool first = break_point_ == -1;
10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!RinfoDone()) {
10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!first) RinfoNext();
10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    first = false;
10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (RinfoDone()) return;
10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // Whenever a statement position or (plain) position is passed update the
109236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // current value of these.
110236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (RelocInfo::IsPosition(rmode())) {
111236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      if (RelocInfo::IsStatementPosition(rmode())) {
112c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        statement_position_ = static_cast<int>(
113c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            rinfo()->data() - debug_info_->shared()->start_position());
11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
115236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      // Always update the position as we don't want that to be before the
116236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      // statement position.
117c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      position_ = static_cast<int>(
118c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org          rinfo()->data() - debug_info_->shared()->start_position());
119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(position_ >= 0);
120e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(statement_position_ >= 0);
12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1232356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    if (IsDebugBreakSlot()) {
1242356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      // There is always a possible break point at a debug break slot.
1252356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      break_point_++;
1262356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      return;
1272356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    } else if (RelocInfo::IsCodeTarget(rmode())) {
1282356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      // Check for breakable code target. Look in the original code as setting
1292356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      // break points can cause the code targets in the running (debugged) code
1302356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      // to be of a different kind than in the original code.
13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Address target = original_rinfo()->target_address();
1328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      Code* code = Code::GetCodeFromTargetAddress(target);
133ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      if ((code->is_inline_cache_stub() &&
13440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org           !code->is_binary_op_stub() &&
1359fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org           !code->is_compare_ic_stub() &&
1369fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org           !code->is_to_boolean_ic_stub()) ||
137ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org          RelocInfo::IsConstructCall(rmode())) {
13843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break_point_++;
13943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return;
14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (code->kind() == Code::STUB) {
142a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org        if (IsDebuggerStatement()) {
143a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org          break_point_++;
144a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org          return;
1458d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        } else if (type_ == ALL_BREAK_LOCATIONS) {
1468d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          if (IsBreakStub(code)) {
14743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            break_point_++;
14843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            return;
14943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        } else {
151e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(type_ == SOURCE_BREAK_LOCATIONS);
1528d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          if (IsSourceBreakStub(code)) {
15343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            break_point_++;
15443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            return;
15543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
15643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
15743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
15843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
15943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Check for break at return.
161236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (RelocInfo::IsJSReturn(rmode())) {
16243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Set the positions to the end of the function.
16343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (debug_info_->shared()->HasSourceCode()) {
16443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        position_ = debug_info_->shared()->end_position() -
165e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org                    debug_info_->shared()->start_position() - 1;
16643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        position_ = 0;
16843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      statement_position_ = position_;
17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break_point_++;
17143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
17243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
17343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::Next(int count) {
17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (count > 0) {
17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Next();
18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    count--;
18143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
18243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
18343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1858a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// Find the break point at the supplied address, or the closest one before
1868a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// the address.
18743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::FindBreakLocationFromAddress(Address pc) {
18843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Run through all break points to locate the one closest to the address.
18943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int closest_break_point = 0;
19043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int distance = kMaxInt;
19143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!Done()) {
19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Check if this break point is closer that what was previously found.
1938a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    if (this->pc() <= pc && pc - this->pc() < distance) {
19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      closest_break_point = break_point();
195c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      distance = static_cast<int>(pc - this->pc());
19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Check whether we can't get any closer.
19743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (distance == 0) break;
19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Next();
20043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Move to the break point found.
20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Reset();
20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Next(closest_break_point);
20543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
20643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Find the break point closest to the supplied source position.
20993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.orgvoid BreakLocationIterator::FindBreakLocationFromPosition(int position,
21093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    BreakPositionAlignment alignment) {
21143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Run through all break points to locate the one closest to the source
21243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // position.
21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int closest_break_point = 0;
21443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int distance = kMaxInt;
21593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!Done()) {
21793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    int next_position;
21893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    switch (alignment) {
21993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    case STATEMENT_ALIGNED:
22093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      next_position = this->statement_position();
22193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      break;
22293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    case BREAK_POSITION_ALIGNED:
22393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      next_position = this->position();
22493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      break;
22593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    default:
22693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      UNREACHABLE();
22793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      next_position = this->statement_position();
22893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    }
22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Check if this break point is closer that what was previously found.
23093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    if (position <= next_position && next_position - position < distance) {
23143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      closest_break_point = break_point();
23293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      distance = next_position - position;
23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Check whether we can't get any closer.
23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (distance == 0) break;
23543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
23643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Next();
23743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
23843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Move to the break point found.
24043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Reset();
24143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Next(closest_break_point);
24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::Reset() {
24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create relocation iterators for the two code objects.
24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (reloc_iterator_ != NULL) delete reloc_iterator_;
24843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (reloc_iterator_original_ != NULL) delete reloc_iterator_original_;
249e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  reloc_iterator_ = new RelocIterator(
250e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      debug_info_->code(),
251e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE));
252e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  reloc_iterator_original_ = new RelocIterator(
253e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      debug_info_->original_code(),
254e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE));
25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Position at the first break point.
25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  break_point_ = -1;
25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  position_ = 1;
25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  statement_position_ = 1;
26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Next();
26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::Done() const {
26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return RinfoDone();
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there is not already a real break point here patch code with debug
27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // break.
2728d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (!HasBreakPoint()) SetDebugBreak();
273e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreak() || IsDebuggerStatement());
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Set the break point information.
27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DebugInfo::SetBreakPoint(debug_info_, code_position(),
27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                           position(), statement_position(),
27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                           break_point_object);
27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear the break point information.
28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there are no more break points here remove the debug break.
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!HasBreakPoint()) {
28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ClearDebugBreak();
287e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!IsDebugBreak());
28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::SetOneShot() {
293a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Debugger statement always calls debugger. No need to modify it.
2948d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (IsDebuggerStatement()) return;
295a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there is a real break point here no more to do.
29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (HasBreakPoint()) {
298e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsDebugBreak());
29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch code with debug break.
30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  SetDebugBreak();
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::ClearOneShot() {
308a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Debugger statement always calls debugger. No need to modify it.
3098d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (IsDebuggerStatement()) return;
310a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there is a real break point here no more to do.
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (HasBreakPoint()) {
313e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsDebugBreak());
31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Patch code removing debug break.
31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ClearDebugBreak();
319e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsDebugBreak());
32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::SetDebugBreak() {
324a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Debugger statement always calls debugger. No need to modify it.
3258d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (IsDebuggerStatement()) return;
326a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there is already a break point here just return. This might happen if
328727e995b7bba3c57fb1e5c156d386ca11894f781v  // the same code is flooded with break points twice. Flooding the same
32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // function twice might happen when stepping in a function with an exception
33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // handler as the handler and the function is the same.
3318d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (IsDebugBreak()) return;
33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
333236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  if (RelocInfo::IsJSReturn(rmode())) {
334245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    // Patch the frame exit code with a break point.
335245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    SetDebugBreakAtReturn();
3362356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  } else if (IsDebugBreakSlot()) {
3372356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    // Patch the code in the break slot.
3382356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    SetDebugBreakAtSlot();
33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
34065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // Patch the IC call.
34165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    SetDebugBreakAtIC();
34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
343e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreak());
34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::ClearDebugBreak() {
348a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Debugger statement always calls debugger. No need to modify it.
3498d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (IsDebuggerStatement()) return;
350a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
351236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  if (RelocInfo::IsJSReturn(rmode())) {
352245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    // Restore the frame exit code.
353245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    ClearDebugBreakAtReturn();
3542356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  } else if (IsDebugBreakSlot()) {
3552356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    // Restore the code in the break slot.
3562356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    ClearDebugBreakAtSlot();
35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
35865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // Patch the IC call.
35965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    ClearDebugBreakAtIC();
36043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
361e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsDebugBreak());
36243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
36343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
36443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgbool BreakLocationIterator::IsStepInLocation(Isolate* isolate) {
366e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  if (RelocInfo::IsConstructCall(original_rmode())) {
3671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return true;
3681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else if (RelocInfo::IsCodeTarget(rmode())) {
3691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HandleScope scope(debug_info_->GetIsolate());
370e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    Address target = original_rinfo()->target_address();
3711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
372594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (target_code->kind() == Code::STUB) {
3739d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org      return CodeStub::GetMajorKey(*target_code) == CodeStub::CallFunction;
374594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
375a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return target_code->is_call_stub();
3761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
377a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  return false;
3781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
3791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
3801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
381c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orgvoid BreakLocationIterator::PrepareStepIn(Isolate* isolate) {
382a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org#ifdef DEBUG
383c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  HandleScope scope(isolate);
384a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Step in can only be prepared if currently positioned on an IC call,
385a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // construct call or CallFunction stub call.
38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address target = rinfo()->target_address();
387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
388a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // All the following stuff is needed only for assertion checks so the code
389a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // is wrapped in ifdef.
390a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  Handle<Code> maybe_call_function_stub = target_code;
391a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  if (IsDebugBreak()) {
392a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Address original_target = original_rinfo()->target_address();
393a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    maybe_call_function_stub =
394a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Handle<Code>(Code::GetCodeFromTargetAddress(original_target));
395a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  }
396a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  bool is_call_function_stub =
397a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      (maybe_call_function_stub->kind() == Code::STUB &&
3989d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org       CodeStub::GetMajorKey(*maybe_call_function_stub) ==
3999d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org           CodeStub::CallFunction);
400a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
401a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // Step in through construct call requires no changes to the running code.
402a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // Step in through getters/setters should already be prepared as well
403a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // because caller of this function (Debug::PrepareStep) is expected to
404a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // flood the top frame's function with one shot breakpoints.
405a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // Step in through CallFunction stub should also be prepared by caller of
406a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // this function (Debug::PrepareStep) which should flood target function
407a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  // with breakpoints.
408e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(RelocInfo::IsConstructCall(rmode()) ||
409a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org         target_code->is_inline_cache_stub() ||
410a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org         is_call_function_stub);
411a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif
41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether the break point is at a position which will exit the function.
41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::IsExit() const {
417236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  return (RelocInfo::IsJSReturn(rmode()));
41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::HasBreakPoint() {
42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return debug_info_->HasBreakPoint(code_position());
42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether there is a debug break at the current position.
42743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::IsDebugBreak() {
428236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  if (RelocInfo::IsJSReturn(rmode())) {
429245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    return IsDebugBreakAtReturn();
4302356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  } else if (IsDebugBreakSlot()) {
4312356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    return IsDebugBreakAtSlot();
43243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Debug::IsDebugBreak(rinfo()->target_address());
43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
43643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4388d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org// Find the builtin to use for invoking the debug break
4398d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgstatic Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) {
4408d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  Isolate* isolate = code->GetIsolate();
4418d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4428d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Find the builtin debug break function matching the calling convention
4438d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // used by the call site.
4448d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (code->is_inline_cache_stub()) {
4458d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    switch (code->kind()) {
4468d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      case Code::CALL_IC:
4478d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        return isolate->builtins()->CallICStub_DebugBreak();
4488d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4498d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      case Code::LOAD_IC:
4508d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        return isolate->builtins()->LoadIC_DebugBreak();
4518d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4528d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      case Code::STORE_IC:
4538d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        return isolate->builtins()->StoreIC_DebugBreak();
4548d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      case Code::KEYED_LOAD_IC:
4568d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        return isolate->builtins()->KeyedLoadIC_DebugBreak();
4578d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4588d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      case Code::KEYED_STORE_IC:
4598d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        return isolate->builtins()->KeyedStoreIC_DebugBreak();
4608d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4618d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      case Code::COMPARE_NIL_IC:
4628d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        return isolate->builtins()->CompareNilIC_DebugBreak();
4638d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4648d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      default:
4658d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        UNREACHABLE();
4668d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    }
4678d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
4688d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (RelocInfo::IsConstructCall(mode)) {
4698d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    if (code->has_function_cache()) {
4708d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
4718d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    } else {
4728d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      return isolate->builtins()->CallConstructStub_DebugBreak();
4738d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    }
4748d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
4758d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (code->kind() == Code::STUB) {
476e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(CodeStub::GetMajorKey(*code) == CodeStub::CallFunction);
4778d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    return isolate->builtins()->CallFunctionStub_DebugBreak();
4788d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
4798d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  UNREACHABLE();
4818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  return Handle<Code>::null();
4828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
4838d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
4848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
48565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtIC() {
48665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Patch the original code with the current address as the current address
48765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // might have changed by the inline caching since the code was copied.
48865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  original_rinfo()->set_target_address(rinfo()->target_address());
48965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
49065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  RelocInfo::Mode mode = rmode();
49165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  if (RelocInfo::IsCodeTarget(mode)) {
49265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    Address target = rinfo()->target_address();
493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
49465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
49565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // Patch the code to invoke the builtin debug break function matching the
49665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // calling convention used by the call site.
4978d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode);
49865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    rinfo()->set_target_address(dbgbrk_code->entry());
49965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
50065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
50165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
50265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
50365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtIC() {
50465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Patch the code to the original invoke.
50565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  rinfo()->set_target_address(original_rinfo()->target_address());
50665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
50765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
50865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
509a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgbool BreakLocationIterator::IsDebuggerStatement() {
5105c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return RelocInfo::DEBUG_BREAK == rmode();
511a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org}
512a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
513a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
5142356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgbool BreakLocationIterator::IsDebugBreakSlot() {
5152356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  return RelocInfo::DEBUG_BREAK_SLOT == rmode();
5162356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org}
5172356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
5182356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
51943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* BreakLocationIterator::BreakPointObjects() {
52043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return debug_info_->GetBreakPointObjects(code_position());
52143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
524381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// Clear out all the debug break code. This is ONLY supposed to be used when
525381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// shutting down the debugger as it will leave the break point information in
526381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// DebugInfo even though the code is patched back to the non break point state.
527381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgvoid BreakLocationIterator::ClearAllDebugBreak() {
528381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  while (!Done()) {
529381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    ClearDebugBreak();
530381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    Next();
531381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  }
532381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org}
533381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
534381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakLocationIterator::RinfoDone() const {
536e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done());
53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return reloc_iterator_->done();
53843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakLocationIterator::RinfoNext() {
54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reloc_iterator_->next();
54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reloc_iterator_original_->next();
54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
545e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(reloc_iterator_->done() == reloc_iterator_original_->done());
54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!reloc_iterator_->done()) {
547e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(rmode() == original_rmode());
54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
55143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Threading support.
55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ThreadInit() {
5557be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  thread_local_.break_count_ = 0;
5567be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  thread_local_.break_id_ = 0;
5577be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  thread_local_.break_frame_id_ = StackFrame::NO_ID;
55843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.last_step_action_ = StepNone;
559236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
56043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.step_count_ = 0;
56143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.last_fp_ = 0;
56234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  thread_local_.queued_step_count_ = 0;
56343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.step_into_fp_ = 0;
564a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  thread_local_.step_out_fp_ = 0;
565ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // TODO(isolates): frames_are_dropped_?
566196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  thread_local_.current_debug_scope_ = NULL;
5670b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  thread_local_.restarter_frame_function_pointer_ = NULL;
56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
56943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar* Debug::ArchiveDebug(char* storage) {
57243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* to = storage;
573d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ThreadInit();
57543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return storage + ArchiveSpacePerThread();
57643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
57743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar* Debug::RestoreDebug(char* storage) {
58043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* from = storage;
581d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
58243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return storage + ArchiveSpacePerThread();
58343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
58443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint Debug::ArchiveSpacePerThread() {
5876a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  return sizeof(ThreadLocal);
58843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
58943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
59043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5918d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch),
592248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org                                             isolate_(isolate) {
5938d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  Heap* heap = isolate_->heap();
5948d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  HandleScope scope(isolate_);
5958d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
5968d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
5978d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // rid of all the cached script wrappers and the second gets rid of the
5988d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // scripts which are no longer referenced.
5998d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
6008d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
6018d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
6028d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Scan heap for Script objects.
6038d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  HeapIterator iterator(heap);
6048d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  DisallowHeapAllocation no_allocation;
6058d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
6068d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
6078d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
6088d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      Add(Handle<Script>(Script::cast(obj)));
6098d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    }
6108d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
6118d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
6128d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
6138d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
61471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid ScriptCache::Add(Handle<Script> script) {
615e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  GlobalHandles* global_handles = isolate_->global_handles();
61671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Create an entry in the hash map for the script.
6171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int id = script->id()->value();
61871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  HashMap::Entry* entry =
61971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org      HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
62071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  if (entry->value != NULL) {
6217c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org#ifdef DEBUG
6227c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    // The code deserializer may introduce duplicate Script objects.
6237c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    // Assert that the Script objects with the same id have the same name.
6247c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    Handle<Script> found(reinterpret_cast<Script**>(entry->value));
625e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(script->id() == found->id());
626e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!script->name()->IsString() ||
6277c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org           String::cast(script->name())->Equals(String::cast(found->name())));
6287c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org#endif
62971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org    return;
63043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
63171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Globalize the script object, make it weak and use the location of the
63271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // global handle as the value in the hash map.
63371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  Handle<Script> script_ =
6344f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      Handle<Script>::cast(global_handles->Create(*script));
6354f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
6364f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                          this,
6374f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                          ScriptCache::HandleWeakScript);
63871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  entry->value = script_.location();
63943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
64043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgHandle<FixedArray> ScriptCache::GetScripts() {
643e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  Factory* factory = isolate_->factory();
644d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<FixedArray> instances = factory->NewFixedArray(occupancy());
64571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  int count = 0;
64671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
647e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(entry->value != NULL);
64871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org    if (entry->value != NULL) {
64971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org      instances->set(count, *reinterpret_cast<Script**>(entry->value));
65071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org      count++;
65171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org    }
65271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  }
65371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  return instances;
65443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
65543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid ScriptCache::Clear() {
65871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Iterate the script cache to get rid of all the weak handles.
65971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
660e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(entry != NULL);
66171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org    Object** location = reinterpret_cast<Object**>(entry->value);
662e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((*location)->IsScript());
6634f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    GlobalHandles::ClearWeakness(location);
6644f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    GlobalHandles::Destroy(location);
66571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  }
66671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Clear the content of the hash map.
66771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  HashMap::Clear();
66871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
66971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
67071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
6714f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.orgvoid ScriptCache::HandleWeakScript(
6724f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    const v8::WeakCallbackData<v8::Value, void>& data) {
6734f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  // Retrieve the script identifier.
6744f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  Handle<Object> object = Utils::OpenHandle(*data.GetValue());
6754f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  int id = Handle<Script>::cast(object)->id()->value();
6764f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  void* key = reinterpret_cast<void*>(id);
6774f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  uint32_t hash = Hash(id);
67871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
6794f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  // Remove the corresponding entry from the cache.
6804f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  ScriptCache* script_cache =
6814f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      reinterpret_cast<ScriptCache*>(data.GetParameter());
6824f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  HashMap::Entry* entry = script_cache->Lookup(key, hash, false);
6834f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  Object** location = reinterpret_cast<Object**>(entry->value);
6844f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  script_cache->Remove(key, hash);
68571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
68671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Clear the weak handle.
6874f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles::Destroy(location);
68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6914f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.orgvoid Debug::HandleWeakDebugInfo(
6924f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    const v8::WeakCallbackData<v8::Value, void>& data) {
6934f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
6944f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  DebugInfoListNode* node =
6954f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      reinterpret_cast<DebugInfoListNode*>(data.GetParameter());
69669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // We need to clear all breakpoints associated with the function to restore
69769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // original code and avoid patching the code twice later because
69869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // the function will live in the heap until next gc, and can be found by
69978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // Debug::FindSharedFunctionInfoInScript.
70069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
70169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  it.ClearAllDebugBreak();
702ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  debug->RemoveDebugInfo(node->debug_info());
70371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#ifdef DEBUG
7044f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  for (DebugInfoListNode* n = debug->debug_info_list_;
7054f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org       n != NULL;
7064f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org       n = n->next()) {
707e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(n != node);
70871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  }
70971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#endif
71071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
71171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
71271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
71371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgDebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
71471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Globalize the request debug info object and make it weak.
7154f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
7164f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info));
7174f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
7184f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                          this,
7194f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                          Debug::HandleWeakDebugInfo);
72071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
72171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
72271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
72371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgDebugInfoListNode::~DebugInfoListNode() {
7244f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location()));
72571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
72671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
72771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
728e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgbool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
7297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Factory* factory = isolate->factory();
7307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate);
73143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73244510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Bail out if the index is invalid.
7336a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  if (index == -1) return false;
73444510671e908d0efc639513d81efcd81e7f14240kasper.lund
73544510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Find source and name for the requested script.
736ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<String> source_code =
7377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      isolate->bootstrapper()->NativesSourceLookup(index);
73843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Vector<const char> name = Natives::GetScriptName(index);
7398496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> script_name =
7408496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      factory->NewStringFromAscii(name).ToHandleChecked();
741355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Handle<Context> context = isolate->native_context();
74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compile the script.
7445d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  Handle<SharedFunctionInfo> function_info;
7454c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  function_info = Compiler::CompileScript(
7464c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org      source_code, script_name, 0, 0, false, context, NULL, NULL,
7474c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org      ScriptCompiler::kNoCompileOptions, NATIVES_CODE);
74843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Silently ignore stack overflows during compilation.
7505d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  if (function_info.is_null()) {
751e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(isolate->has_pending_exception());
7527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    isolate->clear_pending_exception();
75343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return false;
75443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
75543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7565d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Execute the shared function in the debugger context.
75744510671e908d0efc639513d81efcd81e7f14240kasper.lund  Handle<JSFunction> function =
7587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      factory->NewFunctionFromSharedFunctionInfo(function_info, context);
759717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
760ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  MaybeHandle<Object> maybe_exception;
761ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  MaybeHandle<Object> result = Execution::TryCall(
762ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      function, handle(context->global_proxy()), 0, NULL, &maybe_exception);
76344510671e908d0efc639513d81efcd81e7f14240kasper.lund
76444510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Check for caught exceptions.
7652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (result.is_null()) {
766e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!isolate->has_pending_exception());
7677d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    MessageLocation computed_location;
7687d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    isolate->ComputeLocation(&computed_location);
7699258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    Handle<Object> message = MessageHandler::MakeMessageObject(
770d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org        isolate, "error_loading_debugger", &computed_location,
771f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        Vector<Handle<Object> >::empty(), Handle<JSArray>());
772e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!isolate->has_pending_exception());
773ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    Handle<Object> exception;
774ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    if (maybe_exception.ToHandle(&exception)) {
77549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      isolate->set_pending_exception(*exception);
776e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      MessageHandler::ReportMessage(isolate, NULL, message);
77749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      isolate->clear_pending_exception();
77849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    }
77943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return false;
78043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
78143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78244510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Mark this script as native and return successfully.
78344510671e908d0efc639513d81efcd81e7f14240kasper.lund  Handle<Script> script(Script::cast(function->shared()->script()));
784e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
78743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::Load() {
79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return if debugger is already loaded.
7918d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (is_loaded()) return true;
79243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79344510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Bail out if we're already in the process of compiling the native
79444510671e908d0efc639513d81efcd81e7f14240kasper.lund  // JavaScript source code for the debugger.
7958d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (is_suppressed_) return false;
7968d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  SuppressDebug while_loading(this);
79744510671e908d0efc639513d81efcd81e7f14240kasper.lund
79844510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Disable breakpoints and interrupts while compiling and running the
79944510671e908d0efc639513d81efcd81e7f14240kasper.lund  // debugger scripts including the context creation code.
8008d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  DisableBreak disable(this, true);
8017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  PostponeInterruptsScope postpone(isolate_);
80244510671e908d0efc639513d81efcd81e7f14240kasper.lund
80343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the debugger context.
8047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
80526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  ExtensionConfiguration no_extensions;
80644510671e908d0efc639513d81efcd81e7f14240kasper.lund  Handle<Context> context =
8077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      isolate_->bootstrapper()->CreateEnvironment(
80858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org          MaybeHandle<JSGlobalProxy>(),
809ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          v8::Handle<ObjectTemplate>(),
81026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org          &no_extensions);
81144510671e908d0efc639513d81efcd81e7f14240kasper.lund
8127d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  // Fail if no context could be created.
8137d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  if (context.is_null()) return false;
8147d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
81544510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Use the debugger context.
8167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  SaveContext save(isolate_);
8177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  isolate_->set_context(*context);
81844510671e908d0efc639513d81efcd81e7f14240kasper.lund
81944510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Expose the builtins object in the debugger context.
8204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> key = isolate_->factory()->InternalizeOneByteString(
8212c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      STATIC_CHAR_VECTOR("builtins"));
8226a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  Handle<GlobalObject> global =
8236a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      Handle<GlobalObject>(context->global_object(), isolate_);
8246a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  Handle<JSBuiltinsObject> builtin =
8256a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      Handle<JSBuiltinsObject>(global->builtins(), isolate_);
8268f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  RETURN_ON_EXCEPTION_VALUE(
82751e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org      isolate_, Object::SetProperty(global, key, builtin, SLOPPY), false);
82843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compile the JavaScript for the debugger in the debugger context.
83044510671e908d0efc639513d81efcd81e7f14240kasper.lund  bool caught_exception =
831e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      !CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) ||
832e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      !CompileDebuggerScript(isolate_, Natives::GetIndex("debug"));
833ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
834ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (FLAG_enable_liveedit) {
835ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    caught_exception = caught_exception ||
836e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
837ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
83844510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Check for caught exceptions.
83944510671e908d0efc639513d81efcd81e7f14240kasper.lund  if (caught_exception) return false;
84043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
841e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  debug_context_ = Handle<Context>::cast(
842e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      isolate_->global_handles()->Create(*context));
84343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
84443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
84543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::Unload() {
8487e6132b924829c353864933f29124419916db550machenbach@chromium.org  ClearAllBreakPoints();
849d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  ClearStepping();
8507e6132b924829c353864933f29124419916db550machenbach@chromium.org
85143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return debugger is not loaded.
8528d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (!is_loaded()) return;
85343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Clear the script cache.
8558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (script_cache_ != NULL) {
8568d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    delete script_cache_;
8578d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    script_cache_ = NULL;
8588d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
85971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear debugger context global handle.
8616a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  debug_context_ = Handle<Context>();
86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
86443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
866e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid Debug::Break(Arguments args, JavaScriptFrame* frame) {
867c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Heap* heap = isolate_->heap();
868c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  HandleScope scope(isolate_);
869e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(args.length() == 0);
87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8718ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  // Initialize LiveEdit.
8728ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  LiveEdit::InitializeThreadLocal(this);
873bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund
874bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  // Just continue if breaks are disabled or debugger cannot be loaded.
8758d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (break_disabled_) return;
87643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // Enter the debugger.
878196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  DebugScope debug_scope(this);
879196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (debug_scope.failed()) return;
88043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88144510671e908d0efc639513d81efcd81e7f14240kasper.lund  // Postpone interrupt during breakpoint processing.
882c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  PostponeInterruptsScope postpone(isolate_);
88343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the debug info (create it if it does not exist).
88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<SharedFunctionInfo> shared =
886169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      Handle<SharedFunctionInfo>(frame->function()->shared());
88743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the break point where execution has stopped.
89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  BreakLocationIterator break_location_iterator(debug_info,
89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                                ALL_BREAK_LOCATIONS);
8928a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  // pc points to the instruction after the current one, possibly a break
8938a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  // location as well. So the "- 1" to exclude it from the search.
8948a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
89543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check whether step next reached a new statement.
897c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (!StepNextContinue(&break_location_iterator, frame)) {
89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Decrease steps left if performing multiple steps.
899c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    if (thread_local_.step_count_ > 0) {
900c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      thread_local_.step_count_--;
90143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
90243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
90343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there is one or more real break points check whether any of these are
90543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // triggered.
90609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
90743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_location_iterator.HasBreakPoint()) {
90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> break_point_objects =
90909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_);
910c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    break_points_hit = CheckBreakPoints(break_point_objects);
91143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
913a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // If step out is active skip everything until the frame where we need to step
914a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // out to is reached, unless real breakpoint is hit.
9158d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (StepOutActive() &&
9168d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      frame->fp() != thread_local_.step_out_fp_ &&
917a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      break_points_hit->IsUndefined() ) {
918a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // Step count should always be 0 for StepOut.
919e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(thread_local_.step_count_ == 0);
920a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  } else if (!break_points_hit->IsUndefined() ||
921c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org             (thread_local_.last_step_action_ != StepNone &&
922c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org              thread_local_.step_count_ == 0)) {
923a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // Notify debugger if a real break point is triggered or if performing
924a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // single stepping with no more steps to perform. Otherwise do another step.
925a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Clear all current stepping setup.
927c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    ClearStepping();
92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    if (thread_local_.queued_step_count_ > 0) {
93034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      // Perform queued steps
93134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      int step_count = thread_local_.queued_step_count_;
93234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
93334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      // Clear queue
93434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      thread_local_.queued_step_count_ = 0;
93534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
936639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org      PrepareStep(StepNext, step_count, StackFrame::NO_ID);
93734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    } else {
93834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      // Notify the debug event listeners.
939d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      OnDebugBreak(break_points_hit, false);
94034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    }
941c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  } else if (thread_local_.last_step_action_ != StepNone) {
94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Hold on to last step action as it is cleared by the call to
94343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // ClearStepping.
944c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    StepAction step_action = thread_local_.last_step_action_;
945c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    int step_count = thread_local_.step_count_;
94643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    // If StepNext goes deeper in code, StepOut until original frame
94834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    // and keep step count queued up in the meantime.
94934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
95034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      // Count frames until target frame
95134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      int count = 0;
95234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      JavaScriptFrameIterator it(isolate_);
953212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) {
95434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org        count++;
95534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org        it.Advance();
95634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      }
95734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
95881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      // Check that we indeed found the frame we are looking for.
95981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_));
96081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      if (step_count > 1) {
96181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org        // Save old count and action to continue stepping after StepOut.
96281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org        thread_local_.queued_step_count_ = step_count - 1;
963212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      }
964212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
96581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      // Set up for StepOut to reach target frame.
96681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      step_action = StepOut;
96781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      step_count = count;
96834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    }
96934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Clear all current stepping setup.
971c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    ClearStepping();
97243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Set up for the remaining steps.
974639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    PrepareStep(step_action, step_count, StackFrame::NO_ID);
97543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
97643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
97743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
979a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Debug_Break) {
980e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // Get the top-most JavaScript frame.
981e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  JavaScriptFrameIterator it(isolate);
982e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  isolate->debug()->Break(args, it.frame());
983e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  isolate->debug()->SetAfterBreakTarget(it.frame());
984e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  return isolate->heap()->undefined_value();
985c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
986c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
987c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check the break point objects for whether one or more are actually
98943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// triggered. This function returns a JSArray with the break point objects
99043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// which is triggered.
99143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
9927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Factory* factory = isolate_->factory();
9937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
9944d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Count the number of break points hit. If there are multiple break points
9954d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // they are in a FixedArray.
9964d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  Handle<FixedArray> break_points_hit;
99743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int break_points_hit_count = 0;
998e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!break_point_objects->IsUndefined());
99943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_objects->IsFixedArray()) {
100043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
10017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    break_points_hit = factory->NewFixedArray(array->length());
100243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = 0; i < array->length(); i++) {
100309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      Handle<Object> o(array->get(i), isolate_);
100443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (CheckBreakPoint(o)) {
10054d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        break_points_hit->set(break_points_hit_count++, *o);
100643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
100743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
100843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
10097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    break_points_hit = factory->NewFixedArray(1);
101043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (CheckBreakPoint(break_point_objects)) {
10114d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      break_points_hit->set(break_points_hit_count++, *break_point_objects);
101243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
101343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
101443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1015d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Return undefined if no break points were triggered.
101643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_points_hit_count == 0) {
10177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    return factory->undefined_value();
101843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
10194d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Return break points hit as a JSArray.
10207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
10214d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  result->set_length(Smi::FromInt(break_points_hit_count));
10224d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  return result;
102343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
102443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
102543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
102643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether a single break point object is triggered.
102743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
10287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Factory* factory = isolate_->factory();
10297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
1030381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
103143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Ignore check if break point object is not a JSObject.
103243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!break_point_object->IsJSObject()) return true;
103343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10344d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Get the function IsBreakPointTriggered (defined in debug-debugger.js).
10354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> is_break_point_triggered_string =
10364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      factory->InternalizeOneByteString(
10372c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org          STATIC_CHAR_VECTOR("IsBreakPointTriggered"));
10385b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<GlobalObject> debug_global(debug_context()->global_object());
103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<JSFunction> check_break_point =
10402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<JSFunction>::cast(Object::GetProperty(
10412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        debug_global, is_break_point_triggered_string).ToHandleChecked());
104243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the break id as an object.
10447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Call HandleBreakPointx.
1047a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> argv[] = { break_id, break_point_object };
10482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
1049e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (!Execution::TryCall(check_break_point,
1050e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                          isolate_->js_builtins_object(),
1051fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                          arraysize(argv),
1052e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                          argv).ToHandle(&result)) {
1053e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return false;
1054e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return whether the break point is triggered.
10572ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return result->IsTrue();
105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether the function has debug information.
106243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::HasDebugInfo(Handle<SharedFunctionInfo> shared) {
106343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return !shared->debug_info()->IsUndefined();
106443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1067bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// Return the debug info for this function. EnsureDebugInfo must be called
1068bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// prior to ensure the debug info has been generated for shared.
106943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) {
1070e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(HasDebugInfo(shared));
107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info()));
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1075a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.orgbool Debug::SetBreakPoint(Handle<JSFunction> function,
10765ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org                          Handle<Object> break_point_object,
10775ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org                          int* source_position) {
10787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
1079381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
108034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  PrepareForBreakPoints();
108134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
10825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Make sure the function is compiled and has set up the debug info.
10835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
10845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!EnsureDebugInfo(shared, function)) {
1085bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund    // Return if retrieving debug info failed.
1086a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    return true;
108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1089bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Source positions starts with zero.
1091e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(*source_position >= 0);
109243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the break point and change it.
109443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
109593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED);
109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  it.SetBreakPoint(break_point_object);
109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10985ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  *source_position = it.position();
10995ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
110043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // At least one active break point now.
1101a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  return debug_info->GetBreakPointCount() > 0;
110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
110343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgbool Debug::SetBreakPointForScript(Handle<Script> script,
11065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                   Handle<Object> break_point_object,
110793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org                                   int* source_position,
110893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org                                   BreakPositionAlignment alignment) {
11095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HandleScope scope(isolate_);
11105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
111178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  PrepareForBreakPoints();
111278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
111378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // Obtain shared function info for the function.
111478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  Object* result = FindSharedFunctionInfoInScript(script, *source_position);
11155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (result->IsUndefined()) return false;
11165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
11175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Make sure the function has set up the debug info.
11185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result));
11195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
11205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    // Return if retrieving debug info failed.
11215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return false;
11225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
11235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
11245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Find position within function. The script position might be before the
11255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // source position of the first function.
11265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  int position;
11275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (shared->start_position() > *source_position) {
11285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    position = 0;
11295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  } else {
11305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    position = *source_position - shared->start_position();
11315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
11325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
11335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
11345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Source positions starts with zero.
1135e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(position >= 0);
11365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
11375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Find the break point and change it.
11385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
113993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  it.FindBreakLocationFromPosition(position, alignment);
11405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  it.SetBreakPoint(break_point_object);
11415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
11425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  *source_position = it.position() + shared->start_position();
11435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
11445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // At least one active break point now.
1145e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(debug_info->GetBreakPointCount() > 0);
11465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return true;
11475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
11485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
11495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
115043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearBreakPoint(Handle<Object> break_point_object) {
11517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
1152381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
115343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DebugInfoListNode* node = debug_info_list_;
115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (node != NULL) {
115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),
115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                                   break_point_object);
115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!result->IsUndefined()) {
115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Get information in the break point.
115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      BreakPointInfo* break_point_info = BreakPointInfo::cast(result);
116043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<DebugInfo> debug_info = node->debug_info();
116143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
116243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Find the break point and clear it.
116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
11648a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org      it.FindBreakLocationFromAddress(debug_info->code()->entry() +
11658a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org          break_point_info->code_position()->value());
116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      it.ClearBreakPoint(break_point_object);
116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // If there are no more break points left remove the debug info for this
116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // function.
117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (debug_info->GetBreakPointCount() == 0) {
117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        RemoveDebugInfo(debug_info);
117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    node = node->next();
117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1181381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgvoid Debug::ClearAllBreakPoints() {
1182381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  DebugInfoListNode* node = debug_info_list_;
1183381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  while (node != NULL) {
1184381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    // Remove all debug break code.
1185381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1186381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    it.ClearAllDebugBreak();
1187381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    node = node->next();
1188381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  }
1189381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
1190381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  // Remove all debug info.
1191381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  while (debug_info_list_ != NULL) {
1192381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    RemoveDebugInfo(debug_info_list_->debug_info());
1193381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  }
1194381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org}
1195381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
1196381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
11975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgvoid Debug::FloodWithOneShot(Handle<JSFunction> function) {
119834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  PrepareForBreakPoints();
11995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
12005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Make sure the function is compiled and has set up the debug info.
12015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
12025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!EnsureDebugInfo(shared, function)) {
1203bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund    // Return if we failed to retrieve the debug info.
1204bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund    return;
1205bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  }
120643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Flood the function with break points.
1208bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS);
120943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!it.Done()) {
121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    it.SetOneShot();
121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    it.Next();
121243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12162c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) {
12172c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  Handle<FixedArray> new_bindings(function->function_bindings());
121809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex),
121909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                        isolate_);
12202c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
12212c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  if (!bindee.is_null() && bindee->IsJSFunction() &&
1222d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      !JSFunction::cast(*bindee)->IsFromNativeScript()) {
12235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
12245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    Debug::FloodWithOneShot(bindee_function);
12252c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  }
12262c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org}
12272c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
12282c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
122943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::FloodHandlerWithOneShot() {
12308bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // Iterate through the JavaScript stack looking for handlers.
12317be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  StackFrame::Id id = break_frame_id();
12328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  if (id == StackFrame::NO_ID) {
12338bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    // If there is no JavaScript stack don't do anything.
12348bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    return;
12358bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
123674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
123743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    JavaScriptFrame* frame = it.frame();
123843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (frame->HasHandler()) {
123943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Flood the function with the catch block with break points
1240169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      FloodWithOneShot(Handle<JSFunction>(frame->function()));
124143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
124243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (type == BreakUncaughtException) {
124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    break_on_uncaught_exception_ = enable;
125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
125143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    break_on_exception_ = enable;
125243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
125343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
125443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
125543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1256c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgbool Debug::IsBreakOnException(ExceptionBreakType type) {
1257c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  if (type == BreakUncaughtException) {
1258c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org    return break_on_uncaught_exception_;
1259c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  } else {
1260c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org    return break_on_exception_;
1261c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  }
1262c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org}
1263c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
1264c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
12659d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgbool Debug::PromiseHasRejectHandler(Handle<JSObject> promise) {
12669d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Handle<JSFunction> fun = Handle<JSFunction>::cast(
12679d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      JSObject::GetDataProperty(isolate_->js_builtins_object(),
12682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                isolate_->factory()->NewStringFromStaticChars(
12699d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                                    "PromiseHasRejectHandler")));
12709d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Handle<Object> result =
12719d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      Execution::Call(isolate_, fun, promise, 0, NULL).ToHandleChecked();
12729d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  return result->IsTrue();
12739d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
12749d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
12759d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1276639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgvoid Debug::PrepareStep(StepAction step_action,
1277639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                        int step_count,
1278639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                        StackFrame::Id frame_id) {
12797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
128034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
128134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  PrepareForBreakPoints();
128234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
1283e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(in_debug_scope());
128443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Remember this step action and count.
128643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.last_step_action_ = step_action;
1287a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  if (step_action == StepOut) {
1288a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // For step out target frame will be found on the stack so there is no need
1289a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // to set step counter for it. It's expected to always be 0 for StepOut.
1290a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    thread_local_.step_count_ = 0;
1291a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  } else {
1292a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    thread_local_.step_count_ = step_count;
1293a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  }
129443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the frame where the execution has stopped and skip the debug frame if
129643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // any. The debug frame will only be present if execution was stopped due to
129743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // hitting a break point. In other situations (e.g. unhandled exception) the
129843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // debug frame is not present.
12997be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  StackFrame::Id id = break_frame_id();
13008bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  if (id == StackFrame::NO_ID) {
13018bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    // If there is no JavaScript stack don't do anything.
13028bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    return;
13038bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
1304639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (frame_id != StackFrame::NO_ID) {
1305639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    id = frame_id;
1306639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
130774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator frames_it(isolate_, id);
130843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JavaScriptFrame* frame = frames_it.frame();
130943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // First of all ensure there is one-shot break points in the top handler
131143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // if any.
131243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FloodHandlerWithOneShot();
131343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the function on the top frame is unresolved perform step out. This will
131543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // be the case when calling unknown functions and having the debugger stopped
131643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // in an unhandled exception.
131743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!frame->function()->IsJSFunction()) {
131843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Step out: Find the calling JavaScript frame and flood it with
131943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // breakpoints.
132043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    frames_it.Advance();
132143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Fill the function to return to with one-shot break points.
1322169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    JSFunction* function = frames_it.frame()->function();
13235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    FloodWithOneShot(Handle<JSFunction>(function));
132443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
132643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the debug info (create it if it does not exist).
1328169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Handle<JSFunction> function(frame->function());
13295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
13305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!EnsureDebugInfo(shared, function)) {
1331bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund    // Return if ensuring debug info failed.
1332bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund    return;
1333bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  }
133443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the break location where execution has stopped.
133743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  BreakLocationIterator it(debug_info, ALL_BREAK_LOCATIONS);
13388a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  // pc points to the instruction after the current one, possibly a break
13398a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  // location as well. So the "- 1" to exclude it from the search.
13408a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  it.FindBreakLocationFromAddress(frame->pc() - 1);
134143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute whether or not the target is a call target.
1343e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  bool is_load_or_store = false;
1344e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  bool is_inline_cache_stub = false;
1345e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  bool is_at_restarted_function = false;
1346a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  Handle<Code> call_function_stub;
1347a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
1348e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  if (thread_local_.restarter_frame_function_pointer_ == NULL) {
1349e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org    if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
1350e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      bool is_call_target = false;
1351e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      Address target = it.rinfo()->target_address();
1352e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      Code* code = Code::GetCodeFromTargetAddress(target);
1353a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (code->is_call_stub()) {
1354a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        is_call_target = true;
1355a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      }
1356e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      if (code->is_inline_cache_stub()) {
1357e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org        is_inline_cache_stub = true;
1358e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org        is_load_or_store = !is_call_target;
1359e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      }
1360e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
1361e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      // Check if target code is CallFunction stub.
1362e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      Code* maybe_call_function_stub = code;
1363e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      // If there is a breakpoint at this line look at the original code to
1364e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      // check if it is a CallFunction stub.
1365e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      if (it.IsDebugBreak()) {
1366e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org        Address original_target = it.original_rinfo()->target_address();
1367e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org        maybe_call_function_stub =
1368e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org            Code::GetCodeFromTargetAddress(original_target);
1369e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      }
1370a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if ((maybe_call_function_stub->kind() == Code::STUB &&
13719d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org           CodeStub::GetMajorKey(maybe_call_function_stub) ==
13729d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org               CodeStub::CallFunction) ||
1373a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org          maybe_call_function_stub->kind() == Code::CALL_IC) {
1374e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org        // Save reference to the code as we may need it to find out arguments
1375e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org        // count for 'step in' later.
1376e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org        call_function_stub = Handle<Code>(maybe_call_function_stub);
1377e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      }
1378a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    }
1379e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  } else {
1380e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org    is_at_restarted_function = true;
138143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1383727e995b7bba3c57fb1e5c156d386ca11894f781v  // If this is the last break code target step out is the only possibility.
138443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (it.IsExit() || step_action == StepOut) {
1385a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    if (step_action == StepOut) {
1386a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // Skip step_count frames starting with the current one.
1387a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      while (step_count-- > 0 && !frames_it.done()) {
1388a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org        frames_it.Advance();
1389a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      }
1390a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    } else {
1391e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(it.IsExit());
1392a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      frames_it.Advance();
1393a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    }
1394a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // Skip builtin functions on the stack.
1395d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    while (!frames_it.done() &&
1396d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org           frames_it.frame()->function()->IsFromNativeScript()) {
1397a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      frames_it.Advance();
1398a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    }
139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Step out: If there is a JavaScript caller frame, we need to
140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // flood it with breakpoints.
140143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!frames_it.done()) {
140243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Fill the function to return to with one-shot break points.
1403169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      JSFunction* function = frames_it.frame()->function();
14045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      FloodWithOneShot(Handle<JSFunction>(function));
1405a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // Set target frame pointer.
1406a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      ActivateStepOut(frames_it.frame());
140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1408a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
1409e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org               !call_function_stub.is_null() || is_at_restarted_function)
1410e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org             || step_action == StepNext || step_action == StepMin) {
141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Step next or step min.
141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Fill the current function with one-shot break points.
14145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    FloodWithOneShot(function);
141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Remember source position and frame to handle step next.
141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    thread_local_.last_statement_position_ =
141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        debug_info->code()->SourceStatementPosition(frame->pc());
14197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    thread_local_.last_fp_ = frame->UnpaddedFP();
142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
1421e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org    // If there's restarter frame on top of the stack, just get the pointer
1422e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org    // to function which is going to be restarted.
1423e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org    if (is_at_restarted_function) {
1424e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      Handle<JSFunction> restarted_function(
1425e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org          JSFunction::cast(*thread_local_.restarter_frame_function_pointer_));
14265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      FloodWithOneShot(restarted_function);
1427e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org    } else if (!call_function_stub.is_null()) {
1428e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      // If it's CallFunction stub ensure target function is compiled and flood
1429e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      // it with one shot breakpoints.
1430a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      bool is_call_ic = call_function_stub->kind() == Code::CALL_IC;
1431e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
1432a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // Find out number of arguments from the stub minor key.
14337c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org      uint32_t key = call_function_stub->stub_key();
1434a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // Argc in the stub is the number of arguments passed - not the
1435a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // expected arguments of the called function.
1436a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      int call_function_arg_count = is_call_ic
1437a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org          ? CallICStub::ExtractArgcFromMinorKey(CodeStub::MinorKeyFromKey(key))
1438a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org          : CallFunctionStub::ExtractArgcFromMinorKey(
1439b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org              CodeStub::MinorKeyFromKey(key));
1440a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
1441e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(is_call_ic ||
14429d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org             CodeStub::GetMajorKey(*call_function_stub) ==
14439d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                 CodeStub::MajorKeyFromKey(key));
1444a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
1445a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // Find target function on the expression stack.
1446b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      // Expression stack looks like this (top to bottom):
1447a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // argN
1448a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // ...
1449a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // arg0
1450a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // Receiver
1451a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      // Function to call
1452a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      int expressions_count = frame->ComputeExpressionsCount();
1453e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(expressions_count - 2 - call_function_arg_count >= 0);
1454a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      Object* fun = frame->GetExpression(
1455a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org          expressions_count - 2 - call_function_arg_count);
1456a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
1457a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      // Flood the actual target of call/apply.
1458a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (fun->IsJSFunction()) {
1459a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Isolate* isolate = JSFunction::cast(fun)->GetIsolate();
1460a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply);
1461a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall);
1462a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        while (fun->IsJSFunction()) {
1463a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          Code* code = JSFunction::cast(fun)->shared()->code();
1464a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          if (code != apply && code != call) break;
1465a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          fun = frame->GetExpression(
1466a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org              expressions_count - 1 - call_function_arg_count);
1467a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        }
1468a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      }
1469a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
1470a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      if (fun->IsJSFunction()) {
1471a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org        Handle<JSFunction> js_function(JSFunction::cast(fun));
14722c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org        if (js_function->shared()->bound()) {
14732c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          Debug::FloodBoundFunctionWithOneShot(js_function);
1474d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        } else if (!js_function->IsFromNativeScript()) {
14752c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org          // Don't step into builtins.
1476a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org          // It will also compile target function if it's not compiled yet.
14775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          FloodWithOneShot(js_function);
1478a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org        }
1479a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      }
1480a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    }
1481a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Fill the current function with one-shot break points even for step in on
148343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // a call target as the function called might be a native function for
1484e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    // which step in will not stop. It also prepares for stepping in
1485e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    // getters/setters.
14865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    FloodWithOneShot(function);
148743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1488e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    if (is_load_or_store) {
1489e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org      // Remember source position and frame to handle step in getter/setter. If
1490e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org      // there is a custom getter/setter it will be handled in
1491474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      // Object::Get/SetPropertyWithAccessor, otherwise the step action will be
1492e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org      // propagated on the next Debug::Break.
1493e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org      thread_local_.last_statement_position_ =
1494e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org          debug_info->code()->SourceStatementPosition(frame->pc());
14957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      thread_local_.last_fp_ = frame->UnpaddedFP();
1496e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    }
1497e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
149843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Step in or Step in min
1499c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    it.PrepareStepIn(isolate_);
150043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ActivateStepIn(frame);
150143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
150243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
150443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
150543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether the current debug break should be reported to the debugger. It
150643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// is used to have step next and step in only report break back to the debugger
150743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// if on a different frame or in a different statement. In some situations
150843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// there will be several break points in the same statement when the code is
1509727e995b7bba3c57fb1e5c156d386ca11894f781v// flooded with one-shot break points. This function helps to perform several
151043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// steps before reporting break back to the debugger.
151143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
151243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             JavaScriptFrame* frame) {
151334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // StepNext and StepOut shouldn't bring us deeper in code, so last frame
151434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // shouldn't be a parent of current frame.
151534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (thread_local_.last_step_action_ == StepNext ||
151634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      thread_local_.last_step_action_ == StepOut) {
151734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    if (frame->fp() < thread_local_.last_fp_) return true;
151834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
151934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
152043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the step last action was step next or step in make sure that a new
152143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // statement is hit.
152243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (thread_local_.last_step_action_ == StepNext ||
152343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      thread_local_.last_step_action_ == StepIn) {
152443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Never continue if returning from function.
152543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (break_location_iterator->IsExit()) return false;
152643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
152743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Continue if we are still on the same frame and in the same statement.
152843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int current_statement_position =
152943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break_location_iterator->code()->SourceStatementPosition(frame->pc());
15307028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    return thread_local_.last_fp_ == frame->UnpaddedFP() &&
1531236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org        thread_local_.last_statement_position_ == current_statement_position;
153243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
153343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No step next action - don't continue.
153543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
153643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
153743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether the code object at the specified address is a debug break code
154043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object.
154143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::IsDebugBreak(Address addr) {
15428bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  Code* code = Code::GetCodeFromTargetAddress(addr);
1543ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK;
154443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
154543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
154643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1547ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
154843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
154943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
155043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Simple function for returning the source positions for active break points.
155143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Debug::GetSourceBreakLocations(
155293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    Handle<SharedFunctionInfo> shared,
155393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    BreakPositionAlignment position_alignment) {
1554e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  Isolate* isolate = shared->GetIsolate();
15557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Heap* heap = isolate->heap();
155609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (!HasDebugInfo(shared)) {
155709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    return Handle<Object>(heap->undefined_value(), isolate);
155809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  }
155943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
156043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (debug_info->GetBreakPointCount() == 0) {
156109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    return Handle<Object>(heap->undefined_value(), isolate);
156243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
156343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<FixedArray> locations =
15647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
156543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count = 0;
156643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < debug_info->break_points()->length(); i++) {
156743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!debug_info->break_points()->get(i)->IsUndefined()) {
156843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      BreakPointInfo* break_point_info =
156943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          BreakPointInfo::cast(debug_info->break_points()->get(i));
157043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (break_point_info->GetBreakPointCount() > 0) {
157193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org        Smi* position;
157293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org        switch (position_alignment) {
157393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org        case STATEMENT_ALIGNED:
157493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org          position = break_point_info->statement_position();
157593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org          break;
157693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org        case BREAK_POSITION_ALIGNED:
157793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org          position = break_point_info->source_position();
157893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org          break;
157993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org        default:
158093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org          UNREACHABLE();
158193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org          position = break_point_info->statement_position();
158293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org        }
158393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
158493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org        locations->set(count++, position);
158543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return locations;
158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
159237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// Handle stepping into a function.
159337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.comvoid Debug::HandleStepIn(Handle<JSFunction> function,
1594defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org                         Handle<Object> holder,
159537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                         Address fp,
159637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                         bool is_constructor) {
1597c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  Isolate* isolate = function->GetIsolate();
159837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  // If the frame pointer is not supplied by the caller find it.
159937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  if (fp == 0) {
1600c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    StackFrameIterator it(isolate);
160137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    it.Advance();
160237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    // For constructor functions skip another frame.
160337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    if (is_constructor) {
1604e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(it.frame()->is_construct());
160537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      it.Advance();
160637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    }
160737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    fp = it.frame()->fp();
160837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  }
160937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
161037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  // Flood the function with one-shot break points if it is called from where
161137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  // step into was requested.
16128d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (fp == thread_local_.step_into_fp_) {
16132c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    if (function->shared()->bound()) {
16142c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      // Handle Function.prototype.bind
16152c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      Debug::FloodBoundFunctionWithOneShot(function);
1616d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    } else if (!function->IsFromNativeScript()) {
16172c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      // Don't allow step into functions in the native context.
1618acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org      if (function->shared()->code() ==
1619c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org          isolate->builtins()->builtin(Builtins::kFunctionApply) ||
1620acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org          function->shared()->code() ==
1621c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org          isolate->builtins()->builtin(Builtins::kFunctionCall)) {
1622acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org        // Handle function.apply and function.call separately to flood the
1623acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org        // function to be called and not the code for Builtins::FunctionApply or
1624defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org        // Builtins::FunctionCall. The receiver of call/apply is the target
1625defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org        // function.
1626528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        if (!holder.is_null() && holder->IsJSFunction()) {
16275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
1628d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org          if (!js_function->IsFromNativeScript()) {
1629528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org            Debug::FloodWithOneShot(js_function);
1630528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          } else if (js_function->shared()->bound()) {
1631528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org            // Handle Function.prototype.bind
1632528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org            Debug::FloodBoundFunctionWithOneShot(js_function);
1633528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          }
1634acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org        }
1635acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org      } else {
16365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        Debug::FloodWithOneShot(function);
1637acae37894ae73146c7a4788ca8af931d446bd2cakasperl@chromium.org      }
163837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    }
163937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  }
164037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
164137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
164237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
164343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearStepping() {
164443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear the various stepping setup.
164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ClearOneShot();
164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ClearStepIn();
1647a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  ClearStepOut();
164843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ClearStepNext();
164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear multiple step counter.
165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.step_count_ = 0;
165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1654e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Clears all the one-shot break points that are currently set. Normally this
165643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// function is called each time a break point is hit as one shot break points
165743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// are used to support stepping.
165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearOneShot() {
165943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The current implementation just runs through all the breakpoints. When the
1660727e995b7bba3c57fb1e5c156d386ca11894f781v  // last break point for a function is removed that function is automatically
166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // removed from the list.
166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
166343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DebugInfoListNode* node = debug_info_list_;
166443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (node != NULL) {
166543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
166643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (!it.Done()) {
166743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      it.ClearOneShot();
166843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      it.Next();
166943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
167043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    node = node->next();
167143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
167243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
167343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
167443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
167543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ActivateStepIn(StackFrame* frame) {
1676e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!StepOutActive());
16777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  thread_local_.step_into_fp_ = frame->UnpaddedFP();
167843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
167943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
168043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
168143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearStepIn() {
168243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.step_into_fp_ = 0;
168343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
168443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
168543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1686a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid Debug::ActivateStepOut(StackFrame* frame) {
1687e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!StepInActive());
16887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  thread_local_.step_out_fp_ = frame->UnpaddedFP();
1689a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org}
1690a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
1691a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
1692a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid Debug::ClearStepOut() {
1693a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  thread_local_.step_out_fp_ = 0;
1694a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org}
1695a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
1696a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
169743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::ClearStepNext() {
169843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.last_step_action_ = StepNone;
1699236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
170043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_.last_fp_ = 0;
170143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
170343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1704659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgstatic void CollectActiveFunctionsFromThread(
1705659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Isolate* isolate,
1706659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    ThreadLocalTop* top,
1707659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    List<Handle<JSFunction> >* active_functions,
1708659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Object* active_code_marker) {
1709659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // Find all non-optimized code functions with activation frames
1710659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // on the stack. This includes functions which have optimized
1711659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // activations (including inlined functions) on the stack as the
1712659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // non-optimized code is needed for the lazy deoptimization.
1713659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1714659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    JavaScriptFrame* frame = it.frame();
1715659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (frame->is_optimized()) {
1716ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      List<JSFunction*> functions(FLAG_max_inlining_levels + 1);
1717659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      frame->GetFunctions(&functions);
1718659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      for (int i = 0; i < functions.length(); i++) {
1719659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        JSFunction* function = functions[i];
1720659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        active_functions->Add(Handle<JSFunction>(function));
1721659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        function->shared()->code()->set_gc_metadata(active_code_marker);
1722659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      }
1723659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    } else if (frame->function()->IsJSFunction()) {
1724169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      JSFunction* function = frame->function();
1725e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(frame->LookupCode()->kind() == Code::FUNCTION);
1726659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      active_functions->Add(Handle<JSFunction>(function));
1727659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      function->shared()->code()->set_gc_metadata(active_code_marker);
1728659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
1729659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
1730659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
1731659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1732659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1733af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org// Figure out how many bytes of "pc_offset" correspond to actual code by
1734af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org// subtracting off the bytes that correspond to constant/veneer pools.  See
1735af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org// Assembler::CheckConstPool() and Assembler::CheckVeneerPool(). Note that this
1736af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org// is only useful for architectures using constant pools or veneer pools.
1737af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.orgstatic int ComputeCodeOffsetFromPcOffset(Code *code, int pc_offset) {
1738e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(code->kind(), Code::FUNCTION);
1739e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!code->has_debug_break_slots());
1740e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LE(0, pc_offset);
1741e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LT(pc_offset, code->instruction_end() - code->instruction_start());
1742af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1743af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
1744af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org             RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
1745af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  byte *pc = code->instruction_start() + pc_offset;
1746af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  int code_offset = pc_offset;
1747af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  for (RelocIterator it(code, mask); !it.done(); it.next()) {
1748af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    RelocInfo* info = it.rinfo();
1749af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    if (info->pc() >= pc) break;
1750e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(RelocInfo::IsConstPool(info->rmode()));
1751af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    code_offset -= static_cast<int>(info->data());
1752e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_LE(0, code_offset);
1753af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  }
1754af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1755af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  return code_offset;
1756af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org}
1757af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1758af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1759af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org// The inverse of ComputeCodeOffsetFromPcOffset.
1760af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.orgstatic int ComputePcOffsetFromCodeOffset(Code *code, int code_offset) {
1761e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(code->kind(), Code::FUNCTION);
1762af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1763af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
1764af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org             RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
1765af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org             RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
1766af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  int reloc = 0;
1767af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  for (RelocIterator it(code, mask); !it.done(); it.next()) {
1768af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    RelocInfo* info = it.rinfo();
1769af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    if (info->pc() - code->instruction_start() - reloc >= code_offset) break;
1770af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    if (RelocInfo::IsDebugBreakSlot(info->rmode())) {
1771af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      reloc += Assembler::kDebugBreakSlotLength;
1772af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    } else {
1773e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(RelocInfo::IsConstPool(info->rmode()));
1774af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      reloc += static_cast<int>(info->data());
1775af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    }
1776af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  }
1777af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1778af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  int pc_offset = code_offset + reloc;
1779af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1780e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_LT(code->instruction_start() + pc_offset, code->instruction_end());
1781af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1782af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  return pc_offset;
1783af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org}
1784af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1785af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1786659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgstatic void RedirectActivationsToRecompiledCodeOnThread(
1787659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Isolate* isolate,
1788659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    ThreadLocalTop* top) {
1789659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1790659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    JavaScriptFrame* frame = it.frame();
1791659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1792659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (frame->is_optimized() || !frame->function()->IsJSFunction()) continue;
1793659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1794169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    JSFunction* function = frame->function();
1795659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1796e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(frame->LookupCode()->kind() == Code::FUNCTION);
1797659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1798659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Handle<Code> frame_code(frame->LookupCode());
1799659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (frame_code->has_debug_break_slots()) continue;
1800659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1801659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Handle<Code> new_code(function->shared()->code());
1802659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (new_code->kind() != Code::FUNCTION ||
1803659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        !new_code->has_debug_break_slots()) {
1804659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      continue;
1805659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
1806659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1807af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    int old_pc_offset =
1808af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org        static_cast<int>(frame->pc() - frame_code->instruction_start());
1809af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    int code_offset = ComputeCodeOffsetFromPcOffset(*frame_code, old_pc_offset);
1810af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    int new_pc_offset = ComputePcOffsetFromCodeOffset(*new_code, code_offset);
18115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
18125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    // Compute the equivalent pc in the new code.
1813af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    byte* new_pc = new_code->instruction_start() + new_pc_offset;
18145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
1815659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (FLAG_trace_deopt) {
1816659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      PrintF("Replacing code %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
1817659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             "with %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
1818659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             "for debugging, "
1819659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             "changing pc from %08" V8PRIxPTR " to %08" V8PRIxPTR "\n",
1820659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             reinterpret_cast<intptr_t>(
1821659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                 frame_code->instruction_start()),
1822659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             reinterpret_cast<intptr_t>(
1823659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                 frame_code->instruction_start()) +
1824659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             frame_code->instruction_size(),
1825659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             frame_code->instruction_size(),
1826659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             reinterpret_cast<intptr_t>(new_code->instruction_start()),
1827659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             reinterpret_cast<intptr_t>(new_code->instruction_start()) +
1828659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             new_code->instruction_size(),
1829659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             new_code->instruction_size(),
1830659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org             reinterpret_cast<intptr_t>(frame->pc()),
18315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org             reinterpret_cast<intptr_t>(new_pc));
1832659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
1833659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1834d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org    if (FLAG_enable_ool_constant_pool) {
1835d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org      // Update constant pool pointer for new code.
1836d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org      frame->set_constant_pool(new_code->constant_pool());
1837d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org    }
1838d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org
1839659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // Patch the return address to return into the code with
1840659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // debug break slots.
18415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    frame->set_pc(new_pc);
1842659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
1843659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
1844659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1845659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1846659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass ActiveFunctionsCollector : public ThreadVisitor {
1847659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org public:
1848659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  explicit ActiveFunctionsCollector(List<Handle<JSFunction> >* active_functions,
1849659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                    Object* active_code_marker)
1850659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      : active_functions_(active_functions),
1851659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        active_code_marker_(active_code_marker) { }
1852659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1853659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1854659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    CollectActiveFunctionsFromThread(isolate,
1855659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                     top,
1856659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                     active_functions_,
1857659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                     active_code_marker_);
1858659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
1859659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1860659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org private:
1861659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  List<Handle<JSFunction> >* active_functions_;
1862659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Object* active_code_marker_;
1863659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org};
1864659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1865659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1866659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass ActiveFunctionsRedirector : public ThreadVisitor {
1867659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org public:
1868659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1869659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    RedirectActivationsToRecompiledCodeOnThread(isolate, top);
1870659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
1871659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org};
1872659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1873659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
18748d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgstatic void EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) {
1875a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  if (function->code()->kind() == Code::FUNCTION &&
1876a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org      function->code()->has_debug_break_slots()) {
1877a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    // Nothing to do. Function code already had debug break slots.
1878a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    return;
1879a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  }
1880a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  // Make sure that the shared full code is compiled with debug
1881a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  // break slots.
1882a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  if (!function->shared()->code()->has_debug_break_slots()) {
1883a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    MaybeHandle<Code> code = Compiler::GetDebugCode(function);
1884a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    // Recompilation can fail.  In that case leave the code as it was.
18853c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    if (!code.is_null()) function->ReplaceCode(*code.ToHandleChecked());
18863c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  } else {
18873c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    // Simply use shared code if it has debug break slots.
18883c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    function->ReplaceCode(function->shared()->code());
1889a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  }
1890af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org}
1891af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1892af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
18938d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgstatic void RecompileAndRelocateSuspendedGenerators(
1894af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    const List<Handle<JSGeneratorObject> > &generators) {
1895af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  for (int i = 0; i < generators.length(); i++) {
1896af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    Handle<JSFunction> fun(generators[i]->function());
1897af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1898a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    EnsureFunctionHasDebugBreakSlots(fun);
1899af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1900af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    int code_offset = generators[i]->continuation();
1901af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset);
1902af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    generators[i]->set_continuation(pc_offset);
1903af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  }
1904af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org}
1905af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1906af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
190734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgvoid Debug::PrepareForBreakPoints() {
190834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // If preparing for the first break point make sure to deoptimize all
190934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // functions as debugging does not work with optimized code.
191034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (!has_break_points_) {
19119af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    if (isolate_->concurrent_recompilation_enabled()) {
1912594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate_->optimizing_compiler_thread()->Flush();
1913594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
1914594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1915876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    Deoptimizer::DeoptimizeAll(isolate_);
191634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
1917a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    Handle<Code> lazy_compile = isolate_->builtins()->CompileLazy();
1918394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
19195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    // There will be at least one break point when we are done.
19205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    has_break_points_ = true;
19215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
1922394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Keep the list of activated functions in a handlified list as it
1923394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // is used both in GC and non-GC code.
1924394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    List<Handle<JSFunction> > active_functions(100);
1925394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1926af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // A list of all suspended generators.
1927af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    List<Handle<JSGeneratorObject> > suspended_generators;
1928af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1929af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // A list of all generator functions.  We need to recompile all functions,
1930af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // but we don't know until after visiting the whole heap which generator
1931af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // functions have suspended activations and which do not.  As in the case of
1932af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // functions with activations on the stack, we need to be careful with
1933af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // generator functions with suspended activations because although they
1934af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // should be recompiled, recompilation can fail, and we need to avoid
1935af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // leaving the heap in an inconsistent state.
1936af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    //
1937af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // We could perhaps avoid this list and instead re-use the GC metadata
1938af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // links.
1939af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    List<Handle<JSFunction> > generator_functions;
1940af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
1941394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    {
1942394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // We are going to iterate heap to find all functions without
1943394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // debug break slots.
19447c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      Heap* heap = isolate_->heap();
19457c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
19467c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                              "preparing for breakpoints");
1947fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      HeapIterator iterator(heap);
1948394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1949659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      // Ensure no GC in this scope as we are going to use gc_metadata
1950659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      // field in the Code object to mark active functions.
195179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      DisallowHeapAllocation no_allocation;
1952394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
19537c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      Object* active_code_marker = heap->the_hole_value();
1954ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org
1955659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      CollectActiveFunctionsFromThread(isolate_,
1956659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                       isolate_->thread_local_top(),
1957659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                       &active_functions,
1958659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                       active_code_marker);
1959659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      ActiveFunctionsCollector active_functions_collector(&active_functions,
1960659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                                          active_code_marker);
1961659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      isolate_->thread_manager()->IterateArchivedThreads(
1962659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          &active_functions_collector);
1963394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1964659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      // Scan the heap for all non-optimized functions which have no
1965659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      // debug break slots and are not active or inlined into an active
1966659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      // function and mark them for lazy compilation.
1967394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      HeapObject* obj = NULL;
1968394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      while (((obj = iterator.next()) != NULL)) {
1969394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        if (obj->IsJSFunction()) {
1970394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          JSFunction* function = JSFunction::cast(obj);
1971659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          SharedFunctionInfo* shared = function->shared();
19721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
19731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          if (!shared->allows_lazy_compilation()) continue;
19741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          if (!shared->script()->IsScript()) continue;
1975d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org          if (function->IsFromNativeScript()) continue;
19761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          if (shared->code()->gc_metadata() == active_code_marker) continue;
19771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1978af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          if (shared->is_generator()) {
1979af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org            generator_functions.Add(Handle<JSFunction>(function, isolate_));
1980af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org            continue;
1981af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          }
1982af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
19831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          Code::Kind kind = function->code()->kind();
19841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          if (kind == Code::FUNCTION &&
19851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org              !function->code()->has_debug_break_slots()) {
19863c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org            function->ReplaceCode(*lazy_compile);
19873c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org            function->shared()->ReplaceCode(*lazy_compile);
19881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          } else if (kind == Code::BUILTIN &&
19894954674151afa960af66efb4831df06bde727333yangguo@chromium.org              (function->IsInOptimizationQueue() ||
19904954674151afa960af66efb4831df06bde727333yangguo@chromium.org               function->IsMarkedForOptimization() ||
19914954674151afa960af66efb4831df06bde727333yangguo@chromium.org               function->IsMarkedForConcurrentOptimization())) {
19921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            // Abort in-flight compilation.
19931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            Code* shared_code = function->shared()->code();
19941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            if (shared_code->kind() == Code::FUNCTION &&
19951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                shared_code->has_debug_break_slots()) {
19963c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org              function->ReplaceCode(shared_code);
19971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            } else {
19983c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org              function->ReplaceCode(*lazy_compile);
19993c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org              function->shared()->ReplaceCode(*lazy_compile);
20001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org            }
2001394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          }
2002af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org        } else if (obj->IsJSGeneratorObject()) {
2003af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
2004af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          if (!gen->is_suspended()) continue;
2005af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
2006af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          JSFunction* fun = gen->function();
2007e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK_EQ(fun->code()->kind(), Code::FUNCTION);
2008af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          if (fun->code()->has_debug_break_slots()) continue;
2009af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
2010af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          int pc_offset = gen->continuation();
2011e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK_LT(0, pc_offset);
2012af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
2013af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          int code_offset =
2014af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org              ComputeCodeOffsetFromPcOffset(fun->code(), pc_offset);
2015af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
2016af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          // This will be fixed after we recompile the functions.
2017af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          gen->set_continuation(code_offset);
2018af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
2019af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          suspended_generators.Add(Handle<JSGeneratorObject>(gen, isolate_));
2020394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        }
202134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      }
2022394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
2023659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      // Clear gc_metadata field.
2024659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      for (int i = 0; i < active_functions.length(); i++) {
2025659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        Handle<JSFunction> function = active_functions[i];
2026659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        function->shared()->code()->set_gc_metadata(Smi::FromInt(0));
2027659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      }
2028659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
2029394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
2030af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // Recompile generator functions that have suspended activations, and
2031af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // relocate those activations.
2032af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    RecompileAndRelocateSuspendedGenerators(suspended_generators);
2033af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
2034af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // Mark generator functions that didn't have suspended activations for lazy
2035af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // recompilation.  Note that this set does not include any active functions.
2036af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    for (int i = 0; i < generator_functions.length(); i++) {
2037af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      Handle<JSFunction> &function = generator_functions[i];
2038af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      if (function->code()->kind() != Code::FUNCTION) continue;
2039af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      if (function->code()->has_debug_break_slots()) continue;
20403c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      function->ReplaceCode(*lazy_compile);
20413c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      function->shared()->ReplaceCode(*lazy_compile);
2042af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    }
2043af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
2044394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Now recompile all functions with activation frames and and
2045af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // patch the return address to run in the new compiled code.  It could be
2046af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // that some active functions were recompiled already by the suspended
2047af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // generator recompilation pass above; a generator with suspended
2048af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    // activations could also have active activations.  That's fine.
2049394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    for (int i = 0; i < active_functions.length(); i++) {
2050394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<JSFunction> function = active_functions[i];
20517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Handle<SharedFunctionInfo> shared(function->shared());
2052659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2053394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // If recompilation is not possible just skip it.
2054af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      if (shared->is_toplevel()) continue;
2055af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      if (!shared->allows_lazy_compilation()) continue;
2056af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      if (shared->code()->kind() == Code::BUILTIN) continue;
2057394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
2058a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org      EnsureFunctionHasDebugBreakSlots(function);
205934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    }
2060659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2061659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    RedirectActivationsToRecompiledCodeOnThread(isolate_,
2062659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                                isolate_->thread_local_top());
2063659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2064659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    ActiveFunctionsRedirector active_functions_redirector;
2065659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    isolate_->thread_manager()->IterateArchivedThreads(
2066659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          &active_functions_redirector);
206734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
206834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
206934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
207034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
207178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgObject* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
207278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                              int position) {
207378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // Iterate the heap looking for SharedFunctionInfo generated from the
207478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // script. The inner most SharedFunctionInfo containing the source position
207578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // for the requested break point is found.
207678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // NOTE: This might require several heap iterations. If the SharedFunctionInfo
207778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // which is found is not compiled it is compiled and the heap is iterated
207878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // again as the compilation might create inner functions from the newly
207978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // compiled function and the actual requested break point might be in one of
208078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // these functions.
208178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // NOTE: The below fix-point iteration depends on all functions that cannot be
208278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // compiled lazily without a context to not be compiled at all. Compilation
208378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // will be triggered at points where we do not need a context.
208478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  bool done = false;
208578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  // The current candidate for the source position:
208678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  int target_start_position = RelocInfo::kNoPosition;
208778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  Handle<JSFunction> target_function;
208878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  Handle<SharedFunctionInfo> target;
20897c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Heap* heap = isolate_->heap();
209078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  while (!done) {
2091fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    { // Extra scope for iterator.
20927c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      HeapIterator iterator(heap);
209378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      for (HeapObject* obj = iterator.next();
209478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org           obj != NULL; obj = iterator.next()) {
209578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        bool found_next_candidate = false;
209678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        Handle<JSFunction> function;
209778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        Handle<SharedFunctionInfo> shared;
209878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        if (obj->IsJSFunction()) {
209978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          function = Handle<JSFunction>(JSFunction::cast(obj));
210078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          shared = Handle<SharedFunctionInfo>(function->shared());
2101e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(shared->allows_lazy_compilation() || shared->is_compiled());
210278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          found_next_candidate = true;
210378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        } else if (obj->IsSharedFunctionInfo()) {
210478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj));
210578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          // Skip functions that we cannot compile lazily without a context,
210678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          // which is not available here, because there is no closure.
210778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          found_next_candidate = shared->is_compiled() ||
210878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org              shared->allows_lazy_compilation_without_context();
210978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        }
211078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        if (!found_next_candidate) continue;
211178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        if (shared->script() == *script) {
211278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          // If the SharedFunctionInfo found has the requested script data and
211378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          // contains the source position it is a candidate.
211478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          int start_position = shared->function_token_position();
211578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          if (start_position == RelocInfo::kNoPosition) {
211678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org            start_position = shared->start_position();
211778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          }
211878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          if (start_position <= position &&
211978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org              position <= shared->end_position()) {
212078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org            // If there is no candidate or this function is within the current
212178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org            // candidate this is the new candidate.
212278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org            if (target.is_null()) {
212378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org              target_start_position = start_position;
212478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org              target_function = function;
212578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org              target = shared;
212678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org            } else {
212778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org              if (target_start_position == start_position &&
212878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                  shared->end_position() == target->end_position()) {
212978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                // If a top-level function contains only one function
213078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                // declaration the source for the top-level and the function
213178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                // is the same. In that case prefer the non top-level function.
213278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                if (!shared->is_toplevel()) {
213378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                  target_start_position = start_position;
213478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                  target_function = function;
213578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                  target = shared;
213678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                }
213778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org              } else if (target_start_position <= start_position &&
213878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                         shared->end_position() <= target->end_position()) {
213978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                // This containment check includes equality as a function
214078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                // inside a top-level function can share either start or end
214178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                // position with the top-level function.
214278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                target_start_position = start_position;
214378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                target_function = function;
214478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                target = shared;
214578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org              }
214678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org            }
214778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          }
214878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        }
214978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      }  // End for loop.
215078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }  // End no-allocation scope.
215178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
21527c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    if (target.is_null()) return heap->undefined_value();
215378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
215478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    // There will be at least one break point when we are done.
215578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    has_break_points_ = true;
215678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
215778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    // If the candidate found is compiled we are done.
215878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    done = target->is_compiled();
215978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    if (!done) {
216078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // If the candidate is not compiled, compile it to reveal any inner
216178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // functions which might contain the requested source position. This
216278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // will compile all inner functions that cannot be compiled without a
216378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // context, because Compiler::BuildFunctionInfo checks whether the
216478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // debugger is active.
2165a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      MaybeHandle<Code> maybe_result = target_function.is_null()
21664954674151afa960af66efb4831df06bde727333yangguo@chromium.org          ? Compiler::GetUnoptimizedCode(target)
21674954674151afa960af66efb4831df06bde727333yangguo@chromium.org          : Compiler::GetUnoptimizedCode(target_function);
2168a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      if (maybe_result.is_null()) return isolate_->heap()->undefined_value();
216978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }
217078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }  // End while loop.
217178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
217278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  return *target;
217378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org}
217478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
217578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
2176bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// Ensures the debug information is present for shared.
21775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgbool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
21785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                            Handle<JSFunction> function) {
2179d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Isolate* isolate = shared->GetIsolate();
2180d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
2181bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  // Return if we already have the debug info for shared.
218234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (HasDebugInfo(shared)) {
2183e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(shared->is_compiled());
218434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    return true;
218534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
218643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // There will be at least one break point when we are done.
21885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  has_break_points_ = true;
21895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
21905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Ensure function is compiled. Return false if this failed.
21915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!function.is_null() &&
21924954674151afa960af66efb4831df06bde727333yangguo@chromium.org      !Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) {
2193394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return false;
2194394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
219543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
219643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the debug info object.
2197d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared);
219843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
219943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add debug info to the list.
220043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
220143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  node->set_next(debug_info_list_);
220243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  debug_info_list_ = node;
220343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2204bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  return true;
220543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
220643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
220743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
220843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
2209e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(debug_info_list_ != NULL);
221043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Run through the debug info objects to find this one and remove it.
221143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DebugInfoListNode* prev = NULL;
221243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DebugInfoListNode* current = debug_info_list_;
221343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (current != NULL) {
221443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (*current->debug_info() == *debug_info) {
221543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Unlink from list. If prev is NULL we are looking at the first element.
221643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (prev == NULL) {
221743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        debug_info_list_ = current->next();
221843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
221943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        prev->set_next(current->next());
222043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
22217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      current->debug_info()->shared()->set_debug_info(
22227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              isolate_->heap()->undefined_value());
222343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      delete current;
222443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
222543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // If there are no more debug info objects there are not more break
222643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // points.
222743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      has_break_points_ = debug_info_list_ != NULL;
222843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
222943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
223043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
223143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Move to next in list.
223243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    prev = current;
223343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    current = current->next();
223443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
223543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();
223643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
223743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
223843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
223943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
22408ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  after_break_target_ = NULL;
22418ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org
22428ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  if (LiveEdit::SetAfterBreakTarget(this)) return;  // LiveEdit did the job.
2243381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
2244e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  HandleScope scope(isolate_);
224534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  PrepareForBreakPoints();
224634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
224743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the executing function in which the debug break occurred.
22485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<JSFunction> function(JSFunction::cast(frame->function()));
22495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
22505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!EnsureDebugInfo(shared, function)) {
2251bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund    // Return if we failed to retrieve the debug info.
2252bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund    return;
2253bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  }
225443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
225543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Code> code(debug_info->code());
225643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Code> original_code(debug_info->original_code());
225743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the code which is actually executing.
225974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  Handle<Code> frame_code(frame->LookupCode());
2260e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(frame_code.is_identical_to(code));
226143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
226243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
226343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the call address in the running code. This address holds the call to
226443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // either a DebugBreakXXX or to the debug break return entry code if the
226543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // break point is still active after processing the break point.
22669d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Address addr = Assembler::break_address_from_return_address(frame->pc());
226743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22682356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  // Check if the location is at JS exit or debug break slot.
2269a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  bool at_js_return = false;
2270a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  bool break_at_js_return_active = false;
22712356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  bool at_debug_break_slot = false;
227243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RelocIterator it(debug_info->code());
22732356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  while (!it.done() && !at_js_return && !at_debug_break_slot) {
2274236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
2275a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      at_js_return = (it.rinfo()->pc() ==
2276a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org          addr - Assembler::kPatchReturnSequenceAddressOffset);
22779d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com      break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence();
227843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
22792356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) {
22802356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org      at_debug_break_slot = (it.rinfo()->pc() ==
22812356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org          addr - Assembler::kPatchDebugBreakSlotAddressOffset);
22822356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    }
228343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    it.next();
228443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
228543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
228643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle the jump to continue execution after break point depending on the
228743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // break location.
2288a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  if (at_js_return) {
2289a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // If the break point as return is still active jump to the corresponding
2290a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // place in the original code. If not the break point was removed during
2291a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    // break point processing.
2292a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    if (break_at_js_return_active) {
2293e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      addr += original_code->instruction_start() - code->instruction_start();
229443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
229543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2296911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org    // Move back to where the call instruction sequence started.
2297e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    after_break_target_ = addr - Assembler::kPatchReturnSequenceAddressOffset;
22982356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  } else if (at_debug_break_slot) {
22992356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    // Address of where the debug break slot starts.
23002356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset;
23012356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
23022356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org    // Continue just after the slot.
2303e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    after_break_target_ = addr + Assembler::kDebugBreakSlotLength;
23042356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org  } else {
2305d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    addr = Assembler::target_address_from_return_address(frame->pc());
2306d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    if (IsDebugBreak(Assembler::target_address_at(addr, *code))) {
2307d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // We now know that there is still a debug break call at the target
2308d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // address, so the break point is still there and the original code will
2309d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // hold the address to jump to in order to complete the call which is
2310d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // replaced by a call to DebugBreakXXX.
2311d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
2312d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // Find the corresponding address in the original code.
2313d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      addr += original_code->instruction_start() - code->instruction_start();
2314d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
2315d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // Install jump to the call address in the original code. This will be the
2316d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // call which was overwritten by the call to DebugBreakXXX.
2317d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      after_break_target_ = Assembler::target_address_at(addr, *original_code);
2318d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    } else {
2319d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // There is no longer a break point present. Don't try to look in the
2320d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // original code as the running code will have the right address. This
2321d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // takes care of the case where the last break point is removed from the
2322d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      // function and therefore no "original code" is available.
2323d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      after_break_target_ = Assembler::target_address_at(addr, *code);
2324d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    }
232543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
232643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
232743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
232843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23292cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.orgbool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
23307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
23312cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
23326db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // If there are no break points this cannot be break at return, as
23336db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // the debugger statement and stack guard bebug break cannot be at
23346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // return.
23356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  if (!has_break_points_) {
23366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    return false;
23376db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  }
23386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
233934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  PrepareForBreakPoints();
234034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
23412cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // Get the executing function in which the debug break occurred.
23425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<JSFunction> function(JSFunction::cast(frame->function()));
23435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
23445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!EnsureDebugInfo(shared, function)) {
23452cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    // Return if we failed to retrieve the debug info.
23462cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    return false;
23472cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  }
23482cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  Handle<DebugInfo> debug_info = GetDebugInfo(shared);
23492cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  Handle<Code> code(debug_info->code());
23502cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org#ifdef DEBUG
23512cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // Get the code which is actually executing.
235274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  Handle<Code> frame_code(frame->LookupCode());
2353e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(frame_code.is_identical_to(code));
23542cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org#endif
23552cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
23562cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // Find the call address in the running code.
23579d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Address addr = Assembler::break_address_from_return_address(frame->pc());
23582cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
23592cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // Check if the location is at JS return.
23602cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  RelocIterator it(debug_info->code());
23612cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  while (!it.done()) {
23622cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
23632cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      return (it.rinfo()->pc() ==
23642cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org          addr - Assembler::kPatchReturnSequenceAddressOffset);
23652cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    }
23662cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    it.next();
23672cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  }
23682cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  return false;
23692cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org}
23702cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
23712cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
237269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
2373e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org                                  LiveEdit::FrameDropMode mode,
2374e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org                                  Object** restarter_frame_function_pointer) {
2375e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (mode != LiveEdit::CURRENTLY_SET_MODE) {
2376d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org    thread_local_.frame_drop_mode_ = mode;
2377d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org  }
2378357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  thread_local_.break_frame_id_ = new_break_frame_id;
2379e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  thread_local_.restarter_frame_function_pointer_ =
2380e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org      restarter_frame_function_pointer;
2381357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
2382357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
2383357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
238443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Debug::IsDebugGlobal(GlobalObject* global) {
23858d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  return is_loaded() && global == debug_context()->global_object();
238643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
238743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
238843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23893291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgvoid Debug::ClearMirrorCache() {
2390ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  PostponeInterruptsScope postpone(isolate_);
23917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
2392196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  AssertDebugContext();
2393196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Factory* factory = isolate_->factory();
239458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  Handle<GlobalObject> global(isolate_->global_object());
239558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  JSObject::SetProperty(global,
23962c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                        factory->NewStringFromAsciiChecked("next_handle_"),
23972c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                        handle(Smi::FromInt(0), isolate_), SLOPPY).Check();
239858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  JSObject::SetProperty(global,
23992c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                        factory->NewStringFromAsciiChecked("mirror_cache_"),
24002c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                        factory->NewJSArray(0, FAST_ELEMENTS), SLOPPY).Check();
240171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
240271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
240371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
240471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgHandle<FixedArray> Debug::GetLoadedScripts() {
240571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Create and fill the script cache when the loaded scripts is requested for
240671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // the first time.
24078d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
240871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
240971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Perform GC to get unreferenced scripts evicted from the cache before
241071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // returning the content.
2411994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
2412994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                                      "Debug::GetLoadedScripts");
241371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
241471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Get the scripts from the cache.
241571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  return script_cache_->GetScripts();
241671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
241771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
241871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
24194954674151afa960af66efb4831df06bde727333yangguo@chromium.orgvoid Debug::RecordEvalCaller(Handle<Script> script) {
24204954674151afa960af66efb4831df06bde727333yangguo@chromium.org  script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
24214954674151afa960af66efb4831df06bde727333yangguo@chromium.org  // For eval scripts add information on the function from which eval was
24224954674151afa960af66efb4831df06bde727333yangguo@chromium.org  // called.
24234954674151afa960af66efb4831df06bde727333yangguo@chromium.org  StackTraceFrameIterator it(script->GetIsolate());
24244954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (!it.done()) {
24254954674151afa960af66efb4831df06bde727333yangguo@chromium.org    script->set_eval_from_shared(it.frame()->function()->shared());
24264954674151afa960af66efb4831df06bde727333yangguo@chromium.org    Code* code = it.frame()->LookupCode();
24274954674151afa960af66efb4831df06bde727333yangguo@chromium.org    int offset = static_cast<int>(
24284954674151afa960af66efb4831df06bde727333yangguo@chromium.org        it.frame()->pc() - code->instruction_start());
24294954674151afa960af66efb4831df06bde727333yangguo@chromium.org    script->set_eval_from_instructions_offset(Smi::FromInt(offset));
24304954674151afa960af66efb4831df06bde727333yangguo@chromium.org  }
24314954674151afa960af66efb4831df06bde727333yangguo@chromium.org}
24324954674151afa960af66efb4831df06bde727333yangguo@chromium.org
24334954674151afa960af66efb4831df06bde727333yangguo@chromium.org
24348d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgMaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
24358d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                        int argc,
24368d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                        Handle<Object> argv[]) {
2437196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  AssertDebugContext();
243843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the execution state object.
243958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  Handle<GlobalObject> global(isolate_->global_object());
24402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> constructor = Object::GetProperty(
244158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      isolate_, global, constructor_name).ToHandleChecked();
2442e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(constructor->IsJSFunction());
24432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
24448d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // We do not handle interrupts here.  In particular, termination interrupts.
24458d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  PostponeInterruptsScope no_interrupts(isolate_);
24468d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  return Execution::TryCall(Handle<JSFunction>::cast(constructor),
244758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org                            handle(debug_context()->global_proxy()),
24488d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                            argc,
24498d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                            argv);
245043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
245143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
245243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2453d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgMaybeHandle<Object> Debug::MakeExecutionState() {
245443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the execution state object.
24558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
2456fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return MakeJSObject("MakeExecutionState", arraysize(argv), argv);
245743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
245843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
245943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2460d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgMaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
246143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the new break event object.
2462c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
2463c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org                            break_points_hit };
2464fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return MakeJSObject("MakeBreakEvent", arraysize(argv), argv);
246543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
246643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
246743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2468d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgMaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
24698d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                              bool uncaught,
24708d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                              Handle<Object> promise) {
247143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the new exception event object.
2472c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
2473a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                            exception,
2474865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                            isolate_->factory()->ToBoolean(uncaught),
2475865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                            promise };
2476fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return MakeJSObject("MakeExceptionEvent", arraysize(argv), argv);
247743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
247843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
247943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2480d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgMaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
2481248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org                                            v8::DebugEvent type) {
2482e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // Create the compile event object.
24839fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Object> script_wrapper = Script::GetWrapper(script);
2484c3564d8de4ebfc4fa3dc009fc9f6f18968ffcbd7machenbach@chromium.org  Handle<Object> argv[] = { script_wrapper,
2485248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org                            isolate_->factory()->NewNumberFromInt(type) };
2486fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return MakeJSObject("MakeCompileEvent", arraysize(argv), argv);
248743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
248843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
248943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24905de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgMaybeHandle<Object> Debug::MakePromiseEvent(Handle<JSObject> event_data) {
24915de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  // Create the promise event object.
24925de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  Handle<Object> argv[] = { event_data };
2493fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return MakeJSObject("MakePromiseEvent", arraysize(argv), argv);
24945de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org}
24955de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
24965de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
2497d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgMaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
2498d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Create the async task event object.
2499d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  Handle<Object> argv[] = { task_event };
2500fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return MakeJSObject("MakeAsyncTaskEvent", arraysize(argv), argv);
2501d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org}
2502d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
2503d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
25049d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvoid Debug::OnThrow(Handle<Object> exception, bool uncaught) {
2505196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (in_debug_scope() || ignore_events()) return;
25066313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  // Temporarily clear any scheduled_exception to allow evaluating
25076313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  // JavaScript from the debug event handler.
25089d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  HandleScope scope(isolate_);
25096313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  Handle<Object> scheduled_exception;
25106313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  if (isolate_->has_scheduled_exception()) {
25116313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
25126313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    isolate_->clear_scheduled_exception();
25136313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  }
25145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  OnException(exception, uncaught, isolate_->GetPromiseOnStackOnThrow());
25156313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  if (!scheduled_exception.is_null()) {
25166313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
25176313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  }
25189d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
25199d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
252043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25219d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvoid Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) {
25229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  if (in_debug_scope() || ignore_events()) return;
25238d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  HandleScope scope(isolate_);
25249d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  OnException(value, false, promise);
25259d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
2526a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
25279d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
25289d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvoid Debug::OnException(Handle<Object> exception, bool uncaught,
25299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                        Handle<Object> promise) {
25309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  if (promise->IsJSObject()) {
25319d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    uncaught |= !PromiseHasRejectHandler(Handle<JSObject>::cast(promise));
25329d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
253343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bail out if exception breaks are not active
253443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (uncaught) {
253543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Uncaught exceptions are reported by either flags.
25368d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
253743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
253843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Caught exceptions are reported is activated.
25398d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    if (!break_on_exception_) return;
254043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
254143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2542196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  DebugScope debug_scope(this);
2543196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (debug_scope.failed()) return;
254443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
254543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear all current stepping setup.
25468d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  ClearStepping();
2547865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
254843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the event data object.
254943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> event_data;
255043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bail out and don't call debugger if exception.
2551865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  if (!MakeExceptionEvent(
2552865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org          exception, uncaught, promise).ToHandle(&event_data)) {
2553865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    return;
2554865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  }
255543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25565ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // Process debug event.
2557a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
255843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return to continue execution from where the exception was thrown.
255943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
256043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
256143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2562248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.orgvoid Debug::OnCompileError(Handle<Script> script) {
2563248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  // No more to do if not debugging.
2564248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  if (in_debug_scope() || ignore_events()) return;
2565248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
2566248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  HandleScope scope(isolate_);
2567248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  DebugScope debug_scope(this);
2568248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  if (debug_scope.failed()) return;
2569248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
2570248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  // Create the compile state object.
2571248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  Handle<Object> event_data;
2572248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  // Bail out and don't call debugger if exception.
2573248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  if (!MakeCompileEvent(script, v8::CompileError).ToHandle(&event_data)) return;
2574248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
2575248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  // Process debug event.
2576248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  ProcessDebugEvent(v8::CompileError, Handle<JSObject>::cast(event_data), true);
2577248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org}
2578248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
2579248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
2580d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::OnDebugBreak(Handle<Object> break_points_hit,
2581bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                            bool auto_continue) {
2582196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // The caller provided for DebugScope.
2583196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  AssertDebugContext();
258443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bail out if there is no listener for this event
25858d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (ignore_events()) return;
258643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25878d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  HandleScope scope(isolate_);
258843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the event data object.
258943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> event_data;
259043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bail out and don't call debugger if exception.
2591e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
259243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25935ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // Process debug event.
25945ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  ProcessDebugEvent(v8::Break,
25955ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                    Handle<JSObject>::cast(event_data),
25965ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                    auto_continue);
259743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
259843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
259943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2600d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::OnBeforeCompile(Handle<Script> script) {
2601196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (in_debug_scope() || ignore_events()) return;
260243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26038d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  HandleScope scope(isolate_);
2604196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  DebugScope debug_scope(this);
2605196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (debug_scope.failed()) return;
260643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
260743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the event data object.
26082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> event_data;
260943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bail out and don't call debugger if exception.
2610248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  if (!MakeCompileEvent(script, v8::BeforeCompile).ToHandle(&event_data))
2611248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    return;
261243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // Process debug event.
26145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  ProcessDebugEvent(v8::BeforeCompile,
26155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                    Handle<JSObject>::cast(event_data),
26165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                    true);
261743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
261843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
261943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
262043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Handle debugger actions when a new script is compiled.
2621248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.orgvoid Debug::OnAfterCompile(Handle<Script> script) {
262271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Add the newly compiled script to the script cache.
26238d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (script_cache_ != NULL) script_cache_->Add(script);
262443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
262543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No more to do if not debugging.
2626196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (in_debug_scope() || ignore_events()) return;
262771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
26288d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  HandleScope scope(isolate_);
2629196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  DebugScope debug_scope(this);
2630196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (debug_scope.failed()) return;
263143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
263243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If debugging there might be script break points registered for this
263343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // script. Make sure that these break points are set.
263443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26355d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
26364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> update_script_break_points_string =
26374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate_->factory()->InternalizeOneByteString(
26382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org          STATIC_CHAR_VECTOR("UpdateScriptBreakPoints"));
2639d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  Handle<GlobalObject> debug_global(debug_context()->global_object());
264043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> update_script_break_points =
26412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object::GetProperty(
26422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          debug_global, update_script_break_points_string).ToHandleChecked();
264343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!update_script_break_points->IsJSFunction()) {
264443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
264543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
2646e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(update_script_break_points->IsJSFunction());
264743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
264843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Wrap the script object in a proper JS object before passing it
264943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to JavaScript.
26509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Object> wrapper = Script::GetWrapper(script);
265143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
265243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Call UpdateScriptBreakPoints expect no exceptions.
2653a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> argv[] = { wrapper };
26542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
26552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                         isolate_->js_builtins_object(),
2656fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                         arraysize(argv),
26572ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                         argv).is_null()) {
265843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
265943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
266043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
266143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the compile state object.
26622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> event_data;
266343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bail out and don't call debugger if exception.
2664248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  if (!MakeCompileEvent(script, v8::AfterCompile).ToHandle(&event_data)) return;
26652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
26665ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // Process debug event.
26672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
266843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
266943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
267043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26715de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgvoid Debug::OnPromiseEvent(Handle<JSObject> data) {
26725de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  if (in_debug_scope() || ignore_events()) return;
26735de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
26745de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  HandleScope scope(isolate_);
26755de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  DebugScope debug_scope(this);
26765de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  if (debug_scope.failed()) return;
26775de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
26785de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  // Create the script collected state object.
26795de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  Handle<Object> event_data;
26805de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  // Bail out and don't call debugger if exception.
26815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  if (!MakePromiseEvent(data).ToHandle(&event_data)) return;
26825de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
26835de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  // Process debug event.
26845de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  ProcessDebugEvent(v8::PromiseEvent,
26855de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org                    Handle<JSObject>::cast(event_data),
26865de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org                    true);
26875de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org}
26885de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
26895de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
2690d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgvoid Debug::OnAsyncTaskEvent(Handle<JSObject> data) {
2691d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (in_debug_scope() || ignore_events()) return;
2692d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
2693d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  HandleScope scope(isolate_);
2694d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  DebugScope debug_scope(this);
2695d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (debug_scope.failed()) return;
2696d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
2697d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Create the script collected state object.
2698d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  Handle<Object> event_data;
2699d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Bail out and don't call debugger if exception.
2700d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (!MakeAsyncTaskEvent(data).ToHandle(&event_data)) return;
2701d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
2702d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Process debug event.
2703d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ProcessDebugEvent(v8::AsyncTaskEvent,
2704d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                    Handle<JSObject>::cast(event_data),
2705d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                    true);
2706d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org}
2707d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
2708d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
2709d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::ProcessDebugEvent(v8::DebugEvent event,
2710d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                              Handle<JSObject> event_data,
2711d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                              bool auto_continue) {
27127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
2713381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
271443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create the execution state.
27152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> exec_state;
27162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Bail out and don't call debugger if exception.
2717e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (!MakeExecutionState().ToHandle(&exec_state)) return;
2718e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
271941826e77311db718135ef6517b846933dfd275f3ager@chromium.org  // First notify the message handler if any.
272041826e77311db718135ef6517b846933dfd275f3ager@chromium.org  if (message_handler_ != NULL) {
27215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    NotifyMessageHandler(event,
27225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         Handle<JSObject>::cast(exec_state),
27235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         event_data,
27245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         auto_continue);
272543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
272622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  // Notify registered debug event listener. This can be either a C or
272722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  // a JavaScript function. Don't call event listener for v8::Break
272822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  // here, if it's only a debug command -- they will be processed later.
272922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
273022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com    CallEventCallback(event, exec_state, event_data, NULL);
273122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  }
273222762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  // Process pending debug commands.
273322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  if (event == v8::Break) {
273422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com    while (!event_command_queue_.IsEmpty()) {
273522762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com      CommandMessage command = event_command_queue_.Get();
273622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com      if (!event_listener_.is_null()) {
273722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com        CallEventCallback(v8::BreakForCommand,
273822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com                          exec_state,
273922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com                          event_data,
274022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com                          command.client_data());
274122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com      }
274222762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com      command.Dispose();
274343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
274443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
274543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
274643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
274743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2748d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::CallEventCallback(v8::DebugEvent event,
2749d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                              Handle<Object> exec_state,
2750d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                              Handle<Object> event_data,
2751d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                              v8::Debug::ClientData* client_data) {
2752ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  if (event_listener_->IsForeign()) {
27538d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    // Invoke the C debug event listener.
27548d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    v8::Debug::EventCallback callback =
27558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        FUNCTION_CAST<v8::Debug::EventCallback>(
27568d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            Handle<Foreign>::cast(event_listener_)->foreign_address());
27578d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    EventDetailsImpl event_details(event,
27588d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                   Handle<JSObject>::cast(exec_state),
27598d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                   Handle<JSObject>::cast(event_data),
27608d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                   event_listener_data_,
27618d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                   client_data);
27628d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    callback(event_details);
2763e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!isolate_->has_scheduled_exception());
276422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  } else {
27658d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    // Invoke the JavaScript debug event listener.
2766e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(event_listener_->IsJSFunction());
27678d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
27688d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                              exec_state,
27698d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                              event_data,
27708d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                              event_listener_data_ };
277158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    Handle<JSReceiver> global(isolate_->global_proxy());
27728d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
2773fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                       global, arraysize(argv), argv);
277422762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  }
277522762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com}
277622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com
277722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com
2778d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgHandle<Context> Debug::GetDebugContext() {
2779196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  DebugScope debug_scope(this);
27806a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // The global handle may be destroyed soon after.  Return it reboxed.
2781d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  return handle(*debug_context(), isolate_);
2782737cf10f099dd6cdfcf47b0188ff2b9c90bfc460machenbach@chromium.org}
2783737cf10f099dd6cdfcf47b0188ff2b9c90bfc460machenbach@chromium.org
2784737cf10f099dd6cdfcf47b0188ff2b9c90bfc460machenbach@chromium.org
2785d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::NotifyMessageHandler(v8::DebugEvent event,
2786d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                                 Handle<JSObject> exec_state,
2787d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                                 Handle<JSObject> event_data,
2788d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                                 bool auto_continue) {
27898d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Prevent other interrupts from triggering, for example API callbacks,
27908d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // while dispatching message handler callbacks.
27918d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  PostponeInterruptsScope no_interrupts(isolate_);
2792e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_active_);
27937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  HandleScope scope(isolate_);
279443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Process the individual events.
27955ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  bool sendEventMessage = false;
279643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (event) {
279743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case v8::Break:
279822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com    case v8::BreakForCommand:
27995ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      sendEventMessage = !auto_continue;
280043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
280143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case v8::Exception:
28025ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      sendEventMessage = true;
280343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
280443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case v8::BeforeCompile:
280543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
280643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case v8::AfterCompile:
28075ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      sendEventMessage = true;
280843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
280943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case v8::NewFunction:
281043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
281143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
281243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      UNREACHABLE();
281343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
281443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // The debug command interrupt flag might have been set when the command was
28165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // added. It should be enough to clear the flag only once while we are in the
28175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // debugger.
2818e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(in_debug_scope());
28193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  isolate_->stack_guard()->ClearDebugCommand();
28205ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
28215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // Notify the debugger that a debug event has occurred unless auto continue is
28225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // active in which case no event is send.
28235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  if (sendEventMessage) {
28245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    MessageImpl message = MessageImpl::NewEvent(
28255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        event,
28265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        auto_continue,
28275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        Handle<JSObject>::cast(exec_state),
28285ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        Handle<JSObject>::cast(event_data));
28295ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    InvokeMessageHandler(message);
28305ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  }
2831755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
2832755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // If auto continue don't make the event cause a break, but process messages
2833755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // in the queue if any. For script collected events don't even process
2834755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // messages in the queue as the execution state might not be what is expected
2835755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // by the client.
2836248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  if (auto_continue && !has_commands()) return;
283743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28389d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // DebugCommandProcessor goes here.
28399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  bool running = auto_continue;
28409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
28413c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Object> cmd_processor_ctor = Object::GetProperty(
28423c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      isolate_, exec_state, "debugCommandProcessor").ToHandleChecked();
28433c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
28443c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Object> cmd_processor = Execution::Call(
28453c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked();
28463c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
28473c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      Object::GetProperty(
28483c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org          isolate_, cmd_processor, "processDebugRequest").ToHandleChecked());
28493c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Object> is_running = Object::GetProperty(
28503c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      isolate_, cmd_processor, "isRunning").ToHandleChecked();
28513c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
2852bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Process requests from the debugger.
28533c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  do {
2854bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Wait for new command in the queue.
28553c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    command_received_.Wait();
2856bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
2857bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Get the command from the queue.
28583a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org    CommandMessage command = command_queue_.Get();
28596d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    isolate_->logger()->DebugTag(
28606d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        "Got request from command queue, in interactive loop.");
2861d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    if (!is_active()) {
286265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      // Delete command text and user data.
286365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      command.Dispose();
286443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
286543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
286643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28673c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    Vector<const uc16> command_text(
28683c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        const_cast<const uc16*>(command.text().start()),
28693c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        command.text().length());
28703c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
28713c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        command_text).ToHandleChecked();
28723c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    Handle<Object> request_args[] = { request_text };
28733c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    Handle<Object> answer_value;
28743c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    Handle<String> answer;
2875ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    MaybeHandle<Object> maybe_exception;
2876ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    MaybeHandle<Object> maybe_result =
2877ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        Execution::TryCall(process_debug_request, cmd_processor, 1,
2878ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                           request_args, &maybe_exception);
28793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
28803c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    if (maybe_result.ToHandle(&answer_value)) {
28813c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      if (answer_value->IsUndefined()) {
28823c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        answer = isolate_->factory()->empty_string();
2883a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      } else {
28843c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        answer = Handle<String>::cast(answer_value);
2885a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
288643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
288743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Log the JSON request/response.
288843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (FLAG_trace_debug_json) {
28893c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        PrintF("%s\n", request_text->ToCString().get());
28903c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        PrintF("%s\n", answer->ToCString().get());
289143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
289243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28933c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      Handle<Object> is_running_args[] = { answer };
28943c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      maybe_result = Execution::Call(
28953c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org          isolate_, is_running, cmd_processor, 1, is_running_args);
2896ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      Handle<Object> result;
2897ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      if (!maybe_result.ToHandle(&result)) break;
2898ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      running = result->IsTrue();
289943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
2900ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      Handle<Object> exception;
2901ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      if (!maybe_exception.ToHandle(&exception)) break;
2902ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      Handle<Object> result;
2903ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      if (!Execution::ToString(isolate_, exception).ToHandle(&result)) break;
2904ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      answer = Handle<String>::cast(result);
290543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
290643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
290743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Return the result.
29085ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    MessageImpl message = MessageImpl::NewResponse(
29093c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org        event, running, exec_state, event_data, answer, command.client_data());
29105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    InvokeMessageHandler(message);
29115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    command.Dispose();
291243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2913bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Return from debug event processing if either the VM is put into the
2914f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    // running state (through a continue command) or auto continue is active
2915bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // and there are no more commands queued.
29168d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  } while (!running || has_commands());
2917ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  command_queue_.Clear();
291843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
291943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
292043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2921d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::SetEventListener(Handle<Object> callback,
2922d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                             Handle<Object> data) {
29237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  GlobalHandles* global_handles = isolate_->global_handles();
292441826e77311db718135ef6517b846933dfd275f3ager@chromium.org
29256a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // Remove existing entry.
29266a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  GlobalHandles::Destroy(event_listener_.location());
29276a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  event_listener_ = Handle<Object>();
29286a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  GlobalHandles::Destroy(event_listener_data_.location());
29296a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  event_listener_data_ = Handle<Object>();
293041826e77311db718135ef6517b846933dfd275f3ager@chromium.org
29316a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // Set new entry.
293241826e77311db718135ef6517b846933dfd275f3ager@chromium.org  if (!callback->IsUndefined() && !callback->IsNull()) {
29336a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    event_listener_ = global_handles->Create(*callback);
29346a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    if (data.is_null()) data = isolate_->factory()->undefined_value();
29356a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    event_listener_data_ = global_handles->Create(*data);
293641826e77311db718135ef6517b846933dfd275f3ager@chromium.org  }
293741826e77311db718135ef6517b846933dfd275f3ager@chromium.org
29386a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  UpdateState();
293941826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
294041826e77311db718135ef6517b846933dfd275f3ager@chromium.org
294141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
2942d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
294341826e77311db718135ef6517b846933dfd275f3ager@chromium.org  message_handler_ = handler;
29446a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  UpdateState();
2945196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (handler == NULL && in_debug_scope()) {
294671daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org    // Send an empty command to the debugger if in a break to make JavaScript
294771daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org    // run again if the debugger is closed.
29486a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    EnqueueCommandMessage(Vector<const uint16_t>::empty());
294941826e77311db718135ef6517b846933dfd275f3ager@chromium.org  }
295041826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
295141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
295241826e77311db718135ef6517b846933dfd275f3ager@chromium.org
2953d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org
2954d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::UpdateState() {
2955196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  is_active_ = message_handler_ != NULL || !event_listener_.is_null();
2956196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (is_active_ || in_debug_scope()) {
29576a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    // Note that the debug context could have already been loaded to
29586a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    // bootstrap test cases.
29597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    isolate_->compilation_cache()->Disable();
2960196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    is_active_ = Load();
2961196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  } else if (is_loaded()) {
29627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    isolate_->compilation_cache()->Enable();
2963d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    Unload();
296471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  }
296571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org}
296671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
296771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
296841826e77311db718135ef6517b846933dfd275f3ager@chromium.org// Calls the registered debug message handler. This callback is part of the
29695ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// public API.
2970d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::InvokeMessageHandler(MessageImpl message) {
29716a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  if (message_handler_ != NULL) message_handler_(message);
297241826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
297341826e77311db718135ef6517b846933dfd275f3ager@chromium.org
297441826e77311db718135ef6517b846933dfd275f3ager@chromium.org
29757276f14ca716596e0a0d17539516370c1f453847kasper.lund// Puts a command coming from the public API on the queue.  Creates
29767276f14ca716596e0a0d17539516370c1f453847kasper.lund// a copy of the command string managed by the debugger.  Up to this
29777276f14ca716596e0a0d17539516370c1f453847kasper.lund// point, the command data was managed by the API client.  Called
29783a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org// by the API client thread.
2979d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
2980d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                                  v8::Debug::ClientData* client_data) {
298165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Need to cast away const.
29823a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  CommandMessage message = CommandMessage::New(
298341826e77311db718135ef6517b846933dfd275f3ager@chromium.org      Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
298465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org                       command.length()),
298565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      client_data);
29866d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  isolate_->logger()->DebugTag("Put command on command_queue.");
298765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  command_queue_.Put(message);
2988e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  command_received_.Signal();
29893afc15871025a4736634052bd1ff4b4bb2fc2e4fsgjesse@chromium.org
29903afc15871025a4736634052bd1ff4b4bb2fc2e4fsgjesse@chromium.org  // Set the debug command break flag to have the command processed.
2991196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
299241826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
299341826e77311db718135ef6517b846933dfd275f3ager@chromium.org
299441826e77311db718135ef6517b846933dfd275f3ager@chromium.org
2995d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
299622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
299722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  event_command_queue_.Put(message);
299822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com
299922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  // Set the debug command break flag to have the command processed.
3000196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
300122762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com}
300222762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com
300322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com
3004d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgMaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
3005196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  DebugScope debug_scope(this);
3006196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (debug_scope.failed()) return isolate_->factory()->undefined_value();
300741826e77311db718135ef6517b846933dfd275f3ager@chromium.org
300841826e77311db718135ef6517b846933dfd275f3ager@chromium.org  // Create the execution state.
30092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> exec_state;
3010e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (!MakeExecutionState().ToHandle(&exec_state)) {
3011e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return isolate_->factory()->undefined_value();
3012e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
301341826e77311db718135ef6517b846933dfd275f3ager@chromium.org
3014a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> argv[] = { exec_state, data };
30152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return Execution::Call(
30162c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org      isolate_,
3017df7a284a293865a5fa9390be2e8f82ba3ac8598asgjesse@chromium.org      fun,
3018d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      Handle<Object>(debug_context()->global_proxy(), isolate_),
3019fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      arraysize(argv),
30202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      argv);
302141826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
302241826e77311db718135ef6517b846933dfd275f3ager@chromium.org
302341826e77311db718135ef6517b846933dfd275f3ager@chromium.org
30248d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgvoid Debug::HandleDebugBreak() {
30258d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Ignore debug break during bootstrapping.
30268d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (isolate_->bootstrapper()->IsActive()) return;
30278d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Just continue if breaks are disabled.
30288d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (break_disabled_) return;
30298d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Ignore debug break if debugger is not active.
30308d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (!is_active()) return;
30318d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30328d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  StackLimitCheck check(isolate_);
30338d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (check.HasOverflowed()) return;
30348d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30358d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  { JavaScriptFrameIterator it(isolate_);
3036e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!it.done());
30378d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Object* fun = it.frame()->function();
30388d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    if (fun && fun->IsJSFunction()) {
30398d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      // Don't stop in builtin functions.
30408d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      if (JSFunction::cast(fun)->IsBuiltin()) return;
30418d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
30428d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      // Don't stop in debugger functions.
30438d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      if (IsDebugGlobal(global)) return;
30448d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    }
30458d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
30468d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30478d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Collect the break state before clearing the flags.
30488d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
30498d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                            !isolate_->stack_guard()->CheckDebugBreak();
30508d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30518d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  isolate_->stack_guard()->ClearDebugBreak();
30528d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30538d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  ProcessDebugMessages(debug_command_only);
30548d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
30558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30568d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30578d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgvoid Debug::ProcessDebugMessages(bool debug_command_only) {
30588d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  isolate_->stack_guard()->ClearDebugCommand();
30598d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30608d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  StackLimitCheck check(isolate_);
30618d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (check.HasOverflowed()) return;
30628d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30638d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  HandleScope scope(isolate_);
3064196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  DebugScope debug_scope(this);
3065196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (debug_scope.failed()) return;
30668d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30678d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // Notify the debug event listeners. Indicate auto continue if the break was
30688d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  // a debug command break.
30698d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
30708d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
30718d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
30728d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
3073f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.orgDebugScope::DebugScope(Debug* debug)
3074f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org    : debug_(debug),
3075f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org      prev_(debug->debugger_entry()),
3076f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org      save_(debug_->isolate_),
3077f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org      no_termination_exceptons_(debug_->isolate_,
3078f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org                                StackGuard::TERMINATE_EXECUTION) {
3079c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Link recursive debugger entry.
3080196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  debug_->thread_local_.current_debug_scope_ = this;
3081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Store the previous break id and frame id.
3083196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  break_id_ = debug_->break_id();
3084196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  break_frame_id_ = debug_->break_frame_id();
3085c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Create the new break info. If there is no JavaScript frames there is no
3087c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // break frame id.
3088196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  JavaScriptFrameIterator it(isolate());
30898d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  bool has_js_frames = !it.done();
3090196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
3091196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                                        : StackFrame::NO_ID;
3092196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  debug_->SetNextBreakId();
3093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3094196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  debug_->UpdateState();
3095c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Make sure that debugger is loaded and enter the debugger context.
30966a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // The previous context is kept in save_.
3097196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  failed_ = !debug_->is_loaded();
3098196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (!failed_) isolate()->set_context(*debug->debug_context());
3099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3103196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgDebugScope::~DebugScope() {
3104196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (!failed_ && prev_ == NULL) {
3105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Clear mirror cache when leaving the debugger. Skip this if there is a
3106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // pending exception as clearing the mirror cache calls back into
3107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // JavaScript. This can happen if the v8::Debug::Call is used in which
3108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // case the exception should end up in the calling code.
3109196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
3110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If there are commands in the queue when leaving the debugger request
3112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // that these commands are processed.
3113196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
3114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
31167e6132b924829c353864933f29124419916db550machenbach@chromium.org  // Leaving this debugger entry.
3117196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  debug_->thread_local_.current_debug_scope_ = prev_;
3118196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
3119196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // Restore to the previous break state.
3120196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  debug_->thread_local_.break_frame_id_ = break_frame_id_;
3121196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  debug_->thread_local_.break_id_ = break_id_;
31227e6132b924829c353864933f29124419916db550machenbach@chromium.org
3123196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  debug_->UpdateState();
3124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
31275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgMessageImpl MessageImpl::NewEvent(DebugEvent event,
31285ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                                  bool running,
31295ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                                  Handle<JSObject> exec_state,
31305ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                                  Handle<JSObject> event_data) {
31315ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  MessageImpl message(true, event, running,
31325ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                      exec_state, event_data, Handle<String>(), NULL);
31335ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return message;
31345ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
31355ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31365ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31375ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgMessageImpl MessageImpl::NewResponse(DebugEvent event,
31385ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                                     bool running,
31395ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                                     Handle<JSObject> exec_state,
31405ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                                     Handle<JSObject> event_data,
31415ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                                     Handle<String> response_json,
31425ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                                     v8::Debug::ClientData* client_data) {
31435ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  MessageImpl message(false, event, running,
31445ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                      exec_state, event_data, response_json, client_data);
31455ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return message;
31465ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
31475ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31485ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31495ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgMessageImpl::MessageImpl(bool is_event,
31505ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         DebugEvent event,
31515ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         bool running,
31525ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         Handle<JSObject> exec_state,
31535ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         Handle<JSObject> event_data,
31545ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         Handle<String> response_json,
31555ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org                         v8::Debug::ClientData* client_data)
31565ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    : is_event_(is_event),
31575ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      event_(event),
31585ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      running_(running),
31595ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      exec_state_(exec_state),
31605ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      event_data_(event_data),
31615ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      response_json_(response_json),
31625ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      client_data_(client_data) {}
31635ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31645ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31655ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgbool MessageImpl::IsEvent() const {
31665ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return is_event_;
31675ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
31685ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31695ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31705ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgbool MessageImpl::IsResponse() const {
31715ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return !is_event_;
31725ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
31735ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31745ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31755ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgDebugEvent MessageImpl::GetEvent() const {
31765ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return event_;
31775ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
31785ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31795ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31805ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgbool MessageImpl::WillStartRunning() const {
31815ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return running_;
31825ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
31835ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31845ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31855ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Handle<v8::Object> MessageImpl::GetExecutionState() const {
31865ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return v8::Utils::ToLocal(exec_state_);
31875ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
31885ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31895ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
3190c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgv8::Isolate* MessageImpl::GetIsolate() const {
3191c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
3192c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org}
3193c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
3194c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
31955ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Handle<v8::Object> MessageImpl::GetEventData() const {
31965ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return v8::Utils::ToLocal(event_data_);
31975ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
31985ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
31995ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
32005ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Handle<v8::String> MessageImpl::GetJSON() const {
32012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Isolate* isolate = event_data_->GetIsolate();
32022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
32035ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
32045ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  if (IsEvent()) {
32055ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    // Call toJSONProtocol on the debug event object.
32069fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<Object> fun = Object::GetProperty(
32079fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate, event_data_, "toJSONProtocol").ToHandleChecked();
32085ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    if (!fun->IsJSFunction()) {
32095ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      return v8::Handle<v8::String>();
32105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    }
32112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
32122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    MaybeHandle<Object> maybe_json =
32132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Execution::TryCall(Handle<JSFunction>::cast(fun), event_data_, 0, NULL);
32142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> json;
32152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (!maybe_json.ToHandle(&json) || !json->IsString()) {
32165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      return v8::Handle<v8::String>();
32175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    }
3218ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
32195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  } else {
32205ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    return v8::Utils::ToLocal(response_json_);
32215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  }
32225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
32235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
32245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
32255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Handle<v8::Context> MessageImpl::GetEventContext() const {
3226e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  Isolate* isolate = event_data_->GetIsolate();
3227ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
3228ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Isolate::context() may be NULL when "script collected" event occures.
3229e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!context.IsEmpty());
3230717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  return context;
32315ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
32325ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
32335ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
32345ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.orgv8::Debug::ClientData* MessageImpl::GetClientData() const {
32355ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return client_data_;
32365ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
32375ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
32385ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
32399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comEventDetailsImpl::EventDetailsImpl(DebugEvent event,
32409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com                                   Handle<JSObject> exec_state,
32419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com                                   Handle<JSObject> event_data,
324222762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com                                   Handle<Object> callback_data,
324322762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com                                   v8::Debug::ClientData* client_data)
32449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    : event_(event),
32459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com      exec_state_(exec_state),
32469dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com      event_data_(event_data),
324722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com      callback_data_(callback_data),
324822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com      client_data_(client_data) {}
32499dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32519dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comDebugEvent EventDetailsImpl::GetEvent() const {
32529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return event_;
32539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
32549dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32569dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comv8::Handle<v8::Object> EventDetailsImpl::GetExecutionState() const {
32579dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return v8::Utils::ToLocal(exec_state_);
32589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
32599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32619dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comv8::Handle<v8::Object> EventDetailsImpl::GetEventData() const {
32629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return v8::Utils::ToLocal(event_data_);
32639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
32649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comv8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const {
3267e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  return GetDebugEventContext(exec_state_->GetIsolate());
32689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
32699dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comv8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const {
32729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  return v8::Utils::ToLocal(callback_data_);
32739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
32749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
32759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
327622762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.comv8::Debug::ClientData* EventDetailsImpl::GetClientData() const {
327722762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com  return client_data_;
327822762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com}
327922762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com
328022762870ddc5995ca60f432799b94a6abd7680cemikhail.naganov@gmail.com
32813a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
32823a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org                                   client_data_(NULL) {
328341826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
328441826e77311db718135ef6517b846933dfd275f3ager@chromium.org
328541826e77311db718135ef6517b846933dfd275f3ager@chromium.org
32863a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage::CommandMessage(const Vector<uint16_t>& text,
32873a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org                               v8::Debug::ClientData* data)
328865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    : text_(text),
328965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      client_data_(data) {
329065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
329165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
329265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
32933a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid CommandMessage::Dispose() {
329465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  text_.Dispose();
329565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  delete client_data_;
329665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  client_data_ = NULL;
329765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
329865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
329965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
33003a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage CommandMessage::New(const Vector<uint16_t>& command,
33013a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org                                   v8::Debug::ClientData* data) {
33023a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  return CommandMessage(command.Clone(), data);
330365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
330465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
330565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
33063a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
33073a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org                                                     size_(size) {
33083a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  messages_ = NewArray<CommandMessage>(size);
33097276f14ca716596e0a0d17539516370c1f453847kasper.lund}
33107276f14ca716596e0a0d17539516370c1f453847kasper.lund
33117276f14ca716596e0a0d17539516370c1f453847kasper.lund
33123a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessageQueue::~CommandMessageQueue() {
33138d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  while (!IsEmpty()) Get().Dispose();
33147276f14ca716596e0a0d17539516370c1f453847kasper.lund  DeleteArray(messages_);
33157276f14ca716596e0a0d17539516370c1f453847kasper.lund}
33167276f14ca716596e0a0d17539516370c1f453847kasper.lund
33177276f14ca716596e0a0d17539516370c1f453847kasper.lund
33183a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage CommandMessageQueue::Get() {
3319e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsEmpty());
33207276f14ca716596e0a0d17539516370c1f453847kasper.lund  int result = start_;
33217276f14ca716596e0a0d17539516370c1f453847kasper.lund  start_ = (start_ + 1) % size_;
33227276f14ca716596e0a0d17539516370c1f453847kasper.lund  return messages_[result];
33237276f14ca716596e0a0d17539516370c1f453847kasper.lund}
33247276f14ca716596e0a0d17539516370c1f453847kasper.lund
33257276f14ca716596e0a0d17539516370c1f453847kasper.lund
33263a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid CommandMessageQueue::Put(const CommandMessage& message) {
33277276f14ca716596e0a0d17539516370c1f453847kasper.lund  if ((end_ + 1) % size_ == start_) {
33287276f14ca716596e0a0d17539516370c1f453847kasper.lund    Expand();
33297276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
33307276f14ca716596e0a0d17539516370c1f453847kasper.lund  messages_[end_] = message;
33317276f14ca716596e0a0d17539516370c1f453847kasper.lund  end_ = (end_ + 1) % size_;
33327276f14ca716596e0a0d17539516370c1f453847kasper.lund}
33337276f14ca716596e0a0d17539516370c1f453847kasper.lund
33347276f14ca716596e0a0d17539516370c1f453847kasper.lund
33353a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid CommandMessageQueue::Expand() {
33363a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  CommandMessageQueue new_queue(size_ * 2);
33377276f14ca716596e0a0d17539516370c1f453847kasper.lund  while (!IsEmpty()) {
33387276f14ca716596e0a0d17539516370c1f453847kasper.lund    new_queue.Put(Get());
333943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
33403a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  CommandMessage* array_to_free = messages_;
33417276f14ca716596e0a0d17539516370c1f453847kasper.lund  *this = new_queue;
33427276f14ca716596e0a0d17539516370c1f453847kasper.lund  new_queue.messages_ = array_to_free;
334365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Make the new_queue empty so that it doesn't call Dispose on any messages.
334465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  new_queue.start_ = new_queue.end_;
33457276f14ca716596e0a0d17539516370c1f453847kasper.lund  // Automatic destructor called on new_queue, freeing array_to_free.
33467276f14ca716596e0a0d17539516370c1f453847kasper.lund}
33477276f14ca716596e0a0d17539516370c1f453847kasper.lund
33487276f14ca716596e0a0d17539516370c1f453847kasper.lund
33496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgLockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
3350dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    : logger_(logger), queue_(size) {}
33517276f14ca716596e0a0d17539516370c1f453847kasper.lund
33527276f14ca716596e0a0d17539516370c1f453847kasper.lund
33533a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgbool LockingCommandMessageQueue::IsEmpty() const {
33545de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::LockGuard<base::Mutex> lock_guard(&mutex_);
33557276f14ca716596e0a0d17539516370c1f453847kasper.lund  return queue_.IsEmpty();
335643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
335743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33587276f14ca716596e0a0d17539516370c1f453847kasper.lund
33593a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgCommandMessage LockingCommandMessageQueue::Get() {
33605de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::LockGuard<base::Mutex> lock_guard(&mutex_);
33613a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org  CommandMessage result = queue_.Get();
33626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  logger_->DebugEvent("Get", result.text());
33637276f14ca716596e0a0d17539516370c1f453847kasper.lund  return result;
33647276f14ca716596e0a0d17539516370c1f453847kasper.lund}
33657276f14ca716596e0a0d17539516370c1f453847kasper.lund
33667276f14ca716596e0a0d17539516370c1f453847kasper.lund
33673a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid LockingCommandMessageQueue::Put(const CommandMessage& message) {
33685de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::LockGuard<base::Mutex> lock_guard(&mutex_);
33697276f14ca716596e0a0d17539516370c1f453847kasper.lund  queue_.Put(message);
33706d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  logger_->DebugEvent("Put", message.text());
33717276f14ca716596e0a0d17539516370c1f453847kasper.lund}
33727276f14ca716596e0a0d17539516370c1f453847kasper.lund
33737276f14ca716596e0a0d17539516370c1f453847kasper.lund
33743a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.orgvoid LockingCommandMessageQueue::Clear() {
33755de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::LockGuard<base::Mutex> lock_guard(&mutex_);
33767276f14ca716596e0a0d17539516370c1f453847kasper.lund  queue_.Clear();
33777276f14ca716596e0a0d17539516370c1f453847kasper.lund}
33787276f14ca716596e0a0d17539516370c1f453847kasper.lund
337943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
3380