Debugger: move implementation to a separate folder.
authoryangguo <yangguo@chromium.org>
Fri, 31 Jul 2015 11:07:50 +0000 (04:07 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 31 Jul 2015 11:08:15 +0000 (11:08 +0000)
R=cbruni@chromium.org

Review URL: https://codereview.chromium.org/1265923002

Cr-Commit-Position: refs/heads/master@{#29951}

115 files changed:
BUILD.gn
WATCHLISTS
src/api.cc
src/arm/assembler-arm-inl.h
src/arm/builtins-arm.cc
src/arm/debug-arm.cc [deleted file]
src/arm/macro-assembler-arm.cc
src/arm64/assembler-arm64-inl.h
src/arm64/builtins-arm64.cc
src/arm64/debug-arm64.cc [deleted file]
src/arm64/macro-assembler-arm64.cc
src/assembler.cc
src/assert-scope.cc
src/background-parsing-task.cc
src/codegen.cc
src/compiler.cc
src/contexts.cc
src/debug-debugger.js [deleted file]
src/debug.cc [deleted file]
src/debug.h [deleted file]
src/debug/OWNERS [new file with mode: 0644]
src/debug/arm/OWNERS [new file with mode: 0644]
src/debug/arm/debug-arm.cc [new file with mode: 0644]
src/debug/arm64/OWNERS [new file with mode: 0644]
src/debug/arm64/debug-arm64.cc [new file with mode: 0644]
src/debug/debug.cc [new file with mode: 0644]
src/debug/debug.h [new file with mode: 0644]
src/debug/debug.js [new file with mode: 0644]
src/debug/ia32/debug-ia32.cc [new file with mode: 0644]
src/debug/liveedit.cc [new file with mode: 0644]
src/debug/liveedit.h [new file with mode: 0644]
src/debug/liveedit.js [new file with mode: 0644]
src/debug/mips/OWNERS [new file with mode: 0644]
src/debug/mips/debug-mips.cc [new file with mode: 0644]
src/debug/mips64/OWNERS [new file with mode: 0644]
src/debug/mips64/debug-mips64.cc [new file with mode: 0644]
src/debug/mirrors.js [new file with mode: 0644]
src/debug/ppc/OWNERS [new file with mode: 0644]
src/debug/ppc/debug-ppc.cc [new file with mode: 0644]
src/debug/x64/debug-x64.cc [new file with mode: 0644]
src/debug/x87/OWNERS [new file with mode: 0644]
src/debug/x87/debug-x87.cc [new file with mode: 0644]
src/disassembler.cc
src/full-codegen/arm/full-codegen-arm.cc
src/full-codegen/arm64/full-codegen-arm64.cc
src/full-codegen/full-codegen.cc
src/full-codegen/ia32/full-codegen-ia32.cc
src/full-codegen/mips/full-codegen-mips.cc
src/full-codegen/mips64/full-codegen-mips64.cc
src/full-codegen/ppc/full-codegen-ppc.cc
src/full-codegen/x64/full-codegen-x64.cc
src/full-codegen/x87/full-codegen-x87.cc
src/heap-snapshot-generator.cc
src/heap/heap.cc
src/ia32/assembler-ia32-inl.h
src/ia32/debug-ia32.cc [deleted file]
src/ia32/macro-assembler-ia32.cc
src/ic/ic-inl.h
src/isolate.cc
src/liveedit-debugger.js [deleted file]
src/liveedit.cc [deleted file]
src/liveedit.h [deleted file]
src/mips/assembler-mips-inl.h
src/mips/builtins-mips.cc
src/mips/debug-mips.cc [deleted file]
src/mips/macro-assembler-mips.cc
src/mips64/assembler-mips64-inl.h
src/mips64/builtins-mips64.cc
src/mips64/debug-mips64.cc [deleted file]
src/mips64/macro-assembler-mips64.cc
src/mirror-debugger.js [deleted file]
src/objects.cc
src/pending-compilation-error-handler.cc
src/ppc/assembler-ppc-inl.h
src/ppc/builtins-ppc.cc
src/ppc/debug-ppc.cc [deleted file]
src/ppc/macro-assembler-ppc.cc
src/profile-generator.cc
src/property-details.h
src/runtime/runtime-classes.cc
src/runtime/runtime-debug.cc
src/runtime/runtime-internal.cc
src/runtime/runtime-liveedit.cc
src/runtime/runtime-object.cc
src/runtime/runtime-observe.cc
src/v8.cc
src/v8threads.cc
src/x64/assembler-x64-inl.h
src/x64/debug-x64.cc [deleted file]
src/x64/macro-assembler-x64.cc
src/x87/assembler-x87-inl.h
src/x87/debug-x87.cc [deleted file]
src/x87/macro-assembler-x87.cc
test/cctest/cctest.cc
test/cctest/test-api.cc
test/cctest/test-debug.cc
test/cctest/test-deoptimization.cc
test/cctest/test-dictionary.cc
test/cctest/test-disasm-arm.cc
test/cctest/test-disasm-ia32.cc
test/cctest/test-disasm-mips.cc
test/cctest/test-disasm-mips64.cc
test/cctest/test-disasm-ppc.cc
test/cctest/test-disasm-x64.cc
test/cctest/test-disasm-x87.cc
test/cctest/test-feedback-vector.cc
test/cctest/test-func-name-inference.cc
test/cctest/test-heap-profiler.cc
test/cctest/test-liveedit.cc
test/cctest/test-serialize.cc
test/mjsunit/debug-function-scopes.js
test/mjsunit/es6/debug-function-scopes.js
test/unittests/test-utils.cc
tools/gyp/v8.gyp
tools/js2c.py

index 1619d7747d07f08cedc7d99897cff2523b4cb7f7..d194d63256cdeecbe177cc13719aa865f08d91b3 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -227,12 +227,12 @@ action("js2c") {
     "src/json.js",
     "src/array-iterator.js",
     "src/string-iterator.js",
-    "src/debug-debugger.js",
-    "src/mirror-debugger.js",
-    "src/liveedit-debugger.js",
     "src/templates.js",
     "src/harmony-array.js",
     "src/harmony-typedarray.js",
+    "src/debug/debug.js",
+    "src/debug/mirrors.js",
+    "src/debug/liveedit.js",
   ]
 
   outputs = [
@@ -834,8 +834,10 @@ source_set("v8_base") {
     "src/dateparser-inl.h",
     "src/dateparser.cc",
     "src/dateparser.h",
-    "src/debug.cc",
-    "src/debug.h",
+    "src/debug/debug.cc",
+    "src/debug/debug.h",
+    "src/debug/liveedit.cc",
+    "src/debug/liveedit.h",
     "src/deoptimizer.cc",
     "src/deoptimizer.h",
     "src/disasm.h",
@@ -1021,8 +1023,6 @@ source_set("v8_base") {
     "src/lithium-codegen.h",
     "src/lithium.cc",
     "src/lithium.h",
-    "src/liveedit.cc",
-    "src/liveedit.h",
     "src/log-inl.h",
     "src/log-utils.cc",
     "src/log-utils.h",
@@ -1199,7 +1199,6 @@ source_set("v8_base") {
       "src/ia32/codegen-ia32.cc",
       "src/ia32/codegen-ia32.h",
       "src/ia32/cpu-ia32.cc",
-      "src/ia32/debug-ia32.cc",
       "src/ia32/deoptimizer-ia32.cc",
       "src/ia32/disasm-ia32.cc",
       "src/ia32/frames-ia32.cc",
@@ -1219,6 +1218,7 @@ source_set("v8_base") {
       "src/compiler/ia32/instruction-codes-ia32.h",
       "src/compiler/ia32/instruction-selector-ia32.cc",
       "src/compiler/ia32/linkage-ia32.cc",
+      "src/debug/ia32/debug-ia32.cc",
       "src/full-codegen/ia32/full-codegen-ia32.cc",
       "src/ic/ia32/access-compiler-ia32.cc",
       "src/ic/ia32/handler-compiler-ia32.cc",
@@ -1237,7 +1237,6 @@ source_set("v8_base") {
       "src/x64/codegen-x64.cc",
       "src/x64/codegen-x64.h",
       "src/x64/cpu-x64.cc",
-      "src/x64/debug-x64.cc",
       "src/x64/deoptimizer-x64.cc",
       "src/x64/disasm-x64.cc",
       "src/x64/frames-x64.cc",
@@ -1257,6 +1256,7 @@ source_set("v8_base") {
       "src/compiler/x64/instruction-codes-x64.h",
       "src/compiler/x64/instruction-selector-x64.cc",
       "src/compiler/x64/linkage-x64.cc",
+      "src/debug/x64/debug-x64.cc",
       "src/full-codegen/x64/full-codegen-x64.cc",
       "src/ic/x64/access-compiler-x64.cc",
       "src/ic/x64/handler-compiler-x64.cc",
@@ -1277,7 +1277,6 @@ source_set("v8_base") {
       "src/arm/constants-arm.h",
       "src/arm/constants-arm.cc",
       "src/arm/cpu-arm.cc",
-      "src/arm/debug-arm.cc",
       "src/arm/deoptimizer-arm.cc",
       "src/arm/disasm-arm.cc",
       "src/arm/frames-arm.cc",
@@ -1300,6 +1299,7 @@ source_set("v8_base") {
       "src/compiler/arm/instruction-codes-arm.h",
       "src/compiler/arm/instruction-selector-arm.cc",
       "src/compiler/arm/linkage-arm.cc",
+      "src/debug/arm/debug-arm.cc",
       "src/full-codegen/arm/full-codegen-arm.cc",
       "src/ic/arm/access-compiler-arm.cc",
       "src/ic/arm/handler-compiler-arm.cc",
@@ -1319,7 +1319,6 @@ source_set("v8_base") {
       "src/arm64/code-stubs-arm64.h",
       "src/arm64/constants-arm64.h",
       "src/arm64/cpu-arm64.cc",
-      "src/arm64/debug-arm64.cc",
       "src/arm64/decoder-arm64.cc",
       "src/arm64/decoder-arm64.h",
       "src/arm64/decoder-arm64-inl.h",
@@ -1353,6 +1352,7 @@ source_set("v8_base") {
       "src/compiler/arm64/instruction-codes-arm64.h",
       "src/compiler/arm64/instruction-selector-arm64.cc",
       "src/compiler/arm64/linkage-arm64.cc",
+      "src/debug/arm64/debug-arm64.cc",
       "src/full-codegen/arm64/full-codegen-arm64.cc",
       "src/ic/arm64/access-compiler-arm64.cc",
       "src/ic/arm64/handler-compiler-arm64.cc",
@@ -1373,7 +1373,6 @@ source_set("v8_base") {
       "src/mips/constants-mips.cc",
       "src/mips/constants-mips.h",
       "src/mips/cpu-mips.cc",
-      "src/mips/debug-mips.cc",
       "src/mips/deoptimizer-mips.cc",
       "src/mips/disasm-mips.cc",
       "src/mips/frames-mips.cc",
@@ -1395,6 +1394,7 @@ source_set("v8_base") {
       "src/compiler/mips/instruction-codes-mips.h",
       "src/compiler/mips/instruction-selector-mips.cc",
       "src/compiler/mips/linkage-mips.cc",
+      "src/debug/mips/debug-mips.cc",
       "src/full-codegen/mips/full-codegen-mips.cc",
       "src/ic/mips/access-compiler-mips.cc",
       "src/ic/mips/handler-compiler-mips.cc",
@@ -1415,7 +1415,6 @@ source_set("v8_base") {
       "src/mips64/constants-mips64.cc",
       "src/mips64/constants-mips64.h",
       "src/mips64/cpu-mips64.cc",
-      "src/mips64/debug-mips64.cc",
       "src/mips64/deoptimizer-mips64.cc",
       "src/mips64/disasm-mips64.cc",
       "src/mips64/frames-mips64.cc",
@@ -1433,6 +1432,7 @@ source_set("v8_base") {
       "src/mips64/regexp-macro-assembler-mips64.h",
       "src/mips64/simulator-mips64.cc",
       "src/mips64/simulator-mips64.h",
+      "src/debug/mips64/debug-mips64.cc",
       "src/full-codegen/mips64/full-codegen-mips64.cc",
       "src/ic/mips64/access-compiler-mips64.cc",
       "src/ic/mips64/handler-compiler-mips64.cc",
index 64771bc27dc61e56c0073b6913da4132e8ee1188..f57dfa140258f3ab10bf3ccd37bdb48c5d151e87 100644 (file)
@@ -40,7 +40,7 @@
       'filepath': 'src/snapshot/',
     },
     'debugger': {
-      'filepath': 'src/debug\.(cc|h)|src/.*-debugger\.js|src/runtime/runtime-debug\.cc',
+      'filepath': 'src/debug/',
     },
   },
 
index 74970e88fbb830ce6278553f9b2d3d0215ca9a38..586fd8613a5a4b9dcaa5b47bfa4d56e65d804c7b 100644 (file)
@@ -26,7 +26,7 @@
 #include "src/conversions-inl.h"
 #include "src/counters.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/execution.h"
 #include "src/global-handles.h"
index 73bf4bb9c1bd7dfbdcf092129c08f61f23a0f57f..523000ec3a34dc7a796a4151422e0dec08eda555 100644 (file)
@@ -40,7 +40,7 @@
 #include "src/arm/assembler-arm.h"
 
 #include "src/assembler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 
 
 namespace v8 {
index 50066137e404759f01b1f57456002a8144660f92..b33a1957ee829d7ab88c12987fd5ec43d0be7a6b 100644 (file)
@@ -7,7 +7,7 @@
 #if V8_TARGET_ARCH_ARM
 
 #include "src/codegen.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/interpreter/bytecodes.h"
diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc
deleted file mode 100644 (file)
index d2b9a80..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#if V8_TARGET_ARCH_ARM
-
-#include "src/codegen.h"
-#include "src/debug.h"
-
-namespace v8 {
-namespace internal {
-
-#define __ ACCESS_MASM(masm)
-
-
-void EmitDebugBreakSlot(MacroAssembler* masm) {
-  Label check_size;
-  __ bind(&check_size);
-  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
-    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
-  }
-  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
-            masm->InstructionsGeneratedSince(&check_size));
-}
-
-
-void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                                int call_argc) {
-  // Generate enough nop's to make space for a call instruction. Avoid emitting
-  // the constant pool in the debug break slot code.
-  Assembler::BlockConstPoolScope block_const_pool(masm);
-  masm->RecordDebugBreakSlot(mode, call_argc);
-  EmitDebugBreakSlot(masm);
-}
-
-
-void DebugCodegen::ClearDebugBreakSlot(Address pc) {
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
-  EmitDebugBreakSlot(patcher.masm());
-}
-
-
-void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
-  DCHECK_EQ(Code::BUILTIN, code->kind());
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
-  // Patch the code changing the debug break slot code from
-  //   mov r2, r2
-  //   mov r2, r2
-  //   mov r2, r2
-  //   mov r2, r2
-  // to a call to the debug break slot code.
-  //   ldr ip, [pc, #0]
-  //   b skip
-  //   <debug break slot code entry point address>
-  //   skip:
-  //   blx ip
-  Label skip_constant;
-  patcher.masm()->ldr(ip, MemOperand(v8::internal::pc, 0));
-  patcher.masm()->b(&skip_constant);
-  patcher.Emit(code->entry());
-  patcher.masm()->bind(&skip_constant);
-  patcher.masm()->blx(ip);
-}
-
-
-void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
-                                          DebugBreakCallHelperMode mode) {
-  __ RecordComment("Debug break");
-  {
-    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
-
-    // Load padding words on stack.
-    __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue)));
-    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
-      __ push(ip);
-    }
-    __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
-    __ push(ip);
-
-    if (mode == SAVE_RESULT_REGISTER) __ push(r0);
-
-    __ mov(r0, Operand::Zero());  // no arguments
-    __ mov(r1,
-           Operand(ExternalReference(
-               Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
-
-    CEntryStub ceb(masm->isolate(), 1);
-    __ CallStub(&ceb);
-
-    if (FLAG_debug_code) {
-      for (int i = 0; i < kNumJSCallerSaved; i++) {
-        Register reg = {JSCallerSavedCode(i)};
-        __ mov(reg, Operand(kDebugZapValue));
-      }
-    }
-
-    if (mode == SAVE_RESULT_REGISTER) __ pop(r0);
-
-    // Don't bother removing padding bytes pushed on the stack
-    // as the frame is going to be restored right away.
-
-    // Leave the internal frame.
-  }
-
-  // Now that the break point has been handled, resume normal execution by
-  // jumping to the target address intended by the caller and that was
-  // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target =
-      ExternalReference::debug_after_break_target_address(masm->isolate());
-  __ mov(ip, Operand(after_break_target));
-  __ ldr(ip, MemOperand(ip));
-  __ Jump(ip);
-}
-
-
-void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
-  __ Ret();
-}
-
-
-void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
-  ExternalReference restarter_frame_function_slot =
-      ExternalReference::debug_restarter_frame_function_pointer_address(
-          masm->isolate());
-  __ mov(ip, Operand(restarter_frame_function_slot));
-  __ mov(r1, Operand::Zero());
-  __ str(r1, MemOperand(ip, 0));
-
-  // Load the function pointer off of our current stack frame.
-  __ ldr(r1, MemOperand(fp,
-         StandardFrameConstants::kConstantPoolOffset - kPointerSize));
-
-  // Pop return address, frame and constant pool pointer (if
-  // FLAG_enable_embedded_constant_pool).
-  __ LeaveFrame(StackFrame::INTERNAL);
-
-  { ConstantPoolUnavailableScope constant_pool_unavailable(masm);
-    // Load context from the function.
-    __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
-
-    // Get function code.
-    __ ldr(ip, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
-    __ ldr(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset));
-    __ add(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-    // Re-run JSFunction, r1 is function, cp is context.
-    __ Jump(ip);
-  }
-}
-
-
-const bool LiveEdit::kFrameDropperSupported = true;
-
-#undef __
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TARGET_ARCH_ARM
index 7b7d19322fdcf501104d3f67ed3324a665632a48..feeba98d73aeadc7c993499208b715afa1e1aadc 100644 (file)
@@ -13,7 +13,7 @@
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
index 729a5d0fde84fe18b2198a8f255cfae00c32fcf1..9fc89c3042ce48ae5a67d3148e09632666bc4b19 100644 (file)
@@ -7,7 +7,7 @@
 
 #include "src/arm64/assembler-arm64.h"
 #include "src/assembler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 
 
 namespace v8 {
index b99431e0de6fad6930566c113f0c9287fdec2485..d93b5ad62f4f5bf9cdbbf28e21ace71c0b38a97b 100644 (file)
@@ -7,7 +7,7 @@
 #if V8_TARGET_ARCH_ARM64
 
 #include "src/codegen.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/runtime/runtime.h"
diff --git a/src/arm64/debug-arm64.cc b/src/arm64/debug-arm64.cc
deleted file mode 100644 (file)
index 8290ce4..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#if V8_TARGET_ARCH_ARM64
-
-#include "src/codegen.h"
-#include "src/debug.h"
-
-namespace v8 {
-namespace internal {
-
-#define __ ACCESS_MASM(masm)
-
-
-void EmitDebugBreakSlot(Assembler* masm) {
-  Label check_size;
-  __ bind(&check_size);
-  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
-    __ nop(Assembler::DEBUG_BREAK_NOP);
-  }
-  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
-            static_cast<int>(masm->InstructionsGeneratedSince(&check_size)));
-}
-
-
-void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                                int call_argc) {
-  // Generate enough nop's to make space for a call instruction. Avoid emitting
-  // the constant pool in the debug break slot code.
-  InstructionAccurateScope scope(masm, Assembler::kDebugBreakSlotInstructions);
-  masm->RecordDebugBreakSlot(mode, call_argc);
-  EmitDebugBreakSlot(masm);
-}
-
-
-void DebugCodegen::ClearDebugBreakSlot(Address pc) {
-  PatchingAssembler patcher(reinterpret_cast<Instruction*>(pc),
-                            Assembler::kDebugBreakSlotInstructions);
-  EmitDebugBreakSlot(&patcher);
-}
-
-
-void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
-  DCHECK_EQ(Code::BUILTIN, code->kind());
-  PatchingAssembler patcher(reinterpret_cast<Instruction*>(pc),
-                            Assembler::kDebugBreakSlotInstructions);
-  // Patch the code emitted by DebugCodegen::GenerateSlots, changing the debug
-  // break slot code from
-  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
-  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
-  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
-  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
-  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
-  // to a call to the debug slot code.
-  //   ldr ip0, [pc, #(2 * kInstructionSize)]
-  //   blr ip0
-  //   b skip
-  //   <debug break slot code entry point address (64 bits)>
-  //   skip:
-
-  Label skip_constant;
-  // The first instruction of a patched debug break slot must be a load literal
-  // loading the address of the debug break slot code.
-  patcher.ldr_pcrel(ip0, (2 * kInstructionSize) >> kLoadLiteralScaleLog2);
-  patcher.b(&skip_constant);
-  patcher.dc64(reinterpret_cast<int64_t>(code->entry()));
-  patcher.bind(&skip_constant);
-  // TODO(all): check the following is correct.
-  // The debug break slot code will push a frame and call statically compiled
-  // code. By using blr,  this call site will be registered in the frame.
-  // The debugger can now iterate on the frames to find this call.
-  patcher.blr(ip0);
-}
-
-
-void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
-                                          DebugBreakCallHelperMode mode) {
-  __ RecordComment("Debug break");
-  Register scratch = x10;
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Load padding words on stack.
-    __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingValue));
-    __ PushMultipleTimes(scratch, LiveEdit::kFramePaddingInitialSize);
-    __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
-    __ Push(scratch);
-
-    if (mode == SAVE_RESULT_REGISTER) __ Push(x0);
-
-    __ Mov(x0, 0);  // No arguments.
-    __ Mov(x1, ExternalReference(Runtime::FunctionForId(Runtime::kDebugBreak),
-                                 masm->isolate()));
-
-    CEntryStub stub(masm->isolate(), 1);
-    __ CallStub(&stub);
-
-    if (FLAG_debug_code) {
-      for (int i = 0; i < kNumJSCallerSaved; i++) {
-        Register reg = Register::XRegFromCode(JSCallerSavedCode(i));
-        __ Mov(reg, Operand(kDebugZapValue));
-      }
-    }
-
-    // Restore the register values from the expression stack.
-    if (mode == SAVE_RESULT_REGISTER) __ Pop(x0);
-
-    // Don't bother removing padding bytes pushed on the stack
-    // as the frame is going to be restored right away.
-
-    // Leave the internal frame.
-  }
-
-  // Now that the break point has been handled, resume normal execution by
-  // jumping to the target address intended by the caller and that was
-  // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target =
-      ExternalReference::debug_after_break_target_address(masm->isolate());
-  __ Mov(scratch, after_break_target);
-  __ Ldr(scratch, MemOperand(scratch));
-  __ Br(scratch);
-}
-
-
-void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
-  __ Ret();
-}
-
-
-void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
-  ExternalReference restarter_frame_function_slot =
-      ExternalReference::debug_restarter_frame_function_pointer_address(
-          masm->isolate());
-  UseScratchRegisterScope temps(masm);
-  Register scratch = temps.AcquireX();
-
-  __ Mov(scratch, restarter_frame_function_slot);
-  __ Str(xzr, MemOperand(scratch));
-
-  // We do not know our frame height, but set sp based on fp.
-  __ Sub(masm->StackPointer(), fp, kPointerSize);
-  __ AssertStackConsistency();
-
-  __ Pop(x1, fp, lr);  // Function, Frame, Return address.
-
-  // Load context from the function.
-  __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
-
-  // Get function code.
-  __ Ldr(scratch, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
-  __ Ldr(scratch, FieldMemOperand(scratch, SharedFunctionInfo::kCodeOffset));
-  __ Add(scratch, scratch, Code::kHeaderSize - kHeapObjectTag);
-
-  // Re-run JSFunction, x1 is function, cp is context.
-  __ Br(scratch);
-}
-
-
-const bool LiveEdit::kFrameDropperSupported = true;
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TARGET_ARCH_ARM64
index e754241eb67d5f2fbd78603294ba39d27bc71009..e43ffac25e2a078285447984d7fb7b7fd8561d2c 100644 (file)
@@ -11,7 +11,7 @@
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
index 20a172b6526ce1e60ef7fd31bef59d93a352c75b..363e60466e7e386070a3ad1a124f8b893eb1547f 100644 (file)
@@ -45,7 +45,7 @@
 #include "src/codegen.h"
 #include "src/counters.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/execution.h"
 #include "src/ic/ic.h"
index 3b91cf4389777a1377546b0a327c9f4e3d7239e6..6cc2e5a08176e77d946472dc43d5115fc823f9af 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "src/base/lazy-instance.h"
 #include "src/base/platform/platform.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/isolate.h"
 #include "src/utils.h"
 
index c0dba93a533663a51f319e42bda75fb769ecbf54..cc80e0114319a7af442123aea05cbace4ead89a2 100644 (file)
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "src/background-parsing-task.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 
 namespace v8 {
 namespace internal {
index 3e1b93d3810e6a688263e9a10334d01bf47b370e..6eb1ff1155ad4c47adc39386140abf914e05c11d 100644 (file)
@@ -11,7 +11,7 @@
 #include "src/codegen.h"
 #include "src/compiler.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/parser.h"
 #include "src/prettyprinter.h"
 #include "src/rewriter.h"
index 1815c9a8d6441176ba61503aa3ba2186ddc30abe..7f060dc244817809d00e90fa8247a0dab1ff5c5e 100644 (file)
 #include "src/compilation-cache.h"
 #include "src/compiler/pipeline.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
+#include "src/debug/liveedit.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/gdb-jit.h"
 #include "src/hydrogen.h"
 #include "src/lithium.h"
-#include "src/liveedit.h"
 #include "src/messages.h"
 #include "src/parser.h"
 #include "src/prettyprinter.h"
index 31ce98c8986b402bba38a1d13a1f87be9b2f6d9e..8263269d117c2d06a6f8fd2947f31097ef942895 100644 (file)
@@ -5,7 +5,7 @@
 #include "src/v8.h"
 
 #include "src/bootstrapper.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/scopeinfo.h"
 
 namespace v8 {
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
deleted file mode 100644 (file)
index 991af11..0000000
+++ /dev/null
@@ -1,2569 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-"use strict";
-
-// Default number of frames to include in the response to backtrace request.
-var kDefaultBacktraceLength = 10;
-
-var Debug = {};
-
-// Regular expression to skip "crud" at the beginning of a source line which is
-// not really code. Currently the regular expression matches whitespace and
-// comments.
-var sourceLineBeginningSkip = /^(?:\s*(?:\/\*.*?\*\/)*)*/;
-
-// Debug events which can occour in the V8 JavaScript engine. These originate
-// from the API include file debug.h.
-Debug.DebugEvent = { Break: 1,
-                     Exception: 2,
-                     NewFunction: 3,
-                     BeforeCompile: 4,
-                     AfterCompile: 5,
-                     CompileError: 6,
-                     PromiseEvent: 7,
-                     AsyncTaskEvent: 8 };
-
-// Types of exceptions that can be broken upon.
-Debug.ExceptionBreak = { Caught : 0,
-                         Uncaught: 1 };
-
-// The different types of steps.
-Debug.StepAction = { StepOut: 0,
-                     StepNext: 1,
-                     StepIn: 2,
-                     StepMin: 3,
-                     StepInMin: 4,
-                     StepFrame: 5 };
-
-// The different types of scripts matching enum ScriptType in objects.h.
-Debug.ScriptType = { Native: 0,
-                     Extension: 1,
-                     Normal: 2 };
-
-// The different types of script compilations matching enum
-// Script::CompilationType in objects.h.
-Debug.ScriptCompilationType = { Host: 0,
-                                Eval: 1,
-                                JSON: 2 };
-
-// The different script break point types.
-Debug.ScriptBreakPointType = { ScriptId: 0,
-                               ScriptName: 1,
-                               ScriptRegExp: 2 };
-
-// The different types of breakpoint position alignments.
-// Must match BreakPositionAlignment in debug.h.
-Debug.BreakPositionAlignment = {
-  Statement: 0,
-  BreakPosition: 1
-};
-
-function ScriptTypeFlag(type) {
-  return (1 << type);
-}
-
-// Globals.
-var next_response_seq = 0;
-var next_break_point_number = 1;
-var break_points = [];
-var script_break_points = [];
-var debugger_flags = {
-  breakPointsActive: {
-    value: true,
-    getValue: function() { return this.value; },
-    setValue: function(value) {
-      this.value = !!value;
-      %SetDisableBreak(!this.value);
-    }
-  },
-  breakOnCaughtException: {
-    getValue: function() { return Debug.isBreakOnException(); },
-    setValue: function(value) {
-      if (value) {
-        Debug.setBreakOnException();
-      } else {
-        Debug.clearBreakOnException();
-      }
-    }
-  },
-  breakOnUncaughtException: {
-    getValue: function() { return Debug.isBreakOnUncaughtException(); },
-    setValue: function(value) {
-      if (value) {
-        Debug.setBreakOnUncaughtException();
-      } else {
-        Debug.clearBreakOnUncaughtException();
-      }
-    }
-  },
-};
-
-
-// Create a new break point object and add it to the list of break points.
-function MakeBreakPoint(source_position, opt_script_break_point) {
-  var break_point = new BreakPoint(source_position, opt_script_break_point);
-  break_points.push(break_point);
-  return break_point;
-}
-
-
-// Object representing a break point.
-// NOTE: This object does not have a reference to the function having break
-// point as this would cause function not to be garbage collected when it is
-// not used any more. We do not want break points to keep functions alive.
-function BreakPoint(source_position, opt_script_break_point) {
-  this.source_position_ = source_position;
-  if (opt_script_break_point) {
-    this.script_break_point_ = opt_script_break_point;
-  } else {
-    this.number_ = next_break_point_number++;
-  }
-  this.hit_count_ = 0;
-  this.active_ = true;
-  this.condition_ = null;
-  this.ignoreCount_ = 0;
-}
-
-
-BreakPoint.prototype.number = function() {
-  return this.number_;
-};
-
-
-BreakPoint.prototype.func = function() {
-  return this.func_;
-};
-
-
-BreakPoint.prototype.source_position = function() {
-  return this.source_position_;
-};
-
-
-BreakPoint.prototype.hit_count = function() {
-  return this.hit_count_;
-};
-
-
-BreakPoint.prototype.active = function() {
-  if (this.script_break_point()) {
-    return this.script_break_point().active();
-  }
-  return this.active_;
-};
-
-
-BreakPoint.prototype.condition = function() {
-  if (this.script_break_point() && this.script_break_point().condition()) {
-    return this.script_break_point().condition();
-  }
-  return this.condition_;
-};
-
-
-BreakPoint.prototype.ignoreCount = function() {
-  return this.ignoreCount_;
-};
-
-
-BreakPoint.prototype.script_break_point = function() {
-  return this.script_break_point_;
-};
-
-
-BreakPoint.prototype.enable = function() {
-  this.active_ = true;
-};
-
-
-BreakPoint.prototype.disable = function() {
-  this.active_ = false;
-};
-
-
-BreakPoint.prototype.setCondition = function(condition) {
-  this.condition_ = condition;
-};
-
-
-BreakPoint.prototype.setIgnoreCount = function(ignoreCount) {
-  this.ignoreCount_ = ignoreCount;
-};
-
-
-BreakPoint.prototype.isTriggered = function(exec_state) {
-  // Break point not active - not triggered.
-  if (!this.active()) return false;
-
-  // Check for conditional break point.
-  if (this.condition()) {
-    // If break point has condition try to evaluate it in the top frame.
-    try {
-      var mirror = exec_state.frame(0).evaluate(this.condition());
-      // If no sensible mirror or non true value break point not triggered.
-      if (!(mirror instanceof ValueMirror) ||
-          !builtins.$toBoolean(mirror.value_)) {
-        return false;
-      }
-    } catch (e) {
-      // Exception evaluating condition counts as not triggered.
-      return false;
-    }
-  }
-
-  // Update the hit count.
-  this.hit_count_++;
-  if (this.script_break_point_) {
-    this.script_break_point_.hit_count_++;
-  }
-
-  // If the break point has an ignore count it is not triggered.
-  if (this.ignoreCount_ > 0) {
-    this.ignoreCount_--;
-    return false;
-  }
-
-  // Break point triggered.
-  return true;
-};
-
-
-// Function called from the runtime when a break point is hit. Returns true if
-// the break point is triggered and supposed to break execution.
-function IsBreakPointTriggered(break_id, break_point) {
-  return break_point.isTriggered(MakeExecutionState(break_id));
-}
-
-
-// Object representing a script break point. The script is referenced by its
-// script name or script id and the break point is represented as line and
-// column.
-function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
-                          opt_groupId, opt_position_alignment) {
-  this.type_ = type;
-  if (type == Debug.ScriptBreakPointType.ScriptId) {
-    this.script_id_ = script_id_or_name;
-  } else if (type == Debug.ScriptBreakPointType.ScriptName) {
-    this.script_name_ = script_id_or_name;
-  } else if (type == Debug.ScriptBreakPointType.ScriptRegExp) {
-    this.script_regexp_object_ = new RegExp(script_id_or_name);
-  } else {
-    throw new Error("Unexpected breakpoint type " + type);
-  }
-  this.line_ = opt_line || 0;
-  this.column_ = opt_column;
-  this.groupId_ = opt_groupId;
-  this.position_alignment_ = IS_UNDEFINED(opt_position_alignment)
-      ? Debug.BreakPositionAlignment.Statement : opt_position_alignment;
-  this.hit_count_ = 0;
-  this.active_ = true;
-  this.condition_ = null;
-  this.ignoreCount_ = 0;
-  this.break_points_ = [];
-}
-
-
-// Creates a clone of script breakpoint that is linked to another script.
-ScriptBreakPoint.prototype.cloneForOtherScript = function (other_script) {
-  var copy = new ScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
-      other_script.id, this.line_, this.column_, this.groupId_,
-      this.position_alignment_);
-  copy.number_ = next_break_point_number++;
-  script_break_points.push(copy);
-
-  copy.hit_count_ = this.hit_count_;
-  copy.active_ = this.active_;
-  copy.condition_ = this.condition_;
-  copy.ignoreCount_ = this.ignoreCount_;
-  return copy;
-};
-
-
-ScriptBreakPoint.prototype.number = function() {
-  return this.number_;
-};
-
-
-ScriptBreakPoint.prototype.groupId = function() {
-  return this.groupId_;
-};
-
-
-ScriptBreakPoint.prototype.type = function() {
-  return this.type_;
-};
-
-
-ScriptBreakPoint.prototype.script_id = function() {
-  return this.script_id_;
-};
-
-
-ScriptBreakPoint.prototype.script_name = function() {
-  return this.script_name_;
-};
-
-
-ScriptBreakPoint.prototype.script_regexp_object = function() {
-  return this.script_regexp_object_;
-};
-
-
-ScriptBreakPoint.prototype.line = function() {
-  return this.line_;
-};
-
-
-ScriptBreakPoint.prototype.column = function() {
-  return this.column_;
-};
-
-
-ScriptBreakPoint.prototype.actual_locations = function() {
-  var locations = [];
-  for (var i = 0; i < this.break_points_.length; i++) {
-    locations.push(this.break_points_[i].actual_location);
-  }
-  return locations;
-};
-
-
-ScriptBreakPoint.prototype.update_positions = function(line, column) {
-  this.line_ = line;
-  this.column_ = column;
-};
-
-
-ScriptBreakPoint.prototype.hit_count = function() {
-  return this.hit_count_;
-};
-
-
-ScriptBreakPoint.prototype.active = function() {
-  return this.active_;
-};
-
-
-ScriptBreakPoint.prototype.condition = function() {
-  return this.condition_;
-};
-
-
-ScriptBreakPoint.prototype.ignoreCount = function() {
-  return this.ignoreCount_;
-};
-
-
-ScriptBreakPoint.prototype.enable = function() {
-  this.active_ = true;
-};
-
-
-ScriptBreakPoint.prototype.disable = function() {
-  this.active_ = false;
-};
-
-
-ScriptBreakPoint.prototype.setCondition = function(condition) {
-  this.condition_ = condition;
-};
-
-
-ScriptBreakPoint.prototype.setIgnoreCount = function(ignoreCount) {
-  this.ignoreCount_ = ignoreCount;
-
-  // Set ignore count on all break points created from this script break point.
-  for (var i = 0; i < this.break_points_.length; i++) {
-    this.break_points_[i].setIgnoreCount(ignoreCount);
-  }
-};
-
-
-// Check whether a script matches this script break point. Currently this is
-// only based on script name.
-ScriptBreakPoint.prototype.matchesScript = function(script) {
-  if (this.type_ == Debug.ScriptBreakPointType.ScriptId) {
-    return this.script_id_ == script.id;
-  } else {
-    // We might want to account columns here as well.
-    if (!(script.line_offset <= this.line_  &&
-          this.line_ < script.line_offset + script.lineCount())) {
-      return false;
-    }
-    if (this.type_ == Debug.ScriptBreakPointType.ScriptName) {
-      return this.script_name_ == script.nameOrSourceURL();
-    } else if (this.type_ == Debug.ScriptBreakPointType.ScriptRegExp) {
-      return this.script_regexp_object_.test(script.nameOrSourceURL());
-    } else {
-      throw new Error("Unexpected breakpoint type " + this.type_);
-    }
-  }
-};
-
-
-// Set the script break point in a script.
-ScriptBreakPoint.prototype.set = function (script) {
-  var column = this.column();
-  var line = this.line();
-  // If the column is undefined the break is on the line. To help locate the
-  // first piece of breakable code on the line try to find the column on the
-  // line which contains some source.
-  if (IS_UNDEFINED(column)) {
-    var source_line = script.sourceLine(this.line());
-
-    // Allocate array for caching the columns where the actual source starts.
-    if (!script.sourceColumnStart_) {
-      script.sourceColumnStart_ = new Array(script.lineCount());
-    }
-
-    // Fill cache if needed and get column where the actual source starts.
-    if (IS_UNDEFINED(script.sourceColumnStart_[line])) {
-      script.sourceColumnStart_[line] =
-          source_line.match(sourceLineBeginningSkip)[0].length;
-    }
-    column = script.sourceColumnStart_[line];
-  }
-
-  // Convert the line and column into an absolute position within the script.
-  var position = Debug.findScriptSourcePosition(script, this.line(), column);
-
-  // If the position is not found in the script (the script might be shorter
-  // than it used to be) just ignore it.
-  if (IS_NULL(position)) return;
-
-  // Create a break point object and set the break point.
-  var break_point = MakeBreakPoint(position, this);
-  break_point.setIgnoreCount(this.ignoreCount());
-  var actual_position = %SetScriptBreakPoint(script, position,
-                                             this.position_alignment_,
-                                             break_point);
-  if (IS_UNDEFINED(actual_position)) {
-    actual_position = position;
-  }
-  var actual_location = script.locationFromPosition(actual_position, true);
-  break_point.actual_location = { line: actual_location.line,
-                                  column: actual_location.column,
-                                  script_id: script.id };
-  this.break_points_.push(break_point);
-  return break_point;
-};
-
-
-// Clear all the break points created from this script break point
-ScriptBreakPoint.prototype.clear = function () {
-  var remaining_break_points = [];
-  for (var i = 0; i < break_points.length; i++) {
-    if (break_points[i].script_break_point() &&
-        break_points[i].script_break_point() === this) {
-      %ClearBreakPoint(break_points[i]);
-    } else {
-      remaining_break_points.push(break_points[i]);
-    }
-  }
-  break_points = remaining_break_points;
-  this.break_points_ = [];
-};
-
-
-// Function called from runtime when a new script is compiled to set any script
-// break points set in this script.
-function UpdateScriptBreakPoints(script) {
-  for (var i = 0; i < script_break_points.length; i++) {
-    var break_point = script_break_points[i];
-    if ((break_point.type() == Debug.ScriptBreakPointType.ScriptName ||
-         break_point.type() == Debug.ScriptBreakPointType.ScriptRegExp) &&
-        break_point.matchesScript(script)) {
-      break_point.set(script);
-    }
-  }
-}
-
-
-function GetScriptBreakPoints(script) {
-  var result = [];
-  for (var i = 0; i < script_break_points.length; i++) {
-    if (script_break_points[i].matchesScript(script)) {
-      result.push(script_break_points[i]);
-    }
-  }
-  return result;
-}
-
-
-Debug.setListener = function(listener, opt_data) {
-  if (!IS_FUNCTION(listener) && !IS_UNDEFINED(listener) && !IS_NULL(listener)) {
-    throw new Error('Parameters have wrong types.');
-  }
-  %SetDebugEventListener(listener, opt_data);
-};
-
-
-Debug.breakLocations = function(f, opt_position_aligment) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  var position_aligment = IS_UNDEFINED(opt_position_aligment)
-      ? Debug.BreakPositionAlignment.Statement : opt_position_aligment;
-  return %GetBreakLocations(f, position_aligment);
-};
-
-// Returns a Script object. If the parameter is a function the return value
-// is the script in which the function is defined. If the parameter is a string
-// the return value is the script for which the script name has that string
-// value.  If it is a regexp and there is a unique script whose name matches
-// we return that, otherwise undefined.
-Debug.findScript = function(func_or_script_name) {
-  if (IS_FUNCTION(func_or_script_name)) {
-    return %FunctionGetScript(func_or_script_name);
-  } else if (IS_REGEXP(func_or_script_name)) {
-    var scripts = Debug.scripts();
-    var last_result = null;
-    var result_count = 0;
-    for (var i in scripts) {
-      var script = scripts[i];
-      if (func_or_script_name.test(script.name)) {
-        last_result = script;
-        result_count++;
-      }
-    }
-    // Return the unique script matching the regexp.  If there are more
-    // than one we don't return a value since there is no good way to
-    // decide which one to return.  Returning a "random" one, say the
-    // first, would introduce nondeterminism (or something close to it)
-    // because the order is the heap iteration order.
-    if (result_count == 1) {
-      return last_result;
-    } else {
-      return undefined;
-    }
-  } else {
-    return %GetScript(func_or_script_name);
-  }
-};
-
-// Returns the script source. If the parameter is a function the return value
-// is the script source for the script in which the function is defined. If the
-// parameter is a string the return value is the script for which the script
-// name has that string value.
-Debug.scriptSource = function(func_or_script_name) {
-  return this.findScript(func_or_script_name).source;
-};
-
-
-Debug.source = function(f) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  return %FunctionGetSourceCode(f);
-};
-
-
-Debug.sourcePosition = function(f) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  return %FunctionGetScriptSourcePosition(f);
-};
-
-
-Debug.findFunctionSourceLocation = function(func, opt_line, opt_column) {
-  var script = %FunctionGetScript(func);
-  var script_offset = %FunctionGetScriptSourcePosition(func);
-  return script.locationFromLine(opt_line, opt_column, script_offset);
-};
-
-
-// Returns the character position in a script based on a line number and an
-// optional position within that line.
-Debug.findScriptSourcePosition = function(script, opt_line, opt_column) {
-  var location = script.locationFromLine(opt_line, opt_column);
-  return location ? location.position : null;
-};
-
-
-Debug.findBreakPoint = function(break_point_number, remove) {
-  var break_point;
-  for (var i = 0; i < break_points.length; i++) {
-    if (break_points[i].number() == break_point_number) {
-      break_point = break_points[i];
-      // Remove the break point from the list if requested.
-      if (remove) {
-        break_points.splice(i, 1);
-      }
-      break;
-    }
-  }
-  if (break_point) {
-    return break_point;
-  } else {
-    return this.findScriptBreakPoint(break_point_number, remove);
-  }
-};
-
-Debug.findBreakPointActualLocations = function(break_point_number) {
-  for (var i = 0; i < script_break_points.length; i++) {
-    if (script_break_points[i].number() == break_point_number) {
-      return script_break_points[i].actual_locations();
-    }
-  }
-  for (var i = 0; i < break_points.length; i++) {
-    if (break_points[i].number() == break_point_number) {
-      return [break_points[i].actual_location];
-    }
-  }
-  return [];
-};
-
-Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) {
-  if (!IS_FUNCTION(func)) throw new Error('Parameters have wrong types.');
-  // Break points in API functions are not supported.
-  if (%FunctionIsAPIFunction(func)) {
-    throw new Error('Cannot set break point in native code.');
-  }
-  // Find source position relative to start of the function
-  var break_position =
-      this.findFunctionSourceLocation(func, opt_line, opt_column).position;
-  var source_position = break_position - this.sourcePosition(func);
-  // Find the script for the function.
-  var script = %FunctionGetScript(func);
-  // Break in builtin JavaScript code is not supported.
-  if (script.type == Debug.ScriptType.Native) {
-    throw new Error('Cannot set break point in native code.');
-  }
-  // If the script for the function has a name convert this to a script break
-  // point.
-  if (script && script.id) {
-    // Adjust the source position to be script relative.
-    source_position += %FunctionGetScriptSourcePosition(func);
-    // Find line and column for the position in the script and set a script
-    // break point from that.
-    var location = script.locationFromPosition(source_position, false);
-    return this.setScriptBreakPointById(script.id,
-                                        location.line, location.column,
-                                        opt_condition);
-  } else {
-    // Set a break point directly on the function.
-    var break_point = MakeBreakPoint(source_position);
-    var actual_position =
-        %SetFunctionBreakPoint(func, source_position, break_point);
-    actual_position += this.sourcePosition(func);
-    var actual_location = script.locationFromPosition(actual_position, true);
-    break_point.actual_location = { line: actual_location.line,
-                                    column: actual_location.column,
-                                    script_id: script.id };
-    break_point.setCondition(opt_condition);
-    return break_point.number();
-  }
-};
-
-
-Debug.setBreakPointByScriptIdAndPosition = function(script_id, position,
-                                                    condition, enabled,
-                                                    opt_position_alignment)
-{
-  var break_point = MakeBreakPoint(position);
-  break_point.setCondition(condition);
-  if (!enabled) {
-    break_point.disable();
-  }
-  var scripts = this.scripts();
-  var position_alignment = IS_UNDEFINED(opt_position_alignment)
-      ? Debug.BreakPositionAlignment.Statement : opt_position_alignment;
-  for (var i = 0; i < scripts.length; i++) {
-    if (script_id == scripts[i].id) {
-      break_point.actual_position = %SetScriptBreakPoint(scripts[i], position,
-          position_alignment, break_point);
-      break;
-    }
-  }
-  return break_point;
-};
-
-
-Debug.enableBreakPoint = function(break_point_number) {
-  var break_point = this.findBreakPoint(break_point_number, false);
-  // Only enable if the breakpoint hasn't been deleted:
-  if (break_point) {
-    break_point.enable();
-  }
-};
-
-
-Debug.disableBreakPoint = function(break_point_number) {
-  var break_point = this.findBreakPoint(break_point_number, false);
-  // Only enable if the breakpoint hasn't been deleted:
-  if (break_point) {
-    break_point.disable();
-  }
-};
-
-
-Debug.changeBreakPointCondition = function(break_point_number, condition) {
-  var break_point = this.findBreakPoint(break_point_number, false);
-  break_point.setCondition(condition);
-};
-
-
-Debug.changeBreakPointIgnoreCount = function(break_point_number, ignoreCount) {
-  if (ignoreCount < 0) {
-    throw new Error('Invalid argument');
-  }
-  var break_point = this.findBreakPoint(break_point_number, false);
-  break_point.setIgnoreCount(ignoreCount);
-};
-
-
-Debug.clearBreakPoint = function(break_point_number) {
-  var break_point = this.findBreakPoint(break_point_number, true);
-  if (break_point) {
-    return %ClearBreakPoint(break_point);
-  } else {
-    break_point = this.findScriptBreakPoint(break_point_number, true);
-    if (!break_point) {
-      throw new Error('Invalid breakpoint');
-    }
-  }
-};
-
-
-Debug.clearAllBreakPoints = function() {
-  for (var i = 0; i < break_points.length; i++) {
-    var break_point = break_points[i];
-    %ClearBreakPoint(break_point);
-  }
-  break_points = [];
-};
-
-
-Debug.disableAllBreakPoints = function() {
-  // Disable all user defined breakpoints:
-  for (var i = 1; i < next_break_point_number; i++) {
-    Debug.disableBreakPoint(i);
-  }
-  // Disable all exception breakpoints:
-  %ChangeBreakOnException(Debug.ExceptionBreak.Caught, false);
-  %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, false);
-};
-
-
-Debug.findScriptBreakPoint = function(break_point_number, remove) {
-  var script_break_point;
-  for (var i = 0; i < script_break_points.length; i++) {
-    if (script_break_points[i].number() == break_point_number) {
-      script_break_point = script_break_points[i];
-      // Remove the break point from the list if requested.
-      if (remove) {
-        script_break_point.clear();
-        script_break_points.splice(i,1);
-      }
-      break;
-    }
-  }
-  return script_break_point;
-};
-
-
-// Sets a breakpoint in a script identified through id or name at the
-// specified source line and column within that line.
-Debug.setScriptBreakPoint = function(type, script_id_or_name,
-                                     opt_line, opt_column, opt_condition,
-                                     opt_groupId, opt_position_alignment) {
-  // Create script break point object.
-  var script_break_point =
-      new ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
-                           opt_groupId, opt_position_alignment);
-
-  // Assign number to the new script break point and add it.
-  script_break_point.number_ = next_break_point_number++;
-  script_break_point.setCondition(opt_condition);
-  script_break_points.push(script_break_point);
-
-  // Run through all scripts to see if this script break point matches any
-  // loaded scripts.
-  var scripts = this.scripts();
-  for (var i = 0; i < scripts.length; i++) {
-    if (script_break_point.matchesScript(scripts[i])) {
-      script_break_point.set(scripts[i]);
-    }
-  }
-
-  return script_break_point.number();
-};
-
-
-Debug.setScriptBreakPointById = function(script_id,
-                                         opt_line, opt_column,
-                                         opt_condition, opt_groupId,
-                                         opt_position_alignment) {
-  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
-                                  script_id, opt_line, opt_column,
-                                  opt_condition, opt_groupId,
-                                  opt_position_alignment);
-};
-
-
-Debug.setScriptBreakPointByName = function(script_name,
-                                           opt_line, opt_column,
-                                           opt_condition, opt_groupId) {
-  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptName,
-                                  script_name, opt_line, opt_column,
-                                  opt_condition, opt_groupId);
-};
-
-
-Debug.setScriptBreakPointByRegExp = function(script_regexp,
-                                             opt_line, opt_column,
-                                             opt_condition, opt_groupId) {
-  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptRegExp,
-                                  script_regexp, opt_line, opt_column,
-                                  opt_condition, opt_groupId);
-};
-
-
-Debug.enableScriptBreakPoint = function(break_point_number) {
-  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
-  script_break_point.enable();
-};
-
-
-Debug.disableScriptBreakPoint = function(break_point_number) {
-  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
-  script_break_point.disable();
-};
-
-
-Debug.changeScriptBreakPointCondition = function(
-    break_point_number, condition) {
-  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
-  script_break_point.setCondition(condition);
-};
-
-
-Debug.changeScriptBreakPointIgnoreCount = function(
-    break_point_number, ignoreCount) {
-  if (ignoreCount < 0) {
-    throw new Error('Invalid argument');
-  }
-  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
-  script_break_point.setIgnoreCount(ignoreCount);
-};
-
-
-Debug.scriptBreakPoints = function() {
-  return script_break_points;
-};
-
-
-Debug.clearStepping = function() {
-  %ClearStepping();
-};
-
-Debug.setBreakOnException = function() {
-  return %ChangeBreakOnException(Debug.ExceptionBreak.Caught, true);
-};
-
-Debug.clearBreakOnException = function() {
-  return %ChangeBreakOnException(Debug.ExceptionBreak.Caught, false);
-};
-
-Debug.isBreakOnException = function() {
-  return !!%IsBreakOnException(Debug.ExceptionBreak.Caught);
-};
-
-Debug.setBreakOnUncaughtException = function() {
-  return %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, true);
-};
-
-Debug.clearBreakOnUncaughtException = function() {
-  return %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, false);
-};
-
-Debug.isBreakOnUncaughtException = function() {
-  return !!%IsBreakOnException(Debug.ExceptionBreak.Uncaught);
-};
-
-Debug.showBreakPoints = function(f, full, opt_position_alignment) {
-  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
-  var source = full ? this.scriptSource(f) : this.source(f);
-  var offset = full ? this.sourcePosition(f) : 0;
-  var locations = this.breakLocations(f, opt_position_alignment);
-  if (!locations) return source;
-  locations.sort(function(x, y) { return x - y; });
-  var result = "";
-  var prev_pos = 0;
-  var pos;
-  for (var i = 0; i < locations.length; i++) {
-    pos = locations[i] - offset;
-    result += source.slice(prev_pos, pos);
-    result += "[B" + i + "]";
-    prev_pos = pos;
-  }
-  pos = source.length;
-  result += source.substring(prev_pos, pos);
-  return result;
-};
-
-
-// Get all the scripts currently loaded. Locating all the scripts is based on
-// scanning the heap.
-Debug.scripts = function() {
-  // Collect all scripts in the heap.
-  return %DebugGetLoadedScripts();
-};
-
-
-Debug.debuggerFlags = function() {
-  return debugger_flags;
-};
-
-Debug.MakeMirror = MakeMirror;
-
-function MakeExecutionState(break_id) {
-  return new ExecutionState(break_id);
-}
-
-function ExecutionState(break_id) {
-  this.break_id = break_id;
-  this.selected_frame = 0;
-}
-
-ExecutionState.prototype.prepareStep = function(opt_action, opt_count,
-    opt_callframe) {
-  var action = Debug.StepAction.StepIn;
-  if (!IS_UNDEFINED(opt_action)) action = builtins.$toNumber(opt_action);
-  var count = opt_count ? builtins.$toNumber(opt_count) : 1;
-  var callFrameId = 0;
-  if (!IS_UNDEFINED(opt_callframe)) {
-    callFrameId = opt_callframe.details_.frameId();
-  }
-
-  return %PrepareStep(this.break_id, action, count, callFrameId);
-};
-
-ExecutionState.prototype.evaluateGlobal = function(source, disable_break,
-    opt_additional_context) {
-  return MakeMirror(%DebugEvaluateGlobal(this.break_id, source,
-                                         Boolean(disable_break),
-                                         opt_additional_context));
-};
-
-ExecutionState.prototype.frameCount = function() {
-  return %GetFrameCount(this.break_id);
-};
-
-ExecutionState.prototype.threadCount = function() {
-  return %GetThreadCount(this.break_id);
-};
-
-ExecutionState.prototype.frame = function(opt_index) {
-  // If no index supplied return the selected frame.
-  if (opt_index == null) opt_index = this.selected_frame;
-  if (opt_index < 0 || opt_index >= this.frameCount()) {
-    throw new Error('Illegal frame index.');
-  }
-  return new FrameMirror(this.break_id, opt_index);
-};
-
-ExecutionState.prototype.setSelectedFrame = function(index) {
-  var i = builtins.$toNumber(index);
-  if (i < 0 || i >= this.frameCount()) throw new Error('Illegal frame index.');
-  this.selected_frame = i;
-};
-
-ExecutionState.prototype.selectedFrame = function() {
-  return this.selected_frame;
-};
-
-ExecutionState.prototype.debugCommandProcessor = function(opt_is_running) {
-  return new DebugCommandProcessor(this, opt_is_running);
-};
-
-
-function MakeBreakEvent(break_id, break_points_hit) {
-  return new BreakEvent(break_id, break_points_hit);
-}
-
-
-function BreakEvent(break_id, break_points_hit) {
-  this.frame_ = new FrameMirror(break_id, 0);
-  this.break_points_hit_ = break_points_hit;
-}
-
-
-BreakEvent.prototype.eventType = function() {
-  return Debug.DebugEvent.Break;
-};
-
-
-BreakEvent.prototype.func = function() {
-  return this.frame_.func();
-};
-
-
-BreakEvent.prototype.sourceLine = function() {
-  return this.frame_.sourceLine();
-};
-
-
-BreakEvent.prototype.sourceColumn = function() {
-  return this.frame_.sourceColumn();
-};
-
-
-BreakEvent.prototype.sourceLineText = function() {
-  return this.frame_.sourceLineText();
-};
-
-
-BreakEvent.prototype.breakPointsHit = function() {
-  return this.break_points_hit_;
-};
-
-
-BreakEvent.prototype.toJSONProtocol = function() {
-  var o = { seq: next_response_seq++,
-            type: "event",
-            event: "break",
-            body: { invocationText: this.frame_.invocationText() }
-          };
-
-  // Add script related information to the event if available.
-  var script = this.func().script();
-  if (script) {
-    o.body.sourceLine = this.sourceLine(),
-    o.body.sourceColumn = this.sourceColumn(),
-    o.body.sourceLineText = this.sourceLineText(),
-    o.body.script = MakeScriptObject_(script, false);
-  }
-
-  // Add an Array of break points hit if any.
-  if (this.breakPointsHit()) {
-    o.body.breakpoints = [];
-    for (var i = 0; i < this.breakPointsHit().length; i++) {
-      // Find the break point number. For break points originating from a
-      // script break point supply the script break point number.
-      var breakpoint = this.breakPointsHit()[i];
-      var script_break_point = breakpoint.script_break_point();
-      var number;
-      if (script_break_point) {
-        number = script_break_point.number();
-      } else {
-        number = breakpoint.number();
-      }
-      o.body.breakpoints.push(number);
-    }
-  }
-  return JSON.stringify(ObjectToProtocolObject_(o));
-};
-
-
-function MakeExceptionEvent(break_id, exception, uncaught, promise) {
-  return new ExceptionEvent(break_id, exception, uncaught, promise);
-}
-
-
-function ExceptionEvent(break_id, exception, uncaught, promise) {
-  this.exec_state_ = new ExecutionState(break_id);
-  this.exception_ = exception;
-  this.uncaught_ = uncaught;
-  this.promise_ = promise;
-}
-
-
-ExceptionEvent.prototype.eventType = function() {
-  return Debug.DebugEvent.Exception;
-};
-
-
-ExceptionEvent.prototype.exception = function() {
-  return this.exception_;
-};
-
-
-ExceptionEvent.prototype.uncaught = function() {
-  return this.uncaught_;
-};
-
-
-ExceptionEvent.prototype.promise = function() {
-  return this.promise_;
-};
-
-
-ExceptionEvent.prototype.func = function() {
-  return this.exec_state_.frame(0).func();
-};
-
-
-ExceptionEvent.prototype.sourceLine = function() {
-  return this.exec_state_.frame(0).sourceLine();
-};
-
-
-ExceptionEvent.prototype.sourceColumn = function() {
-  return this.exec_state_.frame(0).sourceColumn();
-};
-
-
-ExceptionEvent.prototype.sourceLineText = function() {
-  return this.exec_state_.frame(0).sourceLineText();
-};
-
-
-ExceptionEvent.prototype.toJSONProtocol = function() {
-  var o = new ProtocolMessage();
-  o.event = "exception";
-  o.body = { uncaught: this.uncaught_,
-             exception: MakeMirror(this.exception_)
-           };
-
-  // Exceptions might happen whithout any JavaScript frames.
-  if (this.exec_state_.frameCount() > 0) {
-    o.body.sourceLine = this.sourceLine();
-    o.body.sourceColumn = this.sourceColumn();
-    o.body.sourceLineText = this.sourceLineText();
-
-    // Add script information to the event if available.
-    var script = this.func().script();
-    if (script) {
-      o.body.script = MakeScriptObject_(script, false);
-    }
-  } else {
-    o.body.sourceLine = -1;
-  }
-
-  return o.toJSONProtocol();
-};
-
-
-function MakeCompileEvent(script, type) {
-  return new CompileEvent(script, type);
-}
-
-
-function CompileEvent(script, type) {
-  this.script_ = MakeMirror(script);
-  this.type_ = type;
-}
-
-
-CompileEvent.prototype.eventType = function() {
-  return this.type_;
-};
-
-
-CompileEvent.prototype.script = function() {
-  return this.script_;
-};
-
-
-CompileEvent.prototype.toJSONProtocol = function() {
-  var o = new ProtocolMessage();
-  o.running = true;
-  switch (this.type_) {
-    case Debug.DebugEvent.BeforeCompile:
-      o.event = "beforeCompile";
-      break;
-    case Debug.DebugEvent.AfterCompile:
-      o.event = "afterCompile";
-      break;
-    case Debug.DebugEvent.CompileError:
-      o.event = "compileError";
-      break;
-  }
-  o.body = {};
-  o.body.script = this.script_;
-
-  return o.toJSONProtocol();
-};
-
-
-function MakeScriptObject_(script, include_source) {
-  var o = { id: script.id(),
-            name: script.name(),
-            lineOffset: script.lineOffset(),
-            columnOffset: script.columnOffset(),
-            lineCount: script.lineCount(),
-          };
-  if (!IS_UNDEFINED(script.data())) {
-    o.data = script.data();
-  }
-  if (include_source) {
-    o.source = script.source();
-  }
-  return o;
-}
-
-
-function MakePromiseEvent(event_data) {
-  return new PromiseEvent(event_data);
-}
-
-
-function PromiseEvent(event_data) {
-  this.promise_ = event_data.promise;
-  this.parentPromise_ = event_data.parentPromise;
-  this.status_ = event_data.status;
-  this.value_ = event_data.value;
-}
-
-
-PromiseEvent.prototype.promise = function() {
-  return MakeMirror(this.promise_);
-}
-
-
-PromiseEvent.prototype.parentPromise = function() {
-  return MakeMirror(this.parentPromise_);
-}
-
-
-PromiseEvent.prototype.status = function() {
-  return this.status_;
-}
-
-
-PromiseEvent.prototype.value = function() {
-  return MakeMirror(this.value_);
-}
-
-
-function MakeAsyncTaskEvent(event_data) {
-  return new AsyncTaskEvent(event_data);
-}
-
-
-function AsyncTaskEvent(event_data) {
-  this.type_ = event_data.type;
-  this.name_ = event_data.name;
-  this.id_ = event_data.id;
-}
-
-
-AsyncTaskEvent.prototype.type = function() {
-  return this.type_;
-}
-
-
-AsyncTaskEvent.prototype.name = function() {
-  return this.name_;
-}
-
-
-AsyncTaskEvent.prototype.id = function() {
-  return this.id_;
-}
-
-
-function DebugCommandProcessor(exec_state, opt_is_running) {
-  this.exec_state_ = exec_state;
-  this.running_ = opt_is_running || false;
-}
-
-
-DebugCommandProcessor.prototype.processDebugRequest = function (request) {
-  return this.processDebugJSONRequest(request);
-};
-
-
-function ProtocolMessage(request) {
-  // Update sequence number.
-  this.seq = next_response_seq++;
-
-  if (request) {
-    // If message is based on a request this is a response. Fill the initial
-    // response from the request.
-    this.type = 'response';
-    this.request_seq = request.seq;
-    this.command = request.command;
-  } else {
-    // If message is not based on a request it is a dabugger generated event.
-    this.type = 'event';
-  }
-  this.success = true;
-  // Handler may set this field to control debugger state.
-  this.running = undefined;
-}
-
-
-ProtocolMessage.prototype.setOption = function(name, value) {
-  if (!this.options_) {
-    this.options_ = {};
-  }
-  this.options_[name] = value;
-};
-
-
-ProtocolMessage.prototype.failed = function(message, opt_details) {
-  this.success = false;
-  this.message = message;
-  if (IS_OBJECT(opt_details)) {
-    this.error_details = opt_details;
-  }
-};
-
-
-ProtocolMessage.prototype.toJSONProtocol = function() {
-  // Encode the protocol header.
-  var json = {};
-  json.seq= this.seq;
-  if (this.request_seq) {
-    json.request_seq = this.request_seq;
-  }
-  json.type = this.type;
-  if (this.event) {
-    json.event = this.event;
-  }
-  if (this.command) {
-    json.command = this.command;
-  }
-  if (this.success) {
-    json.success = this.success;
-  } else {
-    json.success = false;
-  }
-  if (this.body) {
-    // Encode the body part.
-    var bodyJson;
-    var serializer = MakeMirrorSerializer(true, this.options_);
-    if (this.body instanceof Mirror) {
-      bodyJson = serializer.serializeValue(this.body);
-    } else if (this.body instanceof Array) {
-      bodyJson = [];
-      for (var i = 0; i < this.body.length; i++) {
-        if (this.body[i] instanceof Mirror) {
-          bodyJson.push(serializer.serializeValue(this.body[i]));
-        } else {
-          bodyJson.push(ObjectToProtocolObject_(this.body[i], serializer));
-        }
-      }
-    } else {
-      bodyJson = ObjectToProtocolObject_(this.body, serializer);
-    }
-    json.body = bodyJson;
-    json.refs = serializer.serializeReferencedObjects();
-  }
-  if (this.message) {
-    json.message = this.message;
-  }
-  if (this.error_details) {
-    json.error_details = this.error_details;
-  }
-  json.running = this.running;
-  return JSON.stringify(json);
-};
-
-
-DebugCommandProcessor.prototype.createResponse = function(request) {
-  return new ProtocolMessage(request);
-};
-
-
-DebugCommandProcessor.prototype.processDebugJSONRequest = function(
-    json_request) {
-  var request;  // Current request.
-  var response;  // Generated response.
-  try {
-    try {
-      // Convert the JSON string to an object.
-      request = JSON.parse(json_request);
-
-      // Create an initial response.
-      response = this.createResponse(request);
-
-      if (!request.type) {
-        throw new Error('Type not specified');
-      }
-
-      if (request.type != 'request') {
-        throw new Error("Illegal type '" + request.type + "' in request");
-      }
-
-      if (!request.command) {
-        throw new Error('Command not specified');
-      }
-
-      if (request.arguments) {
-        var args = request.arguments;
-        // TODO(yurys): remove request.arguments.compactFormat check once
-        // ChromeDevTools are switched to 'inlineRefs'
-        if (args.inlineRefs || args.compactFormat) {
-          response.setOption('inlineRefs', true);
-        }
-        if (!IS_UNDEFINED(args.maxStringLength)) {
-          response.setOption('maxStringLength', args.maxStringLength);
-        }
-      }
-
-      var key = request.command.toLowerCase();
-      var handler = DebugCommandProcessor.prototype.dispatch_[key];
-      if (IS_FUNCTION(handler)) {
-        %_CallFunction(this, request, response, handler);
-      } else {
-        throw new Error('Unknown command "' + request.command + '" in request');
-      }
-    } catch (e) {
-      // If there is no response object created one (without command).
-      if (!response) {
-        response = this.createResponse();
-      }
-      response.success = false;
-      response.message = builtins.$toString(e);
-    }
-
-    // Return the response as a JSON encoded string.
-    try {
-      if (!IS_UNDEFINED(response.running)) {
-        // Response controls running state.
-        this.running_ = response.running;
-      }
-      response.running = this.running_;
-      return response.toJSONProtocol();
-    } catch (e) {
-      // Failed to generate response - return generic error.
-      return '{"seq":' + response.seq + ',' +
-              '"request_seq":' + request.seq + ',' +
-              '"type":"response",' +
-              '"success":false,' +
-              '"message":"Internal error: ' + builtins.$toString(e) + '"}';
-    }
-  } catch (e) {
-    // Failed in one of the catch blocks above - most generic error.
-    return '{"seq":0,"type":"response","success":false,"message":"Internal error"}';
-  }
-};
-
-
-DebugCommandProcessor.prototype.continueRequest_ = function(request, response) {
-  // Check for arguments for continue.
-  if (request.arguments) {
-    var count = 1;
-    var action = Debug.StepAction.StepIn;
-
-    // Pull out arguments.
-    var stepaction = request.arguments.stepaction;
-    var stepcount = request.arguments.stepcount;
-
-    // Get the stepcount argument if any.
-    if (stepcount) {
-      count = builtins.$toNumber(stepcount);
-      if (count < 0) {
-        throw new Error('Invalid stepcount argument "' + stepcount + '".');
-      }
-    }
-
-    // Get the stepaction argument.
-    if (stepaction) {
-      if (stepaction == 'in') {
-        action = Debug.StepAction.StepIn;
-      } else if (stepaction == 'min') {
-        action = Debug.StepAction.StepMin;
-      } else if (stepaction == 'next') {
-        action = Debug.StepAction.StepNext;
-      } else if (stepaction == 'out') {
-        action = Debug.StepAction.StepOut;
-      } else {
-        throw new Error('Invalid stepaction argument "' + stepaction + '".');
-      }
-    }
-
-    // Set up the VM for stepping.
-    this.exec_state_.prepareStep(action, count);
-  }
-
-  // VM should be running after executing this request.
-  response.running = true;
-};
-
-
-DebugCommandProcessor.prototype.breakRequest_ = function(request, response) {
-  // Ignore as break command does not do anything when broken.
-};
-
-
-DebugCommandProcessor.prototype.setBreakPointRequest_ =
-    function(request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var type = request.arguments.type;
-  var target = request.arguments.target;
-  var line = request.arguments.line;
-  var column = request.arguments.column;
-  var enabled = IS_UNDEFINED(request.arguments.enabled) ?
-      true : request.arguments.enabled;
-  var condition = request.arguments.condition;
-  var ignoreCount = request.arguments.ignoreCount;
-  var groupId = request.arguments.groupId;
-
-  // Check for legal arguments.
-  if (!type || IS_UNDEFINED(target)) {
-    response.failed('Missing argument "type" or "target"');
-    return;
-  }
-
-  // Either function or script break point.
-  var break_point_number;
-  if (type == 'function') {
-    // Handle function break point.
-    if (!IS_STRING(target)) {
-      response.failed('Argument "target" is not a string value');
-      return;
-    }
-    var f;
-    try {
-      // Find the function through a global evaluate.
-      f = this.exec_state_.evaluateGlobal(target).value();
-    } catch (e) {
-      response.failed('Error: "' + builtins.$toString(e) +
-                      '" evaluating "' + target + '"');
-      return;
-    }
-    if (!IS_FUNCTION(f)) {
-      response.failed('"' + target + '" does not evaluate to a function');
-      return;
-    }
-
-    // Set function break point.
-    break_point_number = Debug.setBreakPoint(f, line, column, condition);
-  } else if (type == 'handle') {
-    // Find the object pointed by the specified handle.
-    var handle = parseInt(target, 10);
-    var mirror = LookupMirror(handle);
-    if (!mirror) {
-      return response.failed('Object #' + handle + '# not found');
-    }
-    if (!mirror.isFunction()) {
-      return response.failed('Object #' + handle + '# is not a function');
-    }
-
-    // Set function break point.
-    break_point_number = Debug.setBreakPoint(mirror.value(),
-                                             line, column, condition);
-  } else if (type == 'script') {
-    // set script break point.
-    break_point_number =
-        Debug.setScriptBreakPointByName(target, line, column, condition,
-                                        groupId);
-  } else if (type == 'scriptId') {
-    break_point_number =
-        Debug.setScriptBreakPointById(target, line, column, condition, groupId);
-  } else if (type == 'scriptRegExp') {
-    break_point_number =
-        Debug.setScriptBreakPointByRegExp(target, line, column, condition,
-                                          groupId);
-  } else {
-    response.failed('Illegal type "' + type + '"');
-    return;
-  }
-
-  // Set additional break point properties.
-  var break_point = Debug.findBreakPoint(break_point_number);
-  if (ignoreCount) {
-    Debug.changeBreakPointIgnoreCount(break_point_number, ignoreCount);
-  }
-  if (!enabled) {
-    Debug.disableBreakPoint(break_point_number);
-  }
-
-  // Add the break point number to the response.
-  response.body = { type: type,
-                    breakpoint: break_point_number };
-
-  // Add break point information to the response.
-  if (break_point instanceof ScriptBreakPoint) {
-    if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
-      response.body.type = 'scriptId';
-      response.body.script_id = break_point.script_id();
-    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptName) {
-      response.body.type = 'scriptName';
-      response.body.script_name = break_point.script_name();
-    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptRegExp) {
-      response.body.type = 'scriptRegExp';
-      response.body.script_regexp = break_point.script_regexp_object().source;
-    } else {
-      throw new Error("Internal error: Unexpected breakpoint type: " +
-                      break_point.type());
-    }
-    response.body.line = break_point.line();
-    response.body.column = break_point.column();
-    response.body.actual_locations = break_point.actual_locations();
-  } else {
-    response.body.type = 'function';
-    response.body.actual_locations = [break_point.actual_location];
-  }
-};
-
-
-DebugCommandProcessor.prototype.changeBreakPointRequest_ = function(
-    request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var break_point = builtins.$toNumber(request.arguments.breakpoint);
-  var enabled = request.arguments.enabled;
-  var condition = request.arguments.condition;
-  var ignoreCount = request.arguments.ignoreCount;
-
-  // Check for legal arguments.
-  if (!break_point) {
-    response.failed('Missing argument "breakpoint"');
-    return;
-  }
-
-  // Change enabled state if supplied.
-  if (!IS_UNDEFINED(enabled)) {
-    if (enabled) {
-      Debug.enableBreakPoint(break_point);
-    } else {
-      Debug.disableBreakPoint(break_point);
-    }
-  }
-
-  // Change condition if supplied
-  if (!IS_UNDEFINED(condition)) {
-    Debug.changeBreakPointCondition(break_point, condition);
-  }
-
-  // Change ignore count if supplied
-  if (!IS_UNDEFINED(ignoreCount)) {
-    Debug.changeBreakPointIgnoreCount(break_point, ignoreCount);
-  }
-};
-
-
-DebugCommandProcessor.prototype.clearBreakPointGroupRequest_ = function(
-    request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var group_id = request.arguments.groupId;
-
-  // Check for legal arguments.
-  if (!group_id) {
-    response.failed('Missing argument "groupId"');
-    return;
-  }
-
-  var cleared_break_points = [];
-  var new_script_break_points = [];
-  for (var i = 0; i < script_break_points.length; i++) {
-    var next_break_point = script_break_points[i];
-    if (next_break_point.groupId() == group_id) {
-      cleared_break_points.push(next_break_point.number());
-      next_break_point.clear();
-    } else {
-      new_script_break_points.push(next_break_point);
-    }
-  }
-  script_break_points = new_script_break_points;
-
-  // Add the cleared break point numbers to the response.
-  response.body = { breakpoints: cleared_break_points };
-};
-
-
-DebugCommandProcessor.prototype.clearBreakPointRequest_ = function(
-    request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var break_point = builtins.$toNumber(request.arguments.breakpoint);
-
-  // Check for legal arguments.
-  if (!break_point) {
-    response.failed('Missing argument "breakpoint"');
-    return;
-  }
-
-  // Clear break point.
-  Debug.clearBreakPoint(break_point);
-
-  // Add the cleared break point number to the response.
-  response.body = { breakpoint: break_point };
-};
-
-
-DebugCommandProcessor.prototype.listBreakpointsRequest_ = function(
-    request, response) {
-  var array = [];
-  for (var i = 0; i < script_break_points.length; i++) {
-    var break_point = script_break_points[i];
-
-    var description = {
-      number: break_point.number(),
-      line: break_point.line(),
-      column: break_point.column(),
-      groupId: break_point.groupId(),
-      hit_count: break_point.hit_count(),
-      active: break_point.active(),
-      condition: break_point.condition(),
-      ignoreCount: break_point.ignoreCount(),
-      actual_locations: break_point.actual_locations()
-    };
-
-    if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
-      description.type = 'scriptId';
-      description.script_id = break_point.script_id();
-    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptName) {
-      description.type = 'scriptName';
-      description.script_name = break_point.script_name();
-    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptRegExp) {
-      description.type = 'scriptRegExp';
-      description.script_regexp = break_point.script_regexp_object().source;
-    } else {
-      throw new Error("Internal error: Unexpected breakpoint type: " +
-                      break_point.type());
-    }
-    array.push(description);
-  }
-
-  response.body = {
-    breakpoints: array,
-    breakOnExceptions: Debug.isBreakOnException(),
-    breakOnUncaughtExceptions: Debug.isBreakOnUncaughtException()
-  };
-};
-
-
-DebugCommandProcessor.prototype.disconnectRequest_ =
-    function(request, response) {
-  Debug.disableAllBreakPoints();
-  this.continueRequest_(request, response);
-};
-
-
-DebugCommandProcessor.prototype.setExceptionBreakRequest_ =
-    function(request, response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out and check the 'type' argument:
-  var type = request.arguments.type;
-  if (!type) {
-    response.failed('Missing argument "type"');
-    return;
-  }
-
-  // Initialize the default value of enable:
-  var enabled;
-  if (type == 'all') {
-    enabled = !Debug.isBreakOnException();
-  } else if (type == 'uncaught') {
-    enabled = !Debug.isBreakOnUncaughtException();
-  }
-
-  // Pull out and check the 'enabled' argument if present:
-  if (!IS_UNDEFINED(request.arguments.enabled)) {
-    enabled = request.arguments.enabled;
-    if ((enabled != true) && (enabled != false)) {
-      response.failed('Illegal value for "enabled":"' + enabled + '"');
-    }
-  }
-
-  // Now set the exception break state:
-  if (type == 'all') {
-    %ChangeBreakOnException(Debug.ExceptionBreak.Caught, enabled);
-  } else if (type == 'uncaught') {
-    %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, enabled);
-  } else {
-    response.failed('Unknown "type":"' + type + '"');
-  }
-
-  // Add the cleared break point number to the response.
-  response.body = { 'type': type, 'enabled': enabled };
-};
-
-
-DebugCommandProcessor.prototype.backtraceRequest_ = function(
-    request, response) {
-  // Get the number of frames.
-  var total_frames = this.exec_state_.frameCount();
-
-  // Create simple response if there are no frames.
-  if (total_frames == 0) {
-    response.body = {
-      totalFrames: total_frames
-    };
-    return;
-  }
-
-  // Default frame range to include in backtrace.
-  var from_index = 0;
-  var to_index = kDefaultBacktraceLength;
-
-  // Get the range from the arguments.
-  if (request.arguments) {
-    if (request.arguments.fromFrame) {
-      from_index = request.arguments.fromFrame;
-    }
-    if (request.arguments.toFrame) {
-      to_index = request.arguments.toFrame;
-    }
-    if (request.arguments.bottom) {
-      var tmp_index = total_frames - from_index;
-      from_index = total_frames - to_index;
-      to_index = tmp_index;
-    }
-    if (from_index < 0 || to_index < 0) {
-      return response.failed('Invalid frame number');
-    }
-  }
-
-  // Adjust the index.
-  to_index = Math.min(total_frames, to_index);
-
-  if (to_index <= from_index) {
-    var error = 'Invalid frame range';
-    return response.failed(error);
-  }
-
-  // Create the response body.
-  var frames = [];
-  for (var i = from_index; i < to_index; i++) {
-    frames.push(this.exec_state_.frame(i));
-  }
-  response.body = {
-    fromFrame: from_index,
-    toFrame: to_index,
-    totalFrames: total_frames,
-    frames: frames
-  };
-};
-
-
-DebugCommandProcessor.prototype.frameRequest_ = function(request, response) {
-  // No frames no source.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No frames');
-  }
-
-  // With no arguments just keep the selected frame.
-  if (request.arguments) {
-    var index = request.arguments.number;
-    if (index < 0 || this.exec_state_.frameCount() <= index) {
-      return response.failed('Invalid frame number');
-    }
-
-    this.exec_state_.setSelectedFrame(request.arguments.number);
-  }
-  response.body = this.exec_state_.frame();
-};
-
-
-DebugCommandProcessor.prototype.resolveFrameFromScopeDescription_ =
-    function(scope_description) {
-  // Get the frame for which the scope or scopes are requested.
-  // With no frameNumber argument use the currently selected frame.
-  if (scope_description && !IS_UNDEFINED(scope_description.frameNumber)) {
-    var frame_index = scope_description.frameNumber;
-    if (frame_index < 0 || this.exec_state_.frameCount() <= frame_index) {
-      throw new Error('Invalid frame number');
-    }
-    return this.exec_state_.frame(frame_index);
-  } else {
-    return this.exec_state_.frame();
-  }
-};
-
-
-// Gets scope host object from request. It is either a function
-// ('functionHandle' argument must be specified) or a stack frame
-// ('frameNumber' may be specified and the current frame is taken by default).
-DebugCommandProcessor.prototype.resolveScopeHolder_ =
-    function(scope_description) {
-  if (scope_description && "functionHandle" in scope_description) {
-    if (!IS_NUMBER(scope_description.functionHandle)) {
-      throw new Error('Function handle must be a number');
-    }
-    var function_mirror = LookupMirror(scope_description.functionHandle);
-    if (!function_mirror) {
-      throw new Error('Failed to find function object by handle');
-    }
-    if (!function_mirror.isFunction()) {
-      throw new Error('Value of non-function type is found by handle');
-    }
-    return function_mirror;
-  } else {
-    // No frames no scopes.
-    if (this.exec_state_.frameCount() == 0) {
-      throw new Error('No scopes');
-    }
-
-    // Get the frame for which the scopes are requested.
-    var frame = this.resolveFrameFromScopeDescription_(scope_description);
-    return frame;
-  }
-}
-
-
-DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) {
-  var scope_holder = this.resolveScopeHolder_(request.arguments);
-
-  // Fill all scopes for this frame or function.
-  var total_scopes = scope_holder.scopeCount();
-  var scopes = [];
-  for (var i = 0; i < total_scopes; i++) {
-    scopes.push(scope_holder.scope(i));
-  }
-  response.body = {
-    fromScope: 0,
-    toScope: total_scopes,
-    totalScopes: total_scopes,
-    scopes: scopes
-  };
-};
-
-
-DebugCommandProcessor.prototype.scopeRequest_ = function(request, response) {
-  // Get the frame or function for which the scope is requested.
-  var scope_holder = this.resolveScopeHolder_(request.arguments);
-
-  // With no scope argument just return top scope.
-  var scope_index = 0;
-  if (request.arguments && !IS_UNDEFINED(request.arguments.number)) {
-    scope_index = builtins.$toNumber(request.arguments.number);
-    if (scope_index < 0 || scope_holder.scopeCount() <= scope_index) {
-      return response.failed('Invalid scope number');
-    }
-  }
-
-  response.body = scope_holder.scope(scope_index);
-};
-
-
-// Reads value from protocol description. Description may be in form of type
-// (for singletons), raw value (primitive types supported in JSON),
-// string value description plus type (for primitive values) or handle id.
-// Returns raw value or throws exception.
-DebugCommandProcessor.resolveValue_ = function(value_description) {
-  if ("handle" in value_description) {
-    var value_mirror = LookupMirror(value_description.handle);
-    if (!value_mirror) {
-      throw new Error("Failed to resolve value by handle, ' #" +
-          value_description.handle + "# not found");
-    }
-    return value_mirror.value();
-  } else if ("stringDescription" in value_description) {
-    if (value_description.type == BOOLEAN_TYPE) {
-      return Boolean(value_description.stringDescription);
-    } else if (value_description.type == NUMBER_TYPE) {
-      return Number(value_description.stringDescription);
-    } if (value_description.type == STRING_TYPE) {
-      return String(value_description.stringDescription);
-    } else {
-      throw new Error("Unknown type");
-    }
-  } else if ("value" in value_description) {
-    return value_description.value;
-  } else if (value_description.type == UNDEFINED_TYPE) {
-    return UNDEFINED;
-  } else if (value_description.type == NULL_TYPE) {
-    return null;
-  } else {
-    throw new Error("Failed to parse value description");
-  }
-};
-
-
-DebugCommandProcessor.prototype.setVariableValueRequest_ =
-    function(request, response) {
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  if (IS_UNDEFINED(request.arguments.name)) {
-    response.failed('Missing variable name');
-  }
-  var variable_name = request.arguments.name;
-
-  var scope_description = request.arguments.scope;
-
-  // Get the frame or function for which the scope is requested.
-  var scope_holder = this.resolveScopeHolder_(scope_description);
-
-  if (IS_UNDEFINED(scope_description.number)) {
-    response.failed('Missing scope number');
-  }
-  var scope_index = builtins.$toNumber(scope_description.number);
-
-  var scope = scope_holder.scope(scope_index);
-
-  var new_value =
-      DebugCommandProcessor.resolveValue_(request.arguments.newValue);
-
-  scope.setVariableValue(variable_name, new_value);
-
-  var new_value_mirror = MakeMirror(new_value);
-
-  response.body = {
-    newValue: new_value_mirror
-  };
-};
-
-
-DebugCommandProcessor.prototype.evaluateRequest_ = function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-
-  // Pull out arguments.
-  var expression = request.arguments.expression;
-  var frame = request.arguments.frame;
-  var global = request.arguments.global;
-  var disable_break = request.arguments.disable_break;
-  var additional_context = request.arguments.additional_context;
-
-  // The expression argument could be an integer so we convert it to a
-  // string.
-  try {
-    expression = String(expression);
-  } catch(e) {
-    return response.failed('Failed to convert expression argument to string');
-  }
-
-  // Check for legal arguments.
-  if (!IS_UNDEFINED(frame) && global) {
-    return response.failed('Arguments "frame" and "global" are exclusive');
-  }
-
-  var additional_context_object;
-  if (additional_context) {
-    additional_context_object = {};
-    for (var i = 0; i < additional_context.length; i++) {
-      var mapping = additional_context[i];
-
-      if (!IS_STRING(mapping.name)) {
-        return response.failed("Context element #" + i +
-            " doesn't contain name:string property");
-      }
-
-      var raw_value = DebugCommandProcessor.resolveValue_(mapping);
-      additional_context_object[mapping.name] = raw_value;
-    }
-  }
-
-  // Global evaluate.
-  if (global) {
-    // Evaluate in the native context.
-    response.body = this.exec_state_.evaluateGlobal(
-        expression, Boolean(disable_break), additional_context_object);
-    return;
-  }
-
-  // Default value for disable_break is true.
-  if (IS_UNDEFINED(disable_break)) {
-    disable_break = true;
-  }
-
-  // No frames no evaluate in frame.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No frames');
-  }
-
-  // Check whether a frame was specified.
-  if (!IS_UNDEFINED(frame)) {
-    var frame_number = builtins.$toNumber(frame);
-    if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
-      return response.failed('Invalid frame "' + frame + '"');
-    }
-    // Evaluate in the specified frame.
-    response.body = this.exec_state_.frame(frame_number).evaluate(
-        expression, Boolean(disable_break), additional_context_object);
-    return;
-  } else {
-    // Evaluate in the selected frame.
-    response.body = this.exec_state_.frame().evaluate(
-        expression, Boolean(disable_break), additional_context_object);
-    return;
-  }
-};
-
-
-DebugCommandProcessor.prototype.lookupRequest_ = function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-
-  // Pull out arguments.
-  var handles = request.arguments.handles;
-
-  // Check for legal arguments.
-  if (IS_UNDEFINED(handles)) {
-    return response.failed('Argument "handles" missing');
-  }
-
-  // Set 'includeSource' option for script lookup.
-  if (!IS_UNDEFINED(request.arguments.includeSource)) {
-    var includeSource = builtins.$toBoolean(request.arguments.includeSource);
-    response.setOption('includeSource', includeSource);
-  }
-
-  // Lookup handles.
-  var mirrors = {};
-  for (var i = 0; i < handles.length; i++) {
-    var handle = handles[i];
-    var mirror = LookupMirror(handle);
-    if (!mirror) {
-      return response.failed('Object #' + handle + '# not found');
-    }
-    mirrors[handle] = mirror;
-  }
-  response.body = mirrors;
-};
-
-
-DebugCommandProcessor.prototype.referencesRequest_ =
-    function(request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-
-  // Pull out arguments.
-  var type = request.arguments.type;
-  var handle = request.arguments.handle;
-
-  // Check for legal arguments.
-  if (IS_UNDEFINED(type)) {
-    return response.failed('Argument "type" missing');
-  }
-  if (IS_UNDEFINED(handle)) {
-    return response.failed('Argument "handle" missing');
-  }
-  if (type != 'referencedBy' && type != 'constructedBy') {
-    return response.failed('Invalid type "' + type + '"');
-  }
-
-  // Lookup handle and return objects with references the object.
-  var mirror = LookupMirror(handle);
-  if (mirror) {
-    if (type == 'referencedBy') {
-      response.body = mirror.referencedBy();
-    } else {
-      response.body = mirror.constructedBy();
-    }
-  } else {
-    return response.failed('Object #' + handle + '# not found');
-  }
-};
-
-
-DebugCommandProcessor.prototype.sourceRequest_ = function(request, response) {
-  // No frames no source.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No source');
-  }
-
-  var from_line;
-  var to_line;
-  var frame = this.exec_state_.frame();
-  if (request.arguments) {
-    // Pull out arguments.
-    from_line = request.arguments.fromLine;
-    to_line = request.arguments.toLine;
-
-    if (!IS_UNDEFINED(request.arguments.frame)) {
-      var frame_number = builtins.$toNumber(request.arguments.frame);
-      if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
-        return response.failed('Invalid frame "' + frame + '"');
-      }
-      frame = this.exec_state_.frame(frame_number);
-    }
-  }
-
-  // Get the script selected.
-  var script = frame.func().script();
-  if (!script) {
-    return response.failed('No source');
-  }
-
-  // Get the source slice and fill it into the response.
-  var slice = script.sourceSlice(from_line, to_line);
-  if (!slice) {
-    return response.failed('Invalid line interval');
-  }
-  response.body = {};
-  response.body.source = slice.sourceText();
-  response.body.fromLine = slice.from_line;
-  response.body.toLine = slice.to_line;
-  response.body.fromPosition = slice.from_position;
-  response.body.toPosition = slice.to_position;
-  response.body.totalLines = script.lineCount();
-};
-
-
-DebugCommandProcessor.prototype.scriptsRequest_ = function(request, response) {
-  var types = ScriptTypeFlag(Debug.ScriptType.Normal);
-  var includeSource = false;
-  var idsToInclude = null;
-  if (request.arguments) {
-    // Pull out arguments.
-    if (!IS_UNDEFINED(request.arguments.types)) {
-      types = builtins.$toNumber(request.arguments.types);
-      if (isNaN(types) || types < 0) {
-        return response.failed('Invalid types "' +
-                               request.arguments.types + '"');
-      }
-    }
-
-    if (!IS_UNDEFINED(request.arguments.includeSource)) {
-      includeSource = builtins.$toBoolean(request.arguments.includeSource);
-      response.setOption('includeSource', includeSource);
-    }
-
-    if (IS_ARRAY(request.arguments.ids)) {
-      idsToInclude = {};
-      var ids = request.arguments.ids;
-      for (var i = 0; i < ids.length; i++) {
-        idsToInclude[ids[i]] = true;
-      }
-    }
-
-    var filterStr = null;
-    var filterNum = null;
-    if (!IS_UNDEFINED(request.arguments.filter)) {
-      var num = builtins.$toNumber(request.arguments.filter);
-      if (!isNaN(num)) {
-        filterNum = num;
-      }
-      filterStr = request.arguments.filter;
-    }
-  }
-
-  // Collect all scripts in the heap.
-  var scripts = %DebugGetLoadedScripts();
-
-  response.body = [];
-
-  for (var i = 0; i < scripts.length; i++) {
-    if (idsToInclude && !idsToInclude[scripts[i].id]) {
-      continue;
-    }
-    if (filterStr || filterNum) {
-      var script = scripts[i];
-      var found = false;
-      if (filterNum && !found) {
-        if (script.id && script.id === filterNum) {
-          found = true;
-        }
-      }
-      if (filterStr && !found) {
-        if (script.name && script.name.indexOf(filterStr) >= 0) {
-          found = true;
-        }
-      }
-      if (!found) continue;
-    }
-    if (types & ScriptTypeFlag(scripts[i].type)) {
-      response.body.push(MakeMirror(scripts[i]));
-    }
-  }
-};
-
-
-DebugCommandProcessor.prototype.threadsRequest_ = function(request, response) {
-  // Get the number of threads.
-  var total_threads = this.exec_state_.threadCount();
-
-  // Get information for all threads.
-  var threads = [];
-  for (var i = 0; i < total_threads; i++) {
-    var details = %GetThreadDetails(this.exec_state_.break_id, i);
-    var thread_info = { current: details[0],
-                        id: details[1]
-                      };
-    threads.push(thread_info);
-  }
-
-  // Create the response body.
-  response.body = {
-    totalThreads: total_threads,
-    threads: threads
-  };
-};
-
-
-DebugCommandProcessor.prototype.suspendRequest_ = function(request, response) {
-  response.running = false;
-};
-
-
-DebugCommandProcessor.prototype.versionRequest_ = function(request, response) {
-  response.body = {
-    V8Version: %GetV8Version()
-  };
-};
-
-
-DebugCommandProcessor.prototype.changeLiveRequest_ = function(
-    request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-  var script_id = request.arguments.script_id;
-  var preview_only = !!request.arguments.preview_only;
-
-  var scripts = %DebugGetLoadedScripts();
-
-  var the_script = null;
-  for (var i = 0; i < scripts.length; i++) {
-    if (scripts[i].id == script_id) {
-      the_script = scripts[i];
-    }
-  }
-  if (!the_script) {
-    response.failed('Script not found');
-    return;
-  }
-
-  var change_log = new Array();
-
-  if (!IS_STRING(request.arguments.new_source)) {
-    throw "new_source argument expected";
-  }
-
-  var new_source = request.arguments.new_source;
-
-  var result_description;
-  try {
-    result_description = Debug.LiveEdit.SetScriptSource(the_script,
-        new_source, preview_only, change_log);
-  } catch (e) {
-    if (e instanceof Debug.LiveEdit.Failure && "details" in e) {
-      response.failed(e.message, e.details);
-      return;
-    }
-    throw e;
-  }
-  response.body = {change_log: change_log, result: result_description};
-
-  if (!preview_only && !this.running_ && result_description.stack_modified) {
-    response.body.stepin_recommended = true;
-  }
-};
-
-
-DebugCommandProcessor.prototype.restartFrameRequest_ = function(
-    request, response) {
-  if (!request.arguments) {
-    return response.failed('Missing arguments');
-  }
-  var frame = request.arguments.frame;
-
-  // No frames to evaluate in frame.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No frames');
-  }
-
-  var frame_mirror;
-  // Check whether a frame was specified.
-  if (!IS_UNDEFINED(frame)) {
-    var frame_number = builtins.$toNumber(frame);
-    if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
-      return response.failed('Invalid frame "' + frame + '"');
-    }
-    // Restart specified frame.
-    frame_mirror = this.exec_state_.frame(frame_number);
-  } else {
-    // Restart selected frame.
-    frame_mirror = this.exec_state_.frame();
-  }
-
-  var result_description = Debug.LiveEdit.RestartFrame(frame_mirror);
-  response.body = {result: result_description};
-};
-
-
-DebugCommandProcessor.prototype.debuggerFlagsRequest_ = function(request,
-                                                                 response) {
-  // Check for legal request.
-  if (!request.arguments) {
-    response.failed('Missing arguments');
-    return;
-  }
-
-  // Pull out arguments.
-  var flags = request.arguments.flags;
-
-  response.body = { flags: [] };
-  if (!IS_UNDEFINED(flags)) {
-    for (var i = 0; i < flags.length; i++) {
-      var name = flags[i].name;
-      var debugger_flag = debugger_flags[name];
-      if (!debugger_flag) {
-        continue;
-      }
-      if ('value' in flags[i]) {
-        debugger_flag.setValue(flags[i].value);
-      }
-      response.body.flags.push({ name: name, value: debugger_flag.getValue() });
-    }
-  } else {
-    for (var name in debugger_flags) {
-      var value = debugger_flags[name].getValue();
-      response.body.flags.push({ name: name, value: value });
-    }
-  }
-};
-
-
-DebugCommandProcessor.prototype.v8FlagsRequest_ = function(request, response) {
-  var flags = request.arguments.flags;
-  if (!flags) flags = '';
-  %SetFlags(flags);
-};
-
-
-DebugCommandProcessor.prototype.gcRequest_ = function(request, response) {
-  var type = request.arguments.type;
-  if (!type) type = 'all';
-
-  var before = %GetHeapUsage();
-  %CollectGarbage(type);
-  var after = %GetHeapUsage();
-
-  response.body = { "before": before, "after": after };
-};
-
-
-DebugCommandProcessor.prototype.dispatch_ = (function() {
-  var proto = DebugCommandProcessor.prototype;
-  return {
-    "continue":             proto.continueRequest_,
-    "break"   :             proto.breakRequest_,
-    "setbreakpoint" :       proto.setBreakPointRequest_,
-    "changebreakpoint":     proto.changeBreakPointRequest_,
-    "clearbreakpoint":      proto.clearBreakPointRequest_,
-    "clearbreakpointgroup": proto.clearBreakPointGroupRequest_,
-    "disconnect":           proto.disconnectRequest_,
-    "setexceptionbreak":    proto.setExceptionBreakRequest_,
-    "listbreakpoints":      proto.listBreakpointsRequest_,
-    "backtrace":            proto.backtraceRequest_,
-    "frame":                proto.frameRequest_,
-    "scopes":               proto.scopesRequest_,
-    "scope":                proto.scopeRequest_,
-    "setvariablevalue":     proto.setVariableValueRequest_,
-    "evaluate":             proto.evaluateRequest_,
-    "lookup":               proto.lookupRequest_,
-    "references":           proto.referencesRequest_,
-    "source":               proto.sourceRequest_,
-    "scripts":              proto.scriptsRequest_,
-    "threads":              proto.threadsRequest_,
-    "suspend":              proto.suspendRequest_,
-    "version":              proto.versionRequest_,
-    "changelive":           proto.changeLiveRequest_,
-    "restartframe":         proto.restartFrameRequest_,
-    "flags":                proto.debuggerFlagsRequest_,
-    "v8flag":               proto.v8FlagsRequest_,
-    "gc":                   proto.gcRequest_,
-  };
-})();
-
-
-// Check whether the previously processed command caused the VM to become
-// running.
-DebugCommandProcessor.prototype.isRunning = function() {
-  return this.running_;
-};
-
-
-DebugCommandProcessor.prototype.systemBreak = function(cmd, args) {
-  return %SystemBreak();
-};
-
-
-/**
- * Convert an Object to its debugger protocol representation. The representation
- * may be serilized to a JSON object using JSON.stringify().
- * This implementation simply runs through all string property names, converts
- * each property value to a protocol value and adds the property to the result
- * object. For type "object" the function will be called recursively. Note that
- * circular structures will cause infinite recursion.
- * @param {Object} object The object to format as protocol object.
- * @param {MirrorSerializer} mirror_serializer The serializer to use if any
- *     mirror objects are encountered.
- * @return {Object} Protocol object value.
- */
-function ObjectToProtocolObject_(object, mirror_serializer) {
-  var content = {};
-  for (var key in object) {
-    // Only consider string keys.
-    if (typeof key == 'string') {
-      // Format the value based on its type.
-      var property_value_json = ValueToProtocolValue_(object[key],
-                                                      mirror_serializer);
-      // Add the property if relevant.
-      if (!IS_UNDEFINED(property_value_json)) {
-        content[key] = property_value_json;
-      }
-    }
-  }
-
-  return content;
-}
-
-
-/**
- * Convert an array to its debugger protocol representation. It will convert
- * each array element to a protocol value.
- * @param {Array} array The array to format as protocol array.
- * @param {MirrorSerializer} mirror_serializer The serializer to use if any
- *     mirror objects are encountered.
- * @return {Array} Protocol array value.
- */
-function ArrayToProtocolArray_(array, mirror_serializer) {
-  var json = [];
-  for (var i = 0; i < array.length; i++) {
-    json.push(ValueToProtocolValue_(array[i], mirror_serializer));
-  }
-  return json;
-}
-
-
-/**
- * Convert a value to its debugger protocol representation.
- * @param {*} value The value to format as protocol value.
- * @param {MirrorSerializer} mirror_serializer The serializer to use if any
- *     mirror objects are encountered.
- * @return {*} Protocol value.
- */
-function ValueToProtocolValue_(value, mirror_serializer) {
-  // Format the value based on its type.
-  var json;
-  switch (typeof value) {
-    case 'object':
-      if (value instanceof Mirror) {
-        json = mirror_serializer.serializeValue(value);
-      } else if (IS_ARRAY(value)){
-        json = ArrayToProtocolArray_(value, mirror_serializer);
-      } else {
-        json = ObjectToProtocolObject_(value, mirror_serializer);
-      }
-      break;
-
-    case 'boolean':
-    case 'string':
-    case 'number':
-      json = value;
-      break;
-
-    default:
-      json = null;
-  }
-  return json;
-}
diff --git a/src/debug.cc b/src/debug.cc
deleted file mode 100644 (file)
index 38d9f47..0000000
+++ /dev/null
@@ -1,2811 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#include "src/api.h"
-#include "src/arguments.h"
-#include "src/bootstrapper.h"
-#include "src/code-stubs.h"
-#include "src/codegen.h"
-#include "src/compilation-cache.h"
-#include "src/compiler.h"
-#include "src/debug.h"
-#include "src/deoptimizer.h"
-#include "src/execution.h"
-#include "src/full-codegen/full-codegen.h"
-#include "src/global-handles.h"
-#include "src/list.h"
-#include "src/log.h"
-#include "src/messages.h"
-#include "src/snapshot/natives.h"
-
-#include "include/v8-debug.h"
-
-namespace v8 {
-namespace internal {
-
-Debug::Debug(Isolate* isolate)
-    : debug_context_(Handle<Context>()),
-      event_listener_(Handle<Object>()),
-      event_listener_data_(Handle<Object>()),
-      message_handler_(NULL),
-      command_received_(0),
-      command_queue_(isolate->logger(), kQueueInitialSize),
-      is_active_(false),
-      is_suppressed_(false),
-      live_edit_enabled_(true),  // TODO(yangguo): set to false by default.
-      break_disabled_(false),
-      in_debug_event_listener_(false),
-      break_on_exception_(false),
-      break_on_uncaught_exception_(false),
-      script_cache_(NULL),
-      debug_info_list_(NULL),
-      isolate_(isolate) {
-  ThreadInit();
-}
-
-
-static v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
-  Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
-  // Isolate::context() may have been NULL when "script collected" event
-  // occured.
-  if (context.is_null()) return v8::Local<v8::Context>();
-  Handle<Context> native_context(context->native_context());
-  return v8::Utils::ToLocal(native_context);
-}
-
-
-BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo,
-                             int position, int statement_position)
-    : debug_info_(debug_info),
-      pc_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())),
-      rmode_(rinfo->rmode()),
-      data_(rinfo->data()),
-      position_(position),
-      statement_position_(statement_position) {}
-
-
-BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
-                                  BreakLocatorType type)
-    : debug_info_(debug_info),
-      reloc_iterator_(debug_info->code(), GetModeMask(type)),
-      break_index_(-1),
-      position_(1),
-      statement_position_(1) {
-  if (!Done()) Next();
-}
-
-
-int BreakLocation::Iterator::GetModeMask(BreakLocatorType type) {
-  int mask = 0;
-  mask |= RelocInfo::ModeMask(RelocInfo::POSITION);
-  mask |= RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION);
-  mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
-  mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL);
-  mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CONSTRUCT_CALL);
-  if (type == ALL_BREAK_LOCATIONS) {
-    mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
-    mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT);
-  }
-  return mask;
-}
-
-
-void BreakLocation::Iterator::Next() {
-  DisallowHeapAllocation no_gc;
-  DCHECK(!Done());
-
-  // Iterate through reloc info for code and original code stopping at each
-  // breakable code target.
-  bool first = break_index_ == -1;
-  while (!Done()) {
-    if (!first) reloc_iterator_.next();
-    first = false;
-    if (Done()) return;
-
-    // Whenever a statement position or (plain) position is passed update the
-    // current value of these.
-    if (RelocInfo::IsPosition(rmode())) {
-      if (RelocInfo::IsStatementPosition(rmode())) {
-        statement_position_ = static_cast<int>(
-            rinfo()->data() - debug_info_->shared()->start_position());
-      }
-      // Always update the position as we don't want that to be before the
-      // statement position.
-      position_ = static_cast<int>(rinfo()->data() -
-                                   debug_info_->shared()->start_position());
-      DCHECK(position_ >= 0);
-      DCHECK(statement_position_ >= 0);
-      continue;
-    }
-
-    DCHECK(RelocInfo::IsDebugBreakSlot(rmode()) ||
-           RelocInfo::IsDebuggerStatement(rmode()));
-
-    if (RelocInfo::IsDebugBreakSlotAtReturn(rmode())) {
-      // Set the positions to the end of the function.
-      if (debug_info_->shared()->HasSourceCode()) {
-        position_ = debug_info_->shared()->end_position() -
-                    debug_info_->shared()->start_position() - 1;
-      } else {
-        position_ = 0;
-      }
-      statement_position_ = position_;
-    }
-
-    break;
-  }
-  break_index_++;
-}
-
-
-// Find the break point at the supplied address, or the closest one before
-// the address.
-BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info,
-                                         BreakLocatorType type, Address pc) {
-  Iterator it(debug_info, type);
-  it.SkipTo(BreakIndexFromAddress(debug_info, type, pc));
-  return it.GetBreakLocation();
-}
-
-
-// Find the break point at the supplied address, or the closest one before
-// the address.
-void BreakLocation::FromAddressSameStatement(Handle<DebugInfo> debug_info,
-                                             BreakLocatorType type, Address pc,
-                                             List<BreakLocation>* result_out) {
-  int break_index = BreakIndexFromAddress(debug_info, type, pc);
-  Iterator it(debug_info, type);
-  it.SkipTo(break_index);
-  int statement_position = it.statement_position();
-  while (!it.Done() && it.statement_position() == statement_position) {
-    result_out->Add(it.GetBreakLocation());
-    it.Next();
-  }
-}
-
-
-int BreakLocation::BreakIndexFromAddress(Handle<DebugInfo> debug_info,
-                                         BreakLocatorType type, Address pc) {
-  // Run through all break points to locate the one closest to the address.
-  int closest_break = 0;
-  int distance = kMaxInt;
-  for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
-    // Check if this break point is closer that what was previously found.
-    if (it.pc() <= pc && pc - it.pc() < distance) {
-      closest_break = it.break_index();
-      distance = static_cast<int>(pc - it.pc());
-      // Check whether we can't get any closer.
-      if (distance == 0) break;
-    }
-  }
-  return closest_break;
-}
-
-
-BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info,
-                                          BreakLocatorType type, int position,
-                                          BreakPositionAlignment alignment) {
-  // Run through all break points to locate the one closest to the source
-  // position.
-  int closest_break = 0;
-  int distance = kMaxInt;
-
-  for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
-    int next_position;
-    if (alignment == STATEMENT_ALIGNED) {
-      next_position = it.statement_position();
-    } else {
-      DCHECK(alignment == BREAK_POSITION_ALIGNED);
-      next_position = it.position();
-    }
-    if (position <= next_position && next_position - position < distance) {
-      closest_break = it.break_index();
-      distance = next_position - position;
-      // Check whether we can't get any closer.
-      if (distance == 0) break;
-    }
-  }
-
-  Iterator it(debug_info, type);
-  it.SkipTo(closest_break);
-  return it.GetBreakLocation();
-}
-
-
-void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
-  // If there is not already a real break point here patch code with debug
-  // break.
-  if (!HasBreakPoint()) SetDebugBreak();
-  DCHECK(IsDebugBreak() || IsDebuggerStatement());
-  // Set the break point information.
-  DebugInfo::SetBreakPoint(debug_info_, pc_offset_, position_,
-                           statement_position_, break_point_object);
-}
-
-
-void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) {
-  // Clear the break point information.
-  DebugInfo::ClearBreakPoint(debug_info_, pc_offset_, break_point_object);
-  // If there are no more break points here remove the debug break.
-  if (!HasBreakPoint()) {
-    ClearDebugBreak();
-    DCHECK(!IsDebugBreak());
-  }
-}
-
-
-void BreakLocation::SetOneShot() {
-  // Debugger statement always calls debugger. No need to modify it.
-  if (IsDebuggerStatement()) return;
-
-  // If there is a real break point here no more to do.
-  if (HasBreakPoint()) {
-    DCHECK(IsDebugBreak());
-    return;
-  }
-
-  // Patch code with debug break.
-  SetDebugBreak();
-}
-
-
-void BreakLocation::ClearOneShot() {
-  // Debugger statement always calls debugger. No need to modify it.
-  if (IsDebuggerStatement()) return;
-
-  // If there is a real break point here no more to do.
-  if (HasBreakPoint()) {
-    DCHECK(IsDebugBreak());
-    return;
-  }
-
-  // Patch code removing debug break.
-  ClearDebugBreak();
-  DCHECK(!IsDebugBreak());
-}
-
-
-void BreakLocation::SetDebugBreak() {
-  // Debugger statement always calls debugger. No need to modify it.
-  if (IsDebuggerStatement()) return;
-
-  // If there is already a break point here just return. This might happen if
-  // the same code is flooded with break points twice. Flooding the same
-  // function twice might happen when stepping in a function with an exception
-  // handler as the handler and the function is the same.
-  if (IsDebugBreak()) return;
-
-  DCHECK(IsDebugBreakSlot());
-  Builtins* builtins = debug_info_->GetIsolate()->builtins();
-  Handle<Code> target =
-      IsReturn() ? builtins->Return_DebugBreak() : builtins->Slot_DebugBreak();
-  DebugCodegen::PatchDebugBreakSlot(pc(), target);
-  DCHECK(IsDebugBreak());
-}
-
-
-void BreakLocation::ClearDebugBreak() {
-  // Debugger statement always calls debugger. No need to modify it.
-  if (IsDebuggerStatement()) return;
-
-  DCHECK(IsDebugBreakSlot());
-  DebugCodegen::ClearDebugBreakSlot(pc());
-  DCHECK(!IsDebugBreak());
-}
-
-
-bool BreakLocation::IsStepInLocation() const {
-  return IsConstructCall() || IsCall();
-}
-
-
-bool BreakLocation::IsDebugBreak() const {
-  if (IsDebugBreakSlot()) {
-    return rinfo().IsPatchedDebugBreakSlotSequence();
-  }
-  return false;
-}
-
-
-Handle<Object> BreakLocation::BreakPointObjects() const {
-  return debug_info_->GetBreakPointObjects(pc_offset_);
-}
-
-
-// Threading support.
-void Debug::ThreadInit() {
-  thread_local_.break_count_ = 0;
-  thread_local_.break_id_ = 0;
-  thread_local_.break_frame_id_ = StackFrame::NO_ID;
-  thread_local_.last_step_action_ = StepNone;
-  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
-  thread_local_.step_count_ = 0;
-  thread_local_.last_fp_ = 0;
-  thread_local_.queued_step_count_ = 0;
-  thread_local_.step_into_fp_ = 0;
-  thread_local_.step_out_fp_ = 0;
-  // TODO(isolates): frames_are_dropped_?
-  base::NoBarrier_Store(&thread_local_.current_debug_scope_,
-                        static_cast<base::AtomicWord>(0));
-  thread_local_.restarter_frame_function_pointer_ = NULL;
-}
-
-
-char* Debug::ArchiveDebug(char* storage) {
-  char* to = storage;
-  MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
-  ThreadInit();
-  return storage + ArchiveSpacePerThread();
-}
-
-
-char* Debug::RestoreDebug(char* storage) {
-  char* from = storage;
-  MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
-  return storage + ArchiveSpacePerThread();
-}
-
-
-int Debug::ArchiveSpacePerThread() {
-  return sizeof(ThreadLocal);
-}
-
-
-ScriptCache::ScriptCache(Isolate* isolate) : isolate_(isolate) {
-  Heap* heap = isolate_->heap();
-  HandleScope scope(isolate_);
-
-  DCHECK(isolate_->debug()->is_active());
-
-  // Perform a GC to get rid of all unreferenced scripts.
-  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
-
-  // Scan heap for Script objects.
-  List<Handle<Script> > scripts;
-  {
-    HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
-    DisallowHeapAllocation no_allocation;
-    for (HeapObject* obj = iterator.next(); obj != NULL;
-         obj = iterator.next()) {
-      if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
-        scripts.Add(Handle<Script>(Script::cast(obj)));
-      }
-    }
-  }
-
-  GlobalHandles* global_handles = isolate_->global_handles();
-  table_ = Handle<WeakValueHashTable>::cast(global_handles->Create(
-      Object::cast(*WeakValueHashTable::New(isolate_, scripts.length()))));
-  for (int i = 0; i < scripts.length(); i++) Add(scripts[i]);
-}
-
-
-void ScriptCache::Add(Handle<Script> script) {
-  HandleScope scope(isolate_);
-  Handle<Smi> id(script->id(), isolate_);
-
-#ifdef DEBUG
-  Handle<Object> lookup(table_->LookupWeak(id), isolate_);
-  if (!lookup->IsTheHole()) {
-    Handle<Script> found = Handle<Script>::cast(lookup);
-    DCHECK(script->id() == found->id());
-    DCHECK(!script->name()->IsString() ||
-           String::cast(script->name())->Equals(String::cast(found->name())));
-  }
-#endif
-
-  Handle<WeakValueHashTable> new_table =
-      WeakValueHashTable::PutWeak(table_, id, script);
-
-  if (new_table.is_identical_to(table_)) return;
-  GlobalHandles* global_handles = isolate_->global_handles();
-  global_handles->Destroy(Handle<Object>::cast(table_).location());
-  table_ = Handle<WeakValueHashTable>::cast(
-      global_handles->Create(Object::cast(*new_table)));
-}
-
-
-ScriptCache::~ScriptCache() {
-  isolate_->global_handles()->Destroy(Handle<Object>::cast(table_).location());
-  table_ = Handle<WeakValueHashTable>();
-}
-
-
-DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
-  // Globalize the request debug info object and make it weak.
-  GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
-  debug_info_ =
-      Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location();
-}
-
-
-DebugInfoListNode::~DebugInfoListNode() {
-  if (debug_info_ == nullptr) return;
-  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_));
-  debug_info_ = nullptr;
-}
-
-
-bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
-  Factory* factory = isolate->factory();
-  HandleScope scope(isolate);
-
-  // Bail out if the index is invalid.
-  if (index == -1) return false;
-
-  // Find source and name for the requested script.
-  Handle<String> source_code =
-      isolate->bootstrapper()->SourceLookup<Natives>(index);
-  Vector<const char> name = Natives::GetScriptName(index);
-  Handle<String> script_name =
-      factory->NewStringFromAscii(name).ToHandleChecked();
-  Handle<Context> context = isolate->native_context();
-
-  // Compile the script.
-  Handle<SharedFunctionInfo> function_info;
-  function_info = Compiler::CompileScript(
-      source_code, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
-      context, NULL, NULL, ScriptCompiler::kNoCompileOptions, NATIVES_CODE,
-      false);
-  if (function_info.is_null()) return false;
-
-  // Execute the shared function in the debugger context.
-  Handle<JSFunction> function =
-      factory->NewFunctionFromSharedFunctionInfo(function_info, context);
-
-  MaybeHandle<Object> maybe_exception;
-  MaybeHandle<Object> result = Execution::TryCall(
-      function, handle(context->global_proxy()), 0, NULL, &maybe_exception);
-
-  // Check for caught exceptions.
-  if (result.is_null()) {
-    DCHECK(!isolate->has_pending_exception());
-    MessageLocation computed_location;
-    isolate->ComputeLocation(&computed_location);
-    Handle<JSMessageObject> message = MessageHandler::MakeMessageObject(
-        isolate, MessageTemplate::kDebuggerLoading, &computed_location,
-        isolate->factory()->undefined_value(), Handle<JSArray>());
-    DCHECK(!isolate->has_pending_exception());
-    Handle<Object> exception;
-    if (maybe_exception.ToHandle(&exception)) {
-      isolate->set_pending_exception(*exception);
-      MessageHandler::ReportMessage(isolate, NULL, message);
-    }
-    DCHECK(!maybe_exception.is_null());
-    return false;
-  }
-
-  // Mark this script as native and return successfully.
-  Handle<Script> script(Script::cast(function->shared()->script()));
-  script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
-  return true;
-}
-
-
-bool Debug::Load() {
-  // Return if debugger is already loaded.
-  if (is_loaded()) return true;
-
-  // Bail out if we're already in the process of compiling the native
-  // JavaScript source code for the debugger.
-  if (is_suppressed_) return false;
-  SuppressDebug while_loading(this);
-
-  // Disable breakpoints and interrupts while compiling and running the
-  // debugger scripts including the context creation code.
-  DisableBreak disable(this, true);
-  PostponeInterruptsScope postpone(isolate_);
-
-  // Create the debugger context.
-  HandleScope scope(isolate_);
-  ExtensionConfiguration no_extensions;
-  Handle<Context> context = isolate_->bootstrapper()->CreateEnvironment(
-      MaybeHandle<JSGlobalProxy>(), v8::Local<ObjectTemplate>(),
-      &no_extensions);
-
-  // Fail if no context could be created.
-  if (context.is_null()) return false;
-
-  // Use the debugger context.
-  SaveContext save(isolate_);
-  isolate_->set_context(*context);
-
-  // Expose the builtins object in the debugger context.
-  Handle<String> key = isolate_->factory()->InternalizeOneByteString(
-      STATIC_CHAR_VECTOR("builtins"));
-  Handle<GlobalObject> global =
-      Handle<GlobalObject>(context->global_object(), isolate_);
-  Handle<JSBuiltinsObject> builtin =
-      Handle<JSBuiltinsObject>(global->builtins(), isolate_);
-  RETURN_ON_EXCEPTION_VALUE(
-      isolate_, Object::SetProperty(global, key, builtin, SLOPPY), false);
-
-  // Compile the JavaScript for the debugger in the debugger context.
-  bool caught_exception =
-      !CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) ||
-      !CompileDebuggerScript(isolate_, Natives::GetIndex("debug"));
-
-  if (FLAG_enable_liveedit) {
-    caught_exception = caught_exception ||
-        !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
-  }
-  // Check for caught exceptions.
-  if (caught_exception) return false;
-
-  debug_context_ = Handle<Context>::cast(
-      isolate_->global_handles()->Create(*context));
-  return true;
-}
-
-
-void Debug::Unload() {
-  ClearAllBreakPoints();
-  ClearStepping();
-
-  // Return debugger is not loaded.
-  if (!is_loaded()) return;
-
-  // Clear the script cache.
-  if (script_cache_ != NULL) {
-    delete script_cache_;
-    script_cache_ = NULL;
-  }
-
-  // Clear debugger context global handle.
-  GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
-  debug_context_ = Handle<Context>();
-}
-
-
-void Debug::Break(Arguments args, JavaScriptFrame* frame) {
-  Heap* heap = isolate_->heap();
-  HandleScope scope(isolate_);
-  DCHECK(args.length() == 0);
-
-  // Initialize LiveEdit.
-  LiveEdit::InitializeThreadLocal(this);
-
-  // Just continue if breaks are disabled or debugger cannot be loaded.
-  if (break_disabled()) return;
-
-  // Enter the debugger.
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  // Postpone interrupt during breakpoint processing.
-  PostponeInterruptsScope postpone(isolate_);
-
-  // Get the debug info (create it if it does not exist).
-  Handle<SharedFunctionInfo> shared =
-      Handle<SharedFunctionInfo>(frame->function()->shared());
-  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
-
-  // Find the break point where execution has stopped.
-  // PC points to the instruction after the current one, possibly a break
-  // location as well. So the "- 1" to exclude it from the search.
-  Address call_pc = frame->pc() - 1;
-  BreakLocation break_location =
-      BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
-
-  // Check whether step next reached a new statement.
-  if (!StepNextContinue(&break_location, frame)) {
-    // Decrease steps left if performing multiple steps.
-    if (thread_local_.step_count_ > 0) {
-      thread_local_.step_count_--;
-    }
-  }
-
-  // If there is one or more real break points check whether any of these are
-  // triggered.
-  Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
-  if (break_location.HasBreakPoint()) {
-    Handle<Object> break_point_objects = break_location.BreakPointObjects();
-    break_points_hit = CheckBreakPoints(break_point_objects);
-  }
-
-  // If step out is active skip everything until the frame where we need to step
-  // out to is reached, unless real breakpoint is hit.
-  if (StepOutActive() &&
-      frame->fp() != thread_local_.step_out_fp_ &&
-      break_points_hit->IsUndefined() ) {
-      // Step count should always be 0 for StepOut.
-      DCHECK(thread_local_.step_count_ == 0);
-  } else if (!break_points_hit->IsUndefined() ||
-             (thread_local_.last_step_action_ != StepNone &&
-              thread_local_.step_count_ == 0)) {
-    // Notify debugger if a real break point is triggered or if performing
-    // single stepping with no more steps to perform. Otherwise do another step.
-
-    // Clear all current stepping setup.
-    ClearStepping();
-
-    if (thread_local_.queued_step_count_ > 0) {
-      // Perform queued steps
-      int step_count = thread_local_.queued_step_count_;
-
-      // Clear queue
-      thread_local_.queued_step_count_ = 0;
-
-      PrepareStep(StepNext, step_count, StackFrame::NO_ID);
-    } else {
-      // Notify the debug event listeners.
-      OnDebugBreak(break_points_hit, false);
-    }
-  } else if (thread_local_.last_step_action_ != StepNone) {
-    // Hold on to last step action as it is cleared by the call to
-    // ClearStepping.
-    StepAction step_action = thread_local_.last_step_action_;
-    int step_count = thread_local_.step_count_;
-
-    // If StepNext goes deeper in code, StepOut until original frame
-    // and keep step count queued up in the meantime.
-    if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
-      // Count frames until target frame
-      int count = 0;
-      JavaScriptFrameIterator it(isolate_);
-      while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) {
-        count++;
-        it.Advance();
-      }
-
-      // Check that we indeed found the frame we are looking for.
-      CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_));
-      if (step_count > 1) {
-        // Save old count and action to continue stepping after StepOut.
-        thread_local_.queued_step_count_ = step_count - 1;
-      }
-
-      // Set up for StepOut to reach target frame.
-      step_action = StepOut;
-      step_count = count;
-    }
-
-    // Clear all current stepping setup.
-    ClearStepping();
-
-    // Set up for the remaining steps.
-    PrepareStep(step_action, step_count, StackFrame::NO_ID);
-  }
-}
-
-
-// Check the break point objects for whether one or more are actually
-// triggered. This function returns a JSArray with the break point objects
-// which is triggered.
-Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
-  Factory* factory = isolate_->factory();
-
-  // Count the number of break points hit. If there are multiple break points
-  // they are in a FixedArray.
-  Handle<FixedArray> break_points_hit;
-  int break_points_hit_count = 0;
-  DCHECK(!break_point_objects->IsUndefined());
-  if (break_point_objects->IsFixedArray()) {
-    Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
-    break_points_hit = factory->NewFixedArray(array->length());
-    for (int i = 0; i < array->length(); i++) {
-      Handle<Object> o(array->get(i), isolate_);
-      if (CheckBreakPoint(o)) {
-        break_points_hit->set(break_points_hit_count++, *o);
-      }
-    }
-  } else {
-    break_points_hit = factory->NewFixedArray(1);
-    if (CheckBreakPoint(break_point_objects)) {
-      break_points_hit->set(break_points_hit_count++, *break_point_objects);
-    }
-  }
-
-  // Return undefined if no break points were triggered.
-  if (break_points_hit_count == 0) {
-    return factory->undefined_value();
-  }
-  // Return break points hit as a JSArray.
-  Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
-  result->set_length(Smi::FromInt(break_points_hit_count));
-  return result;
-}
-
-
-// Check whether a single break point object is triggered.
-bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
-  Factory* factory = isolate_->factory();
-  HandleScope scope(isolate_);
-
-  // Ignore check if break point object is not a JSObject.
-  if (!break_point_object->IsJSObject()) return true;
-
-  // Get the function IsBreakPointTriggered (defined in debug-debugger.js).
-  Handle<String> is_break_point_triggered_string =
-      factory->InternalizeOneByteString(
-          STATIC_CHAR_VECTOR("IsBreakPointTriggered"));
-  Handle<GlobalObject> debug_global(debug_context()->global_object());
-  Handle<JSFunction> check_break_point =
-    Handle<JSFunction>::cast(Object::GetProperty(
-        debug_global, is_break_point_triggered_string).ToHandleChecked());
-
-  // Get the break id as an object.
-  Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
-
-  // Call HandleBreakPointx.
-  Handle<Object> argv[] = { break_id, break_point_object };
-  Handle<Object> result;
-  if (!Execution::TryCall(check_break_point,
-                          isolate_->js_builtins_object(),
-                          arraysize(argv),
-                          argv).ToHandle(&result)) {
-    return false;
-  }
-
-  // Return whether the break point is triggered.
-  return result->IsTrue();
-}
-
-
-bool Debug::SetBreakPoint(Handle<JSFunction> function,
-                          Handle<Object> break_point_object,
-                          int* source_position) {
-  HandleScope scope(isolate_);
-
-  // Make sure the function is compiled and has set up the debug info.
-  Handle<SharedFunctionInfo> shared(function->shared());
-  if (!EnsureDebugInfo(shared, function)) {
-    // Return if retrieving debug info failed.
-    return true;
-  }
-
-  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
-  // Source positions starts with zero.
-  DCHECK(*source_position >= 0);
-
-  // Find the break point and change it.
-  BreakLocation location = BreakLocation::FromPosition(
-      debug_info, ALL_BREAK_LOCATIONS, *source_position, STATEMENT_ALIGNED);
-  *source_position = location.statement_position();
-  location.SetBreakPoint(break_point_object);
-
-  // At least one active break point now.
-  return debug_info->GetBreakPointCount() > 0;
-}
-
-
-bool Debug::SetBreakPointForScript(Handle<Script> script,
-                                   Handle<Object> break_point_object,
-                                   int* source_position,
-                                   BreakPositionAlignment alignment) {
-  HandleScope scope(isolate_);
-
-  // Obtain shared function info for the function.
-  Handle<Object> result =
-      FindSharedFunctionInfoInScript(script, *source_position);
-  if (result->IsUndefined()) return false;
-
-  // Make sure the function has set up the debug info.
-  Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
-  if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
-    // Return if retrieving debug info failed.
-    return false;
-  }
-
-  // Find position within function. The script position might be before the
-  // source position of the first function.
-  int position;
-  if (shared->start_position() > *source_position) {
-    position = 0;
-  } else {
-    position = *source_position - shared->start_position();
-  }
-
-  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
-  // Source positions starts with zero.
-  DCHECK(position >= 0);
-
-  // Find the break point and change it.
-  BreakLocation location = BreakLocation::FromPosition(
-      debug_info, ALL_BREAK_LOCATIONS, position, alignment);
-  location.SetBreakPoint(break_point_object);
-
-  position = (alignment == STATEMENT_ALIGNED) ? location.statement_position()
-                                              : location.position();
-
-  *source_position = position + shared->start_position();
-
-  // At least one active break point now.
-  DCHECK(debug_info->GetBreakPointCount() > 0);
-  return true;
-}
-
-
-void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
-  HandleScope scope(isolate_);
-
-  DebugInfoListNode* node = debug_info_list_;
-  while (node != NULL) {
-    Handle<Object> result =
-        DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object);
-    if (!result->IsUndefined()) {
-      // Get information in the break point.
-      Handle<BreakPointInfo> break_point_info =
-          Handle<BreakPointInfo>::cast(result);
-      Handle<DebugInfo> debug_info = node->debug_info();
-
-      // Find the break point and clear it.
-      Address pc = debug_info->code()->entry() +
-                   break_point_info->code_position()->value();
-
-      BreakLocation location =
-          BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, pc);
-      location.ClearBreakPoint(break_point_object);
-
-      // If there are no more break points left remove the debug info for this
-      // function.
-      if (debug_info->GetBreakPointCount() == 0) {
-        RemoveDebugInfoAndClearFromShared(debug_info);
-      }
-
-      return;
-    }
-    node = node->next();
-  }
-}
-
-
-// Clear out all the debug break code. This is ONLY supposed to be used when
-// shutting down the debugger as it will leave the break point information in
-// DebugInfo even though the code is patched back to the non break point state.
-void Debug::ClearAllBreakPoints() {
-  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
-       node = node->next()) {
-    for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
-         !it.Done(); it.Next()) {
-      it.GetBreakLocation().ClearDebugBreak();
-    }
-  }
-  // Remove all debug info.
-  while (debug_info_list_ != NULL) {
-    RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
-  }
-}
-
-
-void Debug::FloodWithOneShot(Handle<JSFunction> function,
-                             BreakLocatorType type) {
-  // Make sure the function is compiled and has set up the debug info.
-  Handle<SharedFunctionInfo> shared(function->shared());
-  if (!EnsureDebugInfo(shared, function)) {
-    // Return if we failed to retrieve the debug info.
-    return;
-  }
-
-  // Flood the function with break points.
-  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
-  for (BreakLocation::Iterator it(debug_info, type); !it.Done(); it.Next()) {
-    it.GetBreakLocation().SetOneShot();
-  }
-}
-
-
-void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) {
-  Handle<FixedArray> new_bindings(function->function_bindings());
-  Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex),
-                        isolate_);
-
-  if (!bindee.is_null() && bindee->IsJSFunction()) {
-    Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
-    FloodWithOneShotGeneric(bindee_function);
-  }
-}
-
-
-void Debug::FloodDefaultConstructorWithOneShot(Handle<JSFunction> function) {
-  DCHECK(function->shared()->is_default_constructor());
-  // Instead of stepping into the function we directly step into the super class
-  // constructor.
-  Isolate* isolate = function->GetIsolate();
-  PrototypeIterator iter(isolate, function);
-  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
-  if (!proto->IsJSFunction()) return;  // Object.prototype
-  Handle<JSFunction> function_proto = Handle<JSFunction>::cast(proto);
-  FloodWithOneShotGeneric(function_proto);
-}
-
-
-void Debug::FloodWithOneShotGeneric(Handle<JSFunction> function,
-                                    Handle<Object> holder) {
-  if (function->shared()->bound()) {
-    FloodBoundFunctionWithOneShot(function);
-  } else if (function->shared()->is_default_constructor()) {
-    FloodDefaultConstructorWithOneShot(function);
-  } else {
-    Isolate* isolate = function->GetIsolate();
-    // Don't allow step into functions in the native context.
-    if (function->shared()->code() ==
-            isolate->builtins()->builtin(Builtins::kFunctionApply) ||
-        function->shared()->code() ==
-            isolate->builtins()->builtin(Builtins::kFunctionCall)) {
-      // Handle function.apply and function.call separately to flood the
-      // function to be called and not the code for Builtins::FunctionApply or
-      // Builtins::FunctionCall. The receiver of call/apply is the target
-      // function.
-      if (!holder.is_null() && holder->IsJSFunction()) {
-        Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
-        FloodWithOneShotGeneric(js_function);
-      }
-    } else {
-      FloodWithOneShot(function);
-    }
-  }
-}
-
-
-void Debug::FloodHandlerWithOneShot() {
-  // Iterate through the JavaScript stack looking for handlers.
-  StackFrame::Id id = break_frame_id();
-  if (id == StackFrame::NO_ID) {
-    // If there is no JavaScript stack don't do anything.
-    return;
-  }
-  for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
-    JavaScriptFrame* frame = it.frame();
-    int stack_slots = 0;  // The computed stack slot count is not used.
-    if (frame->LookupExceptionHandlerInTable(&stack_slots, NULL) > 0) {
-      // Flood the function with the catch/finally block with break points.
-      FloodWithOneShot(Handle<JSFunction>(frame->function()));
-      return;
-    }
-  }
-}
-
-
-void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
-  if (type == BreakUncaughtException) {
-    break_on_uncaught_exception_ = enable;
-  } else {
-    break_on_exception_ = enable;
-  }
-}
-
-
-bool Debug::IsBreakOnException(ExceptionBreakType type) {
-  if (type == BreakUncaughtException) {
-    return break_on_uncaught_exception_;
-  } else {
-    return break_on_exception_;
-  }
-}
-
-
-FrameSummary GetFirstFrameSummary(JavaScriptFrame* frame) {
-  List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
-  frame->Summarize(&frames);
-  return frames.first();
-}
-
-
-void Debug::PrepareStep(StepAction step_action,
-                        int step_count,
-                        StackFrame::Id frame_id) {
-  HandleScope scope(isolate_);
-
-  DCHECK(in_debug_scope());
-
-  // Remember this step action and count.
-  thread_local_.last_step_action_ = step_action;
-  if (step_action == StepOut) {
-    // For step out target frame will be found on the stack so there is no need
-    // to set step counter for it. It's expected to always be 0 for StepOut.
-    thread_local_.step_count_ = 0;
-  } else {
-    thread_local_.step_count_ = step_count;
-  }
-
-  // Get the frame where the execution has stopped and skip the debug frame if
-  // any. The debug frame will only be present if execution was stopped due to
-  // hitting a break point. In other situations (e.g. unhandled exception) the
-  // debug frame is not present.
-  StackFrame::Id id = break_frame_id();
-  if (id == StackFrame::NO_ID) {
-    // If there is no JavaScript stack don't do anything.
-    return;
-  }
-  if (frame_id != StackFrame::NO_ID) {
-    id = frame_id;
-  }
-  JavaScriptFrameIterator frames_it(isolate_, id);
-  JavaScriptFrame* frame = frames_it.frame();
-
-  // First of all ensure there is one-shot break points in the top handler
-  // if any.
-  FloodHandlerWithOneShot();
-
-  // If the function on the top frame is unresolved perform step out. This will
-  // be the case when calling unknown function and having the debugger stopped
-  // in an unhandled exception.
-  if (!frame->function()->IsJSFunction()) {
-    // Step out: Find the calling JavaScript frame and flood it with
-    // breakpoints.
-    frames_it.Advance();
-    // Fill the function to return to with one-shot break points.
-    JSFunction* function = frames_it.frame()->function();
-    FloodWithOneShot(Handle<JSFunction>(function));
-    return;
-  }
-
-  // Get the debug info (create it if it does not exist).
-  FrameSummary summary = GetFirstFrameSummary(frame);
-  Handle<JSFunction> function(summary.function());
-  Handle<SharedFunctionInfo> shared(function->shared());
-  if (!EnsureDebugInfo(shared, function)) {
-    // Return if ensuring debug info failed.
-    return;
-  }
-
-  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
-  // Refresh frame summary if the code has been recompiled for debugging.
-  if (shared->code() != *summary.code()) summary = GetFirstFrameSummary(frame);
-
-  // PC points to the instruction after the current one, possibly a break
-  // location as well. So the "- 1" to exclude it from the search.
-  Address call_pc = summary.pc() - 1;
-  BreakLocation location =
-      BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
-
-  // If this is the last break code target step out is the only possibility.
-  if (location.IsReturn() || step_action == StepOut) {
-    if (step_action == StepOut) {
-      // Skip step_count frames starting with the current one.
-      while (step_count-- > 0 && !frames_it.done()) {
-        frames_it.Advance();
-      }
-    } else {
-      DCHECK(location.IsReturn());
-      frames_it.Advance();
-    }
-    // Skip native and extension functions on the stack.
-    while (!frames_it.done() &&
-           !frames_it.frame()->function()->IsSubjectToDebugging()) {
-      frames_it.Advance();
-    }
-    // Step out: If there is a JavaScript caller frame, we need to
-    // flood it with breakpoints.
-    if (!frames_it.done()) {
-      // Fill the function to return to with one-shot break points.
-      JSFunction* function = frames_it.frame()->function();
-      FloodWithOneShot(Handle<JSFunction>(function));
-      // Set target frame pointer.
-      ActivateStepOut(frames_it.frame());
-    }
-    return;
-  }
-
-  if (step_action != StepNext && step_action != StepMin) {
-    // If there's restarter frame on top of the stack, just get the pointer
-    // to function which is going to be restarted.
-    if (thread_local_.restarter_frame_function_pointer_ != NULL) {
-      Handle<JSFunction> restarted_function(
-          JSFunction::cast(*thread_local_.restarter_frame_function_pointer_));
-      FloodWithOneShot(restarted_function);
-    } else if (location.IsCall()) {
-      // Find target function on the expression stack.
-      // Expression stack looks like this (top to bottom):
-      // argN
-      // ...
-      // arg0
-      // Receiver
-      // Function to call
-      int num_expressions_without_args =
-          frame->ComputeExpressionsCount() - location.CallArgumentsCount();
-      DCHECK(num_expressions_without_args >= 2);
-      Object* fun = frame->GetExpression(num_expressions_without_args - 2);
-
-      // Flood the actual target of call/apply.
-      if (fun->IsJSFunction()) {
-        Isolate* isolate = JSFunction::cast(fun)->GetIsolate();
-        Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply);
-        Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall);
-        // Find target function on the expression stack for expression like
-        // Function.call.call...apply(...)
-        int i = 1;
-        while (fun->IsJSFunction()) {
-          Code* code = JSFunction::cast(fun)->shared()->code();
-          if (code != apply && code != call) break;
-          DCHECK(num_expressions_without_args >= i);
-          fun = frame->GetExpression(num_expressions_without_args - i);
-          i--;
-        }
-      }
-
-      if (fun->IsJSFunction()) {
-        Handle<JSFunction> js_function(JSFunction::cast(fun));
-        FloodWithOneShotGeneric(js_function);
-      }
-    }
-
-    ActivateStepIn(frame);
-  }
-
-  // Fill the current function with one-shot break points even for step in on
-  // a call target as the function called might be a native function for
-  // which step in will not stop. It also prepares for stepping in
-  // getters/setters.
-  // If we are stepping into another frame, only fill calls and returns.
-  FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS
-                                                      : ALL_BREAK_LOCATIONS);
-
-  // Remember source position and frame to handle step next.
-  thread_local_.last_statement_position_ =
-      debug_info->code()->SourceStatementPosition(summary.pc());
-  thread_local_.last_fp_ = frame->UnpaddedFP();
-}
-
-
-// Check whether the current debug break should be reported to the debugger. It
-// is used to have step next and step in only report break back to the debugger
-// if on a different frame or in a different statement. In some situations
-// there will be several break points in the same statement when the code is
-// flooded with one-shot break points. This function helps to perform several
-// steps before reporting break back to the debugger.
-bool Debug::StepNextContinue(BreakLocation* break_location,
-                             JavaScriptFrame* frame) {
-  // StepNext and StepOut shouldn't bring us deeper in code, so last frame
-  // shouldn't be a parent of current frame.
-  StepAction step_action = thread_local_.last_step_action_;
-
-  if (step_action == StepNext || step_action == StepOut) {
-    if (frame->fp() < thread_local_.last_fp_) return true;
-  }
-
-  // We stepped into a new frame if the frame pointer changed.
-  if (step_action == StepFrame) {
-    return frame->UnpaddedFP() == thread_local_.last_fp_;
-  }
-
-  // If the step last action was step next or step in make sure that a new
-  // statement is hit.
-  if (step_action == StepNext || step_action == StepIn) {
-    // Never continue if returning from function.
-    if (break_location->IsReturn()) return false;
-
-    // Continue if we are still on the same frame and in the same statement.
-    int current_statement_position =
-        break_location->code()->SourceStatementPosition(frame->pc());
-    return thread_local_.last_fp_ == frame->UnpaddedFP() &&
-        thread_local_.last_statement_position_ == current_statement_position;
-  }
-
-  // No step next action - don't continue.
-  return false;
-}
-
-
-// Check whether the code object at the specified address is a debug break code
-// object.
-bool Debug::IsDebugBreak(Address addr) {
-  Code* code = Code::GetCodeFromTargetAddress(addr);
-  return code->is_debug_stub();
-}
-
-
-// Simple function for returning the source positions for active break points.
-Handle<Object> Debug::GetSourceBreakLocations(
-    Handle<SharedFunctionInfo> shared,
-    BreakPositionAlignment position_alignment) {
-  Isolate* isolate = shared->GetIsolate();
-  Heap* heap = isolate->heap();
-  if (!shared->HasDebugInfo()) {
-    return Handle<Object>(heap->undefined_value(), isolate);
-  }
-  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
-  if (debug_info->GetBreakPointCount() == 0) {
-    return Handle<Object>(heap->undefined_value(), isolate);
-  }
-  Handle<FixedArray> locations =
-      isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
-  int count = 0;
-  for (int i = 0; i < debug_info->break_points()->length(); ++i) {
-    if (!debug_info->break_points()->get(i)->IsUndefined()) {
-      BreakPointInfo* break_point_info =
-          BreakPointInfo::cast(debug_info->break_points()->get(i));
-      int break_points = break_point_info->GetBreakPointCount();
-      if (break_points == 0) continue;
-      Smi* position = NULL;
-      switch (position_alignment) {
-        case STATEMENT_ALIGNED:
-          position = break_point_info->statement_position();
-          break;
-        case BREAK_POSITION_ALIGNED:
-          position = break_point_info->source_position();
-          break;
-      }
-      for (int j = 0; j < break_points; ++j) locations->set(count++, position);
-    }
-  }
-  return locations;
-}
-
-
-// Handle stepping into a function.
-void Debug::HandleStepIn(Handle<Object> function_obj, bool is_constructor) {
-  // Flood getter/setter if we either step in or step to another frame.
-  bool step_frame = thread_local_.last_step_action_ == StepFrame;
-  if (!StepInActive() && !step_frame) return;
-  if (!function_obj->IsJSFunction()) return;
-  Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj);
-  Isolate* isolate = function->GetIsolate();
-
-  StackFrameIterator it(isolate);
-  it.Advance();
-  // For constructor functions skip another frame.
-  if (is_constructor) {
-    DCHECK(it.frame()->is_construct());
-    it.Advance();
-  }
-  Address fp = it.frame()->fp();
-
-  // Flood the function with one-shot break points if it is called from where
-  // step into was requested, or when stepping into a new frame.
-  if (fp == thread_local_.step_into_fp_ || step_frame) {
-    FloodWithOneShotGeneric(function, Handle<Object>());
-  }
-}
-
-
-void Debug::ClearStepping() {
-  // Clear the various stepping setup.
-  ClearOneShot();
-  ClearStepIn();
-  ClearStepOut();
-  ClearStepNext();
-
-  // Clear multiple step counter.
-  thread_local_.step_count_ = 0;
-}
-
-
-// Clears all the one-shot break points that are currently set. Normally this
-// function is called each time a break point is hit as one shot break points
-// are used to support stepping.
-void Debug::ClearOneShot() {
-  // The current implementation just runs through all the breakpoints. When the
-  // last break point for a function is removed that function is automatically
-  // removed from the list.
-  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
-       node = node->next()) {
-    for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
-         !it.Done(); it.Next()) {
-      it.GetBreakLocation().ClearOneShot();
-    }
-  }
-}
-
-
-void Debug::ActivateStepIn(StackFrame* frame) {
-  DCHECK(!StepOutActive());
-  thread_local_.step_into_fp_ = frame->UnpaddedFP();
-}
-
-
-void Debug::ClearStepIn() {
-  thread_local_.step_into_fp_ = 0;
-}
-
-
-void Debug::ActivateStepOut(StackFrame* frame) {
-  DCHECK(!StepInActive());
-  thread_local_.step_out_fp_ = frame->UnpaddedFP();
-}
-
-
-void Debug::ClearStepOut() {
-  thread_local_.step_out_fp_ = 0;
-}
-
-
-void Debug::ClearStepNext() {
-  thread_local_.last_step_action_ = StepNone;
-  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
-  thread_local_.last_fp_ = 0;
-}
-
-
-bool MatchingCodeTargets(Code* target1, Code* target2) {
-  if (target1 == target2) return true;
-  if (target1->kind() != target2->kind()) return false;
-  return target1->is_handler() || target1->is_inline_cache_stub();
-}
-
-
-// Count the number of calls before the current frame PC to find the
-// corresponding PC in the newly recompiled code.
-static Address ComputeNewPcForRedirect(Code* new_code, Code* old_code,
-                                       Address old_pc) {
-  DCHECK_EQ(old_code->kind(), Code::FUNCTION);
-  DCHECK_EQ(new_code->kind(), Code::FUNCTION);
-  DCHECK(new_code->has_debug_break_slots());
-  static const int mask = RelocInfo::kCodeTargetMask;
-
-  // Find the target of the current call.
-  Code* target = NULL;
-  intptr_t delta = 0;
-  for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
-    RelocInfo* rinfo = it.rinfo();
-    Address current_pc = rinfo->pc();
-    // The frame PC is behind the call instruction by the call instruction size.
-    if (current_pc > old_pc) break;
-    delta = old_pc - current_pc;
-    target = Code::GetCodeFromTargetAddress(rinfo->target_address());
-  }
-
-  // Count the number of calls to the same target before the current call.
-  int index = 0;
-  for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
-    RelocInfo* rinfo = it.rinfo();
-    Address current_pc = rinfo->pc();
-    if (current_pc > old_pc) break;
-    Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
-    if (MatchingCodeTargets(target, current)) index++;
-  }
-
-  DCHECK(index > 0);
-
-  // Repeat the count on the new code to find corresponding call.
-  for (RelocIterator it(new_code, mask); !it.done(); it.next()) {
-    RelocInfo* rinfo = it.rinfo();
-    Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
-    if (MatchingCodeTargets(target, current)) index--;
-    if (index == 0) return rinfo->pc() + delta;
-  }
-
-  UNREACHABLE();
-  return NULL;
-}
-
-
-// Count the number of continuations at which the current pc offset is at.
-static int ComputeContinuationIndexFromPcOffset(Code* code, int pc_offset) {
-  DCHECK_EQ(code->kind(), Code::FUNCTION);
-  Address pc = code->instruction_start() + pc_offset;
-  int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
-  int index = 0;
-  for (RelocIterator it(code, mask); !it.done(); it.next()) {
-    index++;
-    RelocInfo* rinfo = it.rinfo();
-    Address current_pc = rinfo->pc();
-    if (current_pc == pc) break;
-    DCHECK(current_pc < pc);
-  }
-  return index;
-}
-
-
-// Find the pc offset for the given continuation index.
-static int ComputePcOffsetFromContinuationIndex(Code* code, int index) {
-  DCHECK_EQ(code->kind(), Code::FUNCTION);
-  DCHECK(code->has_debug_break_slots());
-  int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
-  RelocIterator it(code, mask);
-  for (int i = 1; i < index; i++) it.next();
-  return static_cast<int>(it.rinfo()->pc() - code->instruction_start());
-}
-
-
-class RedirectActiveFunctions : public ThreadVisitor {
- public:
-  explicit RedirectActiveFunctions(SharedFunctionInfo* shared)
-      : shared_(shared) {
-    DCHECK(shared->HasDebugCode());
-  }
-
-  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
-    for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
-      JavaScriptFrame* frame = it.frame();
-      JSFunction* function = frame->function();
-      if (frame->is_optimized()) continue;
-      if (!function->Inlines(shared_)) continue;
-
-      Code* frame_code = frame->LookupCode();
-      DCHECK(frame_code->kind() == Code::FUNCTION);
-      if (frame_code->has_debug_break_slots()) continue;
-
-      Code* new_code = function->shared()->code();
-      Address old_pc = frame->pc();
-      Address new_pc = ComputeNewPcForRedirect(new_code, frame_code, old_pc);
-
-      if (FLAG_trace_deopt) {
-        PrintF("Replacing pc for debugging: %08" V8PRIxPTR " => %08" V8PRIxPTR
-               "\n",
-               reinterpret_cast<intptr_t>(old_pc),
-               reinterpret_cast<intptr_t>(new_pc));
-      }
-
-      if (FLAG_enable_embedded_constant_pool) {
-        // Update constant pool pointer for new code.
-        frame->set_constant_pool(new_code->constant_pool());
-      }
-
-      // Patch the return address to return into the code with
-      // debug break slots.
-      frame->set_pc(new_pc);
-    }
-  }
-
- private:
-  SharedFunctionInfo* shared_;
-  DisallowHeapAllocation no_gc_;
-};
-
-
-bool Debug::PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared) {
-  DCHECK(shared->is_compiled());
-
-  if (isolate_->concurrent_recompilation_enabled()) {
-    isolate_->optimizing_compile_dispatcher()->Flush();
-  }
-
-  List<Handle<JSFunction> > functions;
-  List<Handle<JSGeneratorObject> > suspended_generators;
-
-  if (!shared->optimized_code_map()->IsSmi()) {
-    shared->ClearOptimizedCodeMap();
-  }
-
-  // Make sure we abort incremental marking.
-  isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
-                                      "prepare for break points");
-
-  {
-    HeapIterator iterator(isolate_->heap());
-    HeapObject* obj;
-    bool include_generators = shared->is_generator();
-
-    while ((obj = iterator.next())) {
-      if (obj->IsJSFunction()) {
-        JSFunction* function = JSFunction::cast(obj);
-        if (!function->Inlines(*shared)) continue;
-        if (function->code()->kind() == Code::OPTIMIZED_FUNCTION) {
-          Deoptimizer::DeoptimizeFunction(function);
-        }
-        if (function->shared() == *shared) functions.Add(handle(function));
-      } else if (include_generators && obj->IsJSGeneratorObject()) {
-        JSGeneratorObject* generator_obj = JSGeneratorObject::cast(obj);
-        if (!generator_obj->is_suspended()) continue;
-        JSFunction* function = generator_obj->function();
-        if (!function->Inlines(*shared)) continue;
-        int pc_offset = generator_obj->continuation();
-        int index =
-            ComputeContinuationIndexFromPcOffset(function->code(), pc_offset);
-        generator_obj->set_continuation(index);
-        suspended_generators.Add(handle(generator_obj));
-      }
-    }
-  }
-
-  if (!shared->HasDebugCode()) {
-    DCHECK(functions.length() > 0);
-    if (!Compiler::CompileDebugCode(functions.first())) return false;
-  }
-
-  for (Handle<JSFunction> const function : functions) {
-    function->ReplaceCode(shared->code());
-  }
-
-  for (Handle<JSGeneratorObject> const generator_obj : suspended_generators) {
-    int index = generator_obj->continuation();
-    int pc_offset = ComputePcOffsetFromContinuationIndex(shared->code(), index);
-    generator_obj->set_continuation(pc_offset);
-  }
-
-  // Update PCs on the stack to point to recompiled code.
-  RedirectActiveFunctions redirect_visitor(*shared);
-  redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top());
-  isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor);
-
-  return true;
-}
-
-
-class SharedFunctionInfoFinder {
- public:
-  explicit SharedFunctionInfoFinder(int target_position)
-      : current_candidate_(NULL),
-        current_candidate_closure_(NULL),
-        current_start_position_(RelocInfo::kNoPosition),
-        target_position_(target_position) {}
-
-  void NewCandidate(SharedFunctionInfo* shared, JSFunction* closure = NULL) {
-    int start_position = shared->function_token_position();
-    if (start_position == RelocInfo::kNoPosition) {
-      start_position = shared->start_position();
-    }
-
-    if (start_position > target_position_) return;
-    if (target_position_ > shared->end_position()) return;
-
-    if (current_candidate_ != NULL) {
-      if (current_start_position_ == start_position &&
-          shared->end_position() == current_candidate_->end_position()) {
-        // If a top-level function contains only one function
-        // declaration the source for the top-level and the function
-        // is the same. In that case prefer the non top-level function.
-        if (shared->is_toplevel()) return;
-      } else if (start_position < current_start_position_ ||
-                 current_candidate_->end_position() < shared->end_position()) {
-        return;
-      }
-    }
-
-    current_start_position_ = start_position;
-    current_candidate_ = shared;
-    current_candidate_closure_ = closure;
-  }
-
-  SharedFunctionInfo* Result() { return current_candidate_; }
-
-  JSFunction* ResultClosure() { return current_candidate_closure_; }
-
- private:
-  SharedFunctionInfo* current_candidate_;
-  JSFunction* current_candidate_closure_;
-  int current_start_position_;
-  int target_position_;
-  DisallowHeapAllocation no_gc_;
-};
-
-
-// We need to find a SFI for a literal that may not yet have been compiled yet,
-// and there may not be a JSFunction referencing it. Find the SFI closest to
-// the given position, compile it to reveal possible inner SFIs and repeat.
-// While we are at this, also ensure code with debug break slots so that we do
-// not have to compile a SFI without JSFunction, which is paifu for those that
-// cannot be compiled without context (need to find outer compilable SFI etc.)
-Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
-                                                     int position) {
-  while (true) {
-    // Go through all shared function infos associated with this script to
-    // find the inner most function containing this position.
-    if (!script->shared_function_infos()->IsWeakFixedArray()) break;
-    WeakFixedArray* array =
-        WeakFixedArray::cast(script->shared_function_infos());
-
-    SharedFunctionInfo* shared;
-    {
-      SharedFunctionInfoFinder finder(position);
-      for (int i = 0; i < array->Length(); i++) {
-        Object* item = array->Get(i);
-        if (!item->IsSharedFunctionInfo()) continue;
-        finder.NewCandidate(SharedFunctionInfo::cast(item));
-      }
-      shared = finder.Result();
-      if (shared == NULL) break;
-      // We found it if it's already compiled and has debug code.
-      if (shared->HasDebugCode()) return handle(shared);
-    }
-    // If not, compile to reveal inner functions, if possible.
-    if (shared->allows_lazy_compilation_without_context()) {
-      HandleScope scope(isolate_);
-      if (!Compiler::CompileDebugCode(handle(shared))) break;
-      continue;
-    }
-
-    // If not possible, comb the heap for the best suitable compile target.
-    JSFunction* closure;
-    {
-      HeapIterator it(isolate_->heap());
-      SharedFunctionInfoFinder finder(position);
-      while (HeapObject* object = it.next()) {
-        JSFunction* candidate_closure = NULL;
-        SharedFunctionInfo* candidate = NULL;
-        if (object->IsJSFunction()) {
-          candidate_closure = JSFunction::cast(object);
-          candidate = candidate_closure->shared();
-        } else if (object->IsSharedFunctionInfo()) {
-          candidate = SharedFunctionInfo::cast(object);
-          if (!candidate->allows_lazy_compilation_without_context()) continue;
-        } else {
-          continue;
-        }
-        if (candidate->script() == *script) {
-          finder.NewCandidate(candidate, candidate_closure);
-        }
-      }
-      closure = finder.ResultClosure();
-      shared = finder.Result();
-    }
-    HandleScope scope(isolate_);
-    if (closure == NULL) {
-      if (!Compiler::CompileDebugCode(handle(shared))) break;
-    } else {
-      if (!Compiler::CompileDebugCode(handle(closure))) break;
-    }
-  }
-  return isolate_->factory()->undefined_value();
-}
-
-
-// Ensures the debug information is present for shared.
-bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
-                            Handle<JSFunction> function) {
-  if (!shared->IsSubjectToDebugging()) return false;
-
-  // Return if we already have the debug info for shared.
-  if (shared->HasDebugInfo()) return true;
-
-  if (function.is_null()) {
-    DCHECK(shared->HasDebugCode());
-  } else if (!Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) {
-    return false;
-  }
-
-  if (!PrepareFunctionForBreakPoints(shared)) return false;
-
-  // Make sure IC state is clean. This is so that we correctly flood
-  // accessor pairs when stepping in.
-  shared->code()->ClearInlineCaches();
-  shared->feedback_vector()->ClearICSlots(*shared);
-
-  // Create the debug info object.
-  DCHECK(shared->HasDebugCode());
-  Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared);
-
-  // Add debug info to the list.
-  DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
-  node->set_next(debug_info_list_);
-  debug_info_list_ = node;
-
-  return true;
-}
-
-
-void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
-  HandleScope scope(isolate_);
-  Handle<SharedFunctionInfo> shared(debug_info->shared());
-
-  DCHECK_NOT_NULL(debug_info_list_);
-  // Run through the debug info objects to find this one and remove it.
-  DebugInfoListNode* prev = NULL;
-  DebugInfoListNode* current = debug_info_list_;
-  while (current != NULL) {
-    if (current->debug_info().is_identical_to(debug_info)) {
-      // Unlink from list. If prev is NULL we are looking at the first element.
-      if (prev == NULL) {
-        debug_info_list_ = current->next();
-      } else {
-        prev->set_next(current->next());
-      }
-      delete current;
-      shared->set_debug_info(isolate_->heap()->undefined_value());
-      return;
-    }
-    // Move to next in list.
-    prev = current;
-    current = current->next();
-  }
-
-  UNREACHABLE();
-}
-
-
-void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
-  after_break_target_ = NULL;
-
-  if (LiveEdit::SetAfterBreakTarget(this)) return;  // LiveEdit did the job.
-
-  // Continue just after the slot.
-  after_break_target_ = frame->pc();
-}
-
-
-bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
-  HandleScope scope(isolate_);
-
-  // Get the executing function in which the debug break occurred.
-  Handle<JSFunction> function(JSFunction::cast(frame->function()));
-  Handle<SharedFunctionInfo> shared(function->shared());
-
-  // With no debug info there are no break points, so we can't be at a return.
-  if (!shared->HasDebugInfo()) return false;
-  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
-  Handle<Code> code(debug_info->code());
-#ifdef DEBUG
-  // Get the code which is actually executing.
-  Handle<Code> frame_code(frame->LookupCode());
-  DCHECK(frame_code.is_identical_to(code));
-#endif
-
-  // Find the reloc info matching the start of the debug break slot.
-  Address slot_pc = frame->pc() - Assembler::kDebugBreakSlotLength;
-  int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
-  for (RelocIterator it(*code, mask); !it.done(); it.next()) {
-    if (it.rinfo()->pc() == slot_pc) return true;
-  }
-  return false;
-}
-
-
-void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
-                                  LiveEdit::FrameDropMode mode,
-                                  Object** restarter_frame_function_pointer) {
-  if (mode != LiveEdit::CURRENTLY_SET_MODE) {
-    thread_local_.frame_drop_mode_ = mode;
-  }
-  thread_local_.break_frame_id_ = new_break_frame_id;
-  thread_local_.restarter_frame_function_pointer_ =
-      restarter_frame_function_pointer;
-}
-
-
-bool Debug::IsDebugGlobal(GlobalObject* global) {
-  return is_loaded() && global == debug_context()->global_object();
-}
-
-
-void Debug::ClearMirrorCache() {
-  PostponeInterruptsScope postpone(isolate_);
-  HandleScope scope(isolate_);
-  AssertDebugContext();
-  Factory* factory = isolate_->factory();
-  Handle<GlobalObject> global(isolate_->global_object());
-  JSObject::SetProperty(global,
-                        factory->NewStringFromAsciiChecked("next_handle_"),
-                        handle(Smi::FromInt(0), isolate_), SLOPPY).Check();
-  JSObject::SetProperty(global,
-                        factory->NewStringFromAsciiChecked("mirror_cache_"),
-                        factory->NewJSArray(0, FAST_ELEMENTS), SLOPPY).Check();
-}
-
-
-Handle<FixedArray> Debug::GetLoadedScripts() {
-  // Create and fill the script cache when the loaded scripts is requested for
-  // the first time.
-  if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
-
-  // Perform GC to get unreferenced scripts evicted from the cache before
-  // returning the content.
-  isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
-                                      "Debug::GetLoadedScripts");
-
-  // Get the scripts from the cache.
-  return script_cache_->GetScripts();
-}
-
-
-void Debug::GetStepinPositions(JavaScriptFrame* frame, StackFrame::Id frame_id,
-                               List<int>* results_out) {
-  FrameSummary summary = GetFirstFrameSummary(frame);
-
-  Handle<JSFunction> fun = Handle<JSFunction>(summary.function());
-  Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared());
-
-  if (!EnsureDebugInfo(shared, fun)) return;
-
-  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
-  // Refresh frame summary if the code has been recompiled for debugging.
-  if (shared->code() != *summary.code()) summary = GetFirstFrameSummary(frame);
-
-  // Find range of break points starting from the break point where execution
-  // has stopped.
-  Address call_pc = summary.pc() - 1;
-  List<BreakLocation> locations;
-  BreakLocation::FromAddressSameStatement(debug_info, ALL_BREAK_LOCATIONS,
-                                          call_pc, &locations);
-
-  for (BreakLocation location : locations) {
-    if (location.pc() <= summary.pc()) {
-      // The break point is near our pc. Could be a step-in possibility,
-      // that is currently taken by active debugger call.
-      if (break_frame_id() == StackFrame::NO_ID) {
-        continue;  // We are not stepping.
-      } else {
-        JavaScriptFrameIterator frame_it(isolate_, break_frame_id());
-        // If our frame is a top frame and we are stepping, we can do step-in
-        // at this place.
-        if (frame_it.frame()->id() != frame_id) continue;
-      }
-    }
-    if (location.IsStepInLocation()) results_out->Add(location.position());
-  }
-}
-
-
-void Debug::RecordEvalCaller(Handle<Script> script) {
-  script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
-  // For eval scripts add information on the function from which eval was
-  // called.
-  StackTraceFrameIterator it(script->GetIsolate());
-  if (!it.done()) {
-    script->set_eval_from_shared(it.frame()->function()->shared());
-    Code* code = it.frame()->LookupCode();
-    int offset = static_cast<int>(
-        it.frame()->pc() - code->instruction_start());
-    script->set_eval_from_instructions_offset(Smi::FromInt(offset));
-  }
-}
-
-
-MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
-                                        int argc,
-                                        Handle<Object> argv[]) {
-  AssertDebugContext();
-  // Create the execution state object.
-  Handle<GlobalObject> global(isolate_->global_object());
-  Handle<Object> constructor = Object::GetProperty(
-      isolate_, global, constructor_name).ToHandleChecked();
-  DCHECK(constructor->IsJSFunction());
-  if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
-  // We do not handle interrupts here.  In particular, termination interrupts.
-  PostponeInterruptsScope no_interrupts(isolate_);
-  return Execution::TryCall(Handle<JSFunction>::cast(constructor),
-                            handle(debug_context()->global_proxy()),
-                            argc,
-                            argv);
-}
-
-
-MaybeHandle<Object> Debug::MakeExecutionState() {
-  // Create the execution state object.
-  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
-  return MakeJSObject("MakeExecutionState", arraysize(argv), argv);
-}
-
-
-MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
-  // Create the new break event object.
-  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
-                            break_points_hit };
-  return MakeJSObject("MakeBreakEvent", arraysize(argv), argv);
-}
-
-
-MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
-                                              bool uncaught,
-                                              Handle<Object> promise) {
-  // Create the new exception event object.
-  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
-                            exception,
-                            isolate_->factory()->ToBoolean(uncaught),
-                            promise };
-  return MakeJSObject("MakeExceptionEvent", arraysize(argv), argv);
-}
-
-
-MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
-                                            v8::DebugEvent type) {
-  // Create the compile event object.
-  Handle<Object> script_wrapper = Script::GetWrapper(script);
-  Handle<Object> argv[] = { script_wrapper,
-                            isolate_->factory()->NewNumberFromInt(type) };
-  return MakeJSObject("MakeCompileEvent", arraysize(argv), argv);
-}
-
-
-MaybeHandle<Object> Debug::MakePromiseEvent(Handle<JSObject> event_data) {
-  // Create the promise event object.
-  Handle<Object> argv[] = { event_data };
-  return MakeJSObject("MakePromiseEvent", arraysize(argv), argv);
-}
-
-
-MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
-  // Create the async task event object.
-  Handle<Object> argv[] = { task_event };
-  return MakeJSObject("MakeAsyncTaskEvent", arraysize(argv), argv);
-}
-
-
-void Debug::OnThrow(Handle<Object> exception) {
-  if (in_debug_scope() || ignore_events()) return;
-  // Temporarily clear any scheduled_exception to allow evaluating
-  // JavaScript from the debug event handler.
-  HandleScope scope(isolate_);
-  Handle<Object> scheduled_exception;
-  if (isolate_->has_scheduled_exception()) {
-    scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
-    isolate_->clear_scheduled_exception();
-  }
-  OnException(exception, isolate_->GetPromiseOnStackOnThrow());
-  if (!scheduled_exception.is_null()) {
-    isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
-  }
-}
-
-
-void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) {
-  if (in_debug_scope() || ignore_events()) return;
-  HandleScope scope(isolate_);
-  // Check whether the promise has been marked as having triggered a message.
-  Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
-  if (JSReceiver::GetDataProperty(promise, key)->IsUndefined()) {
-    OnException(value, promise);
-  }
-}
-
-
-MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler(
-    Handle<JSObject> promise) {
-  Handle<JSFunction> fun = Handle<JSFunction>::cast(
-      JSReceiver::GetDataProperty(isolate_->js_builtins_object(),
-                                  isolate_->factory()->NewStringFromStaticChars(
-                                      "$promiseHasUserDefinedRejectHandler")));
-  return Execution::Call(isolate_, fun, promise, 0, NULL);
-}
-
-
-void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
-  // In our prediction, try-finally is not considered to catch.
-  Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher();
-  bool uncaught = (catch_type == Isolate::NOT_CAUGHT);
-  if (promise->IsJSObject()) {
-    Handle<JSObject> jspromise = Handle<JSObject>::cast(promise);
-    // Mark the promise as already having triggered a message.
-    Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
-    JSObject::SetProperty(jspromise, key, key, STRICT).Assert();
-    // Check whether the promise reject is considered an uncaught exception.
-    Handle<Object> has_reject_handler;
-    ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-        isolate_, has_reject_handler,
-        PromiseHasUserDefinedRejectHandler(jspromise), /* void */);
-    uncaught = has_reject_handler->IsFalse();
-  }
-  // Bail out if exception breaks are not active
-  if (uncaught) {
-    // Uncaught exceptions are reported by either flags.
-    if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
-  } else {
-    // Caught exceptions are reported is activated.
-    if (!break_on_exception_) return;
-  }
-
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  // Clear all current stepping setup.
-  ClearStepping();
-
-  // Create the event data object.
-  Handle<Object> event_data;
-  // Bail out and don't call debugger if exception.
-  if (!MakeExceptionEvent(
-          exception, uncaught, promise).ToHandle(&event_data)) {
-    return;
-  }
-
-  // Process debug event.
-  ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
-  // Return to continue execution from where the exception was thrown.
-}
-
-
-void Debug::OnCompileError(Handle<Script> script) {
-  if (ignore_events()) return;
-
-  if (in_debug_scope()) {
-    ProcessCompileEventInDebugScope(v8::CompileError, script);
-    return;
-  }
-
-  HandleScope scope(isolate_);
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  // Create the compile state object.
-  Handle<Object> event_data;
-  // Bail out and don't call debugger if exception.
-  if (!MakeCompileEvent(script, v8::CompileError).ToHandle(&event_data)) return;
-
-  // Process debug event.
-  ProcessDebugEvent(v8::CompileError, Handle<JSObject>::cast(event_data), true);
-}
-
-
-void Debug::OnDebugBreak(Handle<Object> break_points_hit,
-                            bool auto_continue) {
-  // The caller provided for DebugScope.
-  AssertDebugContext();
-  // Bail out if there is no listener for this event
-  if (ignore_events()) return;
-
-  HandleScope scope(isolate_);
-  // Create the event data object.
-  Handle<Object> event_data;
-  // Bail out and don't call debugger if exception.
-  if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
-
-  // Process debug event.
-  ProcessDebugEvent(v8::Break,
-                    Handle<JSObject>::cast(event_data),
-                    auto_continue);
-}
-
-
-void Debug::OnBeforeCompile(Handle<Script> script) {
-  if (in_debug_scope() || ignore_events()) return;
-
-  HandleScope scope(isolate_);
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  // Create the event data object.
-  Handle<Object> event_data;
-  // Bail out and don't call debugger if exception.
-  if (!MakeCompileEvent(script, v8::BeforeCompile).ToHandle(&event_data))
-    return;
-
-  // Process debug event.
-  ProcessDebugEvent(v8::BeforeCompile,
-                    Handle<JSObject>::cast(event_data),
-                    true);
-}
-
-
-// Handle debugger actions when a new script is compiled.
-void Debug::OnAfterCompile(Handle<Script> script) {
-  // Add the newly compiled script to the script cache.
-  if (script_cache_ != NULL) script_cache_->Add(script);
-
-  if (ignore_events()) return;
-
-  if (in_debug_scope()) {
-    ProcessCompileEventInDebugScope(v8::AfterCompile, script);
-    return;
-  }
-
-  HandleScope scope(isolate_);
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  // If debugging there might be script break points registered for this
-  // script. Make sure that these break points are set.
-
-  // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
-  Handle<String> update_script_break_points_string =
-      isolate_->factory()->InternalizeOneByteString(
-          STATIC_CHAR_VECTOR("UpdateScriptBreakPoints"));
-  Handle<GlobalObject> debug_global(debug_context()->global_object());
-  Handle<Object> update_script_break_points =
-      Object::GetProperty(
-          debug_global, update_script_break_points_string).ToHandleChecked();
-  if (!update_script_break_points->IsJSFunction()) {
-    return;
-  }
-  DCHECK(update_script_break_points->IsJSFunction());
-
-  // Wrap the script object in a proper JS object before passing it
-  // to JavaScript.
-  Handle<Object> wrapper = Script::GetWrapper(script);
-
-  // Call UpdateScriptBreakPoints expect no exceptions.
-  Handle<Object> argv[] = { wrapper };
-  if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
-                         isolate_->js_builtins_object(),
-                         arraysize(argv),
-                         argv).is_null()) {
-    return;
-  }
-
-  // Create the compile state object.
-  Handle<Object> event_data;
-  // Bail out and don't call debugger if exception.
-  if (!MakeCompileEvent(script, v8::AfterCompile).ToHandle(&event_data)) return;
-
-  // Process debug event.
-  ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
-}
-
-
-void Debug::OnPromiseEvent(Handle<JSObject> data) {
-  if (in_debug_scope() || ignore_events()) return;
-
-  HandleScope scope(isolate_);
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  // Create the script collected state object.
-  Handle<Object> event_data;
-  // Bail out and don't call debugger if exception.
-  if (!MakePromiseEvent(data).ToHandle(&event_data)) return;
-
-  // Process debug event.
-  ProcessDebugEvent(v8::PromiseEvent,
-                    Handle<JSObject>::cast(event_data),
-                    true);
-}
-
-
-void Debug::OnAsyncTaskEvent(Handle<JSObject> data) {
-  if (in_debug_scope() || ignore_events()) return;
-
-  HandleScope scope(isolate_);
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  // Create the script collected state object.
-  Handle<Object> event_data;
-  // Bail out and don't call debugger if exception.
-  if (!MakeAsyncTaskEvent(data).ToHandle(&event_data)) return;
-
-  // Process debug event.
-  ProcessDebugEvent(v8::AsyncTaskEvent,
-                    Handle<JSObject>::cast(event_data),
-                    true);
-}
-
-
-void Debug::ProcessDebugEvent(v8::DebugEvent event,
-                              Handle<JSObject> event_data,
-                              bool auto_continue) {
-  HandleScope scope(isolate_);
-
-  // Create the execution state.
-  Handle<Object> exec_state;
-  // Bail out and don't call debugger if exception.
-  if (!MakeExecutionState().ToHandle(&exec_state)) return;
-
-  // First notify the message handler if any.
-  if (message_handler_ != NULL) {
-    NotifyMessageHandler(event,
-                         Handle<JSObject>::cast(exec_state),
-                         event_data,
-                         auto_continue);
-  }
-  // Notify registered debug event listener. This can be either a C or
-  // a JavaScript function. Don't call event listener for v8::Break
-  // here, if it's only a debug command -- they will be processed later.
-  if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
-    CallEventCallback(event, exec_state, event_data, NULL);
-  }
-}
-
-
-void Debug::CallEventCallback(v8::DebugEvent event,
-                              Handle<Object> exec_state,
-                              Handle<Object> event_data,
-                              v8::Debug::ClientData* client_data) {
-  bool previous = in_debug_event_listener_;
-  in_debug_event_listener_ = true;
-  if (event_listener_->IsForeign()) {
-    // Invoke the C debug event listener.
-    v8::Debug::EventCallback callback =
-        FUNCTION_CAST<v8::Debug::EventCallback>(
-            Handle<Foreign>::cast(event_listener_)->foreign_address());
-    EventDetailsImpl event_details(event,
-                                   Handle<JSObject>::cast(exec_state),
-                                   Handle<JSObject>::cast(event_data),
-                                   event_listener_data_,
-                                   client_data);
-    callback(event_details);
-    DCHECK(!isolate_->has_scheduled_exception());
-  } else {
-    // Invoke the JavaScript debug event listener.
-    DCHECK(event_listener_->IsJSFunction());
-    Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
-                              exec_state,
-                              event_data,
-                              event_listener_data_ };
-    Handle<JSReceiver> global(isolate_->global_proxy());
-    Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
-                       global, arraysize(argv), argv);
-  }
-  in_debug_event_listener_ = previous;
-}
-
-
-void Debug::ProcessCompileEventInDebugScope(v8::DebugEvent event,
-                                            Handle<Script> script) {
-  if (event_listener_.is_null()) return;
-
-  SuppressDebug while_processing(this);
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  Handle<Object> event_data;
-  // Bail out and don't call debugger if exception.
-  if (!MakeCompileEvent(script, event).ToHandle(&event_data)) return;
-
-  // Create the execution state.
-  Handle<Object> exec_state;
-  // Bail out and don't call debugger if exception.
-  if (!MakeExecutionState().ToHandle(&exec_state)) return;
-
-  CallEventCallback(event, exec_state, event_data, NULL);
-}
-
-
-Handle<Context> Debug::GetDebugContext() {
-  if (!is_loaded()) return Handle<Context>();
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return Handle<Context>();
-  // The global handle may be destroyed soon after.  Return it reboxed.
-  return handle(*debug_context(), isolate_);
-}
-
-
-void Debug::NotifyMessageHandler(v8::DebugEvent event,
-                                 Handle<JSObject> exec_state,
-                                 Handle<JSObject> event_data,
-                                 bool auto_continue) {
-  // Prevent other interrupts from triggering, for example API callbacks,
-  // while dispatching message handler callbacks.
-  PostponeInterruptsScope no_interrupts(isolate_);
-  DCHECK(is_active_);
-  HandleScope scope(isolate_);
-  // Process the individual events.
-  bool sendEventMessage = false;
-  switch (event) {
-    case v8::Break:
-      sendEventMessage = !auto_continue;
-      break;
-    case v8::NewFunction:
-    case v8::BeforeCompile:
-    case v8::CompileError:
-    case v8::PromiseEvent:
-    case v8::AsyncTaskEvent:
-      break;
-    case v8::Exception:
-    case v8::AfterCompile:
-      sendEventMessage = true;
-      break;
-  }
-
-  // The debug command interrupt flag might have been set when the command was
-  // added. It should be enough to clear the flag only once while we are in the
-  // debugger.
-  DCHECK(in_debug_scope());
-  isolate_->stack_guard()->ClearDebugCommand();
-
-  // Notify the debugger that a debug event has occurred unless auto continue is
-  // active in which case no event is send.
-  if (sendEventMessage) {
-    MessageImpl message = MessageImpl::NewEvent(
-        event,
-        auto_continue,
-        Handle<JSObject>::cast(exec_state),
-        Handle<JSObject>::cast(event_data));
-    InvokeMessageHandler(message);
-  }
-
-  // If auto continue don't make the event cause a break, but process messages
-  // in the queue if any. For script collected events don't even process
-  // messages in the queue as the execution state might not be what is expected
-  // by the client.
-  if (auto_continue && !has_commands()) return;
-
-  // DebugCommandProcessor goes here.
-  bool running = auto_continue;
-
-  Handle<Object> cmd_processor_ctor = Object::GetProperty(
-      isolate_, exec_state, "debugCommandProcessor").ToHandleChecked();
-  Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
-  Handle<Object> cmd_processor = Execution::Call(
-      isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked();
-  Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
-      Object::GetProperty(
-          isolate_, cmd_processor, "processDebugRequest").ToHandleChecked());
-  Handle<Object> is_running = Object::GetProperty(
-      isolate_, cmd_processor, "isRunning").ToHandleChecked();
-
-  // Process requests from the debugger.
-  do {
-    // Wait for new command in the queue.
-    command_received_.Wait();
-
-    // Get the command from the queue.
-    CommandMessage command = command_queue_.Get();
-    isolate_->logger()->DebugTag(
-        "Got request from command queue, in interactive loop.");
-    if (!is_active()) {
-      // Delete command text and user data.
-      command.Dispose();
-      return;
-    }
-
-    Vector<const uc16> command_text(
-        const_cast<const uc16*>(command.text().start()),
-        command.text().length());
-    Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
-        command_text).ToHandleChecked();
-    Handle<Object> request_args[] = { request_text };
-    Handle<Object> answer_value;
-    Handle<String> answer;
-    MaybeHandle<Object> maybe_exception;
-    MaybeHandle<Object> maybe_result =
-        Execution::TryCall(process_debug_request, cmd_processor, 1,
-                           request_args, &maybe_exception);
-
-    if (maybe_result.ToHandle(&answer_value)) {
-      if (answer_value->IsUndefined()) {
-        answer = isolate_->factory()->empty_string();
-      } else {
-        answer = Handle<String>::cast(answer_value);
-      }
-
-      // Log the JSON request/response.
-      if (FLAG_trace_debug_json) {
-        PrintF("%s\n", request_text->ToCString().get());
-        PrintF("%s\n", answer->ToCString().get());
-      }
-
-      Handle<Object> is_running_args[] = { answer };
-      maybe_result = Execution::Call(
-          isolate_, is_running, cmd_processor, 1, is_running_args);
-      Handle<Object> result;
-      if (!maybe_result.ToHandle(&result)) break;
-      running = result->IsTrue();
-    } else {
-      Handle<Object> exception;
-      if (!maybe_exception.ToHandle(&exception)) break;
-      Handle<Object> result;
-      if (!Execution::ToString(isolate_, exception).ToHandle(&result)) break;
-      answer = Handle<String>::cast(result);
-    }
-
-    // Return the result.
-    MessageImpl message = MessageImpl::NewResponse(
-        event, running, exec_state, event_data, answer, command.client_data());
-    InvokeMessageHandler(message);
-    command.Dispose();
-
-    // Return from debug event processing if either the VM is put into the
-    // running state (through a continue command) or auto continue is active
-    // and there are no more commands queued.
-  } while (!running || has_commands());
-  command_queue_.Clear();
-}
-
-
-void Debug::SetEventListener(Handle<Object> callback,
-                             Handle<Object> data) {
-  GlobalHandles* global_handles = isolate_->global_handles();
-
-  // Remove existing entry.
-  GlobalHandles::Destroy(event_listener_.location());
-  event_listener_ = Handle<Object>();
-  GlobalHandles::Destroy(event_listener_data_.location());
-  event_listener_data_ = Handle<Object>();
-
-  // Set new entry.
-  if (!callback->IsUndefined() && !callback->IsNull()) {
-    event_listener_ = global_handles->Create(*callback);
-    if (data.is_null()) data = isolate_->factory()->undefined_value();
-    event_listener_data_ = global_handles->Create(*data);
-  }
-
-  UpdateState();
-}
-
-
-void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
-  message_handler_ = handler;
-  UpdateState();
-  if (handler == NULL && in_debug_scope()) {
-    // Send an empty command to the debugger if in a break to make JavaScript
-    // run again if the debugger is closed.
-    EnqueueCommandMessage(Vector<const uint16_t>::empty());
-  }
-}
-
-
-
-void Debug::UpdateState() {
-  bool is_active = message_handler_ != NULL || !event_listener_.is_null();
-  if (is_active || in_debug_scope()) {
-    // Note that the debug context could have already been loaded to
-    // bootstrap test cases.
-    isolate_->compilation_cache()->Disable();
-    is_active = Load();
-  } else if (is_loaded()) {
-    isolate_->compilation_cache()->Enable();
-    Unload();
-  }
-  is_active_ = is_active;
-}
-
-
-// Calls the registered debug message handler. This callback is part of the
-// public API.
-void Debug::InvokeMessageHandler(MessageImpl message) {
-  if (message_handler_ != NULL) message_handler_(message);
-}
-
-
-// Puts a command coming from the public API on the queue.  Creates
-// a copy of the command string managed by the debugger.  Up to this
-// point, the command data was managed by the API client.  Called
-// by the API client thread.
-void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
-                                  v8::Debug::ClientData* client_data) {
-  // Need to cast away const.
-  CommandMessage message = CommandMessage::New(
-      Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
-                       command.length()),
-      client_data);
-  isolate_->logger()->DebugTag("Put command on command_queue.");
-  command_queue_.Put(message);
-  command_received_.Signal();
-
-  // Set the debug command break flag to have the command processed.
-  if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
-}
-
-
-MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return isolate_->factory()->undefined_value();
-
-  // Create the execution state.
-  Handle<Object> exec_state;
-  if (!MakeExecutionState().ToHandle(&exec_state)) {
-    return isolate_->factory()->undefined_value();
-  }
-
-  Handle<Object> argv[] = { exec_state, data };
-  return Execution::Call(
-      isolate_,
-      fun,
-      Handle<Object>(debug_context()->global_proxy(), isolate_),
-      arraysize(argv),
-      argv);
-}
-
-
-void Debug::HandleDebugBreak() {
-  // Ignore debug break during bootstrapping.
-  if (isolate_->bootstrapper()->IsActive()) return;
-  // Just continue if breaks are disabled.
-  if (break_disabled()) return;
-  // Ignore debug break if debugger is not active.
-  if (!is_active()) return;
-
-  StackLimitCheck check(isolate_);
-  if (check.HasOverflowed()) return;
-
-  { JavaScriptFrameIterator it(isolate_);
-    DCHECK(!it.done());
-    Object* fun = it.frame()->function();
-    if (fun && fun->IsJSFunction()) {
-      // Don't stop in builtin functions.
-      if (JSFunction::cast(fun)->IsBuiltin()) return;
-      GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
-      // Don't stop in debugger functions.
-      if (IsDebugGlobal(global)) return;
-    }
-  }
-
-  // Collect the break state before clearing the flags.
-  bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
-                            !isolate_->stack_guard()->CheckDebugBreak();
-
-  isolate_->stack_guard()->ClearDebugBreak();
-
-  ProcessDebugMessages(debug_command_only);
-}
-
-
-void Debug::ProcessDebugMessages(bool debug_command_only) {
-  isolate_->stack_guard()->ClearDebugCommand();
-
-  StackLimitCheck check(isolate_);
-  if (check.HasOverflowed()) return;
-
-  HandleScope scope(isolate_);
-  DebugScope debug_scope(this);
-  if (debug_scope.failed()) return;
-
-  // Notify the debug event listeners. Indicate auto continue if the break was
-  // a debug command break.
-  OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
-}
-
-
-DebugScope::DebugScope(Debug* debug)
-    : debug_(debug),
-      prev_(debug->debugger_entry()),
-      save_(debug_->isolate_),
-      no_termination_exceptons_(debug_->isolate_,
-                                StackGuard::TERMINATE_EXECUTION) {
-  // Link recursive debugger entry.
-  base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
-                        reinterpret_cast<base::AtomicWord>(this));
-
-  // Store the previous break id and frame id.
-  break_id_ = debug_->break_id();
-  break_frame_id_ = debug_->break_frame_id();
-
-  // Create the new break info. If there is no JavaScript frames there is no
-  // break frame id.
-  JavaScriptFrameIterator it(isolate());
-  bool has_js_frames = !it.done();
-  debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
-                                                        : StackFrame::NO_ID;
-  debug_->SetNextBreakId();
-
-  debug_->UpdateState();
-  // Make sure that debugger is loaded and enter the debugger context.
-  // The previous context is kept in save_.
-  failed_ = !debug_->is_loaded();
-  if (!failed_) isolate()->set_context(*debug->debug_context());
-}
-
-
-
-DebugScope::~DebugScope() {
-  if (!failed_ && prev_ == NULL) {
-    // Clear mirror cache when leaving the debugger. Skip this if there is a
-    // pending exception as clearing the mirror cache calls back into
-    // JavaScript. This can happen if the v8::Debug::Call is used in which
-    // case the exception should end up in the calling code.
-    if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
-
-    // If there are commands in the queue when leaving the debugger request
-    // that these commands are processed.
-    if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
-  }
-
-  // Leaving this debugger entry.
-  base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
-                        reinterpret_cast<base::AtomicWord>(prev_));
-
-  // Restore to the previous break state.
-  debug_->thread_local_.break_frame_id_ = break_frame_id_;
-  debug_->thread_local_.break_id_ = break_id_;
-
-  debug_->UpdateState();
-}
-
-
-MessageImpl MessageImpl::NewEvent(DebugEvent event,
-                                  bool running,
-                                  Handle<JSObject> exec_state,
-                                  Handle<JSObject> event_data) {
-  MessageImpl message(true, event, running,
-                      exec_state, event_data, Handle<String>(), NULL);
-  return message;
-}
-
-
-MessageImpl MessageImpl::NewResponse(DebugEvent event,
-                                     bool running,
-                                     Handle<JSObject> exec_state,
-                                     Handle<JSObject> event_data,
-                                     Handle<String> response_json,
-                                     v8::Debug::ClientData* client_data) {
-  MessageImpl message(false, event, running,
-                      exec_state, event_data, response_json, client_data);
-  return message;
-}
-
-
-MessageImpl::MessageImpl(bool is_event,
-                         DebugEvent event,
-                         bool running,
-                         Handle<JSObject> exec_state,
-                         Handle<JSObject> event_data,
-                         Handle<String> response_json,
-                         v8::Debug::ClientData* client_data)
-    : is_event_(is_event),
-      event_(event),
-      running_(running),
-      exec_state_(exec_state),
-      event_data_(event_data),
-      response_json_(response_json),
-      client_data_(client_data) {}
-
-
-bool MessageImpl::IsEvent() const {
-  return is_event_;
-}
-
-
-bool MessageImpl::IsResponse() const {
-  return !is_event_;
-}
-
-
-DebugEvent MessageImpl::GetEvent() const {
-  return event_;
-}
-
-
-bool MessageImpl::WillStartRunning() const {
-  return running_;
-}
-
-
-v8::Local<v8::Object> MessageImpl::GetExecutionState() const {
-  return v8::Utils::ToLocal(exec_state_);
-}
-
-
-v8::Isolate* MessageImpl::GetIsolate() const {
-  return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
-}
-
-
-v8::Local<v8::Object> MessageImpl::GetEventData() const {
-  return v8::Utils::ToLocal(event_data_);
-}
-
-
-v8::Local<v8::String> MessageImpl::GetJSON() const {
-  Isolate* isolate = event_data_->GetIsolate();
-  v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
-
-  if (IsEvent()) {
-    // Call toJSONProtocol on the debug event object.
-    Handle<Object> fun = Object::GetProperty(
-        isolate, event_data_, "toJSONProtocol").ToHandleChecked();
-    if (!fun->IsJSFunction()) {
-      return v8::Local<v8::String>();
-    }
-
-    MaybeHandle<Object> maybe_json =
-        Execution::TryCall(Handle<JSFunction>::cast(fun), event_data_, 0, NULL);
-    Handle<Object> json;
-    if (!maybe_json.ToHandle(&json) || !json->IsString()) {
-      return v8::Local<v8::String>();
-    }
-    return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
-  } else {
-    return v8::Utils::ToLocal(response_json_);
-  }
-}
-
-
-v8::Local<v8::Context> MessageImpl::GetEventContext() const {
-  Isolate* isolate = event_data_->GetIsolate();
-  v8::Local<v8::Context> context = GetDebugEventContext(isolate);
-  // Isolate::context() may be NULL when "script collected" event occurs.
-  DCHECK(!context.IsEmpty());
-  return context;
-}
-
-
-v8::Debug::ClientData* MessageImpl::GetClientData() const {
-  return client_data_;
-}
-
-
-EventDetailsImpl::EventDetailsImpl(DebugEvent event,
-                                   Handle<JSObject> exec_state,
-                                   Handle<JSObject> event_data,
-                                   Handle<Object> callback_data,
-                                   v8::Debug::ClientData* client_data)
-    : event_(event),
-      exec_state_(exec_state),
-      event_data_(event_data),
-      callback_data_(callback_data),
-      client_data_(client_data) {}
-
-
-DebugEvent EventDetailsImpl::GetEvent() const {
-  return event_;
-}
-
-
-v8::Local<v8::Object> EventDetailsImpl::GetExecutionState() const {
-  return v8::Utils::ToLocal(exec_state_);
-}
-
-
-v8::Local<v8::Object> EventDetailsImpl::GetEventData() const {
-  return v8::Utils::ToLocal(event_data_);
-}
-
-
-v8::Local<v8::Context> EventDetailsImpl::GetEventContext() const {
-  return GetDebugEventContext(exec_state_->GetIsolate());
-}
-
-
-v8::Local<v8::Value> EventDetailsImpl::GetCallbackData() const {
-  return v8::Utils::ToLocal(callback_data_);
-}
-
-
-v8::Debug::ClientData* EventDetailsImpl::GetClientData() const {
-  return client_data_;
-}
-
-
-CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
-                                   client_data_(NULL) {
-}
-
-
-CommandMessage::CommandMessage(const Vector<uint16_t>& text,
-                               v8::Debug::ClientData* data)
-    : text_(text),
-      client_data_(data) {
-}
-
-
-void CommandMessage::Dispose() {
-  text_.Dispose();
-  delete client_data_;
-  client_data_ = NULL;
-}
-
-
-CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
-                                   v8::Debug::ClientData* data) {
-  return CommandMessage(command.Clone(), data);
-}
-
-
-CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
-                                                     size_(size) {
-  messages_ = NewArray<CommandMessage>(size);
-}
-
-
-CommandMessageQueue::~CommandMessageQueue() {
-  while (!IsEmpty()) Get().Dispose();
-  DeleteArray(messages_);
-}
-
-
-CommandMessage CommandMessageQueue::Get() {
-  DCHECK(!IsEmpty());
-  int result = start_;
-  start_ = (start_ + 1) % size_;
-  return messages_[result];
-}
-
-
-void CommandMessageQueue::Put(const CommandMessage& message) {
-  if ((end_ + 1) % size_ == start_) {
-    Expand();
-  }
-  messages_[end_] = message;
-  end_ = (end_ + 1) % size_;
-}
-
-
-void CommandMessageQueue::Expand() {
-  CommandMessageQueue new_queue(size_ * 2);
-  while (!IsEmpty()) {
-    new_queue.Put(Get());
-  }
-  CommandMessage* array_to_free = messages_;
-  *this = new_queue;
-  new_queue.messages_ = array_to_free;
-  // Make the new_queue empty so that it doesn't call Dispose on any messages.
-  new_queue.start_ = new_queue.end_;
-  // Automatic destructor called on new_queue, freeing array_to_free.
-}
-
-
-LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
-    : logger_(logger), queue_(size) {}
-
-
-bool LockingCommandMessageQueue::IsEmpty() const {
-  base::LockGuard<base::Mutex> lock_guard(&mutex_);
-  return queue_.IsEmpty();
-}
-
-
-CommandMessage LockingCommandMessageQueue::Get() {
-  base::LockGuard<base::Mutex> lock_guard(&mutex_);
-  CommandMessage result = queue_.Get();
-  logger_->DebugEvent("Get", result.text());
-  return result;
-}
-
-
-void LockingCommandMessageQueue::Put(const CommandMessage& message) {
-  base::LockGuard<base::Mutex> lock_guard(&mutex_);
-  queue_.Put(message);
-  logger_->DebugEvent("Put", message.text());
-}
-
-
-void LockingCommandMessageQueue::Clear() {
-  base::LockGuard<base::Mutex> lock_guard(&mutex_);
-  queue_.Clear();
-}
-
-}  // namespace internal
-}  // namespace v8
diff --git a/src/debug.h b/src/debug.h
deleted file mode 100644 (file)
index 49554f7..0000000
+++ /dev/null
@@ -1,795 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_DEBUG_H_
-#define V8_DEBUG_H_
-
-#include "src/allocation.h"
-#include "src/arguments.h"
-#include "src/assembler.h"
-#include "src/base/atomicops.h"
-#include "src/base/platform/platform.h"
-#include "src/execution.h"
-#include "src/factory.h"
-#include "src/flags.h"
-#include "src/frames-inl.h"
-#include "src/hashmap.h"
-#include "src/liveedit.h"
-#include "src/runtime/runtime.h"
-#include "src/string-stream.h"
-#include "src/v8threads.h"
-
-#include "include/v8-debug.h"
-
-namespace v8 {
-namespace internal {
-
-
-// Forward declarations.
-class DebugScope;
-
-
-// Step actions. NOTE: These values are in macros.py as well.
-enum StepAction {
-  StepNone = -1,  // Stepping not prepared.
-  StepOut = 0,    // Step out of the current function.
-  StepNext = 1,   // Step to the next statement in the current function.
-  StepIn = 2,     // Step into new functions invoked or the next statement
-                  // in the current function.
-  StepMin = 3,    // Perform a minimum step in the current function.
-  StepInMin = 4,  // Step into new functions invoked or perform a minimum step
-                  // in the current function.
-  StepFrame = 5   // Step into a new frame or return to previous frame.
-};
-
-
-// Type of exception break. NOTE: These values are in macros.py as well.
-enum ExceptionBreakType {
-  BreakException = 0,
-  BreakUncaughtException = 1
-};
-
-
-// Type of exception break.
-enum BreakLocatorType { ALL_BREAK_LOCATIONS, CALLS_AND_RETURNS };
-
-
-// The different types of breakpoint position alignments.
-// Must match Debug.BreakPositionAlignment in debug-debugger.js
-enum BreakPositionAlignment {
-  STATEMENT_ALIGNED = 0,
-  BREAK_POSITION_ALIGNED = 1
-};
-
-
-class BreakLocation {
- public:
-  // Find the break point at the supplied address, or the closest one before
-  // the address.
-  static BreakLocation FromAddress(Handle<DebugInfo> debug_info,
-                                   BreakLocatorType type, Address pc);
-
-  static void FromAddressSameStatement(Handle<DebugInfo> debug_info,
-                                       BreakLocatorType type, Address pc,
-                                       List<BreakLocation>* result_out);
-
-  static BreakLocation FromPosition(Handle<DebugInfo> debug_info,
-                                    BreakLocatorType type, int position,
-                                    BreakPositionAlignment alignment);
-
-  bool IsDebugBreak() const;
-
-  inline bool IsReturn() const {
-    return RelocInfo::IsDebugBreakSlotAtReturn(rmode_);
-  }
-  inline bool IsCall() const {
-    return RelocInfo::IsDebugBreakSlotAtCall(rmode_);
-  }
-  inline bool IsConstructCall() const {
-    return RelocInfo::IsDebugBreakSlotAtConstructCall(rmode_);
-  }
-  inline int CallArgumentsCount() const {
-    DCHECK(IsCall());
-    return RelocInfo::DebugBreakCallArgumentsCount(data_);
-  }
-
-  bool IsStepInLocation() const;
-  inline bool HasBreakPoint() const {
-    return debug_info_->HasBreakPoint(pc_offset_);
-  }
-
-  Handle<Object> BreakPointObjects() const;
-
-  void SetBreakPoint(Handle<Object> break_point_object);
-  void ClearBreakPoint(Handle<Object> break_point_object);
-
-  void SetOneShot();
-  void ClearOneShot();
-
-
-  inline RelocInfo rinfo() const {
-    return RelocInfo(pc(), rmode(), data_, code());
-  }
-
-  inline int position() const { return position_; }
-  inline int statement_position() const { return statement_position_; }
-
-  inline Address pc() const { return code()->entry() + pc_offset_; }
-
-  inline RelocInfo::Mode rmode() const { return rmode_; }
-
-  inline Code* code() const { return debug_info_->code(); }
-
- private:
-  BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo, int position,
-                int statement_position);
-
-  class Iterator {
-   public:
-    Iterator(Handle<DebugInfo> debug_info, BreakLocatorType type);
-
-    BreakLocation GetBreakLocation() {
-      return BreakLocation(debug_info_, rinfo(), position(),
-                           statement_position());
-    }
-
-    inline bool Done() const { return reloc_iterator_.done(); }
-    void Next();
-
-    void SkipTo(int count) {
-      while (count-- > 0) Next();
-    }
-
-    inline RelocInfo::Mode rmode() { return reloc_iterator_.rinfo()->rmode(); }
-    inline RelocInfo* rinfo() { return reloc_iterator_.rinfo(); }
-    inline Address pc() { return rinfo()->pc(); }
-    int break_index() const { return break_index_; }
-    inline int position() const { return position_; }
-    inline int statement_position() const { return statement_position_; }
-
-   private:
-    static int GetModeMask(BreakLocatorType type);
-
-    Handle<DebugInfo> debug_info_;
-    RelocIterator reloc_iterator_;
-    int break_index_;
-    int position_;
-    int statement_position_;
-
-    DisallowHeapAllocation no_gc_;
-
-    DISALLOW_COPY_AND_ASSIGN(Iterator);
-  };
-
-  friend class Debug;
-
-  static int BreakIndexFromAddress(Handle<DebugInfo> debug_info,
-                                   BreakLocatorType type, Address pc);
-
-  void SetDebugBreak();
-  void ClearDebugBreak();
-
-  inline bool IsDebuggerStatement() const {
-    return RelocInfo::IsDebuggerStatement(rmode_);
-  }
-  inline bool IsDebugBreakSlot() const {
-    return RelocInfo::IsDebugBreakSlot(rmode_);
-  }
-
-  Handle<DebugInfo> debug_info_;
-  int pc_offset_;
-  RelocInfo::Mode rmode_;
-  intptr_t data_;
-  int position_;
-  int statement_position_;
-};
-
-
-// Cache of all script objects in the heap. When a script is added a weak handle
-// to it is created and that weak handle is stored in the cache. The weak handle
-// callback takes care of removing the script from the cache. The key used in
-// the cache is the script id.
-class ScriptCache {
- public:
-  explicit ScriptCache(Isolate* isolate);
-  ~ScriptCache();
-
-  // Add script to the cache.
-  void Add(Handle<Script> script);
-
-  // Return the scripts in the cache.
-  Handle<FixedArray> GetScripts() {
-    return WeakValueHashTable::GetWeakValues(table_);
-  }
-
- private:
-  Isolate* isolate_;
-  Handle<WeakValueHashTable> table_;
-};
-
-
-// Linked list holding debug info objects. The debug info objects are kept as
-// weak handles to avoid a debug info object to keep a function alive.
-class DebugInfoListNode {
- public:
-  explicit DebugInfoListNode(DebugInfo* debug_info);
-  ~DebugInfoListNode();
-
-  DebugInfoListNode* next() { return next_; }
-  void set_next(DebugInfoListNode* next) { next_ = next; }
-  Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); }
-
- private:
-  // Global (weak) handle to the debug info object.
-  DebugInfo** debug_info_;
-
-  // Next pointer for linked list.
-  DebugInfoListNode* next_;
-};
-
-
-
-// Message delivered to the message handler callback. This is either a debugger
-// event or the response to a command.
-class MessageImpl: public v8::Debug::Message {
- public:
-  // Create a message object for a debug event.
-  static MessageImpl NewEvent(DebugEvent event,
-                              bool running,
-                              Handle<JSObject> exec_state,
-                              Handle<JSObject> event_data);
-
-  // Create a message object for the response to a debug command.
-  static MessageImpl NewResponse(DebugEvent event,
-                                 bool running,
-                                 Handle<JSObject> exec_state,
-                                 Handle<JSObject> event_data,
-                                 Handle<String> response_json,
-                                 v8::Debug::ClientData* client_data);
-
-  // Implementation of interface v8::Debug::Message.
-  virtual bool IsEvent() const;
-  virtual bool IsResponse() const;
-  virtual DebugEvent GetEvent() const;
-  virtual bool WillStartRunning() const;
-  virtual v8::Local<v8::Object> GetExecutionState() const;
-  virtual v8::Local<v8::Object> GetEventData() const;
-  virtual v8::Local<v8::String> GetJSON() const;
-  virtual v8::Local<v8::Context> GetEventContext() const;
-  virtual v8::Debug::ClientData* GetClientData() const;
-  virtual v8::Isolate* GetIsolate() const;
-
- private:
-  MessageImpl(bool is_event,
-              DebugEvent event,
-              bool running,
-              Handle<JSObject> exec_state,
-              Handle<JSObject> event_data,
-              Handle<String> response_json,
-              v8::Debug::ClientData* client_data);
-
-  bool is_event_;  // Does this message represent a debug event?
-  DebugEvent event_;  // Debug event causing the break.
-  bool running_;  // Will the VM start running after this event?
-  Handle<JSObject> exec_state_;  // Current execution state.
-  Handle<JSObject> event_data_;  // Data associated with the event.
-  Handle<String> response_json_;  // Response JSON if message holds a response.
-  v8::Debug::ClientData* client_data_;  // Client data passed with the request.
-};
-
-
-// Details of the debug event delivered to the debug event listener.
-class EventDetailsImpl : public v8::Debug::EventDetails {
- public:
-  EventDetailsImpl(DebugEvent event,
-                   Handle<JSObject> exec_state,
-                   Handle<JSObject> event_data,
-                   Handle<Object> callback_data,
-                   v8::Debug::ClientData* client_data);
-  virtual DebugEvent GetEvent() const;
-  virtual v8::Local<v8::Object> GetExecutionState() const;
-  virtual v8::Local<v8::Object> GetEventData() const;
-  virtual v8::Local<v8::Context> GetEventContext() const;
-  virtual v8::Local<v8::Value> GetCallbackData() const;
-  virtual v8::Debug::ClientData* GetClientData() const;
- private:
-  DebugEvent event_;  // Debug event causing the break.
-  Handle<JSObject> exec_state_;         // Current execution state.
-  Handle<JSObject> event_data_;         // Data associated with the event.
-  Handle<Object> callback_data_;        // User data passed with the callback
-                                        // when it was registered.
-  v8::Debug::ClientData* client_data_;  // Data passed to DebugBreakForCommand.
-};
-
-
-// Message send by user to v8 debugger or debugger output message.
-// In addition to command text it may contain a pointer to some user data
-// which are expected to be passed along with the command reponse to message
-// handler.
-class CommandMessage {
- public:
-  static CommandMessage New(const Vector<uint16_t>& command,
-                            v8::Debug::ClientData* data);
-  CommandMessage();
-
-  // Deletes user data and disposes of the text.
-  void Dispose();
-  Vector<uint16_t> text() const { return text_; }
-  v8::Debug::ClientData* client_data() const { return client_data_; }
- private:
-  CommandMessage(const Vector<uint16_t>& text,
-                 v8::Debug::ClientData* data);
-
-  Vector<uint16_t> text_;
-  v8::Debug::ClientData* client_data_;
-};
-
-
-// A Queue of CommandMessage objects.  A thread-safe version is
-// LockingCommandMessageQueue, based on this class.
-class CommandMessageQueue BASE_EMBEDDED {
- public:
-  explicit CommandMessageQueue(int size);
-  ~CommandMessageQueue();
-  bool IsEmpty() const { return start_ == end_; }
-  CommandMessage Get();
-  void Put(const CommandMessage& message);
-  void Clear() { start_ = end_ = 0; }  // Queue is empty after Clear().
- private:
-  // Doubles the size of the message queue, and copies the messages.
-  void Expand();
-
-  CommandMessage* messages_;
-  int start_;
-  int end_;
-  int size_;  // The size of the queue buffer.  Queue can hold size-1 messages.
-};
-
-
-// LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage
-// messages.  The message data is not managed by LockingCommandMessageQueue.
-// Pointers to the data are passed in and out. Implemented by adding a
-// Mutex to CommandMessageQueue.  Includes logging of all puts and gets.
-class LockingCommandMessageQueue BASE_EMBEDDED {
- public:
-  LockingCommandMessageQueue(Logger* logger, int size);
-  bool IsEmpty() const;
-  CommandMessage Get();
-  void Put(const CommandMessage& message);
-  void Clear();
- private:
-  Logger* logger_;
-  CommandMessageQueue queue_;
-  mutable base::Mutex mutex_;
-  DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue);
-};
-
-
-// This class contains the debugger support. The main purpose is to handle
-// setting break points in the code.
-//
-// This class controls the debug info for all functions which currently have
-// active breakpoints in them. This debug info is held in the heap root object
-// debug_info which is a FixedArray. Each entry in this list is of class
-// DebugInfo.
-class Debug {
- public:
-  // Debug event triggers.
-  void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
-
-  void OnThrow(Handle<Object> exception);
-  void OnPromiseReject(Handle<JSObject> promise, Handle<Object> value);
-  void OnCompileError(Handle<Script> script);
-  void OnBeforeCompile(Handle<Script> script);
-  void OnAfterCompile(Handle<Script> script);
-  void OnPromiseEvent(Handle<JSObject> data);
-  void OnAsyncTaskEvent(Handle<JSObject> data);
-
-  // API facing.
-  void SetEventListener(Handle<Object> callback, Handle<Object> data);
-  void SetMessageHandler(v8::Debug::MessageHandler handler);
-  void EnqueueCommandMessage(Vector<const uint16_t> command,
-                             v8::Debug::ClientData* client_data = NULL);
-  MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun,
-                                           Handle<Object> data);
-  Handle<Context> GetDebugContext();
-  void HandleDebugBreak();
-  void ProcessDebugMessages(bool debug_command_only);
-
-  // Internal logic
-  bool Load();
-  void Break(Arguments args, JavaScriptFrame*);
-  void SetAfterBreakTarget(JavaScriptFrame* frame);
-
-  // Scripts handling.
-  Handle<FixedArray> GetLoadedScripts();
-
-  // Break point handling.
-  bool SetBreakPoint(Handle<JSFunction> function,
-                     Handle<Object> break_point_object,
-                     int* source_position);
-  bool SetBreakPointForScript(Handle<Script> script,
-                              Handle<Object> break_point_object,
-                              int* source_position,
-                              BreakPositionAlignment alignment);
-  void ClearBreakPoint(Handle<Object> break_point_object);
-  void ClearAllBreakPoints();
-  void FloodWithOneShot(Handle<JSFunction> function,
-                        BreakLocatorType type = ALL_BREAK_LOCATIONS);
-  void FloodBoundFunctionWithOneShot(Handle<JSFunction> function);
-  void FloodDefaultConstructorWithOneShot(Handle<JSFunction> function);
-  void FloodWithOneShotGeneric(Handle<JSFunction> function,
-                               Handle<Object> holder = Handle<Object>());
-  void FloodHandlerWithOneShot();
-  void ChangeBreakOnException(ExceptionBreakType type, bool enable);
-  bool IsBreakOnException(ExceptionBreakType type);
-
-  // Stepping handling.
-  void PrepareStep(StepAction step_action,
-                   int step_count,
-                   StackFrame::Id frame_id);
-  void ClearStepping();
-  void ClearStepOut();
-  bool IsStepping() { return thread_local_.step_count_ > 0; }
-  bool StepNextContinue(BreakLocation* location, JavaScriptFrame* frame);
-  bool StepInActive() { return thread_local_.step_into_fp_ != 0; }
-  void HandleStepIn(Handle<Object> function_obj, bool is_constructor);
-  bool StepOutActive() { return thread_local_.step_out_fp_ != 0; }
-
-  void GetStepinPositions(JavaScriptFrame* frame, StackFrame::Id frame_id,
-                          List<int>* results_out);
-
-  bool PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared);
-
-  // Returns whether the operation succeeded. Compilation can only be triggered
-  // if a valid closure is passed as the second argument, otherwise the shared
-  // function needs to be compiled already.
-  bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
-                       Handle<JSFunction> function);
-  static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
-
-  template <typename C>
-  bool CompileToRevealInnerFunctions(C* compilable);
-
-  // This function is used in FunctionNameUsing* tests.
-  Handle<Object> FindSharedFunctionInfoInScript(Handle<Script> script,
-                                                int position);
-
-  // Returns true if the current stub call is patched to call the debugger.
-  static bool IsDebugBreak(Address addr);
-
-  static Handle<Object> GetSourceBreakLocations(
-      Handle<SharedFunctionInfo> shared,
-      BreakPositionAlignment position_aligment);
-
-  // Check whether a global object is the debug global object.
-  bool IsDebugGlobal(GlobalObject* global);
-
-  // Check whether this frame is just about to return.
-  bool IsBreakAtReturn(JavaScriptFrame* frame);
-
-  // Support for LiveEdit
-  void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
-                             LiveEdit::FrameDropMode mode,
-                             Object** restarter_frame_function_pointer);
-
-  // Threading support.
-  char* ArchiveDebug(char* to);
-  char* RestoreDebug(char* from);
-  static int ArchiveSpacePerThread();
-  void FreeThreadResources() { }
-
-  // Record function from which eval was called.
-  static void RecordEvalCaller(Handle<Script> script);
-
-  bool CheckExecutionState(int id) {
-    return is_active() && !debug_context().is_null() && break_id() != 0 &&
-           break_id() == id;
-  }
-
-  // Flags and states.
-  DebugScope* debugger_entry() {
-    return reinterpret_cast<DebugScope*>(
-        base::NoBarrier_Load(&thread_local_.current_debug_scope_));
-  }
-  inline Handle<Context> debug_context() { return debug_context_; }
-  void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
-  bool live_edit_enabled() const {
-    return FLAG_enable_liveedit && live_edit_enabled_ ;
-  }
-
-  inline bool is_active() const { return is_active_; }
-  inline bool is_loaded() const { return !debug_context_.is_null(); }
-  inline bool in_debug_scope() const {
-    return !!base::NoBarrier_Load(&thread_local_.current_debug_scope_);
-  }
-  void set_disable_break(bool v) { break_disabled_ = v; }
-
-  StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
-  int break_id() { return thread_local_.break_id_; }
-
-  // Support for embedding into generated code.
-  Address is_active_address() {
-    return reinterpret_cast<Address>(&is_active_);
-  }
-
-  Address after_break_target_address() {
-    return reinterpret_cast<Address>(&after_break_target_);
-  }
-
-  Address restarter_frame_function_pointer_address() {
-    Object*** address = &thread_local_.restarter_frame_function_pointer_;
-    return reinterpret_cast<Address>(address);
-  }
-
-  Address step_in_fp_addr() {
-    return reinterpret_cast<Address>(&thread_local_.step_into_fp_);
-  }
-
-  StepAction last_step_action() { return thread_local_.last_step_action_; }
-
- private:
-  explicit Debug(Isolate* isolate);
-
-  void UpdateState();
-  void Unload();
-  void SetNextBreakId() {
-    thread_local_.break_id_ = ++thread_local_.break_count_;
-  }
-
-  // Check whether there are commands in the command queue.
-  inline bool has_commands() const { return !command_queue_.IsEmpty(); }
-  inline bool ignore_events() const { return is_suppressed_ || !is_active_; }
-  inline bool break_disabled() const {
-    return break_disabled_ || in_debug_event_listener_;
-  }
-
-  void OnException(Handle<Object> exception, Handle<Object> promise);
-
-  // Constructors for debug event objects.
-  MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
-      const char* constructor_name,
-      int argc,
-      Handle<Object> argv[]);
-  MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
-  MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
-      Handle<Object> break_points_hit);
-  MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
-      Handle<Object> exception,
-      bool uncaught,
-      Handle<Object> promise);
-  MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
-      Handle<Script> script, v8::DebugEvent type);
-  MUST_USE_RESULT MaybeHandle<Object> MakePromiseEvent(
-      Handle<JSObject> promise_event);
-  MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(
-      Handle<JSObject> task_event);
-
-  // Mirror cache handling.
-  void ClearMirrorCache();
-
-  MaybeHandle<Object> PromiseHasUserDefinedRejectHandler(
-      Handle<JSObject> promise);
-
-  void CallEventCallback(v8::DebugEvent event,
-                         Handle<Object> exec_state,
-                         Handle<Object> event_data,
-                         v8::Debug::ClientData* client_data);
-  void ProcessCompileEventInDebugScope(v8::DebugEvent event,
-                                       Handle<Script> script);
-  void ProcessDebugEvent(v8::DebugEvent event,
-                         Handle<JSObject> event_data,
-                         bool auto_continue);
-  void NotifyMessageHandler(v8::DebugEvent event,
-                            Handle<JSObject> exec_state,
-                            Handle<JSObject> event_data,
-                            bool auto_continue);
-  void InvokeMessageHandler(MessageImpl message);
-
-  static bool CompileDebuggerScript(Isolate* isolate, int index);
-  void ClearOneShot();
-  void ActivateStepIn(StackFrame* frame);
-  void ClearStepIn();
-  void ActivateStepOut(StackFrame* frame);
-  void ClearStepNext();
-  void RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info);
-  Handle<Object> CheckBreakPoints(Handle<Object> break_point);
-  bool CheckBreakPoint(Handle<Object> break_point_object);
-
-  inline void AssertDebugContext() {
-    DCHECK(isolate_->context() == *debug_context());
-    DCHECK(in_debug_scope());
-  }
-
-  void ThreadInit();
-
-  // Global handles.
-  Handle<Context> debug_context_;
-  Handle<Object> event_listener_;
-  Handle<Object> event_listener_data_;
-
-  v8::Debug::MessageHandler message_handler_;
-
-  static const int kQueueInitialSize = 4;
-  base::Semaphore command_received_;  // Signaled for each command received.
-  LockingCommandMessageQueue command_queue_;
-
-  bool is_active_;
-  bool is_suppressed_;
-  bool live_edit_enabled_;
-  bool has_break_points_;
-  bool break_disabled_;
-  bool in_debug_event_listener_;
-  bool break_on_exception_;
-  bool break_on_uncaught_exception_;
-
-  ScriptCache* script_cache_;  // Cache of all scripts in the heap.
-  DebugInfoListNode* debug_info_list_;  // List of active debug info objects.
-
-  // Storage location for jump when exiting debug break calls.
-  // Note that this address is not GC safe.  It should be computed immediately
-  // before returning to the DebugBreakCallHelper.
-  Address after_break_target_;
-
-  // Per-thread data.
-  class ThreadLocal {
-   public:
-    // Top debugger entry.
-    base::AtomicWord current_debug_scope_;
-
-    // Counter for generating next break id.
-    int break_count_;
-
-    // Current break id.
-    int break_id_;
-
-    // Frame id for the frame of the current break.
-    StackFrame::Id break_frame_id_;
-
-    // Step action for last step performed.
-    StepAction last_step_action_;
-
-    // Source statement position from last step next action.
-    int last_statement_position_;
-
-    // Number of steps left to perform before debug event.
-    int step_count_;
-
-    // Frame pointer from last step next or step frame action.
-    Address last_fp_;
-
-    // Number of queued steps left to perform before debug event.
-    int queued_step_count_;
-
-    // Frame pointer for frame from which step in was performed.
-    Address step_into_fp_;
-
-    // Frame pointer for the frame where debugger should be called when current
-    // step out action is completed.
-    Address step_out_fp_;
-
-    // Stores the way how LiveEdit has patched the stack. It is used when
-    // debugger returns control back to user script.
-    LiveEdit::FrameDropMode frame_drop_mode_;
-
-    // When restarter frame is on stack, stores the address
-    // of the pointer to function being restarted. Otherwise (most of the time)
-    // stores NULL. This pointer is used with 'step in' implementation.
-    Object** restarter_frame_function_pointer_;
-  };
-
-  // Storage location for registers when handling debug break calls
-  ThreadLocal thread_local_;
-
-  Isolate* isolate_;
-
-  friend class Isolate;
-  friend class DebugScope;
-  friend class DisableBreak;
-  friend class LiveEdit;
-  friend class SuppressDebug;
-
-  friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
-  friend void CheckDebuggerUnloaded(bool check_functions);  // In test-debug.cc
-
-  DISALLOW_COPY_AND_ASSIGN(Debug);
-};
-
-
-// This scope is used to load and enter the debug context and create a new
-// break state.  Leaving the scope will restore the previous state.
-// On failure to load, FailedToEnter returns true.
-class DebugScope BASE_EMBEDDED {
- public:
-  explicit DebugScope(Debug* debug);
-  ~DebugScope();
-
-  // Check whether loading was successful.
-  inline bool failed() { return failed_; }
-
-  // Get the active context from before entering the debugger.
-  inline Handle<Context> GetContext() { return save_.context(); }
-
- private:
-  Isolate* isolate() { return debug_->isolate_; }
-
-  Debug* debug_;
-  DebugScope* prev_;               // Previous scope if entered recursively.
-  StackFrame::Id break_frame_id_;  // Previous break frame id.
-  int break_id_;                   // Previous break id.
-  bool failed_;                    // Did the debug context fail to load?
-  SaveContext save_;               // Saves previous context.
-  PostponeInterruptsScope no_termination_exceptons_;
-};
-
-
-// Stack allocated class for disabling break.
-class DisableBreak BASE_EMBEDDED {
- public:
-  explicit DisableBreak(Debug* debug, bool disable_break)
-      : debug_(debug),
-        previous_break_disabled_(debug->break_disabled_),
-        previous_in_debug_event_listener_(debug->in_debug_event_listener_) {
-    debug_->break_disabled_ = disable_break;
-    debug_->in_debug_event_listener_ = disable_break;
-  }
-  ~DisableBreak() {
-    debug_->break_disabled_ = previous_break_disabled_;
-    debug_->in_debug_event_listener_ = previous_in_debug_event_listener_;
-  }
-
- private:
-  Debug* debug_;
-  bool previous_break_disabled_;
-  bool previous_in_debug_event_listener_;
-  DISALLOW_COPY_AND_ASSIGN(DisableBreak);
-};
-
-
-class SuppressDebug BASE_EMBEDDED {
- public:
-  explicit SuppressDebug(Debug* debug)
-      : debug_(debug), old_state_(debug->is_suppressed_) {
-    debug_->is_suppressed_ = true;
-  }
-  ~SuppressDebug() { debug_->is_suppressed_ = old_state_; }
-
- private:
-  Debug* debug_;
-  bool old_state_;
-  DISALLOW_COPY_AND_ASSIGN(SuppressDebug);
-};
-
-
-// Code generator routines.
-class DebugCodegen : public AllStatic {
- public:
-  enum DebugBreakCallHelperMode {
-    SAVE_RESULT_REGISTER,
-    IGNORE_RESULT_REGISTER
-  };
-
-  static void GenerateDebugBreakStub(MacroAssembler* masm,
-                                     DebugBreakCallHelperMode mode);
-
-  static void GeneratePlainReturnLiveEdit(MacroAssembler* masm);
-
-  // FrameDropper is a code replacement for a JavaScript frame with possibly
-  // several frames above.
-  // There is no calling conventions here, because it never actually gets
-  // called, it only gets returned to.
-  static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
-
-
-  static void GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                           int call_argc = -1);
-
-  static void PatchDebugBreakSlot(Address pc, Handle<Code> code);
-  static void ClearDebugBreakSlot(Address pc);
-};
-
-
-} }  // namespace v8::internal
-
-#endif  // V8_DEBUG_H_
diff --git a/src/debug/OWNERS b/src/debug/OWNERS
new file mode 100644 (file)
index 0000000..03c3e33
--- /dev/null
@@ -0,0 +1,4 @@
+mvstanton@chromium.org
+ulan@chromium.org
+verwaest@chromium.org
+yangguo@chromium.org
diff --git a/src/debug/arm/OWNERS b/src/debug/arm/OWNERS
new file mode 100644 (file)
index 0000000..906a5ce
--- /dev/null
@@ -0,0 +1 @@
+rmcilroy@chromium.org
diff --git a/src/debug/arm/debug-arm.cc b/src/debug/arm/debug-arm.cc
new file mode 100644 (file)
index 0000000..38aadce
--- /dev/null
@@ -0,0 +1,161 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_ARM
+
+#include "src/codegen.h"
+#include "src/debug/debug.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void EmitDebugBreakSlot(MacroAssembler* masm) {
+  Label check_size;
+  __ bind(&check_size);
+  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
+    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
+  }
+  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
+            masm->InstructionsGeneratedSince(&check_size));
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                                int call_argc) {
+  // Generate enough nop's to make space for a call instruction. Avoid emitting
+  // the constant pool in the debug break slot code.
+  Assembler::BlockConstPoolScope block_const_pool(masm);
+  masm->RecordDebugBreakSlot(mode, call_argc);
+  EmitDebugBreakSlot(masm);
+}
+
+
+void DebugCodegen::ClearDebugBreakSlot(Address pc) {
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
+  EmitDebugBreakSlot(patcher.masm());
+}
+
+
+void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
+  DCHECK_EQ(Code::BUILTIN, code->kind());
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
+  // Patch the code changing the debug break slot code from
+  //   mov r2, r2
+  //   mov r2, r2
+  //   mov r2, r2
+  //   mov r2, r2
+  // to a call to the debug break slot code.
+  //   ldr ip, [pc, #0]
+  //   b skip
+  //   <debug break slot code entry point address>
+  //   skip:
+  //   blx ip
+  Label skip_constant;
+  patcher.masm()->ldr(ip, MemOperand(v8::internal::pc, 0));
+  patcher.masm()->b(&skip_constant);
+  patcher.Emit(code->entry());
+  patcher.masm()->bind(&skip_constant);
+  patcher.masm()->blx(ip);
+}
+
+
+void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
+                                          DebugBreakCallHelperMode mode) {
+  __ RecordComment("Debug break");
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue)));
+    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
+      __ push(ip);
+    }
+    __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
+    __ push(ip);
+
+    if (mode == SAVE_RESULT_REGISTER) __ push(r0);
+
+    __ mov(r0, Operand::Zero());  // no arguments
+    __ mov(r1,
+           Operand(ExternalReference(
+               Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
+
+    CEntryStub ceb(masm->isolate(), 1);
+    __ CallStub(&ceb);
+
+    if (FLAG_debug_code) {
+      for (int i = 0; i < kNumJSCallerSaved; i++) {
+        Register reg = {JSCallerSavedCode(i)};
+        __ mov(reg, Operand(kDebugZapValue));
+      }
+    }
+
+    if (mode == SAVE_RESULT_REGISTER) __ pop(r0);
+
+    // Don't bother removing padding bytes pushed on the stack
+    // as the frame is going to be restored right away.
+
+    // Leave the internal frame.
+  }
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ mov(ip, Operand(after_break_target));
+  __ ldr(ip, MemOperand(ip));
+  __ Jump(ip);
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  __ Ret();
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  __ mov(ip, Operand(restarter_frame_function_slot));
+  __ mov(r1, Operand::Zero());
+  __ str(r1, MemOperand(ip, 0));
+
+  // Load the function pointer off of our current stack frame.
+  __ ldr(r1, MemOperand(fp,
+         StandardFrameConstants::kConstantPoolOffset - kPointerSize));
+
+  // Pop return address, frame and constant pool pointer (if
+  // FLAG_enable_embedded_constant_pool).
+  __ LeaveFrame(StackFrame::INTERNAL);
+
+  { ConstantPoolUnavailableScope constant_pool_unavailable(masm);
+    // Load context from the function.
+    __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
+
+    // Get function code.
+    __ ldr(ip, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+    __ ldr(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset));
+    __ add(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
+
+    // Re-run JSFunction, r1 is function, cp is context.
+    __ Jump(ip);
+  }
+}
+
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+#undef __
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_ARM
diff --git a/src/debug/arm64/OWNERS b/src/debug/arm64/OWNERS
new file mode 100644 (file)
index 0000000..906a5ce
--- /dev/null
@@ -0,0 +1 @@
+rmcilroy@chromium.org
diff --git a/src/debug/arm64/debug-arm64.cc b/src/debug/arm64/debug-arm64.cc
new file mode 100644 (file)
index 0000000..e33c1a5
--- /dev/null
@@ -0,0 +1,167 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_ARM64
+
+#include "src/codegen.h"
+#include "src/debug/debug.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void EmitDebugBreakSlot(Assembler* masm) {
+  Label check_size;
+  __ bind(&check_size);
+  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
+    __ nop(Assembler::DEBUG_BREAK_NOP);
+  }
+  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
+            static_cast<int>(masm->InstructionsGeneratedSince(&check_size)));
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                                int call_argc) {
+  // Generate enough nop's to make space for a call instruction. Avoid emitting
+  // the constant pool in the debug break slot code.
+  InstructionAccurateScope scope(masm, Assembler::kDebugBreakSlotInstructions);
+  masm->RecordDebugBreakSlot(mode, call_argc);
+  EmitDebugBreakSlot(masm);
+}
+
+
+void DebugCodegen::ClearDebugBreakSlot(Address pc) {
+  PatchingAssembler patcher(reinterpret_cast<Instruction*>(pc),
+                            Assembler::kDebugBreakSlotInstructions);
+  EmitDebugBreakSlot(&patcher);
+}
+
+
+void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
+  DCHECK_EQ(Code::BUILTIN, code->kind());
+  PatchingAssembler patcher(reinterpret_cast<Instruction*>(pc),
+                            Assembler::kDebugBreakSlotInstructions);
+  // Patch the code emitted by DebugCodegen::GenerateSlots, changing the debug
+  // break slot code from
+  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
+  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
+  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
+  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
+  //   mov x0, x0    @ nop DEBUG_BREAK_NOP
+  // to a call to the debug slot code.
+  //   ldr ip0, [pc, #(2 * kInstructionSize)]
+  //   blr ip0
+  //   b skip
+  //   <debug break slot code entry point address (64 bits)>
+  //   skip:
+
+  Label skip_constant;
+  // The first instruction of a patched debug break slot must be a load literal
+  // loading the address of the debug break slot code.
+  patcher.ldr_pcrel(ip0, (2 * kInstructionSize) >> kLoadLiteralScaleLog2);
+  patcher.b(&skip_constant);
+  patcher.dc64(reinterpret_cast<int64_t>(code->entry()));
+  patcher.bind(&skip_constant);
+  // TODO(all): check the following is correct.
+  // The debug break slot code will push a frame and call statically compiled
+  // code. By using blr,  this call site will be registered in the frame.
+  // The debugger can now iterate on the frames to find this call.
+  patcher.blr(ip0);
+}
+
+
+void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
+                                          DebugBreakCallHelperMode mode) {
+  __ RecordComment("Debug break");
+  Register scratch = x10;
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingValue));
+    __ PushMultipleTimes(scratch, LiveEdit::kFramePaddingInitialSize);
+    __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
+    __ Push(scratch);
+
+    if (mode == SAVE_RESULT_REGISTER) __ Push(x0);
+
+    __ Mov(x0, 0);  // No arguments.
+    __ Mov(x1, ExternalReference(Runtime::FunctionForId(Runtime::kDebugBreak),
+                                 masm->isolate()));
+
+    CEntryStub stub(masm->isolate(), 1);
+    __ CallStub(&stub);
+
+    if (FLAG_debug_code) {
+      for (int i = 0; i < kNumJSCallerSaved; i++) {
+        Register reg = Register::XRegFromCode(JSCallerSavedCode(i));
+        __ Mov(reg, Operand(kDebugZapValue));
+      }
+    }
+
+    // Restore the register values from the expression stack.
+    if (mode == SAVE_RESULT_REGISTER) __ Pop(x0);
+
+    // Don't bother removing padding bytes pushed on the stack
+    // as the frame is going to be restored right away.
+
+    // Leave the internal frame.
+  }
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ Mov(scratch, after_break_target);
+  __ Ldr(scratch, MemOperand(scratch));
+  __ Br(scratch);
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  __ Ret();
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  UseScratchRegisterScope temps(masm);
+  Register scratch = temps.AcquireX();
+
+  __ Mov(scratch, restarter_frame_function_slot);
+  __ Str(xzr, MemOperand(scratch));
+
+  // We do not know our frame height, but set sp based on fp.
+  __ Sub(masm->StackPointer(), fp, kPointerSize);
+  __ AssertStackConsistency();
+
+  __ Pop(x1, fp, lr);  // Function, Frame, Return address.
+
+  // Load context from the function.
+  __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
+
+  // Get function code.
+  __ Ldr(scratch, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
+  __ Ldr(scratch, FieldMemOperand(scratch, SharedFunctionInfo::kCodeOffset));
+  __ Add(scratch, scratch, Code::kHeaderSize - kHeapObjectTag);
+
+  // Re-run JSFunction, x1 is function, cp is context.
+  __ Br(scratch);
+}
+
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_ARM64
diff --git a/src/debug/debug.cc b/src/debug/debug.cc
new file mode 100644 (file)
index 0000000..891c92e
--- /dev/null
@@ -0,0 +1,2812 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/debug/debug.h"
+
+#include "src/api.h"
+#include "src/arguments.h"
+#include "src/bootstrapper.h"
+#include "src/code-stubs.h"
+#include "src/codegen.h"
+#include "src/compilation-cache.h"
+#include "src/compiler.h"
+#include "src/deoptimizer.h"
+#include "src/execution.h"
+#include "src/full-codegen/full-codegen.h"
+#include "src/global-handles.h"
+#include "src/list.h"
+#include "src/log.h"
+#include "src/messages.h"
+#include "src/snapshot/natives.h"
+
+#include "include/v8-debug.h"
+
+namespace v8 {
+namespace internal {
+
+Debug::Debug(Isolate* isolate)
+    : debug_context_(Handle<Context>()),
+      event_listener_(Handle<Object>()),
+      event_listener_data_(Handle<Object>()),
+      message_handler_(NULL),
+      command_received_(0),
+      command_queue_(isolate->logger(), kQueueInitialSize),
+      is_active_(false),
+      is_suppressed_(false),
+      live_edit_enabled_(true),  // TODO(yangguo): set to false by default.
+      break_disabled_(false),
+      in_debug_event_listener_(false),
+      break_on_exception_(false),
+      break_on_uncaught_exception_(false),
+      script_cache_(NULL),
+      debug_info_list_(NULL),
+      isolate_(isolate) {
+  ThreadInit();
+}
+
+
+static v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
+  Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
+  // Isolate::context() may have been NULL when "script collected" event
+  // occured.
+  if (context.is_null()) return v8::Local<v8::Context>();
+  Handle<Context> native_context(context->native_context());
+  return v8::Utils::ToLocal(native_context);
+}
+
+
+BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo,
+                             int position, int statement_position)
+    : debug_info_(debug_info),
+      pc_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())),
+      rmode_(rinfo->rmode()),
+      data_(rinfo->data()),
+      position_(position),
+      statement_position_(statement_position) {}
+
+
+BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
+                                  BreakLocatorType type)
+    : debug_info_(debug_info),
+      reloc_iterator_(debug_info->code(), GetModeMask(type)),
+      break_index_(-1),
+      position_(1),
+      statement_position_(1) {
+  if (!Done()) Next();
+}
+
+
+int BreakLocation::Iterator::GetModeMask(BreakLocatorType type) {
+  int mask = 0;
+  mask |= RelocInfo::ModeMask(RelocInfo::POSITION);
+  mask |= RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION);
+  mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
+  mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL);
+  mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CONSTRUCT_CALL);
+  if (type == ALL_BREAK_LOCATIONS) {
+    mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
+    mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT);
+  }
+  return mask;
+}
+
+
+void BreakLocation::Iterator::Next() {
+  DisallowHeapAllocation no_gc;
+  DCHECK(!Done());
+
+  // Iterate through reloc info for code and original code stopping at each
+  // breakable code target.
+  bool first = break_index_ == -1;
+  while (!Done()) {
+    if (!first) reloc_iterator_.next();
+    first = false;
+    if (Done()) return;
+
+    // Whenever a statement position or (plain) position is passed update the
+    // current value of these.
+    if (RelocInfo::IsPosition(rmode())) {
+      if (RelocInfo::IsStatementPosition(rmode())) {
+        statement_position_ = static_cast<int>(
+            rinfo()->data() - debug_info_->shared()->start_position());
+      }
+      // Always update the position as we don't want that to be before the
+      // statement position.
+      position_ = static_cast<int>(rinfo()->data() -
+                                   debug_info_->shared()->start_position());
+      DCHECK(position_ >= 0);
+      DCHECK(statement_position_ >= 0);
+      continue;
+    }
+
+    DCHECK(RelocInfo::IsDebugBreakSlot(rmode()) ||
+           RelocInfo::IsDebuggerStatement(rmode()));
+
+    if (RelocInfo::IsDebugBreakSlotAtReturn(rmode())) {
+      // Set the positions to the end of the function.
+      if (debug_info_->shared()->HasSourceCode()) {
+        position_ = debug_info_->shared()->end_position() -
+                    debug_info_->shared()->start_position() - 1;
+      } else {
+        position_ = 0;
+      }
+      statement_position_ = position_;
+    }
+
+    break;
+  }
+  break_index_++;
+}
+
+
+// Find the break point at the supplied address, or the closest one before
+// the address.
+BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info,
+                                         BreakLocatorType type, Address pc) {
+  Iterator it(debug_info, type);
+  it.SkipTo(BreakIndexFromAddress(debug_info, type, pc));
+  return it.GetBreakLocation();
+}
+
+
+// Find the break point at the supplied address, or the closest one before
+// the address.
+void BreakLocation::FromAddressSameStatement(Handle<DebugInfo> debug_info,
+                                             BreakLocatorType type, Address pc,
+                                             List<BreakLocation>* result_out) {
+  int break_index = BreakIndexFromAddress(debug_info, type, pc);
+  Iterator it(debug_info, type);
+  it.SkipTo(break_index);
+  int statement_position = it.statement_position();
+  while (!it.Done() && it.statement_position() == statement_position) {
+    result_out->Add(it.GetBreakLocation());
+    it.Next();
+  }
+}
+
+
+int BreakLocation::BreakIndexFromAddress(Handle<DebugInfo> debug_info,
+                                         BreakLocatorType type, Address pc) {
+  // Run through all break points to locate the one closest to the address.
+  int closest_break = 0;
+  int distance = kMaxInt;
+  for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
+    // Check if this break point is closer that what was previously found.
+    if (it.pc() <= pc && pc - it.pc() < distance) {
+      closest_break = it.break_index();
+      distance = static_cast<int>(pc - it.pc());
+      // Check whether we can't get any closer.
+      if (distance == 0) break;
+    }
+  }
+  return closest_break;
+}
+
+
+BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info,
+                                          BreakLocatorType type, int position,
+                                          BreakPositionAlignment alignment) {
+  // Run through all break points to locate the one closest to the source
+  // position.
+  int closest_break = 0;
+  int distance = kMaxInt;
+
+  for (Iterator it(debug_info, type); !it.Done(); it.Next()) {
+    int next_position;
+    if (alignment == STATEMENT_ALIGNED) {
+      next_position = it.statement_position();
+    } else {
+      DCHECK(alignment == BREAK_POSITION_ALIGNED);
+      next_position = it.position();
+    }
+    if (position <= next_position && next_position - position < distance) {
+      closest_break = it.break_index();
+      distance = next_position - position;
+      // Check whether we can't get any closer.
+      if (distance == 0) break;
+    }
+  }
+
+  Iterator it(debug_info, type);
+  it.SkipTo(closest_break);
+  return it.GetBreakLocation();
+}
+
+
+void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
+  // If there is not already a real break point here patch code with debug
+  // break.
+  if (!HasBreakPoint()) SetDebugBreak();
+  DCHECK(IsDebugBreak() || IsDebuggerStatement());
+  // Set the break point information.
+  DebugInfo::SetBreakPoint(debug_info_, pc_offset_, position_,
+                           statement_position_, break_point_object);
+}
+
+
+void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) {
+  // Clear the break point information.
+  DebugInfo::ClearBreakPoint(debug_info_, pc_offset_, break_point_object);
+  // If there are no more break points here remove the debug break.
+  if (!HasBreakPoint()) {
+    ClearDebugBreak();
+    DCHECK(!IsDebugBreak());
+  }
+}
+
+
+void BreakLocation::SetOneShot() {
+  // Debugger statement always calls debugger. No need to modify it.
+  if (IsDebuggerStatement()) return;
+
+  // If there is a real break point here no more to do.
+  if (HasBreakPoint()) {
+    DCHECK(IsDebugBreak());
+    return;
+  }
+
+  // Patch code with debug break.
+  SetDebugBreak();
+}
+
+
+void BreakLocation::ClearOneShot() {
+  // Debugger statement always calls debugger. No need to modify it.
+  if (IsDebuggerStatement()) return;
+
+  // If there is a real break point here no more to do.
+  if (HasBreakPoint()) {
+    DCHECK(IsDebugBreak());
+    return;
+  }
+
+  // Patch code removing debug break.
+  ClearDebugBreak();
+  DCHECK(!IsDebugBreak());
+}
+
+
+void BreakLocation::SetDebugBreak() {
+  // Debugger statement always calls debugger. No need to modify it.
+  if (IsDebuggerStatement()) return;
+
+  // If there is already a break point here just return. This might happen if
+  // the same code is flooded with break points twice. Flooding the same
+  // function twice might happen when stepping in a function with an exception
+  // handler as the handler and the function is the same.
+  if (IsDebugBreak()) return;
+
+  DCHECK(IsDebugBreakSlot());
+  Builtins* builtins = debug_info_->GetIsolate()->builtins();
+  Handle<Code> target =
+      IsReturn() ? builtins->Return_DebugBreak() : builtins->Slot_DebugBreak();
+  DebugCodegen::PatchDebugBreakSlot(pc(), target);
+  DCHECK(IsDebugBreak());
+}
+
+
+void BreakLocation::ClearDebugBreak() {
+  // Debugger statement always calls debugger. No need to modify it.
+  if (IsDebuggerStatement()) return;
+
+  DCHECK(IsDebugBreakSlot());
+  DebugCodegen::ClearDebugBreakSlot(pc());
+  DCHECK(!IsDebugBreak());
+}
+
+
+bool BreakLocation::IsStepInLocation() const {
+  return IsConstructCall() || IsCall();
+}
+
+
+bool BreakLocation::IsDebugBreak() const {
+  if (IsDebugBreakSlot()) {
+    return rinfo().IsPatchedDebugBreakSlotSequence();
+  }
+  return false;
+}
+
+
+Handle<Object> BreakLocation::BreakPointObjects() const {
+  return debug_info_->GetBreakPointObjects(pc_offset_);
+}
+
+
+// Threading support.
+void Debug::ThreadInit() {
+  thread_local_.break_count_ = 0;
+  thread_local_.break_id_ = 0;
+  thread_local_.break_frame_id_ = StackFrame::NO_ID;
+  thread_local_.last_step_action_ = StepNone;
+  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
+  thread_local_.step_count_ = 0;
+  thread_local_.last_fp_ = 0;
+  thread_local_.queued_step_count_ = 0;
+  thread_local_.step_into_fp_ = 0;
+  thread_local_.step_out_fp_ = 0;
+  // TODO(isolates): frames_are_dropped_?
+  base::NoBarrier_Store(&thread_local_.current_debug_scope_,
+                        static_cast<base::AtomicWord>(0));
+  thread_local_.restarter_frame_function_pointer_ = NULL;
+}
+
+
+char* Debug::ArchiveDebug(char* storage) {
+  char* to = storage;
+  MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
+  ThreadInit();
+  return storage + ArchiveSpacePerThread();
+}
+
+
+char* Debug::RestoreDebug(char* storage) {
+  char* from = storage;
+  MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
+  return storage + ArchiveSpacePerThread();
+}
+
+
+int Debug::ArchiveSpacePerThread() {
+  return sizeof(ThreadLocal);
+}
+
+
+ScriptCache::ScriptCache(Isolate* isolate) : isolate_(isolate) {
+  Heap* heap = isolate_->heap();
+  HandleScope scope(isolate_);
+
+  DCHECK(isolate_->debug()->is_active());
+
+  // Perform a GC to get rid of all unreferenced scripts.
+  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
+
+  // Scan heap for Script objects.
+  List<Handle<Script> > scripts;
+  {
+    HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
+    DisallowHeapAllocation no_allocation;
+    for (HeapObject* obj = iterator.next(); obj != NULL;
+         obj = iterator.next()) {
+      if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
+        scripts.Add(Handle<Script>(Script::cast(obj)));
+      }
+    }
+  }
+
+  GlobalHandles* global_handles = isolate_->global_handles();
+  table_ = Handle<WeakValueHashTable>::cast(global_handles->Create(
+      Object::cast(*WeakValueHashTable::New(isolate_, scripts.length()))));
+  for (int i = 0; i < scripts.length(); i++) Add(scripts[i]);
+}
+
+
+void ScriptCache::Add(Handle<Script> script) {
+  HandleScope scope(isolate_);
+  Handle<Smi> id(script->id(), isolate_);
+
+#ifdef DEBUG
+  Handle<Object> lookup(table_->LookupWeak(id), isolate_);
+  if (!lookup->IsTheHole()) {
+    Handle<Script> found = Handle<Script>::cast(lookup);
+    DCHECK(script->id() == found->id());
+    DCHECK(!script->name()->IsString() ||
+           String::cast(script->name())->Equals(String::cast(found->name())));
+  }
+#endif
+
+  Handle<WeakValueHashTable> new_table =
+      WeakValueHashTable::PutWeak(table_, id, script);
+
+  if (new_table.is_identical_to(table_)) return;
+  GlobalHandles* global_handles = isolate_->global_handles();
+  global_handles->Destroy(Handle<Object>::cast(table_).location());
+  table_ = Handle<WeakValueHashTable>::cast(
+      global_handles->Create(Object::cast(*new_table)));
+}
+
+
+ScriptCache::~ScriptCache() {
+  isolate_->global_handles()->Destroy(Handle<Object>::cast(table_).location());
+  table_ = Handle<WeakValueHashTable>();
+}
+
+
+DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
+  // Globalize the request debug info object and make it weak.
+  GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
+  debug_info_ =
+      Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location();
+}
+
+
+DebugInfoListNode::~DebugInfoListNode() {
+  if (debug_info_ == nullptr) return;
+  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_));
+  debug_info_ = nullptr;
+}
+
+
+bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
+  Factory* factory = isolate->factory();
+  HandleScope scope(isolate);
+
+  // Bail out if the index is invalid.
+  if (index == -1) return false;
+
+  // Find source and name for the requested script.
+  Handle<String> source_code =
+      isolate->bootstrapper()->SourceLookup<Natives>(index);
+  Vector<const char> name = Natives::GetScriptName(index);
+  Handle<String> script_name =
+      factory->NewStringFromAscii(name).ToHandleChecked();
+  Handle<Context> context = isolate->native_context();
+
+  // Compile the script.
+  Handle<SharedFunctionInfo> function_info;
+  function_info = Compiler::CompileScript(
+      source_code, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
+      context, NULL, NULL, ScriptCompiler::kNoCompileOptions, NATIVES_CODE,
+      false);
+  if (function_info.is_null()) return false;
+
+  // Execute the shared function in the debugger context.
+  Handle<JSFunction> function =
+      factory->NewFunctionFromSharedFunctionInfo(function_info, context);
+
+  MaybeHandle<Object> maybe_exception;
+  MaybeHandle<Object> result = Execution::TryCall(
+      function, handle(context->global_proxy()), 0, NULL, &maybe_exception);
+
+  // Check for caught exceptions.
+  if (result.is_null()) {
+    DCHECK(!isolate->has_pending_exception());
+    MessageLocation computed_location;
+    isolate->ComputeLocation(&computed_location);
+    Handle<JSMessageObject> message = MessageHandler::MakeMessageObject(
+        isolate, MessageTemplate::kDebuggerLoading, &computed_location,
+        isolate->factory()->undefined_value(), Handle<JSArray>());
+    DCHECK(!isolate->has_pending_exception());
+    Handle<Object> exception;
+    if (maybe_exception.ToHandle(&exception)) {
+      isolate->set_pending_exception(*exception);
+      MessageHandler::ReportMessage(isolate, NULL, message);
+    }
+    DCHECK(!maybe_exception.is_null());
+    return false;
+  }
+
+  // Mark this script as native and return successfully.
+  Handle<Script> script(Script::cast(function->shared()->script()));
+  script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
+  return true;
+}
+
+
+bool Debug::Load() {
+  // Return if debugger is already loaded.
+  if (is_loaded()) return true;
+
+  // Bail out if we're already in the process of compiling the native
+  // JavaScript source code for the debugger.
+  if (is_suppressed_) return false;
+  SuppressDebug while_loading(this);
+
+  // Disable breakpoints and interrupts while compiling and running the
+  // debugger scripts including the context creation code.
+  DisableBreak disable(this, true);
+  PostponeInterruptsScope postpone(isolate_);
+
+  // Create the debugger context.
+  HandleScope scope(isolate_);
+  ExtensionConfiguration no_extensions;
+  Handle<Context> context = isolate_->bootstrapper()->CreateEnvironment(
+      MaybeHandle<JSGlobalProxy>(), v8::Local<ObjectTemplate>(),
+      &no_extensions);
+
+  // Fail if no context could be created.
+  if (context.is_null()) return false;
+
+  // Use the debugger context.
+  SaveContext save(isolate_);
+  isolate_->set_context(*context);
+
+  // Expose the builtins object in the debugger context.
+  Handle<String> key = isolate_->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("builtins"));
+  Handle<GlobalObject> global =
+      Handle<GlobalObject>(context->global_object(), isolate_);
+  Handle<JSBuiltinsObject> builtin =
+      Handle<JSBuiltinsObject>(global->builtins(), isolate_);
+  RETURN_ON_EXCEPTION_VALUE(
+      isolate_, Object::SetProperty(global, key, builtin, SLOPPY), false);
+
+  // Compile the JavaScript for the debugger in the debugger context.
+  bool caught_exception =
+      !CompileDebuggerScript(isolate_, Natives::GetIndex("mirrors")) ||
+      !CompileDebuggerScript(isolate_, Natives::GetIndex("debug"));
+
+  if (FLAG_enable_liveedit) {
+    caught_exception = caught_exception ||
+        !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
+  }
+  // Check for caught exceptions.
+  if (caught_exception) return false;
+
+  debug_context_ = Handle<Context>::cast(
+      isolate_->global_handles()->Create(*context));
+  return true;
+}
+
+
+void Debug::Unload() {
+  ClearAllBreakPoints();
+  ClearStepping();
+
+  // Return debugger is not loaded.
+  if (!is_loaded()) return;
+
+  // Clear the script cache.
+  if (script_cache_ != NULL) {
+    delete script_cache_;
+    script_cache_ = NULL;
+  }
+
+  // Clear debugger context global handle.
+  GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
+  debug_context_ = Handle<Context>();
+}
+
+
+void Debug::Break(Arguments args, JavaScriptFrame* frame) {
+  Heap* heap = isolate_->heap();
+  HandleScope scope(isolate_);
+  DCHECK(args.length() == 0);
+
+  // Initialize LiveEdit.
+  LiveEdit::InitializeThreadLocal(this);
+
+  // Just continue if breaks are disabled or debugger cannot be loaded.
+  if (break_disabled()) return;
+
+  // Enter the debugger.
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // Postpone interrupt during breakpoint processing.
+  PostponeInterruptsScope postpone(isolate_);
+
+  // Get the debug info (create it if it does not exist).
+  Handle<SharedFunctionInfo> shared =
+      Handle<SharedFunctionInfo>(frame->function()->shared());
+  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
+
+  // Find the break point where execution has stopped.
+  // PC points to the instruction after the current one, possibly a break
+  // location as well. So the "- 1" to exclude it from the search.
+  Address call_pc = frame->pc() - 1;
+  BreakLocation break_location =
+      BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
+
+  // Check whether step next reached a new statement.
+  if (!StepNextContinue(&break_location, frame)) {
+    // Decrease steps left if performing multiple steps.
+    if (thread_local_.step_count_ > 0) {
+      thread_local_.step_count_--;
+    }
+  }
+
+  // If there is one or more real break points check whether any of these are
+  // triggered.
+  Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
+  if (break_location.HasBreakPoint()) {
+    Handle<Object> break_point_objects = break_location.BreakPointObjects();
+    break_points_hit = CheckBreakPoints(break_point_objects);
+  }
+
+  // If step out is active skip everything until the frame where we need to step
+  // out to is reached, unless real breakpoint is hit.
+  if (StepOutActive() &&
+      frame->fp() != thread_local_.step_out_fp_ &&
+      break_points_hit->IsUndefined() ) {
+      // Step count should always be 0 for StepOut.
+      DCHECK(thread_local_.step_count_ == 0);
+  } else if (!break_points_hit->IsUndefined() ||
+             (thread_local_.last_step_action_ != StepNone &&
+              thread_local_.step_count_ == 0)) {
+    // Notify debugger if a real break point is triggered or if performing
+    // single stepping with no more steps to perform. Otherwise do another step.
+
+    // Clear all current stepping setup.
+    ClearStepping();
+
+    if (thread_local_.queued_step_count_ > 0) {
+      // Perform queued steps
+      int step_count = thread_local_.queued_step_count_;
+
+      // Clear queue
+      thread_local_.queued_step_count_ = 0;
+
+      PrepareStep(StepNext, step_count, StackFrame::NO_ID);
+    } else {
+      // Notify the debug event listeners.
+      OnDebugBreak(break_points_hit, false);
+    }
+  } else if (thread_local_.last_step_action_ != StepNone) {
+    // Hold on to last step action as it is cleared by the call to
+    // ClearStepping.
+    StepAction step_action = thread_local_.last_step_action_;
+    int step_count = thread_local_.step_count_;
+
+    // If StepNext goes deeper in code, StepOut until original frame
+    // and keep step count queued up in the meantime.
+    if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
+      // Count frames until target frame
+      int count = 0;
+      JavaScriptFrameIterator it(isolate_);
+      while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) {
+        count++;
+        it.Advance();
+      }
+
+      // Check that we indeed found the frame we are looking for.
+      CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_));
+      if (step_count > 1) {
+        // Save old count and action to continue stepping after StepOut.
+        thread_local_.queued_step_count_ = step_count - 1;
+      }
+
+      // Set up for StepOut to reach target frame.
+      step_action = StepOut;
+      step_count = count;
+    }
+
+    // Clear all current stepping setup.
+    ClearStepping();
+
+    // Set up for the remaining steps.
+    PrepareStep(step_action, step_count, StackFrame::NO_ID);
+  }
+}
+
+
+// Check the break point objects for whether one or more are actually
+// triggered. This function returns a JSArray with the break point objects
+// which is triggered.
+Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
+  Factory* factory = isolate_->factory();
+
+  // Count the number of break points hit. If there are multiple break points
+  // they are in a FixedArray.
+  Handle<FixedArray> break_points_hit;
+  int break_points_hit_count = 0;
+  DCHECK(!break_point_objects->IsUndefined());
+  if (break_point_objects->IsFixedArray()) {
+    Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
+    break_points_hit = factory->NewFixedArray(array->length());
+    for (int i = 0; i < array->length(); i++) {
+      Handle<Object> o(array->get(i), isolate_);
+      if (CheckBreakPoint(o)) {
+        break_points_hit->set(break_points_hit_count++, *o);
+      }
+    }
+  } else {
+    break_points_hit = factory->NewFixedArray(1);
+    if (CheckBreakPoint(break_point_objects)) {
+      break_points_hit->set(break_points_hit_count++, *break_point_objects);
+    }
+  }
+
+  // Return undefined if no break points were triggered.
+  if (break_points_hit_count == 0) {
+    return factory->undefined_value();
+  }
+  // Return break points hit as a JSArray.
+  Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
+  result->set_length(Smi::FromInt(break_points_hit_count));
+  return result;
+}
+
+
+// Check whether a single break point object is triggered.
+bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
+  Factory* factory = isolate_->factory();
+  HandleScope scope(isolate_);
+
+  // Ignore check if break point object is not a JSObject.
+  if (!break_point_object->IsJSObject()) return true;
+
+  // Get the function IsBreakPointTriggered (defined in debug.js).
+  Handle<String> is_break_point_triggered_string =
+      factory->InternalizeOneByteString(
+          STATIC_CHAR_VECTOR("IsBreakPointTriggered"));
+  Handle<GlobalObject> debug_global(debug_context()->global_object());
+  Handle<JSFunction> check_break_point =
+    Handle<JSFunction>::cast(Object::GetProperty(
+        debug_global, is_break_point_triggered_string).ToHandleChecked());
+
+  // Get the break id as an object.
+  Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
+
+  // Call HandleBreakPointx.
+  Handle<Object> argv[] = { break_id, break_point_object };
+  Handle<Object> result;
+  if (!Execution::TryCall(check_break_point,
+                          isolate_->js_builtins_object(),
+                          arraysize(argv),
+                          argv).ToHandle(&result)) {
+    return false;
+  }
+
+  // Return whether the break point is triggered.
+  return result->IsTrue();
+}
+
+
+bool Debug::SetBreakPoint(Handle<JSFunction> function,
+                          Handle<Object> break_point_object,
+                          int* source_position) {
+  HandleScope scope(isolate_);
+
+  // Make sure the function is compiled and has set up the debug info.
+  Handle<SharedFunctionInfo> shared(function->shared());
+  if (!EnsureDebugInfo(shared, function)) {
+    // Return if retrieving debug info failed.
+    return true;
+  }
+
+  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
+  // Source positions starts with zero.
+  DCHECK(*source_position >= 0);
+
+  // Find the break point and change it.
+  BreakLocation location = BreakLocation::FromPosition(
+      debug_info, ALL_BREAK_LOCATIONS, *source_position, STATEMENT_ALIGNED);
+  *source_position = location.statement_position();
+  location.SetBreakPoint(break_point_object);
+
+  // At least one active break point now.
+  return debug_info->GetBreakPointCount() > 0;
+}
+
+
+bool Debug::SetBreakPointForScript(Handle<Script> script,
+                                   Handle<Object> break_point_object,
+                                   int* source_position,
+                                   BreakPositionAlignment alignment) {
+  HandleScope scope(isolate_);
+
+  // Obtain shared function info for the function.
+  Handle<Object> result =
+      FindSharedFunctionInfoInScript(script, *source_position);
+  if (result->IsUndefined()) return false;
+
+  // Make sure the function has set up the debug info.
+  Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
+  if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
+    // Return if retrieving debug info failed.
+    return false;
+  }
+
+  // Find position within function. The script position might be before the
+  // source position of the first function.
+  int position;
+  if (shared->start_position() > *source_position) {
+    position = 0;
+  } else {
+    position = *source_position - shared->start_position();
+  }
+
+  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
+  // Source positions starts with zero.
+  DCHECK(position >= 0);
+
+  // Find the break point and change it.
+  BreakLocation location = BreakLocation::FromPosition(
+      debug_info, ALL_BREAK_LOCATIONS, position, alignment);
+  location.SetBreakPoint(break_point_object);
+
+  position = (alignment == STATEMENT_ALIGNED) ? location.statement_position()
+                                              : location.position();
+
+  *source_position = position + shared->start_position();
+
+  // At least one active break point now.
+  DCHECK(debug_info->GetBreakPointCount() > 0);
+  return true;
+}
+
+
+void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
+  HandleScope scope(isolate_);
+
+  DebugInfoListNode* node = debug_info_list_;
+  while (node != NULL) {
+    Handle<Object> result =
+        DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object);
+    if (!result->IsUndefined()) {
+      // Get information in the break point.
+      Handle<BreakPointInfo> break_point_info =
+          Handle<BreakPointInfo>::cast(result);
+      Handle<DebugInfo> debug_info = node->debug_info();
+
+      // Find the break point and clear it.
+      Address pc = debug_info->code()->entry() +
+                   break_point_info->code_position()->value();
+
+      BreakLocation location =
+          BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, pc);
+      location.ClearBreakPoint(break_point_object);
+
+      // If there are no more break points left remove the debug info for this
+      // function.
+      if (debug_info->GetBreakPointCount() == 0) {
+        RemoveDebugInfoAndClearFromShared(debug_info);
+      }
+
+      return;
+    }
+    node = node->next();
+  }
+}
+
+
+// Clear out all the debug break code. This is ONLY supposed to be used when
+// shutting down the debugger as it will leave the break point information in
+// DebugInfo even though the code is patched back to the non break point state.
+void Debug::ClearAllBreakPoints() {
+  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
+       node = node->next()) {
+    for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
+         !it.Done(); it.Next()) {
+      it.GetBreakLocation().ClearDebugBreak();
+    }
+  }
+  // Remove all debug info.
+  while (debug_info_list_ != NULL) {
+    RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
+  }
+}
+
+
+void Debug::FloodWithOneShot(Handle<JSFunction> function,
+                             BreakLocatorType type) {
+  // Make sure the function is compiled and has set up the debug info.
+  Handle<SharedFunctionInfo> shared(function->shared());
+  if (!EnsureDebugInfo(shared, function)) {
+    // Return if we failed to retrieve the debug info.
+    return;
+  }
+
+  // Flood the function with break points.
+  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
+  for (BreakLocation::Iterator it(debug_info, type); !it.Done(); it.Next()) {
+    it.GetBreakLocation().SetOneShot();
+  }
+}
+
+
+void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) {
+  Handle<FixedArray> new_bindings(function->function_bindings());
+  Handle<Object> bindee(new_bindings->get(JSFunction::kBoundFunctionIndex),
+                        isolate_);
+
+  if (!bindee.is_null() && bindee->IsJSFunction()) {
+    Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
+    FloodWithOneShotGeneric(bindee_function);
+  }
+}
+
+
+void Debug::FloodDefaultConstructorWithOneShot(Handle<JSFunction> function) {
+  DCHECK(function->shared()->is_default_constructor());
+  // Instead of stepping into the function we directly step into the super class
+  // constructor.
+  Isolate* isolate = function->GetIsolate();
+  PrototypeIterator iter(isolate, function);
+  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+  if (!proto->IsJSFunction()) return;  // Object.prototype
+  Handle<JSFunction> function_proto = Handle<JSFunction>::cast(proto);
+  FloodWithOneShotGeneric(function_proto);
+}
+
+
+void Debug::FloodWithOneShotGeneric(Handle<JSFunction> function,
+                                    Handle<Object> holder) {
+  if (function->shared()->bound()) {
+    FloodBoundFunctionWithOneShot(function);
+  } else if (function->shared()->is_default_constructor()) {
+    FloodDefaultConstructorWithOneShot(function);
+  } else {
+    Isolate* isolate = function->GetIsolate();
+    // Don't allow step into functions in the native context.
+    if (function->shared()->code() ==
+            isolate->builtins()->builtin(Builtins::kFunctionApply) ||
+        function->shared()->code() ==
+            isolate->builtins()->builtin(Builtins::kFunctionCall)) {
+      // Handle function.apply and function.call separately to flood the
+      // function to be called and not the code for Builtins::FunctionApply or
+      // Builtins::FunctionCall. The receiver of call/apply is the target
+      // function.
+      if (!holder.is_null() && holder->IsJSFunction()) {
+        Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
+        FloodWithOneShotGeneric(js_function);
+      }
+    } else {
+      FloodWithOneShot(function);
+    }
+  }
+}
+
+
+void Debug::FloodHandlerWithOneShot() {
+  // Iterate through the JavaScript stack looking for handlers.
+  StackFrame::Id id = break_frame_id();
+  if (id == StackFrame::NO_ID) {
+    // If there is no JavaScript stack don't do anything.
+    return;
+  }
+  for (JavaScriptFrameIterator it(isolate_, id); !it.done(); it.Advance()) {
+    JavaScriptFrame* frame = it.frame();
+    int stack_slots = 0;  // The computed stack slot count is not used.
+    if (frame->LookupExceptionHandlerInTable(&stack_slots, NULL) > 0) {
+      // Flood the function with the catch/finally block with break points.
+      FloodWithOneShot(Handle<JSFunction>(frame->function()));
+      return;
+    }
+  }
+}
+
+
+void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
+  if (type == BreakUncaughtException) {
+    break_on_uncaught_exception_ = enable;
+  } else {
+    break_on_exception_ = enable;
+  }
+}
+
+
+bool Debug::IsBreakOnException(ExceptionBreakType type) {
+  if (type == BreakUncaughtException) {
+    return break_on_uncaught_exception_;
+  } else {
+    return break_on_exception_;
+  }
+}
+
+
+FrameSummary GetFirstFrameSummary(JavaScriptFrame* frame) {
+  List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
+  frame->Summarize(&frames);
+  return frames.first();
+}
+
+
+void Debug::PrepareStep(StepAction step_action,
+                        int step_count,
+                        StackFrame::Id frame_id) {
+  HandleScope scope(isolate_);
+
+  DCHECK(in_debug_scope());
+
+  // Remember this step action and count.
+  thread_local_.last_step_action_ = step_action;
+  if (step_action == StepOut) {
+    // For step out target frame will be found on the stack so there is no need
+    // to set step counter for it. It's expected to always be 0 for StepOut.
+    thread_local_.step_count_ = 0;
+  } else {
+    thread_local_.step_count_ = step_count;
+  }
+
+  // Get the frame where the execution has stopped and skip the debug frame if
+  // any. The debug frame will only be present if execution was stopped due to
+  // hitting a break point. In other situations (e.g. unhandled exception) the
+  // debug frame is not present.
+  StackFrame::Id id = break_frame_id();
+  if (id == StackFrame::NO_ID) {
+    // If there is no JavaScript stack don't do anything.
+    return;
+  }
+  if (frame_id != StackFrame::NO_ID) {
+    id = frame_id;
+  }
+  JavaScriptFrameIterator frames_it(isolate_, id);
+  JavaScriptFrame* frame = frames_it.frame();
+
+  // First of all ensure there is one-shot break points in the top handler
+  // if any.
+  FloodHandlerWithOneShot();
+
+  // If the function on the top frame is unresolved perform step out. This will
+  // be the case when calling unknown function and having the debugger stopped
+  // in an unhandled exception.
+  if (!frame->function()->IsJSFunction()) {
+    // Step out: Find the calling JavaScript frame and flood it with
+    // breakpoints.
+    frames_it.Advance();
+    // Fill the function to return to with one-shot break points.
+    JSFunction* function = frames_it.frame()->function();
+    FloodWithOneShot(Handle<JSFunction>(function));
+    return;
+  }
+
+  // Get the debug info (create it if it does not exist).
+  FrameSummary summary = GetFirstFrameSummary(frame);
+  Handle<JSFunction> function(summary.function());
+  Handle<SharedFunctionInfo> shared(function->shared());
+  if (!EnsureDebugInfo(shared, function)) {
+    // Return if ensuring debug info failed.
+    return;
+  }
+
+  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
+  // Refresh frame summary if the code has been recompiled for debugging.
+  if (shared->code() != *summary.code()) summary = GetFirstFrameSummary(frame);
+
+  // PC points to the instruction after the current one, possibly a break
+  // location as well. So the "- 1" to exclude it from the search.
+  Address call_pc = summary.pc() - 1;
+  BreakLocation location =
+      BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);
+
+  // If this is the last break code target step out is the only possibility.
+  if (location.IsReturn() || step_action == StepOut) {
+    if (step_action == StepOut) {
+      // Skip step_count frames starting with the current one.
+      while (step_count-- > 0 && !frames_it.done()) {
+        frames_it.Advance();
+      }
+    } else {
+      DCHECK(location.IsReturn());
+      frames_it.Advance();
+    }
+    // Skip native and extension functions on the stack.
+    while (!frames_it.done() &&
+           !frames_it.frame()->function()->IsSubjectToDebugging()) {
+      frames_it.Advance();
+    }
+    // Step out: If there is a JavaScript caller frame, we need to
+    // flood it with breakpoints.
+    if (!frames_it.done()) {
+      // Fill the function to return to with one-shot break points.
+      JSFunction* function = frames_it.frame()->function();
+      FloodWithOneShot(Handle<JSFunction>(function));
+      // Set target frame pointer.
+      ActivateStepOut(frames_it.frame());
+    }
+    return;
+  }
+
+  if (step_action != StepNext && step_action != StepMin) {
+    // If there's restarter frame on top of the stack, just get the pointer
+    // to function which is going to be restarted.
+    if (thread_local_.restarter_frame_function_pointer_ != NULL) {
+      Handle<JSFunction> restarted_function(
+          JSFunction::cast(*thread_local_.restarter_frame_function_pointer_));
+      FloodWithOneShot(restarted_function);
+    } else if (location.IsCall()) {
+      // Find target function on the expression stack.
+      // Expression stack looks like this (top to bottom):
+      // argN
+      // ...
+      // arg0
+      // Receiver
+      // Function to call
+      int num_expressions_without_args =
+          frame->ComputeExpressionsCount() - location.CallArgumentsCount();
+      DCHECK(num_expressions_without_args >= 2);
+      Object* fun = frame->GetExpression(num_expressions_without_args - 2);
+
+      // Flood the actual target of call/apply.
+      if (fun->IsJSFunction()) {
+        Isolate* isolate = JSFunction::cast(fun)->GetIsolate();
+        Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply);
+        Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall);
+        // Find target function on the expression stack for expression like
+        // Function.call.call...apply(...)
+        int i = 1;
+        while (fun->IsJSFunction()) {
+          Code* code = JSFunction::cast(fun)->shared()->code();
+          if (code != apply && code != call) break;
+          DCHECK(num_expressions_without_args >= i);
+          fun = frame->GetExpression(num_expressions_without_args - i);
+          i--;
+        }
+      }
+
+      if (fun->IsJSFunction()) {
+        Handle<JSFunction> js_function(JSFunction::cast(fun));
+        FloodWithOneShotGeneric(js_function);
+      }
+    }
+
+    ActivateStepIn(frame);
+  }
+
+  // Fill the current function with one-shot break points even for step in on
+  // a call target as the function called might be a native function for
+  // which step in will not stop. It also prepares for stepping in
+  // getters/setters.
+  // If we are stepping into another frame, only fill calls and returns.
+  FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS
+                                                      : ALL_BREAK_LOCATIONS);
+
+  // Remember source position and frame to handle step next.
+  thread_local_.last_statement_position_ =
+      debug_info->code()->SourceStatementPosition(summary.pc());
+  thread_local_.last_fp_ = frame->UnpaddedFP();
+}
+
+
+// Check whether the current debug break should be reported to the debugger. It
+// is used to have step next and step in only report break back to the debugger
+// if on a different frame or in a different statement. In some situations
+// there will be several break points in the same statement when the code is
+// flooded with one-shot break points. This function helps to perform several
+// steps before reporting break back to the debugger.
+bool Debug::StepNextContinue(BreakLocation* break_location,
+                             JavaScriptFrame* frame) {
+  // StepNext and StepOut shouldn't bring us deeper in code, so last frame
+  // shouldn't be a parent of current frame.
+  StepAction step_action = thread_local_.last_step_action_;
+
+  if (step_action == StepNext || step_action == StepOut) {
+    if (frame->fp() < thread_local_.last_fp_) return true;
+  }
+
+  // We stepped into a new frame if the frame pointer changed.
+  if (step_action == StepFrame) {
+    return frame->UnpaddedFP() == thread_local_.last_fp_;
+  }
+
+  // If the step last action was step next or step in make sure that a new
+  // statement is hit.
+  if (step_action == StepNext || step_action == StepIn) {
+    // Never continue if returning from function.
+    if (break_location->IsReturn()) return false;
+
+    // Continue if we are still on the same frame and in the same statement.
+    int current_statement_position =
+        break_location->code()->SourceStatementPosition(frame->pc());
+    return thread_local_.last_fp_ == frame->UnpaddedFP() &&
+        thread_local_.last_statement_position_ == current_statement_position;
+  }
+
+  // No step next action - don't continue.
+  return false;
+}
+
+
+// Check whether the code object at the specified address is a debug break code
+// object.
+bool Debug::IsDebugBreak(Address addr) {
+  Code* code = Code::GetCodeFromTargetAddress(addr);
+  return code->is_debug_stub();
+}
+
+
+// Simple function for returning the source positions for active break points.
+Handle<Object> Debug::GetSourceBreakLocations(
+    Handle<SharedFunctionInfo> shared,
+    BreakPositionAlignment position_alignment) {
+  Isolate* isolate = shared->GetIsolate();
+  Heap* heap = isolate->heap();
+  if (!shared->HasDebugInfo()) {
+    return Handle<Object>(heap->undefined_value(), isolate);
+  }
+  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
+  if (debug_info->GetBreakPointCount() == 0) {
+    return Handle<Object>(heap->undefined_value(), isolate);
+  }
+  Handle<FixedArray> locations =
+      isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
+  int count = 0;
+  for (int i = 0; i < debug_info->break_points()->length(); ++i) {
+    if (!debug_info->break_points()->get(i)->IsUndefined()) {
+      BreakPointInfo* break_point_info =
+          BreakPointInfo::cast(debug_info->break_points()->get(i));
+      int break_points = break_point_info->GetBreakPointCount();
+      if (break_points == 0) continue;
+      Smi* position = NULL;
+      switch (position_alignment) {
+        case STATEMENT_ALIGNED:
+          position = break_point_info->statement_position();
+          break;
+        case BREAK_POSITION_ALIGNED:
+          position = break_point_info->source_position();
+          break;
+      }
+      for (int j = 0; j < break_points; ++j) locations->set(count++, position);
+    }
+  }
+  return locations;
+}
+
+
+// Handle stepping into a function.
+void Debug::HandleStepIn(Handle<Object> function_obj, bool is_constructor) {
+  // Flood getter/setter if we either step in or step to another frame.
+  bool step_frame = thread_local_.last_step_action_ == StepFrame;
+  if (!StepInActive() && !step_frame) return;
+  if (!function_obj->IsJSFunction()) return;
+  Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj);
+  Isolate* isolate = function->GetIsolate();
+
+  StackFrameIterator it(isolate);
+  it.Advance();
+  // For constructor functions skip another frame.
+  if (is_constructor) {
+    DCHECK(it.frame()->is_construct());
+    it.Advance();
+  }
+  Address fp = it.frame()->fp();
+
+  // Flood the function with one-shot break points if it is called from where
+  // step into was requested, or when stepping into a new frame.
+  if (fp == thread_local_.step_into_fp_ || step_frame) {
+    FloodWithOneShotGeneric(function, Handle<Object>());
+  }
+}
+
+
+void Debug::ClearStepping() {
+  // Clear the various stepping setup.
+  ClearOneShot();
+  ClearStepIn();
+  ClearStepOut();
+  ClearStepNext();
+
+  // Clear multiple step counter.
+  thread_local_.step_count_ = 0;
+}
+
+
+// Clears all the one-shot break points that are currently set. Normally this
+// function is called each time a break point is hit as one shot break points
+// are used to support stepping.
+void Debug::ClearOneShot() {
+  // The current implementation just runs through all the breakpoints. When the
+  // last break point for a function is removed that function is automatically
+  // removed from the list.
+  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
+       node = node->next()) {
+    for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
+         !it.Done(); it.Next()) {
+      it.GetBreakLocation().ClearOneShot();
+    }
+  }
+}
+
+
+void Debug::ActivateStepIn(StackFrame* frame) {
+  DCHECK(!StepOutActive());
+  thread_local_.step_into_fp_ = frame->UnpaddedFP();
+}
+
+
+void Debug::ClearStepIn() {
+  thread_local_.step_into_fp_ = 0;
+}
+
+
+void Debug::ActivateStepOut(StackFrame* frame) {
+  DCHECK(!StepInActive());
+  thread_local_.step_out_fp_ = frame->UnpaddedFP();
+}
+
+
+void Debug::ClearStepOut() {
+  thread_local_.step_out_fp_ = 0;
+}
+
+
+void Debug::ClearStepNext() {
+  thread_local_.last_step_action_ = StepNone;
+  thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
+  thread_local_.last_fp_ = 0;
+}
+
+
+bool MatchingCodeTargets(Code* target1, Code* target2) {
+  if (target1 == target2) return true;
+  if (target1->kind() != target2->kind()) return false;
+  return target1->is_handler() || target1->is_inline_cache_stub();
+}
+
+
+// Count the number of calls before the current frame PC to find the
+// corresponding PC in the newly recompiled code.
+static Address ComputeNewPcForRedirect(Code* new_code, Code* old_code,
+                                       Address old_pc) {
+  DCHECK_EQ(old_code->kind(), Code::FUNCTION);
+  DCHECK_EQ(new_code->kind(), Code::FUNCTION);
+  DCHECK(new_code->has_debug_break_slots());
+  static const int mask = RelocInfo::kCodeTargetMask;
+
+  // Find the target of the current call.
+  Code* target = NULL;
+  intptr_t delta = 0;
+  for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
+    RelocInfo* rinfo = it.rinfo();
+    Address current_pc = rinfo->pc();
+    // The frame PC is behind the call instruction by the call instruction size.
+    if (current_pc > old_pc) break;
+    delta = old_pc - current_pc;
+    target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+  }
+
+  // Count the number of calls to the same target before the current call.
+  int index = 0;
+  for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
+    RelocInfo* rinfo = it.rinfo();
+    Address current_pc = rinfo->pc();
+    if (current_pc > old_pc) break;
+    Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
+    if (MatchingCodeTargets(target, current)) index++;
+  }
+
+  DCHECK(index > 0);
+
+  // Repeat the count on the new code to find corresponding call.
+  for (RelocIterator it(new_code, mask); !it.done(); it.next()) {
+    RelocInfo* rinfo = it.rinfo();
+    Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
+    if (MatchingCodeTargets(target, current)) index--;
+    if (index == 0) return rinfo->pc() + delta;
+  }
+
+  UNREACHABLE();
+  return NULL;
+}
+
+
+// Count the number of continuations at which the current pc offset is at.
+static int ComputeContinuationIndexFromPcOffset(Code* code, int pc_offset) {
+  DCHECK_EQ(code->kind(), Code::FUNCTION);
+  Address pc = code->instruction_start() + pc_offset;
+  int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
+  int index = 0;
+  for (RelocIterator it(code, mask); !it.done(); it.next()) {
+    index++;
+    RelocInfo* rinfo = it.rinfo();
+    Address current_pc = rinfo->pc();
+    if (current_pc == pc) break;
+    DCHECK(current_pc < pc);
+  }
+  return index;
+}
+
+
+// Find the pc offset for the given continuation index.
+static int ComputePcOffsetFromContinuationIndex(Code* code, int index) {
+  DCHECK_EQ(code->kind(), Code::FUNCTION);
+  DCHECK(code->has_debug_break_slots());
+  int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
+  RelocIterator it(code, mask);
+  for (int i = 1; i < index; i++) it.next();
+  return static_cast<int>(it.rinfo()->pc() - code->instruction_start());
+}
+
+
+class RedirectActiveFunctions : public ThreadVisitor {
+ public:
+  explicit RedirectActiveFunctions(SharedFunctionInfo* shared)
+      : shared_(shared) {
+    DCHECK(shared->HasDebugCode());
+  }
+
+  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
+    for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
+      JavaScriptFrame* frame = it.frame();
+      JSFunction* function = frame->function();
+      if (frame->is_optimized()) continue;
+      if (!function->Inlines(shared_)) continue;
+
+      Code* frame_code = frame->LookupCode();
+      DCHECK(frame_code->kind() == Code::FUNCTION);
+      if (frame_code->has_debug_break_slots()) continue;
+
+      Code* new_code = function->shared()->code();
+      Address old_pc = frame->pc();
+      Address new_pc = ComputeNewPcForRedirect(new_code, frame_code, old_pc);
+
+      if (FLAG_trace_deopt) {
+        PrintF("Replacing pc for debugging: %08" V8PRIxPTR " => %08" V8PRIxPTR
+               "\n",
+               reinterpret_cast<intptr_t>(old_pc),
+               reinterpret_cast<intptr_t>(new_pc));
+      }
+
+      if (FLAG_enable_embedded_constant_pool) {
+        // Update constant pool pointer for new code.
+        frame->set_constant_pool(new_code->constant_pool());
+      }
+
+      // Patch the return address to return into the code with
+      // debug break slots.
+      frame->set_pc(new_pc);
+    }
+  }
+
+ private:
+  SharedFunctionInfo* shared_;
+  DisallowHeapAllocation no_gc_;
+};
+
+
+bool Debug::PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared) {
+  DCHECK(shared->is_compiled());
+
+  if (isolate_->concurrent_recompilation_enabled()) {
+    isolate_->optimizing_compile_dispatcher()->Flush();
+  }
+
+  List<Handle<JSFunction> > functions;
+  List<Handle<JSGeneratorObject> > suspended_generators;
+
+  if (!shared->optimized_code_map()->IsSmi()) {
+    shared->ClearOptimizedCodeMap();
+  }
+
+  // Make sure we abort incremental marking.
+  isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
+                                      "prepare for break points");
+
+  {
+    HeapIterator iterator(isolate_->heap());
+    HeapObject* obj;
+    bool include_generators = shared->is_generator();
+
+    while ((obj = iterator.next())) {
+      if (obj->IsJSFunction()) {
+        JSFunction* function = JSFunction::cast(obj);
+        if (!function->Inlines(*shared)) continue;
+        if (function->code()->kind() == Code::OPTIMIZED_FUNCTION) {
+          Deoptimizer::DeoptimizeFunction(function);
+        }
+        if (function->shared() == *shared) functions.Add(handle(function));
+      } else if (include_generators && obj->IsJSGeneratorObject()) {
+        JSGeneratorObject* generator_obj = JSGeneratorObject::cast(obj);
+        if (!generator_obj->is_suspended()) continue;
+        JSFunction* function = generator_obj->function();
+        if (!function->Inlines(*shared)) continue;
+        int pc_offset = generator_obj->continuation();
+        int index =
+            ComputeContinuationIndexFromPcOffset(function->code(), pc_offset);
+        generator_obj->set_continuation(index);
+        suspended_generators.Add(handle(generator_obj));
+      }
+    }
+  }
+
+  if (!shared->HasDebugCode()) {
+    DCHECK(functions.length() > 0);
+    if (!Compiler::CompileDebugCode(functions.first())) return false;
+  }
+
+  for (Handle<JSFunction> const function : functions) {
+    function->ReplaceCode(shared->code());
+  }
+
+  for (Handle<JSGeneratorObject> const generator_obj : suspended_generators) {
+    int index = generator_obj->continuation();
+    int pc_offset = ComputePcOffsetFromContinuationIndex(shared->code(), index);
+    generator_obj->set_continuation(pc_offset);
+  }
+
+  // Update PCs on the stack to point to recompiled code.
+  RedirectActiveFunctions redirect_visitor(*shared);
+  redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top());
+  isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor);
+
+  return true;
+}
+
+
+class SharedFunctionInfoFinder {
+ public:
+  explicit SharedFunctionInfoFinder(int target_position)
+      : current_candidate_(NULL),
+        current_candidate_closure_(NULL),
+        current_start_position_(RelocInfo::kNoPosition),
+        target_position_(target_position) {}
+
+  void NewCandidate(SharedFunctionInfo* shared, JSFunction* closure = NULL) {
+    int start_position = shared->function_token_position();
+    if (start_position == RelocInfo::kNoPosition) {
+      start_position = shared->start_position();
+    }
+
+    if (start_position > target_position_) return;
+    if (target_position_ > shared->end_position()) return;
+
+    if (current_candidate_ != NULL) {
+      if (current_start_position_ == start_position &&
+          shared->end_position() == current_candidate_->end_position()) {
+        // If a top-level function contains only one function
+        // declaration the source for the top-level and the function
+        // is the same. In that case prefer the non top-level function.
+        if (shared->is_toplevel()) return;
+      } else if (start_position < current_start_position_ ||
+                 current_candidate_->end_position() < shared->end_position()) {
+        return;
+      }
+    }
+
+    current_start_position_ = start_position;
+    current_candidate_ = shared;
+    current_candidate_closure_ = closure;
+  }
+
+  SharedFunctionInfo* Result() { return current_candidate_; }
+
+  JSFunction* ResultClosure() { return current_candidate_closure_; }
+
+ private:
+  SharedFunctionInfo* current_candidate_;
+  JSFunction* current_candidate_closure_;
+  int current_start_position_;
+  int target_position_;
+  DisallowHeapAllocation no_gc_;
+};
+
+
+// We need to find a SFI for a literal that may not yet have been compiled yet,
+// and there may not be a JSFunction referencing it. Find the SFI closest to
+// the given position, compile it to reveal possible inner SFIs and repeat.
+// While we are at this, also ensure code with debug break slots so that we do
+// not have to compile a SFI without JSFunction, which is paifu for those that
+// cannot be compiled without context (need to find outer compilable SFI etc.)
+Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
+                                                     int position) {
+  while (true) {
+    // Go through all shared function infos associated with this script to
+    // find the inner most function containing this position.
+    if (!script->shared_function_infos()->IsWeakFixedArray()) break;
+    WeakFixedArray* array =
+        WeakFixedArray::cast(script->shared_function_infos());
+
+    SharedFunctionInfo* shared;
+    {
+      SharedFunctionInfoFinder finder(position);
+      for (int i = 0; i < array->Length(); i++) {
+        Object* item = array->Get(i);
+        if (!item->IsSharedFunctionInfo()) continue;
+        finder.NewCandidate(SharedFunctionInfo::cast(item));
+      }
+      shared = finder.Result();
+      if (shared == NULL) break;
+      // We found it if it's already compiled and has debug code.
+      if (shared->HasDebugCode()) return handle(shared);
+    }
+    // If not, compile to reveal inner functions, if possible.
+    if (shared->allows_lazy_compilation_without_context()) {
+      HandleScope scope(isolate_);
+      if (!Compiler::CompileDebugCode(handle(shared))) break;
+      continue;
+    }
+
+    // If not possible, comb the heap for the best suitable compile target.
+    JSFunction* closure;
+    {
+      HeapIterator it(isolate_->heap());
+      SharedFunctionInfoFinder finder(position);
+      while (HeapObject* object = it.next()) {
+        JSFunction* candidate_closure = NULL;
+        SharedFunctionInfo* candidate = NULL;
+        if (object->IsJSFunction()) {
+          candidate_closure = JSFunction::cast(object);
+          candidate = candidate_closure->shared();
+        } else if (object->IsSharedFunctionInfo()) {
+          candidate = SharedFunctionInfo::cast(object);
+          if (!candidate->allows_lazy_compilation_without_context()) continue;
+        } else {
+          continue;
+        }
+        if (candidate->script() == *script) {
+          finder.NewCandidate(candidate, candidate_closure);
+        }
+      }
+      closure = finder.ResultClosure();
+      shared = finder.Result();
+    }
+    HandleScope scope(isolate_);
+    if (closure == NULL) {
+      if (!Compiler::CompileDebugCode(handle(shared))) break;
+    } else {
+      if (!Compiler::CompileDebugCode(handle(closure))) break;
+    }
+  }
+  return isolate_->factory()->undefined_value();
+}
+
+
+// Ensures the debug information is present for shared.
+bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
+                            Handle<JSFunction> function) {
+  if (!shared->IsSubjectToDebugging()) return false;
+
+  // Return if we already have the debug info for shared.
+  if (shared->HasDebugInfo()) return true;
+
+  if (function.is_null()) {
+    DCHECK(shared->HasDebugCode());
+  } else if (!Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) {
+    return false;
+  }
+
+  if (!PrepareFunctionForBreakPoints(shared)) return false;
+
+  // Make sure IC state is clean. This is so that we correctly flood
+  // accessor pairs when stepping in.
+  shared->code()->ClearInlineCaches();
+  shared->feedback_vector()->ClearICSlots(*shared);
+
+  // Create the debug info object.
+  DCHECK(shared->HasDebugCode());
+  Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared);
+
+  // Add debug info to the list.
+  DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
+  node->set_next(debug_info_list_);
+  debug_info_list_ = node;
+
+  return true;
+}
+
+
+void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
+  HandleScope scope(isolate_);
+  Handle<SharedFunctionInfo> shared(debug_info->shared());
+
+  DCHECK_NOT_NULL(debug_info_list_);
+  // Run through the debug info objects to find this one and remove it.
+  DebugInfoListNode* prev = NULL;
+  DebugInfoListNode* current = debug_info_list_;
+  while (current != NULL) {
+    if (current->debug_info().is_identical_to(debug_info)) {
+      // Unlink from list. If prev is NULL we are looking at the first element.
+      if (prev == NULL) {
+        debug_info_list_ = current->next();
+      } else {
+        prev->set_next(current->next());
+      }
+      delete current;
+      shared->set_debug_info(isolate_->heap()->undefined_value());
+      return;
+    }
+    // Move to next in list.
+    prev = current;
+    current = current->next();
+  }
+
+  UNREACHABLE();
+}
+
+
+void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
+  after_break_target_ = NULL;
+
+  if (LiveEdit::SetAfterBreakTarget(this)) return;  // LiveEdit did the job.
+
+  // Continue just after the slot.
+  after_break_target_ = frame->pc();
+}
+
+
+bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
+  HandleScope scope(isolate_);
+
+  // Get the executing function in which the debug break occurred.
+  Handle<JSFunction> function(JSFunction::cast(frame->function()));
+  Handle<SharedFunctionInfo> shared(function->shared());
+
+  // With no debug info there are no break points, so we can't be at a return.
+  if (!shared->HasDebugInfo()) return false;
+  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
+  Handle<Code> code(debug_info->code());
+#ifdef DEBUG
+  // Get the code which is actually executing.
+  Handle<Code> frame_code(frame->LookupCode());
+  DCHECK(frame_code.is_identical_to(code));
+#endif
+
+  // Find the reloc info matching the start of the debug break slot.
+  Address slot_pc = frame->pc() - Assembler::kDebugBreakSlotLength;
+  int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
+  for (RelocIterator it(*code, mask); !it.done(); it.next()) {
+    if (it.rinfo()->pc() == slot_pc) return true;
+  }
+  return false;
+}
+
+
+void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
+                                  LiveEdit::FrameDropMode mode,
+                                  Object** restarter_frame_function_pointer) {
+  if (mode != LiveEdit::CURRENTLY_SET_MODE) {
+    thread_local_.frame_drop_mode_ = mode;
+  }
+  thread_local_.break_frame_id_ = new_break_frame_id;
+  thread_local_.restarter_frame_function_pointer_ =
+      restarter_frame_function_pointer;
+}
+
+
+bool Debug::IsDebugGlobal(GlobalObject* global) {
+  return is_loaded() && global == debug_context()->global_object();
+}
+
+
+void Debug::ClearMirrorCache() {
+  PostponeInterruptsScope postpone(isolate_);
+  HandleScope scope(isolate_);
+  AssertDebugContext();
+  Factory* factory = isolate_->factory();
+  Handle<GlobalObject> global(isolate_->global_object());
+  JSObject::SetProperty(global,
+                        factory->NewStringFromAsciiChecked("next_handle_"),
+                        handle(Smi::FromInt(0), isolate_), SLOPPY).Check();
+  JSObject::SetProperty(global,
+                        factory->NewStringFromAsciiChecked("mirror_cache_"),
+                        factory->NewJSArray(0, FAST_ELEMENTS), SLOPPY).Check();
+}
+
+
+Handle<FixedArray> Debug::GetLoadedScripts() {
+  // Create and fill the script cache when the loaded scripts is requested for
+  // the first time.
+  if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
+
+  // Perform GC to get unreferenced scripts evicted from the cache before
+  // returning the content.
+  isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
+                                      "Debug::GetLoadedScripts");
+
+  // Get the scripts from the cache.
+  return script_cache_->GetScripts();
+}
+
+
+void Debug::GetStepinPositions(JavaScriptFrame* frame, StackFrame::Id frame_id,
+                               List<int>* results_out) {
+  FrameSummary summary = GetFirstFrameSummary(frame);
+
+  Handle<JSFunction> fun = Handle<JSFunction>(summary.function());
+  Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared());
+
+  if (!EnsureDebugInfo(shared, fun)) return;
+
+  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
+  // Refresh frame summary if the code has been recompiled for debugging.
+  if (shared->code() != *summary.code()) summary = GetFirstFrameSummary(frame);
+
+  // Find range of break points starting from the break point where execution
+  // has stopped.
+  Address call_pc = summary.pc() - 1;
+  List<BreakLocation> locations;
+  BreakLocation::FromAddressSameStatement(debug_info, ALL_BREAK_LOCATIONS,
+                                          call_pc, &locations);
+
+  for (BreakLocation location : locations) {
+    if (location.pc() <= summary.pc()) {
+      // The break point is near our pc. Could be a step-in possibility,
+      // that is currently taken by active debugger call.
+      if (break_frame_id() == StackFrame::NO_ID) {
+        continue;  // We are not stepping.
+      } else {
+        JavaScriptFrameIterator frame_it(isolate_, break_frame_id());
+        // If our frame is a top frame and we are stepping, we can do step-in
+        // at this place.
+        if (frame_it.frame()->id() != frame_id) continue;
+      }
+    }
+    if (location.IsStepInLocation()) results_out->Add(location.position());
+  }
+}
+
+
+void Debug::RecordEvalCaller(Handle<Script> script) {
+  script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
+  // For eval scripts add information on the function from which eval was
+  // called.
+  StackTraceFrameIterator it(script->GetIsolate());
+  if (!it.done()) {
+    script->set_eval_from_shared(it.frame()->function()->shared());
+    Code* code = it.frame()->LookupCode();
+    int offset = static_cast<int>(
+        it.frame()->pc() - code->instruction_start());
+    script->set_eval_from_instructions_offset(Smi::FromInt(offset));
+  }
+}
+
+
+MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
+                                        int argc,
+                                        Handle<Object> argv[]) {
+  AssertDebugContext();
+  // Create the execution state object.
+  Handle<GlobalObject> global(isolate_->global_object());
+  Handle<Object> constructor = Object::GetProperty(
+      isolate_, global, constructor_name).ToHandleChecked();
+  DCHECK(constructor->IsJSFunction());
+  if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
+  // We do not handle interrupts here.  In particular, termination interrupts.
+  PostponeInterruptsScope no_interrupts(isolate_);
+  return Execution::TryCall(Handle<JSFunction>::cast(constructor),
+                            handle(debug_context()->global_proxy()),
+                            argc,
+                            argv);
+}
+
+
+MaybeHandle<Object> Debug::MakeExecutionState() {
+  // Create the execution state object.
+  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
+  return MakeJSObject("MakeExecutionState", arraysize(argv), argv);
+}
+
+
+MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
+  // Create the new break event object.
+  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
+                            break_points_hit };
+  return MakeJSObject("MakeBreakEvent", arraysize(argv), argv);
+}
+
+
+MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
+                                              bool uncaught,
+                                              Handle<Object> promise) {
+  // Create the new exception event object.
+  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
+                            exception,
+                            isolate_->factory()->ToBoolean(uncaught),
+                            promise };
+  return MakeJSObject("MakeExceptionEvent", arraysize(argv), argv);
+}
+
+
+MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
+                                            v8::DebugEvent type) {
+  // Create the compile event object.
+  Handle<Object> script_wrapper = Script::GetWrapper(script);
+  Handle<Object> argv[] = { script_wrapper,
+                            isolate_->factory()->NewNumberFromInt(type) };
+  return MakeJSObject("MakeCompileEvent", arraysize(argv), argv);
+}
+
+
+MaybeHandle<Object> Debug::MakePromiseEvent(Handle<JSObject> event_data) {
+  // Create the promise event object.
+  Handle<Object> argv[] = { event_data };
+  return MakeJSObject("MakePromiseEvent", arraysize(argv), argv);
+}
+
+
+MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
+  // Create the async task event object.
+  Handle<Object> argv[] = { task_event };
+  return MakeJSObject("MakeAsyncTaskEvent", arraysize(argv), argv);
+}
+
+
+void Debug::OnThrow(Handle<Object> exception) {
+  if (in_debug_scope() || ignore_events()) return;
+  // Temporarily clear any scheduled_exception to allow evaluating
+  // JavaScript from the debug event handler.
+  HandleScope scope(isolate_);
+  Handle<Object> scheduled_exception;
+  if (isolate_->has_scheduled_exception()) {
+    scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
+    isolate_->clear_scheduled_exception();
+  }
+  OnException(exception, isolate_->GetPromiseOnStackOnThrow());
+  if (!scheduled_exception.is_null()) {
+    isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
+  }
+}
+
+
+void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) {
+  if (in_debug_scope() || ignore_events()) return;
+  HandleScope scope(isolate_);
+  // Check whether the promise has been marked as having triggered a message.
+  Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
+  if (JSReceiver::GetDataProperty(promise, key)->IsUndefined()) {
+    OnException(value, promise);
+  }
+}
+
+
+MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler(
+    Handle<JSObject> promise) {
+  Handle<JSFunction> fun = Handle<JSFunction>::cast(
+      JSReceiver::GetDataProperty(isolate_->js_builtins_object(),
+                                  isolate_->factory()->NewStringFromStaticChars(
+                                      "$promiseHasUserDefinedRejectHandler")));
+  return Execution::Call(isolate_, fun, promise, 0, NULL);
+}
+
+
+void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
+  // In our prediction, try-finally is not considered to catch.
+  Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher();
+  bool uncaught = (catch_type == Isolate::NOT_CAUGHT);
+  if (promise->IsJSObject()) {
+    Handle<JSObject> jspromise = Handle<JSObject>::cast(promise);
+    // Mark the promise as already having triggered a message.
+    Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
+    JSObject::SetProperty(jspromise, key, key, STRICT).Assert();
+    // Check whether the promise reject is considered an uncaught exception.
+    Handle<Object> has_reject_handler;
+    ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+        isolate_, has_reject_handler,
+        PromiseHasUserDefinedRejectHandler(jspromise), /* void */);
+    uncaught = has_reject_handler->IsFalse();
+  }
+  // Bail out if exception breaks are not active
+  if (uncaught) {
+    // Uncaught exceptions are reported by either flags.
+    if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
+  } else {
+    // Caught exceptions are reported is activated.
+    if (!break_on_exception_) return;
+  }
+
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // Clear all current stepping setup.
+  ClearStepping();
+
+  // Create the event data object.
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakeExceptionEvent(
+          exception, uncaught, promise).ToHandle(&event_data)) {
+    return;
+  }
+
+  // Process debug event.
+  ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
+  // Return to continue execution from where the exception was thrown.
+}
+
+
+void Debug::OnCompileError(Handle<Script> script) {
+  if (ignore_events()) return;
+
+  if (in_debug_scope()) {
+    ProcessCompileEventInDebugScope(v8::CompileError, script);
+    return;
+  }
+
+  HandleScope scope(isolate_);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // Create the compile state object.
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakeCompileEvent(script, v8::CompileError).ToHandle(&event_data)) return;
+
+  // Process debug event.
+  ProcessDebugEvent(v8::CompileError, Handle<JSObject>::cast(event_data), true);
+}
+
+
+void Debug::OnDebugBreak(Handle<Object> break_points_hit,
+                            bool auto_continue) {
+  // The caller provided for DebugScope.
+  AssertDebugContext();
+  // Bail out if there is no listener for this event
+  if (ignore_events()) return;
+
+  HandleScope scope(isolate_);
+  // Create the event data object.
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
+
+  // Process debug event.
+  ProcessDebugEvent(v8::Break,
+                    Handle<JSObject>::cast(event_data),
+                    auto_continue);
+}
+
+
+void Debug::OnBeforeCompile(Handle<Script> script) {
+  if (in_debug_scope() || ignore_events()) return;
+
+  HandleScope scope(isolate_);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // Create the event data object.
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakeCompileEvent(script, v8::BeforeCompile).ToHandle(&event_data))
+    return;
+
+  // Process debug event.
+  ProcessDebugEvent(v8::BeforeCompile,
+                    Handle<JSObject>::cast(event_data),
+                    true);
+}
+
+
+// Handle debugger actions when a new script is compiled.
+void Debug::OnAfterCompile(Handle<Script> script) {
+  // Add the newly compiled script to the script cache.
+  if (script_cache_ != NULL) script_cache_->Add(script);
+
+  if (ignore_events()) return;
+
+  if (in_debug_scope()) {
+    ProcessCompileEventInDebugScope(v8::AfterCompile, script);
+    return;
+  }
+
+  HandleScope scope(isolate_);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // If debugging there might be script break points registered for this
+  // script. Make sure that these break points are set.
+
+  // Get the function UpdateScriptBreakPoints (defined in debug.js).
+  Handle<String> update_script_break_points_string =
+      isolate_->factory()->InternalizeOneByteString(
+          STATIC_CHAR_VECTOR("UpdateScriptBreakPoints"));
+  Handle<GlobalObject> debug_global(debug_context()->global_object());
+  Handle<Object> update_script_break_points =
+      Object::GetProperty(
+          debug_global, update_script_break_points_string).ToHandleChecked();
+  if (!update_script_break_points->IsJSFunction()) {
+    return;
+  }
+  DCHECK(update_script_break_points->IsJSFunction());
+
+  // Wrap the script object in a proper JS object before passing it
+  // to JavaScript.
+  Handle<Object> wrapper = Script::GetWrapper(script);
+
+  // Call UpdateScriptBreakPoints expect no exceptions.
+  Handle<Object> argv[] = { wrapper };
+  if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
+                         isolate_->js_builtins_object(),
+                         arraysize(argv),
+                         argv).is_null()) {
+    return;
+  }
+
+  // Create the compile state object.
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakeCompileEvent(script, v8::AfterCompile).ToHandle(&event_data)) return;
+
+  // Process debug event.
+  ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
+}
+
+
+void Debug::OnPromiseEvent(Handle<JSObject> data) {
+  if (in_debug_scope() || ignore_events()) return;
+
+  HandleScope scope(isolate_);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // Create the script collected state object.
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakePromiseEvent(data).ToHandle(&event_data)) return;
+
+  // Process debug event.
+  ProcessDebugEvent(v8::PromiseEvent,
+                    Handle<JSObject>::cast(event_data),
+                    true);
+}
+
+
+void Debug::OnAsyncTaskEvent(Handle<JSObject> data) {
+  if (in_debug_scope() || ignore_events()) return;
+
+  HandleScope scope(isolate_);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // Create the script collected state object.
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakeAsyncTaskEvent(data).ToHandle(&event_data)) return;
+
+  // Process debug event.
+  ProcessDebugEvent(v8::AsyncTaskEvent,
+                    Handle<JSObject>::cast(event_data),
+                    true);
+}
+
+
+void Debug::ProcessDebugEvent(v8::DebugEvent event,
+                              Handle<JSObject> event_data,
+                              bool auto_continue) {
+  HandleScope scope(isolate_);
+
+  // Create the execution state.
+  Handle<Object> exec_state;
+  // Bail out and don't call debugger if exception.
+  if (!MakeExecutionState().ToHandle(&exec_state)) return;
+
+  // First notify the message handler if any.
+  if (message_handler_ != NULL) {
+    NotifyMessageHandler(event,
+                         Handle<JSObject>::cast(exec_state),
+                         event_data,
+                         auto_continue);
+  }
+  // Notify registered debug event listener. This can be either a C or
+  // a JavaScript function. Don't call event listener for v8::Break
+  // here, if it's only a debug command -- they will be processed later.
+  if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
+    CallEventCallback(event, exec_state, event_data, NULL);
+  }
+}
+
+
+void Debug::CallEventCallback(v8::DebugEvent event,
+                              Handle<Object> exec_state,
+                              Handle<Object> event_data,
+                              v8::Debug::ClientData* client_data) {
+  bool previous = in_debug_event_listener_;
+  in_debug_event_listener_ = true;
+  if (event_listener_->IsForeign()) {
+    // Invoke the C debug event listener.
+    v8::Debug::EventCallback callback =
+        FUNCTION_CAST<v8::Debug::EventCallback>(
+            Handle<Foreign>::cast(event_listener_)->foreign_address());
+    EventDetailsImpl event_details(event,
+                                   Handle<JSObject>::cast(exec_state),
+                                   Handle<JSObject>::cast(event_data),
+                                   event_listener_data_,
+                                   client_data);
+    callback(event_details);
+    DCHECK(!isolate_->has_scheduled_exception());
+  } else {
+    // Invoke the JavaScript debug event listener.
+    DCHECK(event_listener_->IsJSFunction());
+    Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
+                              exec_state,
+                              event_data,
+                              event_listener_data_ };
+    Handle<JSReceiver> global(isolate_->global_proxy());
+    Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
+                       global, arraysize(argv), argv);
+  }
+  in_debug_event_listener_ = previous;
+}
+
+
+void Debug::ProcessCompileEventInDebugScope(v8::DebugEvent event,
+                                            Handle<Script> script) {
+  if (event_listener_.is_null()) return;
+
+  SuppressDebug while_processing(this);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakeCompileEvent(script, event).ToHandle(&event_data)) return;
+
+  // Create the execution state.
+  Handle<Object> exec_state;
+  // Bail out and don't call debugger if exception.
+  if (!MakeExecutionState().ToHandle(&exec_state)) return;
+
+  CallEventCallback(event, exec_state, event_data, NULL);
+}
+
+
+Handle<Context> Debug::GetDebugContext() {
+  if (!is_loaded()) return Handle<Context>();
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return Handle<Context>();
+  // The global handle may be destroyed soon after.  Return it reboxed.
+  return handle(*debug_context(), isolate_);
+}
+
+
+void Debug::NotifyMessageHandler(v8::DebugEvent event,
+                                 Handle<JSObject> exec_state,
+                                 Handle<JSObject> event_data,
+                                 bool auto_continue) {
+  // Prevent other interrupts from triggering, for example API callbacks,
+  // while dispatching message handler callbacks.
+  PostponeInterruptsScope no_interrupts(isolate_);
+  DCHECK(is_active_);
+  HandleScope scope(isolate_);
+  // Process the individual events.
+  bool sendEventMessage = false;
+  switch (event) {
+    case v8::Break:
+      sendEventMessage = !auto_continue;
+      break;
+    case v8::NewFunction:
+    case v8::BeforeCompile:
+    case v8::CompileError:
+    case v8::PromiseEvent:
+    case v8::AsyncTaskEvent:
+      break;
+    case v8::Exception:
+    case v8::AfterCompile:
+      sendEventMessage = true;
+      break;
+  }
+
+  // The debug command interrupt flag might have been set when the command was
+  // added. It should be enough to clear the flag only once while we are in the
+  // debugger.
+  DCHECK(in_debug_scope());
+  isolate_->stack_guard()->ClearDebugCommand();
+
+  // Notify the debugger that a debug event has occurred unless auto continue is
+  // active in which case no event is send.
+  if (sendEventMessage) {
+    MessageImpl message = MessageImpl::NewEvent(
+        event,
+        auto_continue,
+        Handle<JSObject>::cast(exec_state),
+        Handle<JSObject>::cast(event_data));
+    InvokeMessageHandler(message);
+  }
+
+  // If auto continue don't make the event cause a break, but process messages
+  // in the queue if any. For script collected events don't even process
+  // messages in the queue as the execution state might not be what is expected
+  // by the client.
+  if (auto_continue && !has_commands()) return;
+
+  // DebugCommandProcessor goes here.
+  bool running = auto_continue;
+
+  Handle<Object> cmd_processor_ctor = Object::GetProperty(
+      isolate_, exec_state, "debugCommandProcessor").ToHandleChecked();
+  Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
+  Handle<Object> cmd_processor = Execution::Call(
+      isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked();
+  Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
+      Object::GetProperty(
+          isolate_, cmd_processor, "processDebugRequest").ToHandleChecked());
+  Handle<Object> is_running = Object::GetProperty(
+      isolate_, cmd_processor, "isRunning").ToHandleChecked();
+
+  // Process requests from the debugger.
+  do {
+    // Wait for new command in the queue.
+    command_received_.Wait();
+
+    // Get the command from the queue.
+    CommandMessage command = command_queue_.Get();
+    isolate_->logger()->DebugTag(
+        "Got request from command queue, in interactive loop.");
+    if (!is_active()) {
+      // Delete command text and user data.
+      command.Dispose();
+      return;
+    }
+
+    Vector<const uc16> command_text(
+        const_cast<const uc16*>(command.text().start()),
+        command.text().length());
+    Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
+        command_text).ToHandleChecked();
+    Handle<Object> request_args[] = { request_text };
+    Handle<Object> answer_value;
+    Handle<String> answer;
+    MaybeHandle<Object> maybe_exception;
+    MaybeHandle<Object> maybe_result =
+        Execution::TryCall(process_debug_request, cmd_processor, 1,
+                           request_args, &maybe_exception);
+
+    if (maybe_result.ToHandle(&answer_value)) {
+      if (answer_value->IsUndefined()) {
+        answer = isolate_->factory()->empty_string();
+      } else {
+        answer = Handle<String>::cast(answer_value);
+      }
+
+      // Log the JSON request/response.
+      if (FLAG_trace_debug_json) {
+        PrintF("%s\n", request_text->ToCString().get());
+        PrintF("%s\n", answer->ToCString().get());
+      }
+
+      Handle<Object> is_running_args[] = { answer };
+      maybe_result = Execution::Call(
+          isolate_, is_running, cmd_processor, 1, is_running_args);
+      Handle<Object> result;
+      if (!maybe_result.ToHandle(&result)) break;
+      running = result->IsTrue();
+    } else {
+      Handle<Object> exception;
+      if (!maybe_exception.ToHandle(&exception)) break;
+      Handle<Object> result;
+      if (!Execution::ToString(isolate_, exception).ToHandle(&result)) break;
+      answer = Handle<String>::cast(result);
+    }
+
+    // Return the result.
+    MessageImpl message = MessageImpl::NewResponse(
+        event, running, exec_state, event_data, answer, command.client_data());
+    InvokeMessageHandler(message);
+    command.Dispose();
+
+    // Return from debug event processing if either the VM is put into the
+    // running state (through a continue command) or auto continue is active
+    // and there are no more commands queued.
+  } while (!running || has_commands());
+  command_queue_.Clear();
+}
+
+
+void Debug::SetEventListener(Handle<Object> callback,
+                             Handle<Object> data) {
+  GlobalHandles* global_handles = isolate_->global_handles();
+
+  // Remove existing entry.
+  GlobalHandles::Destroy(event_listener_.location());
+  event_listener_ = Handle<Object>();
+  GlobalHandles::Destroy(event_listener_data_.location());
+  event_listener_data_ = Handle<Object>();
+
+  // Set new entry.
+  if (!callback->IsUndefined() && !callback->IsNull()) {
+    event_listener_ = global_handles->Create(*callback);
+    if (data.is_null()) data = isolate_->factory()->undefined_value();
+    event_listener_data_ = global_handles->Create(*data);
+  }
+
+  UpdateState();
+}
+
+
+void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
+  message_handler_ = handler;
+  UpdateState();
+  if (handler == NULL && in_debug_scope()) {
+    // Send an empty command to the debugger if in a break to make JavaScript
+    // run again if the debugger is closed.
+    EnqueueCommandMessage(Vector<const uint16_t>::empty());
+  }
+}
+
+
+
+void Debug::UpdateState() {
+  bool is_active = message_handler_ != NULL || !event_listener_.is_null();
+  if (is_active || in_debug_scope()) {
+    // Note that the debug context could have already been loaded to
+    // bootstrap test cases.
+    isolate_->compilation_cache()->Disable();
+    is_active = Load();
+  } else if (is_loaded()) {
+    isolate_->compilation_cache()->Enable();
+    Unload();
+  }
+  is_active_ = is_active;
+}
+
+
+// Calls the registered debug message handler. This callback is part of the
+// public API.
+void Debug::InvokeMessageHandler(MessageImpl message) {
+  if (message_handler_ != NULL) message_handler_(message);
+}
+
+
+// Puts a command coming from the public API on the queue.  Creates
+// a copy of the command string managed by the debugger.  Up to this
+// point, the command data was managed by the API client.  Called
+// by the API client thread.
+void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
+                                  v8::Debug::ClientData* client_data) {
+  // Need to cast away const.
+  CommandMessage message = CommandMessage::New(
+      Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
+                       command.length()),
+      client_data);
+  isolate_->logger()->DebugTag("Put command on command_queue.");
+  command_queue_.Put(message);
+  command_received_.Signal();
+
+  // Set the debug command break flag to have the command processed.
+  if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
+}
+
+
+MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return isolate_->factory()->undefined_value();
+
+  // Create the execution state.
+  Handle<Object> exec_state;
+  if (!MakeExecutionState().ToHandle(&exec_state)) {
+    return isolate_->factory()->undefined_value();
+  }
+
+  Handle<Object> argv[] = { exec_state, data };
+  return Execution::Call(
+      isolate_,
+      fun,
+      Handle<Object>(debug_context()->global_proxy(), isolate_),
+      arraysize(argv),
+      argv);
+}
+
+
+void Debug::HandleDebugBreak() {
+  // Ignore debug break during bootstrapping.
+  if (isolate_->bootstrapper()->IsActive()) return;
+  // Just continue if breaks are disabled.
+  if (break_disabled()) return;
+  // Ignore debug break if debugger is not active.
+  if (!is_active()) return;
+
+  StackLimitCheck check(isolate_);
+  if (check.HasOverflowed()) return;
+
+  { JavaScriptFrameIterator it(isolate_);
+    DCHECK(!it.done());
+    Object* fun = it.frame()->function();
+    if (fun && fun->IsJSFunction()) {
+      // Don't stop in builtin functions.
+      if (JSFunction::cast(fun)->IsBuiltin()) return;
+      GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
+      // Don't stop in debugger functions.
+      if (IsDebugGlobal(global)) return;
+    }
+  }
+
+  // Collect the break state before clearing the flags.
+  bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
+                            !isolate_->stack_guard()->CheckDebugBreak();
+
+  isolate_->stack_guard()->ClearDebugBreak();
+
+  ProcessDebugMessages(debug_command_only);
+}
+
+
+void Debug::ProcessDebugMessages(bool debug_command_only) {
+  isolate_->stack_guard()->ClearDebugCommand();
+
+  StackLimitCheck check(isolate_);
+  if (check.HasOverflowed()) return;
+
+  HandleScope scope(isolate_);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  // Notify the debug event listeners. Indicate auto continue if the break was
+  // a debug command break.
+  OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
+}
+
+
+DebugScope::DebugScope(Debug* debug)
+    : debug_(debug),
+      prev_(debug->debugger_entry()),
+      save_(debug_->isolate_),
+      no_termination_exceptons_(debug_->isolate_,
+                                StackGuard::TERMINATE_EXECUTION) {
+  // Link recursive debugger entry.
+  base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
+                        reinterpret_cast<base::AtomicWord>(this));
+
+  // Store the previous break id and frame id.
+  break_id_ = debug_->break_id();
+  break_frame_id_ = debug_->break_frame_id();
+
+  // Create the new break info. If there is no JavaScript frames there is no
+  // break frame id.
+  JavaScriptFrameIterator it(isolate());
+  bool has_js_frames = !it.done();
+  debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
+                                                        : StackFrame::NO_ID;
+  debug_->SetNextBreakId();
+
+  debug_->UpdateState();
+  // Make sure that debugger is loaded and enter the debugger context.
+  // The previous context is kept in save_.
+  failed_ = !debug_->is_loaded();
+  if (!failed_) isolate()->set_context(*debug->debug_context());
+}
+
+
+
+DebugScope::~DebugScope() {
+  if (!failed_ && prev_ == NULL) {
+    // Clear mirror cache when leaving the debugger. Skip this if there is a
+    // pending exception as clearing the mirror cache calls back into
+    // JavaScript. This can happen if the v8::Debug::Call is used in which
+    // case the exception should end up in the calling code.
+    if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
+
+    // If there are commands in the queue when leaving the debugger request
+    // that these commands are processed.
+    if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
+  }
+
+  // Leaving this debugger entry.
+  base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
+                        reinterpret_cast<base::AtomicWord>(prev_));
+
+  // Restore to the previous break state.
+  debug_->thread_local_.break_frame_id_ = break_frame_id_;
+  debug_->thread_local_.break_id_ = break_id_;
+
+  debug_->UpdateState();
+}
+
+
+MessageImpl MessageImpl::NewEvent(DebugEvent event,
+                                  bool running,
+                                  Handle<JSObject> exec_state,
+                                  Handle<JSObject> event_data) {
+  MessageImpl message(true, event, running,
+                      exec_state, event_data, Handle<String>(), NULL);
+  return message;
+}
+
+
+MessageImpl MessageImpl::NewResponse(DebugEvent event,
+                                     bool running,
+                                     Handle<JSObject> exec_state,
+                                     Handle<JSObject> event_data,
+                                     Handle<String> response_json,
+                                     v8::Debug::ClientData* client_data) {
+  MessageImpl message(false, event, running,
+                      exec_state, event_data, response_json, client_data);
+  return message;
+}
+
+
+MessageImpl::MessageImpl(bool is_event,
+                         DebugEvent event,
+                         bool running,
+                         Handle<JSObject> exec_state,
+                         Handle<JSObject> event_data,
+                         Handle<String> response_json,
+                         v8::Debug::ClientData* client_data)
+    : is_event_(is_event),
+      event_(event),
+      running_(running),
+      exec_state_(exec_state),
+      event_data_(event_data),
+      response_json_(response_json),
+      client_data_(client_data) {}
+
+
+bool MessageImpl::IsEvent() const {
+  return is_event_;
+}
+
+
+bool MessageImpl::IsResponse() const {
+  return !is_event_;
+}
+
+
+DebugEvent MessageImpl::GetEvent() const {
+  return event_;
+}
+
+
+bool MessageImpl::WillStartRunning() const {
+  return running_;
+}
+
+
+v8::Local<v8::Object> MessageImpl::GetExecutionState() const {
+  return v8::Utils::ToLocal(exec_state_);
+}
+
+
+v8::Isolate* MessageImpl::GetIsolate() const {
+  return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
+}
+
+
+v8::Local<v8::Object> MessageImpl::GetEventData() const {
+  return v8::Utils::ToLocal(event_data_);
+}
+
+
+v8::Local<v8::String> MessageImpl::GetJSON() const {
+  Isolate* isolate = event_data_->GetIsolate();
+  v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
+
+  if (IsEvent()) {
+    // Call toJSONProtocol on the debug event object.
+    Handle<Object> fun = Object::GetProperty(
+        isolate, event_data_, "toJSONProtocol").ToHandleChecked();
+    if (!fun->IsJSFunction()) {
+      return v8::Local<v8::String>();
+    }
+
+    MaybeHandle<Object> maybe_json =
+        Execution::TryCall(Handle<JSFunction>::cast(fun), event_data_, 0, NULL);
+    Handle<Object> json;
+    if (!maybe_json.ToHandle(&json) || !json->IsString()) {
+      return v8::Local<v8::String>();
+    }
+    return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
+  } else {
+    return v8::Utils::ToLocal(response_json_);
+  }
+}
+
+
+v8::Local<v8::Context> MessageImpl::GetEventContext() const {
+  Isolate* isolate = event_data_->GetIsolate();
+  v8::Local<v8::Context> context = GetDebugEventContext(isolate);
+  // Isolate::context() may be NULL when "script collected" event occurs.
+  DCHECK(!context.IsEmpty());
+  return context;
+}
+
+
+v8::Debug::ClientData* MessageImpl::GetClientData() const {
+  return client_data_;
+}
+
+
+EventDetailsImpl::EventDetailsImpl(DebugEvent event,
+                                   Handle<JSObject> exec_state,
+                                   Handle<JSObject> event_data,
+                                   Handle<Object> callback_data,
+                                   v8::Debug::ClientData* client_data)
+    : event_(event),
+      exec_state_(exec_state),
+      event_data_(event_data),
+      callback_data_(callback_data),
+      client_data_(client_data) {}
+
+
+DebugEvent EventDetailsImpl::GetEvent() const {
+  return event_;
+}
+
+
+v8::Local<v8::Object> EventDetailsImpl::GetExecutionState() const {
+  return v8::Utils::ToLocal(exec_state_);
+}
+
+
+v8::Local<v8::Object> EventDetailsImpl::GetEventData() const {
+  return v8::Utils::ToLocal(event_data_);
+}
+
+
+v8::Local<v8::Context> EventDetailsImpl::GetEventContext() const {
+  return GetDebugEventContext(exec_state_->GetIsolate());
+}
+
+
+v8::Local<v8::Value> EventDetailsImpl::GetCallbackData() const {
+  return v8::Utils::ToLocal(callback_data_);
+}
+
+
+v8::Debug::ClientData* EventDetailsImpl::GetClientData() const {
+  return client_data_;
+}
+
+
+CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
+                                   client_data_(NULL) {
+}
+
+
+CommandMessage::CommandMessage(const Vector<uint16_t>& text,
+                               v8::Debug::ClientData* data)
+    : text_(text),
+      client_data_(data) {
+}
+
+
+void CommandMessage::Dispose() {
+  text_.Dispose();
+  delete client_data_;
+  client_data_ = NULL;
+}
+
+
+CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
+                                   v8::Debug::ClientData* data) {
+  return CommandMessage(command.Clone(), data);
+}
+
+
+CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
+                                                     size_(size) {
+  messages_ = NewArray<CommandMessage>(size);
+}
+
+
+CommandMessageQueue::~CommandMessageQueue() {
+  while (!IsEmpty()) Get().Dispose();
+  DeleteArray(messages_);
+}
+
+
+CommandMessage CommandMessageQueue::Get() {
+  DCHECK(!IsEmpty());
+  int result = start_;
+  start_ = (start_ + 1) % size_;
+  return messages_[result];
+}
+
+
+void CommandMessageQueue::Put(const CommandMessage& message) {
+  if ((end_ + 1) % size_ == start_) {
+    Expand();
+  }
+  messages_[end_] = message;
+  end_ = (end_ + 1) % size_;
+}
+
+
+void CommandMessageQueue::Expand() {
+  CommandMessageQueue new_queue(size_ * 2);
+  while (!IsEmpty()) {
+    new_queue.Put(Get());
+  }
+  CommandMessage* array_to_free = messages_;
+  *this = new_queue;
+  new_queue.messages_ = array_to_free;
+  // Make the new_queue empty so that it doesn't call Dispose on any messages.
+  new_queue.start_ = new_queue.end_;
+  // Automatic destructor called on new_queue, freeing array_to_free.
+}
+
+
+LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
+    : logger_(logger), queue_(size) {}
+
+
+bool LockingCommandMessageQueue::IsEmpty() const {
+  base::LockGuard<base::Mutex> lock_guard(&mutex_);
+  return queue_.IsEmpty();
+}
+
+
+CommandMessage LockingCommandMessageQueue::Get() {
+  base::LockGuard<base::Mutex> lock_guard(&mutex_);
+  CommandMessage result = queue_.Get();
+  logger_->DebugEvent("Get", result.text());
+  return result;
+}
+
+
+void LockingCommandMessageQueue::Put(const CommandMessage& message) {
+  base::LockGuard<base::Mutex> lock_guard(&mutex_);
+  queue_.Put(message);
+  logger_->DebugEvent("Put", message.text());
+}
+
+
+void LockingCommandMessageQueue::Clear() {
+  base::LockGuard<base::Mutex> lock_guard(&mutex_);
+  queue_.Clear();
+}
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/debug/debug.h b/src/debug/debug.h
new file mode 100644 (file)
index 0000000..e14457a
--- /dev/null
@@ -0,0 +1,795 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_DEBUG_DEBUG_H_
+#define V8_DEBUG_DEBUG_H_
+
+#include "src/allocation.h"
+#include "src/arguments.h"
+#include "src/assembler.h"
+#include "src/base/atomicops.h"
+#include "src/base/platform/platform.h"
+#include "src/debug/liveedit.h"
+#include "src/execution.h"
+#include "src/factory.h"
+#include "src/flags.h"
+#include "src/frames-inl.h"
+#include "src/hashmap.h"
+#include "src/runtime/runtime.h"
+#include "src/string-stream.h"
+#include "src/v8threads.h"
+
+#include "include/v8-debug.h"
+
+namespace v8 {
+namespace internal {
+
+
+// Forward declarations.
+class DebugScope;
+
+
+// Step actions. NOTE: These values are in macros.py as well.
+enum StepAction {
+  StepNone = -1,  // Stepping not prepared.
+  StepOut = 0,    // Step out of the current function.
+  StepNext = 1,   // Step to the next statement in the current function.
+  StepIn = 2,     // Step into new functions invoked or the next statement
+                  // in the current function.
+  StepMin = 3,    // Perform a minimum step in the current function.
+  StepInMin = 4,  // Step into new functions invoked or perform a minimum step
+                  // in the current function.
+  StepFrame = 5   // Step into a new frame or return to previous frame.
+};
+
+
+// Type of exception break. NOTE: These values are in macros.py as well.
+enum ExceptionBreakType {
+  BreakException = 0,
+  BreakUncaughtException = 1
+};
+
+
+// Type of exception break.
+enum BreakLocatorType { ALL_BREAK_LOCATIONS, CALLS_AND_RETURNS };
+
+
+// The different types of breakpoint position alignments.
+// Must match Debug.BreakPositionAlignment in debug.js
+enum BreakPositionAlignment {
+  STATEMENT_ALIGNED = 0,
+  BREAK_POSITION_ALIGNED = 1
+};
+
+
+class BreakLocation {
+ public:
+  // Find the break point at the supplied address, or the closest one before
+  // the address.
+  static BreakLocation FromAddress(Handle<DebugInfo> debug_info,
+                                   BreakLocatorType type, Address pc);
+
+  static void FromAddressSameStatement(Handle<DebugInfo> debug_info,
+                                       BreakLocatorType type, Address pc,
+                                       List<BreakLocation>* result_out);
+
+  static BreakLocation FromPosition(Handle<DebugInfo> debug_info,
+                                    BreakLocatorType type, int position,
+                                    BreakPositionAlignment alignment);
+
+  bool IsDebugBreak() const;
+
+  inline bool IsReturn() const {
+    return RelocInfo::IsDebugBreakSlotAtReturn(rmode_);
+  }
+  inline bool IsCall() const {
+    return RelocInfo::IsDebugBreakSlotAtCall(rmode_);
+  }
+  inline bool IsConstructCall() const {
+    return RelocInfo::IsDebugBreakSlotAtConstructCall(rmode_);
+  }
+  inline int CallArgumentsCount() const {
+    DCHECK(IsCall());
+    return RelocInfo::DebugBreakCallArgumentsCount(data_);
+  }
+
+  bool IsStepInLocation() const;
+  inline bool HasBreakPoint() const {
+    return debug_info_->HasBreakPoint(pc_offset_);
+  }
+
+  Handle<Object> BreakPointObjects() const;
+
+  void SetBreakPoint(Handle<Object> break_point_object);
+  void ClearBreakPoint(Handle<Object> break_point_object);
+
+  void SetOneShot();
+  void ClearOneShot();
+
+
+  inline RelocInfo rinfo() const {
+    return RelocInfo(pc(), rmode(), data_, code());
+  }
+
+  inline int position() const { return position_; }
+  inline int statement_position() const { return statement_position_; }
+
+  inline Address pc() const { return code()->entry() + pc_offset_; }
+
+  inline RelocInfo::Mode rmode() const { return rmode_; }
+
+  inline Code* code() const { return debug_info_->code(); }
+
+ private:
+  BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo, int position,
+                int statement_position);
+
+  class Iterator {
+   public:
+    Iterator(Handle<DebugInfo> debug_info, BreakLocatorType type);
+
+    BreakLocation GetBreakLocation() {
+      return BreakLocation(debug_info_, rinfo(), position(),
+                           statement_position());
+    }
+
+    inline bool Done() const { return reloc_iterator_.done(); }
+    void Next();
+
+    void SkipTo(int count) {
+      while (count-- > 0) Next();
+    }
+
+    inline RelocInfo::Mode rmode() { return reloc_iterator_.rinfo()->rmode(); }
+    inline RelocInfo* rinfo() { return reloc_iterator_.rinfo(); }
+    inline Address pc() { return rinfo()->pc(); }
+    int break_index() const { return break_index_; }
+    inline int position() const { return position_; }
+    inline int statement_position() const { return statement_position_; }
+
+   private:
+    static int GetModeMask(BreakLocatorType type);
+
+    Handle<DebugInfo> debug_info_;
+    RelocIterator reloc_iterator_;
+    int break_index_;
+    int position_;
+    int statement_position_;
+
+    DisallowHeapAllocation no_gc_;
+
+    DISALLOW_COPY_AND_ASSIGN(Iterator);
+  };
+
+  friend class Debug;
+
+  static int BreakIndexFromAddress(Handle<DebugInfo> debug_info,
+                                   BreakLocatorType type, Address pc);
+
+  void SetDebugBreak();
+  void ClearDebugBreak();
+
+  inline bool IsDebuggerStatement() const {
+    return RelocInfo::IsDebuggerStatement(rmode_);
+  }
+  inline bool IsDebugBreakSlot() const {
+    return RelocInfo::IsDebugBreakSlot(rmode_);
+  }
+
+  Handle<DebugInfo> debug_info_;
+  int pc_offset_;
+  RelocInfo::Mode rmode_;
+  intptr_t data_;
+  int position_;
+  int statement_position_;
+};
+
+
+// Cache of all script objects in the heap. When a script is added a weak handle
+// to it is created and that weak handle is stored in the cache. The weak handle
+// callback takes care of removing the script from the cache. The key used in
+// the cache is the script id.
+class ScriptCache {
+ public:
+  explicit ScriptCache(Isolate* isolate);
+  ~ScriptCache();
+
+  // Add script to the cache.
+  void Add(Handle<Script> script);
+
+  // Return the scripts in the cache.
+  Handle<FixedArray> GetScripts() {
+    return WeakValueHashTable::GetWeakValues(table_);
+  }
+
+ private:
+  Isolate* isolate_;
+  Handle<WeakValueHashTable> table_;
+};
+
+
+// Linked list holding debug info objects. The debug info objects are kept as
+// weak handles to avoid a debug info object to keep a function alive.
+class DebugInfoListNode {
+ public:
+  explicit DebugInfoListNode(DebugInfo* debug_info);
+  ~DebugInfoListNode();
+
+  DebugInfoListNode* next() { return next_; }
+  void set_next(DebugInfoListNode* next) { next_ = next; }
+  Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); }
+
+ private:
+  // Global (weak) handle to the debug info object.
+  DebugInfo** debug_info_;
+
+  // Next pointer for linked list.
+  DebugInfoListNode* next_;
+};
+
+
+
+// Message delivered to the message handler callback. This is either a debugger
+// event or the response to a command.
+class MessageImpl: public v8::Debug::Message {
+ public:
+  // Create a message object for a debug event.
+  static MessageImpl NewEvent(DebugEvent event,
+                              bool running,
+                              Handle<JSObject> exec_state,
+                              Handle<JSObject> event_data);
+
+  // Create a message object for the response to a debug command.
+  static MessageImpl NewResponse(DebugEvent event,
+                                 bool running,
+                                 Handle<JSObject> exec_state,
+                                 Handle<JSObject> event_data,
+                                 Handle<String> response_json,
+                                 v8::Debug::ClientData* client_data);
+
+  // Implementation of interface v8::Debug::Message.
+  virtual bool IsEvent() const;
+  virtual bool IsResponse() const;
+  virtual DebugEvent GetEvent() const;
+  virtual bool WillStartRunning() const;
+  virtual v8::Local<v8::Object> GetExecutionState() const;
+  virtual v8::Local<v8::Object> GetEventData() const;
+  virtual v8::Local<v8::String> GetJSON() const;
+  virtual v8::Local<v8::Context> GetEventContext() const;
+  virtual v8::Debug::ClientData* GetClientData() const;
+  virtual v8::Isolate* GetIsolate() const;
+
+ private:
+  MessageImpl(bool is_event,
+              DebugEvent event,
+              bool running,
+              Handle<JSObject> exec_state,
+              Handle<JSObject> event_data,
+              Handle<String> response_json,
+              v8::Debug::ClientData* client_data);
+
+  bool is_event_;  // Does this message represent a debug event?
+  DebugEvent event_;  // Debug event causing the break.
+  bool running_;  // Will the VM start running after this event?
+  Handle<JSObject> exec_state_;  // Current execution state.
+  Handle<JSObject> event_data_;  // Data associated with the event.
+  Handle<String> response_json_;  // Response JSON if message holds a response.
+  v8::Debug::ClientData* client_data_;  // Client data passed with the request.
+};
+
+
+// Details of the debug event delivered to the debug event listener.
+class EventDetailsImpl : public v8::Debug::EventDetails {
+ public:
+  EventDetailsImpl(DebugEvent event,
+                   Handle<JSObject> exec_state,
+                   Handle<JSObject> event_data,
+                   Handle<Object> callback_data,
+                   v8::Debug::ClientData* client_data);
+  virtual DebugEvent GetEvent() const;
+  virtual v8::Local<v8::Object> GetExecutionState() const;
+  virtual v8::Local<v8::Object> GetEventData() const;
+  virtual v8::Local<v8::Context> GetEventContext() const;
+  virtual v8::Local<v8::Value> GetCallbackData() const;
+  virtual v8::Debug::ClientData* GetClientData() const;
+ private:
+  DebugEvent event_;  // Debug event causing the break.
+  Handle<JSObject> exec_state_;         // Current execution state.
+  Handle<JSObject> event_data_;         // Data associated with the event.
+  Handle<Object> callback_data_;        // User data passed with the callback
+                                        // when it was registered.
+  v8::Debug::ClientData* client_data_;  // Data passed to DebugBreakForCommand.
+};
+
+
+// Message send by user to v8 debugger or debugger output message.
+// In addition to command text it may contain a pointer to some user data
+// which are expected to be passed along with the command reponse to message
+// handler.
+class CommandMessage {
+ public:
+  static CommandMessage New(const Vector<uint16_t>& command,
+                            v8::Debug::ClientData* data);
+  CommandMessage();
+
+  // Deletes user data and disposes of the text.
+  void Dispose();
+  Vector<uint16_t> text() const { return text_; }
+  v8::Debug::ClientData* client_data() const { return client_data_; }
+ private:
+  CommandMessage(const Vector<uint16_t>& text,
+                 v8::Debug::ClientData* data);
+
+  Vector<uint16_t> text_;
+  v8::Debug::ClientData* client_data_;
+};
+
+
+// A Queue of CommandMessage objects.  A thread-safe version is
+// LockingCommandMessageQueue, based on this class.
+class CommandMessageQueue BASE_EMBEDDED {
+ public:
+  explicit CommandMessageQueue(int size);
+  ~CommandMessageQueue();
+  bool IsEmpty() const { return start_ == end_; }
+  CommandMessage Get();
+  void Put(const CommandMessage& message);
+  void Clear() { start_ = end_ = 0; }  // Queue is empty after Clear().
+ private:
+  // Doubles the size of the message queue, and copies the messages.
+  void Expand();
+
+  CommandMessage* messages_;
+  int start_;
+  int end_;
+  int size_;  // The size of the queue buffer.  Queue can hold size-1 messages.
+};
+
+
+// LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage
+// messages.  The message data is not managed by LockingCommandMessageQueue.
+// Pointers to the data are passed in and out. Implemented by adding a
+// Mutex to CommandMessageQueue.  Includes logging of all puts and gets.
+class LockingCommandMessageQueue BASE_EMBEDDED {
+ public:
+  LockingCommandMessageQueue(Logger* logger, int size);
+  bool IsEmpty() const;
+  CommandMessage Get();
+  void Put(const CommandMessage& message);
+  void Clear();
+ private:
+  Logger* logger_;
+  CommandMessageQueue queue_;
+  mutable base::Mutex mutex_;
+  DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue);
+};
+
+
+// This class contains the debugger support. The main purpose is to handle
+// setting break points in the code.
+//
+// This class controls the debug info for all functions which currently have
+// active breakpoints in them. This debug info is held in the heap root object
+// debug_info which is a FixedArray. Each entry in this list is of class
+// DebugInfo.
+class Debug {
+ public:
+  // Debug event triggers.
+  void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
+
+  void OnThrow(Handle<Object> exception);
+  void OnPromiseReject(Handle<JSObject> promise, Handle<Object> value);
+  void OnCompileError(Handle<Script> script);
+  void OnBeforeCompile(Handle<Script> script);
+  void OnAfterCompile(Handle<Script> script);
+  void OnPromiseEvent(Handle<JSObject> data);
+  void OnAsyncTaskEvent(Handle<JSObject> data);
+
+  // API facing.
+  void SetEventListener(Handle<Object> callback, Handle<Object> data);
+  void SetMessageHandler(v8::Debug::MessageHandler handler);
+  void EnqueueCommandMessage(Vector<const uint16_t> command,
+                             v8::Debug::ClientData* client_data = NULL);
+  MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun,
+                                           Handle<Object> data);
+  Handle<Context> GetDebugContext();
+  void HandleDebugBreak();
+  void ProcessDebugMessages(bool debug_command_only);
+
+  // Internal logic
+  bool Load();
+  void Break(Arguments args, JavaScriptFrame*);
+  void SetAfterBreakTarget(JavaScriptFrame* frame);
+
+  // Scripts handling.
+  Handle<FixedArray> GetLoadedScripts();
+
+  // Break point handling.
+  bool SetBreakPoint(Handle<JSFunction> function,
+                     Handle<Object> break_point_object,
+                     int* source_position);
+  bool SetBreakPointForScript(Handle<Script> script,
+                              Handle<Object> break_point_object,
+                              int* source_position,
+                              BreakPositionAlignment alignment);
+  void ClearBreakPoint(Handle<Object> break_point_object);
+  void ClearAllBreakPoints();
+  void FloodWithOneShot(Handle<JSFunction> function,
+                        BreakLocatorType type = ALL_BREAK_LOCATIONS);
+  void FloodBoundFunctionWithOneShot(Handle<JSFunction> function);
+  void FloodDefaultConstructorWithOneShot(Handle<JSFunction> function);
+  void FloodWithOneShotGeneric(Handle<JSFunction> function,
+                               Handle<Object> holder = Handle<Object>());
+  void FloodHandlerWithOneShot();
+  void ChangeBreakOnException(ExceptionBreakType type, bool enable);
+  bool IsBreakOnException(ExceptionBreakType type);
+
+  // Stepping handling.
+  void PrepareStep(StepAction step_action,
+                   int step_count,
+                   StackFrame::Id frame_id);
+  void ClearStepping();
+  void ClearStepOut();
+  bool IsStepping() { return thread_local_.step_count_ > 0; }
+  bool StepNextContinue(BreakLocation* location, JavaScriptFrame* frame);
+  bool StepInActive() { return thread_local_.step_into_fp_ != 0; }
+  void HandleStepIn(Handle<Object> function_obj, bool is_constructor);
+  bool StepOutActive() { return thread_local_.step_out_fp_ != 0; }
+
+  void GetStepinPositions(JavaScriptFrame* frame, StackFrame::Id frame_id,
+                          List<int>* results_out);
+
+  bool PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared);
+
+  // Returns whether the operation succeeded. Compilation can only be triggered
+  // if a valid closure is passed as the second argument, otherwise the shared
+  // function needs to be compiled already.
+  bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
+                       Handle<JSFunction> function);
+  static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
+
+  template <typename C>
+  bool CompileToRevealInnerFunctions(C* compilable);
+
+  // This function is used in FunctionNameUsing* tests.
+  Handle<Object> FindSharedFunctionInfoInScript(Handle<Script> script,
+                                                int position);
+
+  // Returns true if the current stub call is patched to call the debugger.
+  static bool IsDebugBreak(Address addr);
+
+  static Handle<Object> GetSourceBreakLocations(
+      Handle<SharedFunctionInfo> shared,
+      BreakPositionAlignment position_aligment);
+
+  // Check whether a global object is the debug global object.
+  bool IsDebugGlobal(GlobalObject* global);
+
+  // Check whether this frame is just about to return.
+  bool IsBreakAtReturn(JavaScriptFrame* frame);
+
+  // Support for LiveEdit
+  void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
+                             LiveEdit::FrameDropMode mode,
+                             Object** restarter_frame_function_pointer);
+
+  // Threading support.
+  char* ArchiveDebug(char* to);
+  char* RestoreDebug(char* from);
+  static int ArchiveSpacePerThread();
+  void FreeThreadResources() { }
+
+  // Record function from which eval was called.
+  static void RecordEvalCaller(Handle<Script> script);
+
+  bool CheckExecutionState(int id) {
+    return is_active() && !debug_context().is_null() && break_id() != 0 &&
+           break_id() == id;
+  }
+
+  // Flags and states.
+  DebugScope* debugger_entry() {
+    return reinterpret_cast<DebugScope*>(
+        base::NoBarrier_Load(&thread_local_.current_debug_scope_));
+  }
+  inline Handle<Context> debug_context() { return debug_context_; }
+  void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
+  bool live_edit_enabled() const {
+    return FLAG_enable_liveedit && live_edit_enabled_ ;
+  }
+
+  inline bool is_active() const { return is_active_; }
+  inline bool is_loaded() const { return !debug_context_.is_null(); }
+  inline bool in_debug_scope() const {
+    return !!base::NoBarrier_Load(&thread_local_.current_debug_scope_);
+  }
+  void set_disable_break(bool v) { break_disabled_ = v; }
+
+  StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
+  int break_id() { return thread_local_.break_id_; }
+
+  // Support for embedding into generated code.
+  Address is_active_address() {
+    return reinterpret_cast<Address>(&is_active_);
+  }
+
+  Address after_break_target_address() {
+    return reinterpret_cast<Address>(&after_break_target_);
+  }
+
+  Address restarter_frame_function_pointer_address() {
+    Object*** address = &thread_local_.restarter_frame_function_pointer_;
+    return reinterpret_cast<Address>(address);
+  }
+
+  Address step_in_fp_addr() {
+    return reinterpret_cast<Address>(&thread_local_.step_into_fp_);
+  }
+
+  StepAction last_step_action() { return thread_local_.last_step_action_; }
+
+ private:
+  explicit Debug(Isolate* isolate);
+
+  void UpdateState();
+  void Unload();
+  void SetNextBreakId() {
+    thread_local_.break_id_ = ++thread_local_.break_count_;
+  }
+
+  // Check whether there are commands in the command queue.
+  inline bool has_commands() const { return !command_queue_.IsEmpty(); }
+  inline bool ignore_events() const { return is_suppressed_ || !is_active_; }
+  inline bool break_disabled() const {
+    return break_disabled_ || in_debug_event_listener_;
+  }
+
+  void OnException(Handle<Object> exception, Handle<Object> promise);
+
+  // Constructors for debug event objects.
+  MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
+      const char* constructor_name,
+      int argc,
+      Handle<Object> argv[]);
+  MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
+  MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
+      Handle<Object> break_points_hit);
+  MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
+      Handle<Object> exception,
+      bool uncaught,
+      Handle<Object> promise);
+  MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
+      Handle<Script> script, v8::DebugEvent type);
+  MUST_USE_RESULT MaybeHandle<Object> MakePromiseEvent(
+      Handle<JSObject> promise_event);
+  MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(
+      Handle<JSObject> task_event);
+
+  // Mirror cache handling.
+  void ClearMirrorCache();
+
+  MaybeHandle<Object> PromiseHasUserDefinedRejectHandler(
+      Handle<JSObject> promise);
+
+  void CallEventCallback(v8::DebugEvent event,
+                         Handle<Object> exec_state,
+                         Handle<Object> event_data,
+                         v8::Debug::ClientData* client_data);
+  void ProcessCompileEventInDebugScope(v8::DebugEvent event,
+                                       Handle<Script> script);
+  void ProcessDebugEvent(v8::DebugEvent event,
+                         Handle<JSObject> event_data,
+                         bool auto_continue);
+  void NotifyMessageHandler(v8::DebugEvent event,
+                            Handle<JSObject> exec_state,
+                            Handle<JSObject> event_data,
+                            bool auto_continue);
+  void InvokeMessageHandler(MessageImpl message);
+
+  static bool CompileDebuggerScript(Isolate* isolate, int index);
+  void ClearOneShot();
+  void ActivateStepIn(StackFrame* frame);
+  void ClearStepIn();
+  void ActivateStepOut(StackFrame* frame);
+  void ClearStepNext();
+  void RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info);
+  Handle<Object> CheckBreakPoints(Handle<Object> break_point);
+  bool CheckBreakPoint(Handle<Object> break_point_object);
+
+  inline void AssertDebugContext() {
+    DCHECK(isolate_->context() == *debug_context());
+    DCHECK(in_debug_scope());
+  }
+
+  void ThreadInit();
+
+  // Global handles.
+  Handle<Context> debug_context_;
+  Handle<Object> event_listener_;
+  Handle<Object> event_listener_data_;
+
+  v8::Debug::MessageHandler message_handler_;
+
+  static const int kQueueInitialSize = 4;
+  base::Semaphore command_received_;  // Signaled for each command received.
+  LockingCommandMessageQueue command_queue_;
+
+  bool is_active_;
+  bool is_suppressed_;
+  bool live_edit_enabled_;
+  bool has_break_points_;
+  bool break_disabled_;
+  bool in_debug_event_listener_;
+  bool break_on_exception_;
+  bool break_on_uncaught_exception_;
+
+  ScriptCache* script_cache_;  // Cache of all scripts in the heap.
+  DebugInfoListNode* debug_info_list_;  // List of active debug info objects.
+
+  // Storage location for jump when exiting debug break calls.
+  // Note that this address is not GC safe.  It should be computed immediately
+  // before returning to the DebugBreakCallHelper.
+  Address after_break_target_;
+
+  // Per-thread data.
+  class ThreadLocal {
+   public:
+    // Top debugger entry.
+    base::AtomicWord current_debug_scope_;
+
+    // Counter for generating next break id.
+    int break_count_;
+
+    // Current break id.
+    int break_id_;
+
+    // Frame id for the frame of the current break.
+    StackFrame::Id break_frame_id_;
+
+    // Step action for last step performed.
+    StepAction last_step_action_;
+
+    // Source statement position from last step next action.
+    int last_statement_position_;
+
+    // Number of steps left to perform before debug event.
+    int step_count_;
+
+    // Frame pointer from last step next or step frame action.
+    Address last_fp_;
+
+    // Number of queued steps left to perform before debug event.
+    int queued_step_count_;
+
+    // Frame pointer for frame from which step in was performed.
+    Address step_into_fp_;
+
+    // Frame pointer for the frame where debugger should be called when current
+    // step out action is completed.
+    Address step_out_fp_;
+
+    // Stores the way how LiveEdit has patched the stack. It is used when
+    // debugger returns control back to user script.
+    LiveEdit::FrameDropMode frame_drop_mode_;
+
+    // When restarter frame is on stack, stores the address
+    // of the pointer to function being restarted. Otherwise (most of the time)
+    // stores NULL. This pointer is used with 'step in' implementation.
+    Object** restarter_frame_function_pointer_;
+  };
+
+  // Storage location for registers when handling debug break calls
+  ThreadLocal thread_local_;
+
+  Isolate* isolate_;
+
+  friend class Isolate;
+  friend class DebugScope;
+  friend class DisableBreak;
+  friend class LiveEdit;
+  friend class SuppressDebug;
+
+  friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
+  friend void CheckDebuggerUnloaded(bool check_functions);  // In test-debug.cc
+
+  DISALLOW_COPY_AND_ASSIGN(Debug);
+};
+
+
+// This scope is used to load and enter the debug context and create a new
+// break state.  Leaving the scope will restore the previous state.
+// On failure to load, FailedToEnter returns true.
+class DebugScope BASE_EMBEDDED {
+ public:
+  explicit DebugScope(Debug* debug);
+  ~DebugScope();
+
+  // Check whether loading was successful.
+  inline bool failed() { return failed_; }
+
+  // Get the active context from before entering the debugger.
+  inline Handle<Context> GetContext() { return save_.context(); }
+
+ private:
+  Isolate* isolate() { return debug_->isolate_; }
+
+  Debug* debug_;
+  DebugScope* prev_;               // Previous scope if entered recursively.
+  StackFrame::Id break_frame_id_;  // Previous break frame id.
+  int break_id_;                   // Previous break id.
+  bool failed_;                    // Did the debug context fail to load?
+  SaveContext save_;               // Saves previous context.
+  PostponeInterruptsScope no_termination_exceptons_;
+};
+
+
+// Stack allocated class for disabling break.
+class DisableBreak BASE_EMBEDDED {
+ public:
+  explicit DisableBreak(Debug* debug, bool disable_break)
+      : debug_(debug),
+        previous_break_disabled_(debug->break_disabled_),
+        previous_in_debug_event_listener_(debug->in_debug_event_listener_) {
+    debug_->break_disabled_ = disable_break;
+    debug_->in_debug_event_listener_ = disable_break;
+  }
+  ~DisableBreak() {
+    debug_->break_disabled_ = previous_break_disabled_;
+    debug_->in_debug_event_listener_ = previous_in_debug_event_listener_;
+  }
+
+ private:
+  Debug* debug_;
+  bool previous_break_disabled_;
+  bool previous_in_debug_event_listener_;
+  DISALLOW_COPY_AND_ASSIGN(DisableBreak);
+};
+
+
+class SuppressDebug BASE_EMBEDDED {
+ public:
+  explicit SuppressDebug(Debug* debug)
+      : debug_(debug), old_state_(debug->is_suppressed_) {
+    debug_->is_suppressed_ = true;
+  }
+  ~SuppressDebug() { debug_->is_suppressed_ = old_state_; }
+
+ private:
+  Debug* debug_;
+  bool old_state_;
+  DISALLOW_COPY_AND_ASSIGN(SuppressDebug);
+};
+
+
+// Code generator routines.
+class DebugCodegen : public AllStatic {
+ public:
+  enum DebugBreakCallHelperMode {
+    SAVE_RESULT_REGISTER,
+    IGNORE_RESULT_REGISTER
+  };
+
+  static void GenerateDebugBreakStub(MacroAssembler* masm,
+                                     DebugBreakCallHelperMode mode);
+
+  static void GeneratePlainReturnLiveEdit(MacroAssembler* masm);
+
+  // FrameDropper is a code replacement for a JavaScript frame with possibly
+  // several frames above.
+  // There is no calling conventions here, because it never actually gets
+  // called, it only gets returned to.
+  static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
+
+
+  static void GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                           int call_argc = -1);
+
+  static void PatchDebugBreakSlot(Address pc, Handle<Code> code);
+  static void ClearDebugBreakSlot(Address pc);
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_DEBUG_DEBUG_H_
diff --git a/src/debug/debug.js b/src/debug/debug.js
new file mode 100644 (file)
index 0000000..991af11
--- /dev/null
@@ -0,0 +1,2569 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+"use strict";
+
+// Default number of frames to include in the response to backtrace request.
+var kDefaultBacktraceLength = 10;
+
+var Debug = {};
+
+// Regular expression to skip "crud" at the beginning of a source line which is
+// not really code. Currently the regular expression matches whitespace and
+// comments.
+var sourceLineBeginningSkip = /^(?:\s*(?:\/\*.*?\*\/)*)*/;
+
+// Debug events which can occour in the V8 JavaScript engine. These originate
+// from the API include file debug.h.
+Debug.DebugEvent = { Break: 1,
+                     Exception: 2,
+                     NewFunction: 3,
+                     BeforeCompile: 4,
+                     AfterCompile: 5,
+                     CompileError: 6,
+                     PromiseEvent: 7,
+                     AsyncTaskEvent: 8 };
+
+// Types of exceptions that can be broken upon.
+Debug.ExceptionBreak = { Caught : 0,
+                         Uncaught: 1 };
+
+// The different types of steps.
+Debug.StepAction = { StepOut: 0,
+                     StepNext: 1,
+                     StepIn: 2,
+                     StepMin: 3,
+                     StepInMin: 4,
+                     StepFrame: 5 };
+
+// The different types of scripts matching enum ScriptType in objects.h.
+Debug.ScriptType = { Native: 0,
+                     Extension: 1,
+                     Normal: 2 };
+
+// The different types of script compilations matching enum
+// Script::CompilationType in objects.h.
+Debug.ScriptCompilationType = { Host: 0,
+                                Eval: 1,
+                                JSON: 2 };
+
+// The different script break point types.
+Debug.ScriptBreakPointType = { ScriptId: 0,
+                               ScriptName: 1,
+                               ScriptRegExp: 2 };
+
+// The different types of breakpoint position alignments.
+// Must match BreakPositionAlignment in debug.h.
+Debug.BreakPositionAlignment = {
+  Statement: 0,
+  BreakPosition: 1
+};
+
+function ScriptTypeFlag(type) {
+  return (1 << type);
+}
+
+// Globals.
+var next_response_seq = 0;
+var next_break_point_number = 1;
+var break_points = [];
+var script_break_points = [];
+var debugger_flags = {
+  breakPointsActive: {
+    value: true,
+    getValue: function() { return this.value; },
+    setValue: function(value) {
+      this.value = !!value;
+      %SetDisableBreak(!this.value);
+    }
+  },
+  breakOnCaughtException: {
+    getValue: function() { return Debug.isBreakOnException(); },
+    setValue: function(value) {
+      if (value) {
+        Debug.setBreakOnException();
+      } else {
+        Debug.clearBreakOnException();
+      }
+    }
+  },
+  breakOnUncaughtException: {
+    getValue: function() { return Debug.isBreakOnUncaughtException(); },
+    setValue: function(value) {
+      if (value) {
+        Debug.setBreakOnUncaughtException();
+      } else {
+        Debug.clearBreakOnUncaughtException();
+      }
+    }
+  },
+};
+
+
+// Create a new break point object and add it to the list of break points.
+function MakeBreakPoint(source_position, opt_script_break_point) {
+  var break_point = new BreakPoint(source_position, opt_script_break_point);
+  break_points.push(break_point);
+  return break_point;
+}
+
+
+// Object representing a break point.
+// NOTE: This object does not have a reference to the function having break
+// point as this would cause function not to be garbage collected when it is
+// not used any more. We do not want break points to keep functions alive.
+function BreakPoint(source_position, opt_script_break_point) {
+  this.source_position_ = source_position;
+  if (opt_script_break_point) {
+    this.script_break_point_ = opt_script_break_point;
+  } else {
+    this.number_ = next_break_point_number++;
+  }
+  this.hit_count_ = 0;
+  this.active_ = true;
+  this.condition_ = null;
+  this.ignoreCount_ = 0;
+}
+
+
+BreakPoint.prototype.number = function() {
+  return this.number_;
+};
+
+
+BreakPoint.prototype.func = function() {
+  return this.func_;
+};
+
+
+BreakPoint.prototype.source_position = function() {
+  return this.source_position_;
+};
+
+
+BreakPoint.prototype.hit_count = function() {
+  return this.hit_count_;
+};
+
+
+BreakPoint.prototype.active = function() {
+  if (this.script_break_point()) {
+    return this.script_break_point().active();
+  }
+  return this.active_;
+};
+
+
+BreakPoint.prototype.condition = function() {
+  if (this.script_break_point() && this.script_break_point().condition()) {
+    return this.script_break_point().condition();
+  }
+  return this.condition_;
+};
+
+
+BreakPoint.prototype.ignoreCount = function() {
+  return this.ignoreCount_;
+};
+
+
+BreakPoint.prototype.script_break_point = function() {
+  return this.script_break_point_;
+};
+
+
+BreakPoint.prototype.enable = function() {
+  this.active_ = true;
+};
+
+
+BreakPoint.prototype.disable = function() {
+  this.active_ = false;
+};
+
+
+BreakPoint.prototype.setCondition = function(condition) {
+  this.condition_ = condition;
+};
+
+
+BreakPoint.prototype.setIgnoreCount = function(ignoreCount) {
+  this.ignoreCount_ = ignoreCount;
+};
+
+
+BreakPoint.prototype.isTriggered = function(exec_state) {
+  // Break point not active - not triggered.
+  if (!this.active()) return false;
+
+  // Check for conditional break point.
+  if (this.condition()) {
+    // If break point has condition try to evaluate it in the top frame.
+    try {
+      var mirror = exec_state.frame(0).evaluate(this.condition());
+      // If no sensible mirror or non true value break point not triggered.
+      if (!(mirror instanceof ValueMirror) ||
+          !builtins.$toBoolean(mirror.value_)) {
+        return false;
+      }
+    } catch (e) {
+      // Exception evaluating condition counts as not triggered.
+      return false;
+    }
+  }
+
+  // Update the hit count.
+  this.hit_count_++;
+  if (this.script_break_point_) {
+    this.script_break_point_.hit_count_++;
+  }
+
+  // If the break point has an ignore count it is not triggered.
+  if (this.ignoreCount_ > 0) {
+    this.ignoreCount_--;
+    return false;
+  }
+
+  // Break point triggered.
+  return true;
+};
+
+
+// Function called from the runtime when a break point is hit. Returns true if
+// the break point is triggered and supposed to break execution.
+function IsBreakPointTriggered(break_id, break_point) {
+  return break_point.isTriggered(MakeExecutionState(break_id));
+}
+
+
+// Object representing a script break point. The script is referenced by its
+// script name or script id and the break point is represented as line and
+// column.
+function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
+                          opt_groupId, opt_position_alignment) {
+  this.type_ = type;
+  if (type == Debug.ScriptBreakPointType.ScriptId) {
+    this.script_id_ = script_id_or_name;
+  } else if (type == Debug.ScriptBreakPointType.ScriptName) {
+    this.script_name_ = script_id_or_name;
+  } else if (type == Debug.ScriptBreakPointType.ScriptRegExp) {
+    this.script_regexp_object_ = new RegExp(script_id_or_name);
+  } else {
+    throw new Error("Unexpected breakpoint type " + type);
+  }
+  this.line_ = opt_line || 0;
+  this.column_ = opt_column;
+  this.groupId_ = opt_groupId;
+  this.position_alignment_ = IS_UNDEFINED(opt_position_alignment)
+      ? Debug.BreakPositionAlignment.Statement : opt_position_alignment;
+  this.hit_count_ = 0;
+  this.active_ = true;
+  this.condition_ = null;
+  this.ignoreCount_ = 0;
+  this.break_points_ = [];
+}
+
+
+// Creates a clone of script breakpoint that is linked to another script.
+ScriptBreakPoint.prototype.cloneForOtherScript = function (other_script) {
+  var copy = new ScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
+      other_script.id, this.line_, this.column_, this.groupId_,
+      this.position_alignment_);
+  copy.number_ = next_break_point_number++;
+  script_break_points.push(copy);
+
+  copy.hit_count_ = this.hit_count_;
+  copy.active_ = this.active_;
+  copy.condition_ = this.condition_;
+  copy.ignoreCount_ = this.ignoreCount_;
+  return copy;
+};
+
+
+ScriptBreakPoint.prototype.number = function() {
+  return this.number_;
+};
+
+
+ScriptBreakPoint.prototype.groupId = function() {
+  return this.groupId_;
+};
+
+
+ScriptBreakPoint.prototype.type = function() {
+  return this.type_;
+};
+
+
+ScriptBreakPoint.prototype.script_id = function() {
+  return this.script_id_;
+};
+
+
+ScriptBreakPoint.prototype.script_name = function() {
+  return this.script_name_;
+};
+
+
+ScriptBreakPoint.prototype.script_regexp_object = function() {
+  return this.script_regexp_object_;
+};
+
+
+ScriptBreakPoint.prototype.line = function() {
+  return this.line_;
+};
+
+
+ScriptBreakPoint.prototype.column = function() {
+  return this.column_;
+};
+
+
+ScriptBreakPoint.prototype.actual_locations = function() {
+  var locations = [];
+  for (var i = 0; i < this.break_points_.length; i++) {
+    locations.push(this.break_points_[i].actual_location);
+  }
+  return locations;
+};
+
+
+ScriptBreakPoint.prototype.update_positions = function(line, column) {
+  this.line_ = line;
+  this.column_ = column;
+};
+
+
+ScriptBreakPoint.prototype.hit_count = function() {
+  return this.hit_count_;
+};
+
+
+ScriptBreakPoint.prototype.active = function() {
+  return this.active_;
+};
+
+
+ScriptBreakPoint.prototype.condition = function() {
+  return this.condition_;
+};
+
+
+ScriptBreakPoint.prototype.ignoreCount = function() {
+  return this.ignoreCount_;
+};
+
+
+ScriptBreakPoint.prototype.enable = function() {
+  this.active_ = true;
+};
+
+
+ScriptBreakPoint.prototype.disable = function() {
+  this.active_ = false;
+};
+
+
+ScriptBreakPoint.prototype.setCondition = function(condition) {
+  this.condition_ = condition;
+};
+
+
+ScriptBreakPoint.prototype.setIgnoreCount = function(ignoreCount) {
+  this.ignoreCount_ = ignoreCount;
+
+  // Set ignore count on all break points created from this script break point.
+  for (var i = 0; i < this.break_points_.length; i++) {
+    this.break_points_[i].setIgnoreCount(ignoreCount);
+  }
+};
+
+
+// Check whether a script matches this script break point. Currently this is
+// only based on script name.
+ScriptBreakPoint.prototype.matchesScript = function(script) {
+  if (this.type_ == Debug.ScriptBreakPointType.ScriptId) {
+    return this.script_id_ == script.id;
+  } else {
+    // We might want to account columns here as well.
+    if (!(script.line_offset <= this.line_  &&
+          this.line_ < script.line_offset + script.lineCount())) {
+      return false;
+    }
+    if (this.type_ == Debug.ScriptBreakPointType.ScriptName) {
+      return this.script_name_ == script.nameOrSourceURL();
+    } else if (this.type_ == Debug.ScriptBreakPointType.ScriptRegExp) {
+      return this.script_regexp_object_.test(script.nameOrSourceURL());
+    } else {
+      throw new Error("Unexpected breakpoint type " + this.type_);
+    }
+  }
+};
+
+
+// Set the script break point in a script.
+ScriptBreakPoint.prototype.set = function (script) {
+  var column = this.column();
+  var line = this.line();
+  // If the column is undefined the break is on the line. To help locate the
+  // first piece of breakable code on the line try to find the column on the
+  // line which contains some source.
+  if (IS_UNDEFINED(column)) {
+    var source_line = script.sourceLine(this.line());
+
+    // Allocate array for caching the columns where the actual source starts.
+    if (!script.sourceColumnStart_) {
+      script.sourceColumnStart_ = new Array(script.lineCount());
+    }
+
+    // Fill cache if needed and get column where the actual source starts.
+    if (IS_UNDEFINED(script.sourceColumnStart_[line])) {
+      script.sourceColumnStart_[line] =
+          source_line.match(sourceLineBeginningSkip)[0].length;
+    }
+    column = script.sourceColumnStart_[line];
+  }
+
+  // Convert the line and column into an absolute position within the script.
+  var position = Debug.findScriptSourcePosition(script, this.line(), column);
+
+  // If the position is not found in the script (the script might be shorter
+  // than it used to be) just ignore it.
+  if (IS_NULL(position)) return;
+
+  // Create a break point object and set the break point.
+  var break_point = MakeBreakPoint(position, this);
+  break_point.setIgnoreCount(this.ignoreCount());
+  var actual_position = %SetScriptBreakPoint(script, position,
+                                             this.position_alignment_,
+                                             break_point);
+  if (IS_UNDEFINED(actual_position)) {
+    actual_position = position;
+  }
+  var actual_location = script.locationFromPosition(actual_position, true);
+  break_point.actual_location = { line: actual_location.line,
+                                  column: actual_location.column,
+                                  script_id: script.id };
+  this.break_points_.push(break_point);
+  return break_point;
+};
+
+
+// Clear all the break points created from this script break point
+ScriptBreakPoint.prototype.clear = function () {
+  var remaining_break_points = [];
+  for (var i = 0; i < break_points.length; i++) {
+    if (break_points[i].script_break_point() &&
+        break_points[i].script_break_point() === this) {
+      %ClearBreakPoint(break_points[i]);
+    } else {
+      remaining_break_points.push(break_points[i]);
+    }
+  }
+  break_points = remaining_break_points;
+  this.break_points_ = [];
+};
+
+
+// Function called from runtime when a new script is compiled to set any script
+// break points set in this script.
+function UpdateScriptBreakPoints(script) {
+  for (var i = 0; i < script_break_points.length; i++) {
+    var break_point = script_break_points[i];
+    if ((break_point.type() == Debug.ScriptBreakPointType.ScriptName ||
+         break_point.type() == Debug.ScriptBreakPointType.ScriptRegExp) &&
+        break_point.matchesScript(script)) {
+      break_point.set(script);
+    }
+  }
+}
+
+
+function GetScriptBreakPoints(script) {
+  var result = [];
+  for (var i = 0; i < script_break_points.length; i++) {
+    if (script_break_points[i].matchesScript(script)) {
+      result.push(script_break_points[i]);
+    }
+  }
+  return result;
+}
+
+
+Debug.setListener = function(listener, opt_data) {
+  if (!IS_FUNCTION(listener) && !IS_UNDEFINED(listener) && !IS_NULL(listener)) {
+    throw new Error('Parameters have wrong types.');
+  }
+  %SetDebugEventListener(listener, opt_data);
+};
+
+
+Debug.breakLocations = function(f, opt_position_aligment) {
+  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
+  var position_aligment = IS_UNDEFINED(opt_position_aligment)
+      ? Debug.BreakPositionAlignment.Statement : opt_position_aligment;
+  return %GetBreakLocations(f, position_aligment);
+};
+
+// Returns a Script object. If the parameter is a function the return value
+// is the script in which the function is defined. If the parameter is a string
+// the return value is the script for which the script name has that string
+// value.  If it is a regexp and there is a unique script whose name matches
+// we return that, otherwise undefined.
+Debug.findScript = function(func_or_script_name) {
+  if (IS_FUNCTION(func_or_script_name)) {
+    return %FunctionGetScript(func_or_script_name);
+  } else if (IS_REGEXP(func_or_script_name)) {
+    var scripts = Debug.scripts();
+    var last_result = null;
+    var result_count = 0;
+    for (var i in scripts) {
+      var script = scripts[i];
+      if (func_or_script_name.test(script.name)) {
+        last_result = script;
+        result_count++;
+      }
+    }
+    // Return the unique script matching the regexp.  If there are more
+    // than one we don't return a value since there is no good way to
+    // decide which one to return.  Returning a "random" one, say the
+    // first, would introduce nondeterminism (or something close to it)
+    // because the order is the heap iteration order.
+    if (result_count == 1) {
+      return last_result;
+    } else {
+      return undefined;
+    }
+  } else {
+    return %GetScript(func_or_script_name);
+  }
+};
+
+// Returns the script source. If the parameter is a function the return value
+// is the script source for the script in which the function is defined. If the
+// parameter is a string the return value is the script for which the script
+// name has that string value.
+Debug.scriptSource = function(func_or_script_name) {
+  return this.findScript(func_or_script_name).source;
+};
+
+
+Debug.source = function(f) {
+  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
+  return %FunctionGetSourceCode(f);
+};
+
+
+Debug.sourcePosition = function(f) {
+  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
+  return %FunctionGetScriptSourcePosition(f);
+};
+
+
+Debug.findFunctionSourceLocation = function(func, opt_line, opt_column) {
+  var script = %FunctionGetScript(func);
+  var script_offset = %FunctionGetScriptSourcePosition(func);
+  return script.locationFromLine(opt_line, opt_column, script_offset);
+};
+
+
+// Returns the character position in a script based on a line number and an
+// optional position within that line.
+Debug.findScriptSourcePosition = function(script, opt_line, opt_column) {
+  var location = script.locationFromLine(opt_line, opt_column);
+  return location ? location.position : null;
+};
+
+
+Debug.findBreakPoint = function(break_point_number, remove) {
+  var break_point;
+  for (var i = 0; i < break_points.length; i++) {
+    if (break_points[i].number() == break_point_number) {
+      break_point = break_points[i];
+      // Remove the break point from the list if requested.
+      if (remove) {
+        break_points.splice(i, 1);
+      }
+      break;
+    }
+  }
+  if (break_point) {
+    return break_point;
+  } else {
+    return this.findScriptBreakPoint(break_point_number, remove);
+  }
+};
+
+Debug.findBreakPointActualLocations = function(break_point_number) {
+  for (var i = 0; i < script_break_points.length; i++) {
+    if (script_break_points[i].number() == break_point_number) {
+      return script_break_points[i].actual_locations();
+    }
+  }
+  for (var i = 0; i < break_points.length; i++) {
+    if (break_points[i].number() == break_point_number) {
+      return [break_points[i].actual_location];
+    }
+  }
+  return [];
+};
+
+Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) {
+  if (!IS_FUNCTION(func)) throw new Error('Parameters have wrong types.');
+  // Break points in API functions are not supported.
+  if (%FunctionIsAPIFunction(func)) {
+    throw new Error('Cannot set break point in native code.');
+  }
+  // Find source position relative to start of the function
+  var break_position =
+      this.findFunctionSourceLocation(func, opt_line, opt_column).position;
+  var source_position = break_position - this.sourcePosition(func);
+  // Find the script for the function.
+  var script = %FunctionGetScript(func);
+  // Break in builtin JavaScript code is not supported.
+  if (script.type == Debug.ScriptType.Native) {
+    throw new Error('Cannot set break point in native code.');
+  }
+  // If the script for the function has a name convert this to a script break
+  // point.
+  if (script && script.id) {
+    // Adjust the source position to be script relative.
+    source_position += %FunctionGetScriptSourcePosition(func);
+    // Find line and column for the position in the script and set a script
+    // break point from that.
+    var location = script.locationFromPosition(source_position, false);
+    return this.setScriptBreakPointById(script.id,
+                                        location.line, location.column,
+                                        opt_condition);
+  } else {
+    // Set a break point directly on the function.
+    var break_point = MakeBreakPoint(source_position);
+    var actual_position =
+        %SetFunctionBreakPoint(func, source_position, break_point);
+    actual_position += this.sourcePosition(func);
+    var actual_location = script.locationFromPosition(actual_position, true);
+    break_point.actual_location = { line: actual_location.line,
+                                    column: actual_location.column,
+                                    script_id: script.id };
+    break_point.setCondition(opt_condition);
+    return break_point.number();
+  }
+};
+
+
+Debug.setBreakPointByScriptIdAndPosition = function(script_id, position,
+                                                    condition, enabled,
+                                                    opt_position_alignment)
+{
+  var break_point = MakeBreakPoint(position);
+  break_point.setCondition(condition);
+  if (!enabled) {
+    break_point.disable();
+  }
+  var scripts = this.scripts();
+  var position_alignment = IS_UNDEFINED(opt_position_alignment)
+      ? Debug.BreakPositionAlignment.Statement : opt_position_alignment;
+  for (var i = 0; i < scripts.length; i++) {
+    if (script_id == scripts[i].id) {
+      break_point.actual_position = %SetScriptBreakPoint(scripts[i], position,
+          position_alignment, break_point);
+      break;
+    }
+  }
+  return break_point;
+};
+
+
+Debug.enableBreakPoint = function(break_point_number) {
+  var break_point = this.findBreakPoint(break_point_number, false);
+  // Only enable if the breakpoint hasn't been deleted:
+  if (break_point) {
+    break_point.enable();
+  }
+};
+
+
+Debug.disableBreakPoint = function(break_point_number) {
+  var break_point = this.findBreakPoint(break_point_number, false);
+  // Only enable if the breakpoint hasn't been deleted:
+  if (break_point) {
+    break_point.disable();
+  }
+};
+
+
+Debug.changeBreakPointCondition = function(break_point_number, condition) {
+  var break_point = this.findBreakPoint(break_point_number, false);
+  break_point.setCondition(condition);
+};
+
+
+Debug.changeBreakPointIgnoreCount = function(break_point_number, ignoreCount) {
+  if (ignoreCount < 0) {
+    throw new Error('Invalid argument');
+  }
+  var break_point = this.findBreakPoint(break_point_number, false);
+  break_point.setIgnoreCount(ignoreCount);
+};
+
+
+Debug.clearBreakPoint = function(break_point_number) {
+  var break_point = this.findBreakPoint(break_point_number, true);
+  if (break_point) {
+    return %ClearBreakPoint(break_point);
+  } else {
+    break_point = this.findScriptBreakPoint(break_point_number, true);
+    if (!break_point) {
+      throw new Error('Invalid breakpoint');
+    }
+  }
+};
+
+
+Debug.clearAllBreakPoints = function() {
+  for (var i = 0; i < break_points.length; i++) {
+    var break_point = break_points[i];
+    %ClearBreakPoint(break_point);
+  }
+  break_points = [];
+};
+
+
+Debug.disableAllBreakPoints = function() {
+  // Disable all user defined breakpoints:
+  for (var i = 1; i < next_break_point_number; i++) {
+    Debug.disableBreakPoint(i);
+  }
+  // Disable all exception breakpoints:
+  %ChangeBreakOnException(Debug.ExceptionBreak.Caught, false);
+  %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, false);
+};
+
+
+Debug.findScriptBreakPoint = function(break_point_number, remove) {
+  var script_break_point;
+  for (var i = 0; i < script_break_points.length; i++) {
+    if (script_break_points[i].number() == break_point_number) {
+      script_break_point = script_break_points[i];
+      // Remove the break point from the list if requested.
+      if (remove) {
+        script_break_point.clear();
+        script_break_points.splice(i,1);
+      }
+      break;
+    }
+  }
+  return script_break_point;
+};
+
+
+// Sets a breakpoint in a script identified through id or name at the
+// specified source line and column within that line.
+Debug.setScriptBreakPoint = function(type, script_id_or_name,
+                                     opt_line, opt_column, opt_condition,
+                                     opt_groupId, opt_position_alignment) {
+  // Create script break point object.
+  var script_break_point =
+      new ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
+                           opt_groupId, opt_position_alignment);
+
+  // Assign number to the new script break point and add it.
+  script_break_point.number_ = next_break_point_number++;
+  script_break_point.setCondition(opt_condition);
+  script_break_points.push(script_break_point);
+
+  // Run through all scripts to see if this script break point matches any
+  // loaded scripts.
+  var scripts = this.scripts();
+  for (var i = 0; i < scripts.length; i++) {
+    if (script_break_point.matchesScript(scripts[i])) {
+      script_break_point.set(scripts[i]);
+    }
+  }
+
+  return script_break_point.number();
+};
+
+
+Debug.setScriptBreakPointById = function(script_id,
+                                         opt_line, opt_column,
+                                         opt_condition, opt_groupId,
+                                         opt_position_alignment) {
+  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
+                                  script_id, opt_line, opt_column,
+                                  opt_condition, opt_groupId,
+                                  opt_position_alignment);
+};
+
+
+Debug.setScriptBreakPointByName = function(script_name,
+                                           opt_line, opt_column,
+                                           opt_condition, opt_groupId) {
+  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptName,
+                                  script_name, opt_line, opt_column,
+                                  opt_condition, opt_groupId);
+};
+
+
+Debug.setScriptBreakPointByRegExp = function(script_regexp,
+                                             opt_line, opt_column,
+                                             opt_condition, opt_groupId) {
+  return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptRegExp,
+                                  script_regexp, opt_line, opt_column,
+                                  opt_condition, opt_groupId);
+};
+
+
+Debug.enableScriptBreakPoint = function(break_point_number) {
+  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
+  script_break_point.enable();
+};
+
+
+Debug.disableScriptBreakPoint = function(break_point_number) {
+  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
+  script_break_point.disable();
+};
+
+
+Debug.changeScriptBreakPointCondition = function(
+    break_point_number, condition) {
+  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
+  script_break_point.setCondition(condition);
+};
+
+
+Debug.changeScriptBreakPointIgnoreCount = function(
+    break_point_number, ignoreCount) {
+  if (ignoreCount < 0) {
+    throw new Error('Invalid argument');
+  }
+  var script_break_point = this.findScriptBreakPoint(break_point_number, false);
+  script_break_point.setIgnoreCount(ignoreCount);
+};
+
+
+Debug.scriptBreakPoints = function() {
+  return script_break_points;
+};
+
+
+Debug.clearStepping = function() {
+  %ClearStepping();
+};
+
+Debug.setBreakOnException = function() {
+  return %ChangeBreakOnException(Debug.ExceptionBreak.Caught, true);
+};
+
+Debug.clearBreakOnException = function() {
+  return %ChangeBreakOnException(Debug.ExceptionBreak.Caught, false);
+};
+
+Debug.isBreakOnException = function() {
+  return !!%IsBreakOnException(Debug.ExceptionBreak.Caught);
+};
+
+Debug.setBreakOnUncaughtException = function() {
+  return %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, true);
+};
+
+Debug.clearBreakOnUncaughtException = function() {
+  return %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, false);
+};
+
+Debug.isBreakOnUncaughtException = function() {
+  return !!%IsBreakOnException(Debug.ExceptionBreak.Uncaught);
+};
+
+Debug.showBreakPoints = function(f, full, opt_position_alignment) {
+  if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.');
+  var source = full ? this.scriptSource(f) : this.source(f);
+  var offset = full ? this.sourcePosition(f) : 0;
+  var locations = this.breakLocations(f, opt_position_alignment);
+  if (!locations) return source;
+  locations.sort(function(x, y) { return x - y; });
+  var result = "";
+  var prev_pos = 0;
+  var pos;
+  for (var i = 0; i < locations.length; i++) {
+    pos = locations[i] - offset;
+    result += source.slice(prev_pos, pos);
+    result += "[B" + i + "]";
+    prev_pos = pos;
+  }
+  pos = source.length;
+  result += source.substring(prev_pos, pos);
+  return result;
+};
+
+
+// Get all the scripts currently loaded. Locating all the scripts is based on
+// scanning the heap.
+Debug.scripts = function() {
+  // Collect all scripts in the heap.
+  return %DebugGetLoadedScripts();
+};
+
+
+Debug.debuggerFlags = function() {
+  return debugger_flags;
+};
+
+Debug.MakeMirror = MakeMirror;
+
+function MakeExecutionState(break_id) {
+  return new ExecutionState(break_id);
+}
+
+function ExecutionState(break_id) {
+  this.break_id = break_id;
+  this.selected_frame = 0;
+}
+
+ExecutionState.prototype.prepareStep = function(opt_action, opt_count,
+    opt_callframe) {
+  var action = Debug.StepAction.StepIn;
+  if (!IS_UNDEFINED(opt_action)) action = builtins.$toNumber(opt_action);
+  var count = opt_count ? builtins.$toNumber(opt_count) : 1;
+  var callFrameId = 0;
+  if (!IS_UNDEFINED(opt_callframe)) {
+    callFrameId = opt_callframe.details_.frameId();
+  }
+
+  return %PrepareStep(this.break_id, action, count, callFrameId);
+};
+
+ExecutionState.prototype.evaluateGlobal = function(source, disable_break,
+    opt_additional_context) {
+  return MakeMirror(%DebugEvaluateGlobal(this.break_id, source,
+                                         Boolean(disable_break),
+                                         opt_additional_context));
+};
+
+ExecutionState.prototype.frameCount = function() {
+  return %GetFrameCount(this.break_id);
+};
+
+ExecutionState.prototype.threadCount = function() {
+  return %GetThreadCount(this.break_id);
+};
+
+ExecutionState.prototype.frame = function(opt_index) {
+  // If no index supplied return the selected frame.
+  if (opt_index == null) opt_index = this.selected_frame;
+  if (opt_index < 0 || opt_index >= this.frameCount()) {
+    throw new Error('Illegal frame index.');
+  }
+  return new FrameMirror(this.break_id, opt_index);
+};
+
+ExecutionState.prototype.setSelectedFrame = function(index) {
+  var i = builtins.$toNumber(index);
+  if (i < 0 || i >= this.frameCount()) throw new Error('Illegal frame index.');
+  this.selected_frame = i;
+};
+
+ExecutionState.prototype.selectedFrame = function() {
+  return this.selected_frame;
+};
+
+ExecutionState.prototype.debugCommandProcessor = function(opt_is_running) {
+  return new DebugCommandProcessor(this, opt_is_running);
+};
+
+
+function MakeBreakEvent(break_id, break_points_hit) {
+  return new BreakEvent(break_id, break_points_hit);
+}
+
+
+function BreakEvent(break_id, break_points_hit) {
+  this.frame_ = new FrameMirror(break_id, 0);
+  this.break_points_hit_ = break_points_hit;
+}
+
+
+BreakEvent.prototype.eventType = function() {
+  return Debug.DebugEvent.Break;
+};
+
+
+BreakEvent.prototype.func = function() {
+  return this.frame_.func();
+};
+
+
+BreakEvent.prototype.sourceLine = function() {
+  return this.frame_.sourceLine();
+};
+
+
+BreakEvent.prototype.sourceColumn = function() {
+  return this.frame_.sourceColumn();
+};
+
+
+BreakEvent.prototype.sourceLineText = function() {
+  return this.frame_.sourceLineText();
+};
+
+
+BreakEvent.prototype.breakPointsHit = function() {
+  return this.break_points_hit_;
+};
+
+
+BreakEvent.prototype.toJSONProtocol = function() {
+  var o = { seq: next_response_seq++,
+            type: "event",
+            event: "break",
+            body: { invocationText: this.frame_.invocationText() }
+          };
+
+  // Add script related information to the event if available.
+  var script = this.func().script();
+  if (script) {
+    o.body.sourceLine = this.sourceLine(),
+    o.body.sourceColumn = this.sourceColumn(),
+    o.body.sourceLineText = this.sourceLineText(),
+    o.body.script = MakeScriptObject_(script, false);
+  }
+
+  // Add an Array of break points hit if any.
+  if (this.breakPointsHit()) {
+    o.body.breakpoints = [];
+    for (var i = 0; i < this.breakPointsHit().length; i++) {
+      // Find the break point number. For break points originating from a
+      // script break point supply the script break point number.
+      var breakpoint = this.breakPointsHit()[i];
+      var script_break_point = breakpoint.script_break_point();
+      var number;
+      if (script_break_point) {
+        number = script_break_point.number();
+      } else {
+        number = breakpoint.number();
+      }
+      o.body.breakpoints.push(number);
+    }
+  }
+  return JSON.stringify(ObjectToProtocolObject_(o));
+};
+
+
+function MakeExceptionEvent(break_id, exception, uncaught, promise) {
+  return new ExceptionEvent(break_id, exception, uncaught, promise);
+}
+
+
+function ExceptionEvent(break_id, exception, uncaught, promise) {
+  this.exec_state_ = new ExecutionState(break_id);
+  this.exception_ = exception;
+  this.uncaught_ = uncaught;
+  this.promise_ = promise;
+}
+
+
+ExceptionEvent.prototype.eventType = function() {
+  return Debug.DebugEvent.Exception;
+};
+
+
+ExceptionEvent.prototype.exception = function() {
+  return this.exception_;
+};
+
+
+ExceptionEvent.prototype.uncaught = function() {
+  return this.uncaught_;
+};
+
+
+ExceptionEvent.prototype.promise = function() {
+  return this.promise_;
+};
+
+
+ExceptionEvent.prototype.func = function() {
+  return this.exec_state_.frame(0).func();
+};
+
+
+ExceptionEvent.prototype.sourceLine = function() {
+  return this.exec_state_.frame(0).sourceLine();
+};
+
+
+ExceptionEvent.prototype.sourceColumn = function() {
+  return this.exec_state_.frame(0).sourceColumn();
+};
+
+
+ExceptionEvent.prototype.sourceLineText = function() {
+  return this.exec_state_.frame(0).sourceLineText();
+};
+
+
+ExceptionEvent.prototype.toJSONProtocol = function() {
+  var o = new ProtocolMessage();
+  o.event = "exception";
+  o.body = { uncaught: this.uncaught_,
+             exception: MakeMirror(this.exception_)
+           };
+
+  // Exceptions might happen whithout any JavaScript frames.
+  if (this.exec_state_.frameCount() > 0) {
+    o.body.sourceLine = this.sourceLine();
+    o.body.sourceColumn = this.sourceColumn();
+    o.body.sourceLineText = this.sourceLineText();
+
+    // Add script information to the event if available.
+    var script = this.func().script();
+    if (script) {
+      o.body.script = MakeScriptObject_(script, false);
+    }
+  } else {
+    o.body.sourceLine = -1;
+  }
+
+  return o.toJSONProtocol();
+};
+
+
+function MakeCompileEvent(script, type) {
+  return new CompileEvent(script, type);
+}
+
+
+function CompileEvent(script, type) {
+  this.script_ = MakeMirror(script);
+  this.type_ = type;
+}
+
+
+CompileEvent.prototype.eventType = function() {
+  return this.type_;
+};
+
+
+CompileEvent.prototype.script = function() {
+  return this.script_;
+};
+
+
+CompileEvent.prototype.toJSONProtocol = function() {
+  var o = new ProtocolMessage();
+  o.running = true;
+  switch (this.type_) {
+    case Debug.DebugEvent.BeforeCompile:
+      o.event = "beforeCompile";
+      break;
+    case Debug.DebugEvent.AfterCompile:
+      o.event = "afterCompile";
+      break;
+    case Debug.DebugEvent.CompileError:
+      o.event = "compileError";
+      break;
+  }
+  o.body = {};
+  o.body.script = this.script_;
+
+  return o.toJSONProtocol();
+};
+
+
+function MakeScriptObject_(script, include_source) {
+  var o = { id: script.id(),
+            name: script.name(),
+            lineOffset: script.lineOffset(),
+            columnOffset: script.columnOffset(),
+            lineCount: script.lineCount(),
+          };
+  if (!IS_UNDEFINED(script.data())) {
+    o.data = script.data();
+  }
+  if (include_source) {
+    o.source = script.source();
+  }
+  return o;
+}
+
+
+function MakePromiseEvent(event_data) {
+  return new PromiseEvent(event_data);
+}
+
+
+function PromiseEvent(event_data) {
+  this.promise_ = event_data.promise;
+  this.parentPromise_ = event_data.parentPromise;
+  this.status_ = event_data.status;
+  this.value_ = event_data.value;
+}
+
+
+PromiseEvent.prototype.promise = function() {
+  return MakeMirror(this.promise_);
+}
+
+
+PromiseEvent.prototype.parentPromise = function() {
+  return MakeMirror(this.parentPromise_);
+}
+
+
+PromiseEvent.prototype.status = function() {
+  return this.status_;
+}
+
+
+PromiseEvent.prototype.value = function() {
+  return MakeMirror(this.value_);
+}
+
+
+function MakeAsyncTaskEvent(event_data) {
+  return new AsyncTaskEvent(event_data);
+}
+
+
+function AsyncTaskEvent(event_data) {
+  this.type_ = event_data.type;
+  this.name_ = event_data.name;
+  this.id_ = event_data.id;
+}
+
+
+AsyncTaskEvent.prototype.type = function() {
+  return this.type_;
+}
+
+
+AsyncTaskEvent.prototype.name = function() {
+  return this.name_;
+}
+
+
+AsyncTaskEvent.prototype.id = function() {
+  return this.id_;
+}
+
+
+function DebugCommandProcessor(exec_state, opt_is_running) {
+  this.exec_state_ = exec_state;
+  this.running_ = opt_is_running || false;
+}
+
+
+DebugCommandProcessor.prototype.processDebugRequest = function (request) {
+  return this.processDebugJSONRequest(request);
+};
+
+
+function ProtocolMessage(request) {
+  // Update sequence number.
+  this.seq = next_response_seq++;
+
+  if (request) {
+    // If message is based on a request this is a response. Fill the initial
+    // response from the request.
+    this.type = 'response';
+    this.request_seq = request.seq;
+    this.command = request.command;
+  } else {
+    // If message is not based on a request it is a dabugger generated event.
+    this.type = 'event';
+  }
+  this.success = true;
+  // Handler may set this field to control debugger state.
+  this.running = undefined;
+}
+
+
+ProtocolMessage.prototype.setOption = function(name, value) {
+  if (!this.options_) {
+    this.options_ = {};
+  }
+  this.options_[name] = value;
+};
+
+
+ProtocolMessage.prototype.failed = function(message, opt_details) {
+  this.success = false;
+  this.message = message;
+  if (IS_OBJECT(opt_details)) {
+    this.error_details = opt_details;
+  }
+};
+
+
+ProtocolMessage.prototype.toJSONProtocol = function() {
+  // Encode the protocol header.
+  var json = {};
+  json.seq= this.seq;
+  if (this.request_seq) {
+    json.request_seq = this.request_seq;
+  }
+  json.type = this.type;
+  if (this.event) {
+    json.event = this.event;
+  }
+  if (this.command) {
+    json.command = this.command;
+  }
+  if (this.success) {
+    json.success = this.success;
+  } else {
+    json.success = false;
+  }
+  if (this.body) {
+    // Encode the body part.
+    var bodyJson;
+    var serializer = MakeMirrorSerializer(true, this.options_);
+    if (this.body instanceof Mirror) {
+      bodyJson = serializer.serializeValue(this.body);
+    } else if (this.body instanceof Array) {
+      bodyJson = [];
+      for (var i = 0; i < this.body.length; i++) {
+        if (this.body[i] instanceof Mirror) {
+          bodyJson.push(serializer.serializeValue(this.body[i]));
+        } else {
+          bodyJson.push(ObjectToProtocolObject_(this.body[i], serializer));
+        }
+      }
+    } else {
+      bodyJson = ObjectToProtocolObject_(this.body, serializer);
+    }
+    json.body = bodyJson;
+    json.refs = serializer.serializeReferencedObjects();
+  }
+  if (this.message) {
+    json.message = this.message;
+  }
+  if (this.error_details) {
+    json.error_details = this.error_details;
+  }
+  json.running = this.running;
+  return JSON.stringify(json);
+};
+
+
+DebugCommandProcessor.prototype.createResponse = function(request) {
+  return new ProtocolMessage(request);
+};
+
+
+DebugCommandProcessor.prototype.processDebugJSONRequest = function(
+    json_request) {
+  var request;  // Current request.
+  var response;  // Generated response.
+  try {
+    try {
+      // Convert the JSON string to an object.
+      request = JSON.parse(json_request);
+
+      // Create an initial response.
+      response = this.createResponse(request);
+
+      if (!request.type) {
+        throw new Error('Type not specified');
+      }
+
+      if (request.type != 'request') {
+        throw new Error("Illegal type '" + request.type + "' in request");
+      }
+
+      if (!request.command) {
+        throw new Error('Command not specified');
+      }
+
+      if (request.arguments) {
+        var args = request.arguments;
+        // TODO(yurys): remove request.arguments.compactFormat check once
+        // ChromeDevTools are switched to 'inlineRefs'
+        if (args.inlineRefs || args.compactFormat) {
+          response.setOption('inlineRefs', true);
+        }
+        if (!IS_UNDEFINED(args.maxStringLength)) {
+          response.setOption('maxStringLength', args.maxStringLength);
+        }
+      }
+
+      var key = request.command.toLowerCase();
+      var handler = DebugCommandProcessor.prototype.dispatch_[key];
+      if (IS_FUNCTION(handler)) {
+        %_CallFunction(this, request, response, handler);
+      } else {
+        throw new Error('Unknown command "' + request.command + '" in request');
+      }
+    } catch (e) {
+      // If there is no response object created one (without command).
+      if (!response) {
+        response = this.createResponse();
+      }
+      response.success = false;
+      response.message = builtins.$toString(e);
+    }
+
+    // Return the response as a JSON encoded string.
+    try {
+      if (!IS_UNDEFINED(response.running)) {
+        // Response controls running state.
+        this.running_ = response.running;
+      }
+      response.running = this.running_;
+      return response.toJSONProtocol();
+    } catch (e) {
+      // Failed to generate response - return generic error.
+      return '{"seq":' + response.seq + ',' +
+              '"request_seq":' + request.seq + ',' +
+              '"type":"response",' +
+              '"success":false,' +
+              '"message":"Internal error: ' + builtins.$toString(e) + '"}';
+    }
+  } catch (e) {
+    // Failed in one of the catch blocks above - most generic error.
+    return '{"seq":0,"type":"response","success":false,"message":"Internal error"}';
+  }
+};
+
+
+DebugCommandProcessor.prototype.continueRequest_ = function(request, response) {
+  // Check for arguments for continue.
+  if (request.arguments) {
+    var count = 1;
+    var action = Debug.StepAction.StepIn;
+
+    // Pull out arguments.
+    var stepaction = request.arguments.stepaction;
+    var stepcount = request.arguments.stepcount;
+
+    // Get the stepcount argument if any.
+    if (stepcount) {
+      count = builtins.$toNumber(stepcount);
+      if (count < 0) {
+        throw new Error('Invalid stepcount argument "' + stepcount + '".');
+      }
+    }
+
+    // Get the stepaction argument.
+    if (stepaction) {
+      if (stepaction == 'in') {
+        action = Debug.StepAction.StepIn;
+      } else if (stepaction == 'min') {
+        action = Debug.StepAction.StepMin;
+      } else if (stepaction == 'next') {
+        action = Debug.StepAction.StepNext;
+      } else if (stepaction == 'out') {
+        action = Debug.StepAction.StepOut;
+      } else {
+        throw new Error('Invalid stepaction argument "' + stepaction + '".');
+      }
+    }
+
+    // Set up the VM for stepping.
+    this.exec_state_.prepareStep(action, count);
+  }
+
+  // VM should be running after executing this request.
+  response.running = true;
+};
+
+
+DebugCommandProcessor.prototype.breakRequest_ = function(request, response) {
+  // Ignore as break command does not do anything when broken.
+};
+
+
+DebugCommandProcessor.prototype.setBreakPointRequest_ =
+    function(request, response) {
+  // Check for legal request.
+  if (!request.arguments) {
+    response.failed('Missing arguments');
+    return;
+  }
+
+  // Pull out arguments.
+  var type = request.arguments.type;
+  var target = request.arguments.target;
+  var line = request.arguments.line;
+  var column = request.arguments.column;
+  var enabled = IS_UNDEFINED(request.arguments.enabled) ?
+      true : request.arguments.enabled;
+  var condition = request.arguments.condition;
+  var ignoreCount = request.arguments.ignoreCount;
+  var groupId = request.arguments.groupId;
+
+  // Check for legal arguments.
+  if (!type || IS_UNDEFINED(target)) {
+    response.failed('Missing argument "type" or "target"');
+    return;
+  }
+
+  // Either function or script break point.
+  var break_point_number;
+  if (type == 'function') {
+    // Handle function break point.
+    if (!IS_STRING(target)) {
+      response.failed('Argument "target" is not a string value');
+      return;
+    }
+    var f;
+    try {
+      // Find the function through a global evaluate.
+      f = this.exec_state_.evaluateGlobal(target).value();
+    } catch (e) {
+      response.failed('Error: "' + builtins.$toString(e) +
+                      '" evaluating "' + target + '"');
+      return;
+    }
+    if (!IS_FUNCTION(f)) {
+      response.failed('"' + target + '" does not evaluate to a function');
+      return;
+    }
+
+    // Set function break point.
+    break_point_number = Debug.setBreakPoint(f, line, column, condition);
+  } else if (type == 'handle') {
+    // Find the object pointed by the specified handle.
+    var handle = parseInt(target, 10);
+    var mirror = LookupMirror(handle);
+    if (!mirror) {
+      return response.failed('Object #' + handle + '# not found');
+    }
+    if (!mirror.isFunction()) {
+      return response.failed('Object #' + handle + '# is not a function');
+    }
+
+    // Set function break point.
+    break_point_number = Debug.setBreakPoint(mirror.value(),
+                                             line, column, condition);
+  } else if (type == 'script') {
+    // set script break point.
+    break_point_number =
+        Debug.setScriptBreakPointByName(target, line, column, condition,
+                                        groupId);
+  } else if (type == 'scriptId') {
+    break_point_number =
+        Debug.setScriptBreakPointById(target, line, column, condition, groupId);
+  } else if (type == 'scriptRegExp') {
+    break_point_number =
+        Debug.setScriptBreakPointByRegExp(target, line, column, condition,
+                                          groupId);
+  } else {
+    response.failed('Illegal type "' + type + '"');
+    return;
+  }
+
+  // Set additional break point properties.
+  var break_point = Debug.findBreakPoint(break_point_number);
+  if (ignoreCount) {
+    Debug.changeBreakPointIgnoreCount(break_point_number, ignoreCount);
+  }
+  if (!enabled) {
+    Debug.disableBreakPoint(break_point_number);
+  }
+
+  // Add the break point number to the response.
+  response.body = { type: type,
+                    breakpoint: break_point_number };
+
+  // Add break point information to the response.
+  if (break_point instanceof ScriptBreakPoint) {
+    if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
+      response.body.type = 'scriptId';
+      response.body.script_id = break_point.script_id();
+    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptName) {
+      response.body.type = 'scriptName';
+      response.body.script_name = break_point.script_name();
+    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptRegExp) {
+      response.body.type = 'scriptRegExp';
+      response.body.script_regexp = break_point.script_regexp_object().source;
+    } else {
+      throw new Error("Internal error: Unexpected breakpoint type: " +
+                      break_point.type());
+    }
+    response.body.line = break_point.line();
+    response.body.column = break_point.column();
+    response.body.actual_locations = break_point.actual_locations();
+  } else {
+    response.body.type = 'function';
+    response.body.actual_locations = [break_point.actual_location];
+  }
+};
+
+
+DebugCommandProcessor.prototype.changeBreakPointRequest_ = function(
+    request, response) {
+  // Check for legal request.
+  if (!request.arguments) {
+    response.failed('Missing arguments');
+    return;
+  }
+
+  // Pull out arguments.
+  var break_point = builtins.$toNumber(request.arguments.breakpoint);
+  var enabled = request.arguments.enabled;
+  var condition = request.arguments.condition;
+  var ignoreCount = request.arguments.ignoreCount;
+
+  // Check for legal arguments.
+  if (!break_point) {
+    response.failed('Missing argument "breakpoint"');
+    return;
+  }
+
+  // Change enabled state if supplied.
+  if (!IS_UNDEFINED(enabled)) {
+    if (enabled) {
+      Debug.enableBreakPoint(break_point);
+    } else {
+      Debug.disableBreakPoint(break_point);
+    }
+  }
+
+  // Change condition if supplied
+  if (!IS_UNDEFINED(condition)) {
+    Debug.changeBreakPointCondition(break_point, condition);
+  }
+
+  // Change ignore count if supplied
+  if (!IS_UNDEFINED(ignoreCount)) {
+    Debug.changeBreakPointIgnoreCount(break_point, ignoreCount);
+  }
+};
+
+
+DebugCommandProcessor.prototype.clearBreakPointGroupRequest_ = function(
+    request, response) {
+  // Check for legal request.
+  if (!request.arguments) {
+    response.failed('Missing arguments');
+    return;
+  }
+
+  // Pull out arguments.
+  var group_id = request.arguments.groupId;
+
+  // Check for legal arguments.
+  if (!group_id) {
+    response.failed('Missing argument "groupId"');
+    return;
+  }
+
+  var cleared_break_points = [];
+  var new_script_break_points = [];
+  for (var i = 0; i < script_break_points.length; i++) {
+    var next_break_point = script_break_points[i];
+    if (next_break_point.groupId() == group_id) {
+      cleared_break_points.push(next_break_point.number());
+      next_break_point.clear();
+    } else {
+      new_script_break_points.push(next_break_point);
+    }
+  }
+  script_break_points = new_script_break_points;
+
+  // Add the cleared break point numbers to the response.
+  response.body = { breakpoints: cleared_break_points };
+};
+
+
+DebugCommandProcessor.prototype.clearBreakPointRequest_ = function(
+    request, response) {
+  // Check for legal request.
+  if (!request.arguments) {
+    response.failed('Missing arguments');
+    return;
+  }
+
+  // Pull out arguments.
+  var break_point = builtins.$toNumber(request.arguments.breakpoint);
+
+  // Check for legal arguments.
+  if (!break_point) {
+    response.failed('Missing argument "breakpoint"');
+    return;
+  }
+
+  // Clear break point.
+  Debug.clearBreakPoint(break_point);
+
+  // Add the cleared break point number to the response.
+  response.body = { breakpoint: break_point };
+};
+
+
+DebugCommandProcessor.prototype.listBreakpointsRequest_ = function(
+    request, response) {
+  var array = [];
+  for (var i = 0; i < script_break_points.length; i++) {
+    var break_point = script_break_points[i];
+
+    var description = {
+      number: break_point.number(),
+      line: break_point.line(),
+      column: break_point.column(),
+      groupId: break_point.groupId(),
+      hit_count: break_point.hit_count(),
+      active: break_point.active(),
+      condition: break_point.condition(),
+      ignoreCount: break_point.ignoreCount(),
+      actual_locations: break_point.actual_locations()
+    };
+
+    if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
+      description.type = 'scriptId';
+      description.script_id = break_point.script_id();
+    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptName) {
+      description.type = 'scriptName';
+      description.script_name = break_point.script_name();
+    } else if (break_point.type() == Debug.ScriptBreakPointType.ScriptRegExp) {
+      description.type = 'scriptRegExp';
+      description.script_regexp = break_point.script_regexp_object().source;
+    } else {
+      throw new Error("Internal error: Unexpected breakpoint type: " +
+                      break_point.type());
+    }
+    array.push(description);
+  }
+
+  response.body = {
+    breakpoints: array,
+    breakOnExceptions: Debug.isBreakOnException(),
+    breakOnUncaughtExceptions: Debug.isBreakOnUncaughtException()
+  };
+};
+
+
+DebugCommandProcessor.prototype.disconnectRequest_ =
+    function(request, response) {
+  Debug.disableAllBreakPoints();
+  this.continueRequest_(request, response);
+};
+
+
+DebugCommandProcessor.prototype.setExceptionBreakRequest_ =
+    function(request, response) {
+  // Check for legal request.
+  if (!request.arguments) {
+    response.failed('Missing arguments');
+    return;
+  }
+
+  // Pull out and check the 'type' argument:
+  var type = request.arguments.type;
+  if (!type) {
+    response.failed('Missing argument "type"');
+    return;
+  }
+
+  // Initialize the default value of enable:
+  var enabled;
+  if (type == 'all') {
+    enabled = !Debug.isBreakOnException();
+  } else if (type == 'uncaught') {
+    enabled = !Debug.isBreakOnUncaughtException();
+  }
+
+  // Pull out and check the 'enabled' argument if present:
+  if (!IS_UNDEFINED(request.arguments.enabled)) {
+    enabled = request.arguments.enabled;
+    if ((enabled != true) && (enabled != false)) {
+      response.failed('Illegal value for "enabled":"' + enabled + '"');
+    }
+  }
+
+  // Now set the exception break state:
+  if (type == 'all') {
+    %ChangeBreakOnException(Debug.ExceptionBreak.Caught, enabled);
+  } else if (type == 'uncaught') {
+    %ChangeBreakOnException(Debug.ExceptionBreak.Uncaught, enabled);
+  } else {
+    response.failed('Unknown "type":"' + type + '"');
+  }
+
+  // Add the cleared break point number to the response.
+  response.body = { 'type': type, 'enabled': enabled };
+};
+
+
+DebugCommandProcessor.prototype.backtraceRequest_ = function(
+    request, response) {
+  // Get the number of frames.
+  var total_frames = this.exec_state_.frameCount();
+
+  // Create simple response if there are no frames.
+  if (total_frames == 0) {
+    response.body = {
+      totalFrames: total_frames
+    };
+    return;
+  }
+
+  // Default frame range to include in backtrace.
+  var from_index = 0;
+  var to_index = kDefaultBacktraceLength;
+
+  // Get the range from the arguments.
+  if (request.arguments) {
+    if (request.arguments.fromFrame) {
+      from_index = request.arguments.fromFrame;
+    }
+    if (request.arguments.toFrame) {
+      to_index = request.arguments.toFrame;
+    }
+    if (request.arguments.bottom) {
+      var tmp_index = total_frames - from_index;
+      from_index = total_frames - to_index;
+      to_index = tmp_index;
+    }
+    if (from_index < 0 || to_index < 0) {
+      return response.failed('Invalid frame number');
+    }
+  }
+
+  // Adjust the index.
+  to_index = Math.min(total_frames, to_index);
+
+  if (to_index <= from_index) {
+    var error = 'Invalid frame range';
+    return response.failed(error);
+  }
+
+  // Create the response body.
+  var frames = [];
+  for (var i = from_index; i < to_index; i++) {
+    frames.push(this.exec_state_.frame(i));
+  }
+  response.body = {
+    fromFrame: from_index,
+    toFrame: to_index,
+    totalFrames: total_frames,
+    frames: frames
+  };
+};
+
+
+DebugCommandProcessor.prototype.frameRequest_ = function(request, response) {
+  // No frames no source.
+  if (this.exec_state_.frameCount() == 0) {
+    return response.failed('No frames');
+  }
+
+  // With no arguments just keep the selected frame.
+  if (request.arguments) {
+    var index = request.arguments.number;
+    if (index < 0 || this.exec_state_.frameCount() <= index) {
+      return response.failed('Invalid frame number');
+    }
+
+    this.exec_state_.setSelectedFrame(request.arguments.number);
+  }
+  response.body = this.exec_state_.frame();
+};
+
+
+DebugCommandProcessor.prototype.resolveFrameFromScopeDescription_ =
+    function(scope_description) {
+  // Get the frame for which the scope or scopes are requested.
+  // With no frameNumber argument use the currently selected frame.
+  if (scope_description && !IS_UNDEFINED(scope_description.frameNumber)) {
+    var frame_index = scope_description.frameNumber;
+    if (frame_index < 0 || this.exec_state_.frameCount() <= frame_index) {
+      throw new Error('Invalid frame number');
+    }
+    return this.exec_state_.frame(frame_index);
+  } else {
+    return this.exec_state_.frame();
+  }
+};
+
+
+// Gets scope host object from request. It is either a function
+// ('functionHandle' argument must be specified) or a stack frame
+// ('frameNumber' may be specified and the current frame is taken by default).
+DebugCommandProcessor.prototype.resolveScopeHolder_ =
+    function(scope_description) {
+  if (scope_description && "functionHandle" in scope_description) {
+    if (!IS_NUMBER(scope_description.functionHandle)) {
+      throw new Error('Function handle must be a number');
+    }
+    var function_mirror = LookupMirror(scope_description.functionHandle);
+    if (!function_mirror) {
+      throw new Error('Failed to find function object by handle');
+    }
+    if (!function_mirror.isFunction()) {
+      throw new Error('Value of non-function type is found by handle');
+    }
+    return function_mirror;
+  } else {
+    // No frames no scopes.
+    if (this.exec_state_.frameCount() == 0) {
+      throw new Error('No scopes');
+    }
+
+    // Get the frame for which the scopes are requested.
+    var frame = this.resolveFrameFromScopeDescription_(scope_description);
+    return frame;
+  }
+}
+
+
+DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) {
+  var scope_holder = this.resolveScopeHolder_(request.arguments);
+
+  // Fill all scopes for this frame or function.
+  var total_scopes = scope_holder.scopeCount();
+  var scopes = [];
+  for (var i = 0; i < total_scopes; i++) {
+    scopes.push(scope_holder.scope(i));
+  }
+  response.body = {
+    fromScope: 0,
+    toScope: total_scopes,
+    totalScopes: total_scopes,
+    scopes: scopes
+  };
+};
+
+
+DebugCommandProcessor.prototype.scopeRequest_ = function(request, response) {
+  // Get the frame or function for which the scope is requested.
+  var scope_holder = this.resolveScopeHolder_(request.arguments);
+
+  // With no scope argument just return top scope.
+  var scope_index = 0;
+  if (request.arguments && !IS_UNDEFINED(request.arguments.number)) {
+    scope_index = builtins.$toNumber(request.arguments.number);
+    if (scope_index < 0 || scope_holder.scopeCount() <= scope_index) {
+      return response.failed('Invalid scope number');
+    }
+  }
+
+  response.body = scope_holder.scope(scope_index);
+};
+
+
+// Reads value from protocol description. Description may be in form of type
+// (for singletons), raw value (primitive types supported in JSON),
+// string value description plus type (for primitive values) or handle id.
+// Returns raw value or throws exception.
+DebugCommandProcessor.resolveValue_ = function(value_description) {
+  if ("handle" in value_description) {
+    var value_mirror = LookupMirror(value_description.handle);
+    if (!value_mirror) {
+      throw new Error("Failed to resolve value by handle, ' #" +
+          value_description.handle + "# not found");
+    }
+    return value_mirror.value();
+  } else if ("stringDescription" in value_description) {
+    if (value_description.type == BOOLEAN_TYPE) {
+      return Boolean(value_description.stringDescription);
+    } else if (value_description.type == NUMBER_TYPE) {
+      return Number(value_description.stringDescription);
+    } if (value_description.type == STRING_TYPE) {
+      return String(value_description.stringDescription);
+    } else {
+      throw new Error("Unknown type");
+    }
+  } else if ("value" in value_description) {
+    return value_description.value;
+  } else if (value_description.type == UNDEFINED_TYPE) {
+    return UNDEFINED;
+  } else if (value_description.type == NULL_TYPE) {
+    return null;
+  } else {
+    throw new Error("Failed to parse value description");
+  }
+};
+
+
+DebugCommandProcessor.prototype.setVariableValueRequest_ =
+    function(request, response) {
+  if (!request.arguments) {
+    response.failed('Missing arguments');
+    return;
+  }
+
+  if (IS_UNDEFINED(request.arguments.name)) {
+    response.failed('Missing variable name');
+  }
+  var variable_name = request.arguments.name;
+
+  var scope_description = request.arguments.scope;
+
+  // Get the frame or function for which the scope is requested.
+  var scope_holder = this.resolveScopeHolder_(scope_description);
+
+  if (IS_UNDEFINED(scope_description.number)) {
+    response.failed('Missing scope number');
+  }
+  var scope_index = builtins.$toNumber(scope_description.number);
+
+  var scope = scope_holder.scope(scope_index);
+
+  var new_value =
+      DebugCommandProcessor.resolveValue_(request.arguments.newValue);
+
+  scope.setVariableValue(variable_name, new_value);
+
+  var new_value_mirror = MakeMirror(new_value);
+
+  response.body = {
+    newValue: new_value_mirror
+  };
+};
+
+
+DebugCommandProcessor.prototype.evaluateRequest_ = function(request, response) {
+  if (!request.arguments) {
+    return response.failed('Missing arguments');
+  }
+
+  // Pull out arguments.
+  var expression = request.arguments.expression;
+  var frame = request.arguments.frame;
+  var global = request.arguments.global;
+  var disable_break = request.arguments.disable_break;
+  var additional_context = request.arguments.additional_context;
+
+  // The expression argument could be an integer so we convert it to a
+  // string.
+  try {
+    expression = String(expression);
+  } catch(e) {
+    return response.failed('Failed to convert expression argument to string');
+  }
+
+  // Check for legal arguments.
+  if (!IS_UNDEFINED(frame) && global) {
+    return response.failed('Arguments "frame" and "global" are exclusive');
+  }
+
+  var additional_context_object;
+  if (additional_context) {
+    additional_context_object = {};
+    for (var i = 0; i < additional_context.length; i++) {
+      var mapping = additional_context[i];
+
+      if (!IS_STRING(mapping.name)) {
+        return response.failed("Context element #" + i +
+            " doesn't contain name:string property");
+      }
+
+      var raw_value = DebugCommandProcessor.resolveValue_(mapping);
+      additional_context_object[mapping.name] = raw_value;
+    }
+  }
+
+  // Global evaluate.
+  if (global) {
+    // Evaluate in the native context.
+    response.body = this.exec_state_.evaluateGlobal(
+        expression, Boolean(disable_break), additional_context_object);
+    return;
+  }
+
+  // Default value for disable_break is true.
+  if (IS_UNDEFINED(disable_break)) {
+    disable_break = true;
+  }
+
+  // No frames no evaluate in frame.
+  if (this.exec_state_.frameCount() == 0) {
+    return response.failed('No frames');
+  }
+
+  // Check whether a frame was specified.
+  if (!IS_UNDEFINED(frame)) {
+    var frame_number = builtins.$toNumber(frame);
+    if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
+      return response.failed('Invalid frame "' + frame + '"');
+    }
+    // Evaluate in the specified frame.
+    response.body = this.exec_state_.frame(frame_number).evaluate(
+        expression, Boolean(disable_break), additional_context_object);
+    return;
+  } else {
+    // Evaluate in the selected frame.
+    response.body = this.exec_state_.frame().evaluate(
+        expression, Boolean(disable_break), additional_context_object);
+    return;
+  }
+};
+
+
+DebugCommandProcessor.prototype.lookupRequest_ = function(request, response) {
+  if (!request.arguments) {
+    return response.failed('Missing arguments');
+  }
+
+  // Pull out arguments.
+  var handles = request.arguments.handles;
+
+  // Check for legal arguments.
+  if (IS_UNDEFINED(handles)) {
+    return response.failed('Argument "handles" missing');
+  }
+
+  // Set 'includeSource' option for script lookup.
+  if (!IS_UNDEFINED(request.arguments.includeSource)) {
+    var includeSource = builtins.$toBoolean(request.arguments.includeSource);
+    response.setOption('includeSource', includeSource);
+  }
+
+  // Lookup handles.
+  var mirrors = {};
+  for (var i = 0; i < handles.length; i++) {
+    var handle = handles[i];
+    var mirror = LookupMirror(handle);
+    if (!mirror) {
+      return response.failed('Object #' + handle + '# not found');
+    }
+    mirrors[handle] = mirror;
+  }
+  response.body = mirrors;
+};
+
+
+DebugCommandProcessor.prototype.referencesRequest_ =
+    function(request, response) {
+  if (!request.arguments) {
+    return response.failed('Missing arguments');
+  }
+
+  // Pull out arguments.
+  var type = request.arguments.type;
+  var handle = request.arguments.handle;
+
+  // Check for legal arguments.
+  if (IS_UNDEFINED(type)) {
+    return response.failed('Argument "type" missing');
+  }
+  if (IS_UNDEFINED(handle)) {
+    return response.failed('Argument "handle" missing');
+  }
+  if (type != 'referencedBy' && type != 'constructedBy') {
+    return response.failed('Invalid type "' + type + '"');
+  }
+
+  // Lookup handle and return objects with references the object.
+  var mirror = LookupMirror(handle);
+  if (mirror) {
+    if (type == 'referencedBy') {
+      response.body = mirror.referencedBy();
+    } else {
+      response.body = mirror.constructedBy();
+    }
+  } else {
+    return response.failed('Object #' + handle + '# not found');
+  }
+};
+
+
+DebugCommandProcessor.prototype.sourceRequest_ = function(request, response) {
+  // No frames no source.
+  if (this.exec_state_.frameCount() == 0) {
+    return response.failed('No source');
+  }
+
+  var from_line;
+  var to_line;
+  var frame = this.exec_state_.frame();
+  if (request.arguments) {
+    // Pull out arguments.
+    from_line = request.arguments.fromLine;
+    to_line = request.arguments.toLine;
+
+    if (!IS_UNDEFINED(request.arguments.frame)) {
+      var frame_number = builtins.$toNumber(request.arguments.frame);
+      if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
+        return response.failed('Invalid frame "' + frame + '"');
+      }
+      frame = this.exec_state_.frame(frame_number);
+    }
+  }
+
+  // Get the script selected.
+  var script = frame.func().script();
+  if (!script) {
+    return response.failed('No source');
+  }
+
+  // Get the source slice and fill it into the response.
+  var slice = script.sourceSlice(from_line, to_line);
+  if (!slice) {
+    return response.failed('Invalid line interval');
+  }
+  response.body = {};
+  response.body.source = slice.sourceText();
+  response.body.fromLine = slice.from_line;
+  response.body.toLine = slice.to_line;
+  response.body.fromPosition = slice.from_position;
+  response.body.toPosition = slice.to_position;
+  response.body.totalLines = script.lineCount();
+};
+
+
+DebugCommandProcessor.prototype.scriptsRequest_ = function(request, response) {
+  var types = ScriptTypeFlag(Debug.ScriptType.Normal);
+  var includeSource = false;
+  var idsToInclude = null;
+  if (request.arguments) {
+    // Pull out arguments.
+    if (!IS_UNDEFINED(request.arguments.types)) {
+      types = builtins.$toNumber(request.arguments.types);
+      if (isNaN(types) || types < 0) {
+        return response.failed('Invalid types "' +
+                               request.arguments.types + '"');
+      }
+    }
+
+    if (!IS_UNDEFINED(request.arguments.includeSource)) {
+      includeSource = builtins.$toBoolean(request.arguments.includeSource);
+      response.setOption('includeSource', includeSource);
+    }
+
+    if (IS_ARRAY(request.arguments.ids)) {
+      idsToInclude = {};
+      var ids = request.arguments.ids;
+      for (var i = 0; i < ids.length; i++) {
+        idsToInclude[ids[i]] = true;
+      }
+    }
+
+    var filterStr = null;
+    var filterNum = null;
+    if (!IS_UNDEFINED(request.arguments.filter)) {
+      var num = builtins.$toNumber(request.arguments.filter);
+      if (!isNaN(num)) {
+        filterNum = num;
+      }
+      filterStr = request.arguments.filter;
+    }
+  }
+
+  // Collect all scripts in the heap.
+  var scripts = %DebugGetLoadedScripts();
+
+  response.body = [];
+
+  for (var i = 0; i < scripts.length; i++) {
+    if (idsToInclude && !idsToInclude[scripts[i].id]) {
+      continue;
+    }
+    if (filterStr || filterNum) {
+      var script = scripts[i];
+      var found = false;
+      if (filterNum && !found) {
+        if (script.id && script.id === filterNum) {
+          found = true;
+        }
+      }
+      if (filterStr && !found) {
+        if (script.name && script.name.indexOf(filterStr) >= 0) {
+          found = true;
+        }
+      }
+      if (!found) continue;
+    }
+    if (types & ScriptTypeFlag(scripts[i].type)) {
+      response.body.push(MakeMirror(scripts[i]));
+    }
+  }
+};
+
+
+DebugCommandProcessor.prototype.threadsRequest_ = function(request, response) {
+  // Get the number of threads.
+  var total_threads = this.exec_state_.threadCount();
+
+  // Get information for all threads.
+  var threads = [];
+  for (var i = 0; i < total_threads; i++) {
+    var details = %GetThreadDetails(this.exec_state_.break_id, i);
+    var thread_info = { current: details[0],
+                        id: details[1]
+                      };
+    threads.push(thread_info);
+  }
+
+  // Create the response body.
+  response.body = {
+    totalThreads: total_threads,
+    threads: threads
+  };
+};
+
+
+DebugCommandProcessor.prototype.suspendRequest_ = function(request, response) {
+  response.running = false;
+};
+
+
+DebugCommandProcessor.prototype.versionRequest_ = function(request, response) {
+  response.body = {
+    V8Version: %GetV8Version()
+  };
+};
+
+
+DebugCommandProcessor.prototype.changeLiveRequest_ = function(
+    request, response) {
+  if (!request.arguments) {
+    return response.failed('Missing arguments');
+  }
+  var script_id = request.arguments.script_id;
+  var preview_only = !!request.arguments.preview_only;
+
+  var scripts = %DebugGetLoadedScripts();
+
+  var the_script = null;
+  for (var i = 0; i < scripts.length; i++) {
+    if (scripts[i].id == script_id) {
+      the_script = scripts[i];
+    }
+  }
+  if (!the_script) {
+    response.failed('Script not found');
+    return;
+  }
+
+  var change_log = new Array();
+
+  if (!IS_STRING(request.arguments.new_source)) {
+    throw "new_source argument expected";
+  }
+
+  var new_source = request.arguments.new_source;
+
+  var result_description;
+  try {
+    result_description = Debug.LiveEdit.SetScriptSource(the_script,
+        new_source, preview_only, change_log);
+  } catch (e) {
+    if (e instanceof Debug.LiveEdit.Failure && "details" in e) {
+      response.failed(e.message, e.details);
+      return;
+    }
+    throw e;
+  }
+  response.body = {change_log: change_log, result: result_description};
+
+  if (!preview_only && !this.running_ && result_description.stack_modified) {
+    response.body.stepin_recommended = true;
+  }
+};
+
+
+DebugCommandProcessor.prototype.restartFrameRequest_ = function(
+    request, response) {
+  if (!request.arguments) {
+    return response.failed('Missing arguments');
+  }
+  var frame = request.arguments.frame;
+
+  // No frames to evaluate in frame.
+  if (this.exec_state_.frameCount() == 0) {
+    return response.failed('No frames');
+  }
+
+  var frame_mirror;
+  // Check whether a frame was specified.
+  if (!IS_UNDEFINED(frame)) {
+    var frame_number = builtins.$toNumber(frame);
+    if (frame_number < 0 || frame_number >= this.exec_state_.frameCount()) {
+      return response.failed('Invalid frame "' + frame + '"');
+    }
+    // Restart specified frame.
+    frame_mirror = this.exec_state_.frame(frame_number);
+  } else {
+    // Restart selected frame.
+    frame_mirror = this.exec_state_.frame();
+  }
+
+  var result_description = Debug.LiveEdit.RestartFrame(frame_mirror);
+  response.body = {result: result_description};
+};
+
+
+DebugCommandProcessor.prototype.debuggerFlagsRequest_ = function(request,
+                                                                 response) {
+  // Check for legal request.
+  if (!request.arguments) {
+    response.failed('Missing arguments');
+    return;
+  }
+
+  // Pull out arguments.
+  var flags = request.arguments.flags;
+
+  response.body = { flags: [] };
+  if (!IS_UNDEFINED(flags)) {
+    for (var i = 0; i < flags.length; i++) {
+      var name = flags[i].name;
+      var debugger_flag = debugger_flags[name];
+      if (!debugger_flag) {
+        continue;
+      }
+      if ('value' in flags[i]) {
+        debugger_flag.setValue(flags[i].value);
+      }
+      response.body.flags.push({ name: name, value: debugger_flag.getValue() });
+    }
+  } else {
+    for (var name in debugger_flags) {
+      var value = debugger_flags[name].getValue();
+      response.body.flags.push({ name: name, value: value });
+    }
+  }
+};
+
+
+DebugCommandProcessor.prototype.v8FlagsRequest_ = function(request, response) {
+  var flags = request.arguments.flags;
+  if (!flags) flags = '';
+  %SetFlags(flags);
+};
+
+
+DebugCommandProcessor.prototype.gcRequest_ = function(request, response) {
+  var type = request.arguments.type;
+  if (!type) type = 'all';
+
+  var before = %GetHeapUsage();
+  %CollectGarbage(type);
+  var after = %GetHeapUsage();
+
+  response.body = { "before": before, "after": after };
+};
+
+
+DebugCommandProcessor.prototype.dispatch_ = (function() {
+  var proto = DebugCommandProcessor.prototype;
+  return {
+    "continue":             proto.continueRequest_,
+    "break"   :             proto.breakRequest_,
+    "setbreakpoint" :       proto.setBreakPointRequest_,
+    "changebreakpoint":     proto.changeBreakPointRequest_,
+    "clearbreakpoint":      proto.clearBreakPointRequest_,
+    "clearbreakpointgroup": proto.clearBreakPointGroupRequest_,
+    "disconnect":           proto.disconnectRequest_,
+    "setexceptionbreak":    proto.setExceptionBreakRequest_,
+    "listbreakpoints":      proto.listBreakpointsRequest_,
+    "backtrace":            proto.backtraceRequest_,
+    "frame":                proto.frameRequest_,
+    "scopes":               proto.scopesRequest_,
+    "scope":                proto.scopeRequest_,
+    "setvariablevalue":     proto.setVariableValueRequest_,
+    "evaluate":             proto.evaluateRequest_,
+    "lookup":               proto.lookupRequest_,
+    "references":           proto.referencesRequest_,
+    "source":               proto.sourceRequest_,
+    "scripts":              proto.scriptsRequest_,
+    "threads":              proto.threadsRequest_,
+    "suspend":              proto.suspendRequest_,
+    "version":              proto.versionRequest_,
+    "changelive":           proto.changeLiveRequest_,
+    "restartframe":         proto.restartFrameRequest_,
+    "flags":                proto.debuggerFlagsRequest_,
+    "v8flag":               proto.v8FlagsRequest_,
+    "gc":                   proto.gcRequest_,
+  };
+})();
+
+
+// Check whether the previously processed command caused the VM to become
+// running.
+DebugCommandProcessor.prototype.isRunning = function() {
+  return this.running_;
+};
+
+
+DebugCommandProcessor.prototype.systemBreak = function(cmd, args) {
+  return %SystemBreak();
+};
+
+
+/**
+ * Convert an Object to its debugger protocol representation. The representation
+ * may be serilized to a JSON object using JSON.stringify().
+ * This implementation simply runs through all string property names, converts
+ * each property value to a protocol value and adds the property to the result
+ * object. For type "object" the function will be called recursively. Note that
+ * circular structures will cause infinite recursion.
+ * @param {Object} object The object to format as protocol object.
+ * @param {MirrorSerializer} mirror_serializer The serializer to use if any
+ *     mirror objects are encountered.
+ * @return {Object} Protocol object value.
+ */
+function ObjectToProtocolObject_(object, mirror_serializer) {
+  var content = {};
+  for (var key in object) {
+    // Only consider string keys.
+    if (typeof key == 'string') {
+      // Format the value based on its type.
+      var property_value_json = ValueToProtocolValue_(object[key],
+                                                      mirror_serializer);
+      // Add the property if relevant.
+      if (!IS_UNDEFINED(property_value_json)) {
+        content[key] = property_value_json;
+      }
+    }
+  }
+
+  return content;
+}
+
+
+/**
+ * Convert an array to its debugger protocol representation. It will convert
+ * each array element to a protocol value.
+ * @param {Array} array The array to format as protocol array.
+ * @param {MirrorSerializer} mirror_serializer The serializer to use if any
+ *     mirror objects are encountered.
+ * @return {Array} Protocol array value.
+ */
+function ArrayToProtocolArray_(array, mirror_serializer) {
+  var json = [];
+  for (var i = 0; i < array.length; i++) {
+    json.push(ValueToProtocolValue_(array[i], mirror_serializer));
+  }
+  return json;
+}
+
+
+/**
+ * Convert a value to its debugger protocol representation.
+ * @param {*} value The value to format as protocol value.
+ * @param {MirrorSerializer} mirror_serializer The serializer to use if any
+ *     mirror objects are encountered.
+ * @return {*} Protocol value.
+ */
+function ValueToProtocolValue_(value, mirror_serializer) {
+  // Format the value based on its type.
+  var json;
+  switch (typeof value) {
+    case 'object':
+      if (value instanceof Mirror) {
+        json = mirror_serializer.serializeValue(value);
+      } else if (IS_ARRAY(value)){
+        json = ArrayToProtocolArray_(value, mirror_serializer);
+      } else {
+        json = ObjectToProtocolObject_(value, mirror_serializer);
+      }
+      break;
+
+    case 'boolean':
+    case 'string':
+    case 'number':
+      json = value;
+      break;
+
+    default:
+      json = null;
+  }
+  return json;
+}
diff --git a/src/debug/ia32/debug-ia32.cc b/src/debug/ia32/debug-ia32.cc
new file mode 100644 (file)
index 0000000..cf21bd8
--- /dev/null
@@ -0,0 +1,147 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_IA32
+
+#include "src/codegen.h"
+#include "src/debug/debug.h"
+
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void EmitDebugBreakSlot(MacroAssembler* masm) {
+  Label check_codesize;
+  __ bind(&check_codesize);
+  __ Nop(Assembler::kDebugBreakSlotLength);
+  DCHECK_EQ(Assembler::kDebugBreakSlotLength,
+            masm->SizeOfCodeGeneratedSince(&check_codesize));
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                                int call_argc) {
+  // Generate enough nop's to make space for a call instruction.
+  masm->RecordDebugBreakSlot(mode, call_argc);
+  EmitDebugBreakSlot(masm);
+}
+
+
+void DebugCodegen::ClearDebugBreakSlot(Address pc) {
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotLength);
+  EmitDebugBreakSlot(patcher.masm());
+}
+
+
+void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
+  DCHECK_EQ(Code::BUILTIN, code->kind());
+  static const int kSize = Assembler::kDebugBreakSlotLength;
+  CodePatcher patcher(pc, kSize);
+
+  // Add a label for checking the size of the code used for returning.
+  Label check_codesize;
+  patcher.masm()->bind(&check_codesize);
+  patcher.masm()->call(code->entry(), RelocInfo::NONE32);
+  // Check that the size of the code generated is as expected.
+  DCHECK_EQ(kSize, patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
+}
+
+
+void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
+                                          DebugBreakCallHelperMode mode) {
+  __ RecordComment("Debug break");
+
+  // Enter an internal frame.
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
+      __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue)));
+    }
+    __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
+
+    if (mode == SAVE_RESULT_REGISTER) __ push(eax);
+
+    __ Move(eax, Immediate(0));  // No arguments.
+    __ mov(ebx,
+           Immediate(ExternalReference(
+               Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
+
+    CEntryStub ceb(masm->isolate(), 1);
+    __ CallStub(&ceb);
+
+    if (FLAG_debug_code) {
+      for (int i = 0; i < kNumJSCallerSaved; ++i) {
+        Register reg = {JSCallerSavedCode(i)};
+        __ Move(reg, Immediate(kDebugZapValue));
+      }
+    }
+
+    if (mode == SAVE_RESULT_REGISTER) __ pop(eax);
+
+    __ pop(ebx);
+    // We divide stored value by 2 (untagging) and multiply it by word's size.
+    STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0);
+    __ lea(esp, Operand(esp, ebx, times_half_pointer_size, 0));
+
+    // Get rid of the internal frame.
+  }
+
+  // This call did not replace a call , so there will be an unwanted
+  // return address left on the stack. Here we get rid of that.
+  __ add(esp, Immediate(kPointerSize));
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ jmp(Operand::StaticVariable(after_break_target));
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  masm->ret(0);
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
+
+  // We do not know our frame height, but set esp based on ebp.
+  __ lea(esp, Operand(ebp, -1 * kPointerSize));
+
+  __ pop(edi);  // Function.
+  __ pop(ebp);
+
+  // Load context from the function.
+  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
+
+  // Get function code.
+  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+  __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
+  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
+
+  // Re-run JSFunction, edi is function, esi is context.
+  __ jmp(edx);
+}
+
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+#undef __
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_IA32
diff --git a/src/debug/liveedit.cc b/src/debug/liveedit.cc
new file mode 100644 (file)
index 0000000..5cb7592
--- /dev/null
@@ -0,0 +1,2029 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+#include "src/v8.h"
+
+#include "src/debug/liveedit.h"
+
+#include "src/code-stubs.h"
+#include "src/compilation-cache.h"
+#include "src/compiler.h"
+#include "src/debug/debug.h"
+#include "src/deoptimizer.h"
+#include "src/global-handles.h"
+#include "src/messages.h"
+#include "src/parser.h"
+#include "src/scopeinfo.h"
+#include "src/scopes.h"
+#include "src/v8memory.h"
+
+namespace v8 {
+namespace internal {
+
+void SetElementSloppy(Handle<JSObject> object,
+                      uint32_t index,
+                      Handle<Object> value) {
+  // Ignore return value from SetElement. It can only be a failure if there
+  // are element setters causing exceptions and the debugger context has none
+  // of these.
+  Object::SetElement(object->GetIsolate(), object, index, value, SLOPPY)
+      .Assert();
+}
+
+
+// A simple implementation of dynamic programming algorithm. It solves
+// the problem of finding the difference of 2 arrays. It uses a table of results
+// of subproblems. Each cell contains a number together with 2-bit flag
+// that helps building the chunk list.
+class Differencer {
+ public:
+  explicit Differencer(Comparator::Input* input)
+      : input_(input), len1_(input->GetLength1()), len2_(input->GetLength2()) {
+    buffer_ = NewArray<int>(len1_ * len2_);
+  }
+  ~Differencer() {
+    DeleteArray(buffer_);
+  }
+
+  void Initialize() {
+    int array_size = len1_ * len2_;
+    for (int i = 0; i < array_size; i++) {
+      buffer_[i] = kEmptyCellValue;
+    }
+  }
+
+  // Makes sure that result for the full problem is calculated and stored
+  // in the table together with flags showing a path through subproblems.
+  void FillTable() {
+    CompareUpToTail(0, 0);
+  }
+
+  void SaveResult(Comparator::Output* chunk_writer) {
+    ResultWriter writer(chunk_writer);
+
+    int pos1 = 0;
+    int pos2 = 0;
+    while (true) {
+      if (pos1 < len1_) {
+        if (pos2 < len2_) {
+          Direction dir = get_direction(pos1, pos2);
+          switch (dir) {
+            case EQ:
+              writer.eq();
+              pos1++;
+              pos2++;
+              break;
+            case SKIP1:
+              writer.skip1(1);
+              pos1++;
+              break;
+            case SKIP2:
+            case SKIP_ANY:
+              writer.skip2(1);
+              pos2++;
+              break;
+            default:
+              UNREACHABLE();
+          }
+        } else {
+          writer.skip1(len1_ - pos1);
+          break;
+        }
+      } else {
+        if (len2_ != pos2) {
+          writer.skip2(len2_ - pos2);
+        }
+        break;
+      }
+    }
+    writer.close();
+  }
+
+ private:
+  Comparator::Input* input_;
+  int* buffer_;
+  int len1_;
+  int len2_;
+
+  enum Direction {
+    EQ = 0,
+    SKIP1,
+    SKIP2,
+    SKIP_ANY,
+
+    MAX_DIRECTION_FLAG_VALUE = SKIP_ANY
+  };
+
+  // Computes result for a subtask and optionally caches it in the buffer table.
+  // All results values are shifted to make space for flags in the lower bits.
+  int CompareUpToTail(int pos1, int pos2) {
+    if (pos1 < len1_) {
+      if (pos2 < len2_) {
+        int cached_res = get_value4(pos1, pos2);
+        if (cached_res == kEmptyCellValue) {
+          Direction dir;
+          int res;
+          if (input_->Equals(pos1, pos2)) {
+            res = CompareUpToTail(pos1 + 1, pos2 + 1);
+            dir = EQ;
+          } else {
+            int res1 = CompareUpToTail(pos1 + 1, pos2) +
+                (1 << kDirectionSizeBits);
+            int res2 = CompareUpToTail(pos1, pos2 + 1) +
+                (1 << kDirectionSizeBits);
+            if (res1 == res2) {
+              res = res1;
+              dir = SKIP_ANY;
+            } else if (res1 < res2) {
+              res = res1;
+              dir = SKIP1;
+            } else {
+              res = res2;
+              dir = SKIP2;
+            }
+          }
+          set_value4_and_dir(pos1, pos2, res, dir);
+          cached_res = res;
+        }
+        return cached_res;
+      } else {
+        return (len1_ - pos1) << kDirectionSizeBits;
+      }
+    } else {
+      return (len2_ - pos2) << kDirectionSizeBits;
+    }
+  }
+
+  inline int& get_cell(int i1, int i2) {
+    return buffer_[i1 + i2 * len1_];
+  }
+
+  // Each cell keeps a value plus direction. Value is multiplied by 4.
+  void set_value4_and_dir(int i1, int i2, int value4, Direction dir) {
+    DCHECK((value4 & kDirectionMask) == 0);
+    get_cell(i1, i2) = value4 | dir;
+  }
+
+  int get_value4(int i1, int i2) {
+    return get_cell(i1, i2) & (kMaxUInt32 ^ kDirectionMask);
+  }
+  Direction get_direction(int i1, int i2) {
+    return static_cast<Direction>(get_cell(i1, i2) & kDirectionMask);
+  }
+
+  static const int kDirectionSizeBits = 2;
+  static const int kDirectionMask = (1 << kDirectionSizeBits) - 1;
+  static const int kEmptyCellValue = ~0u << kDirectionSizeBits;
+
+  // This method only holds static assert statement (unfortunately you cannot
+  // place one in class scope).
+  void StaticAssertHolder() {
+    STATIC_ASSERT(MAX_DIRECTION_FLAG_VALUE < (1 << kDirectionSizeBits));
+  }
+
+  class ResultWriter {
+   public:
+    explicit ResultWriter(Comparator::Output* chunk_writer)
+        : chunk_writer_(chunk_writer), pos1_(0), pos2_(0),
+          pos1_begin_(-1), pos2_begin_(-1), has_open_chunk_(false) {
+    }
+    void eq() {
+      FlushChunk();
+      pos1_++;
+      pos2_++;
+    }
+    void skip1(int len1) {
+      StartChunk();
+      pos1_ += len1;
+    }
+    void skip2(int len2) {
+      StartChunk();
+      pos2_ += len2;
+    }
+    void close() {
+      FlushChunk();
+    }
+
+   private:
+    Comparator::Output* chunk_writer_;
+    int pos1_;
+    int pos2_;
+    int pos1_begin_;
+    int pos2_begin_;
+    bool has_open_chunk_;
+
+    void StartChunk() {
+      if (!has_open_chunk_) {
+        pos1_begin_ = pos1_;
+        pos2_begin_ = pos2_;
+        has_open_chunk_ = true;
+      }
+    }
+
+    void FlushChunk() {
+      if (has_open_chunk_) {
+        chunk_writer_->AddChunk(pos1_begin_, pos2_begin_,
+                                pos1_ - pos1_begin_, pos2_ - pos2_begin_);
+        has_open_chunk_ = false;
+      }
+    }
+  };
+};
+
+
+void Comparator::CalculateDifference(Comparator::Input* input,
+                                     Comparator::Output* result_writer) {
+  Differencer differencer(input);
+  differencer.Initialize();
+  differencer.FillTable();
+  differencer.SaveResult(result_writer);
+}
+
+
+static bool CompareSubstrings(Handle<String> s1, int pos1,
+                              Handle<String> s2, int pos2, int len) {
+  for (int i = 0; i < len; i++) {
+    if (s1->Get(i + pos1) != s2->Get(i + pos2)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+// Additional to Input interface. Lets switch Input range to subrange.
+// More elegant way would be to wrap one Input as another Input object
+// and translate positions there, but that would cost us additional virtual
+// call per comparison.
+class SubrangableInput : public Comparator::Input {
+ public:
+  virtual void SetSubrange1(int offset, int len) = 0;
+  virtual void SetSubrange2(int offset, int len) = 0;
+};
+
+
+class SubrangableOutput : public Comparator::Output {
+ public:
+  virtual void SetSubrange1(int offset, int len) = 0;
+  virtual void SetSubrange2(int offset, int len) = 0;
+};
+
+
+static int min(int a, int b) {
+  return a < b ? a : b;
+}
+
+
+// Finds common prefix and suffix in input. This parts shouldn't take space in
+// linear programming table. Enable subranging in input and output.
+static void NarrowDownInput(SubrangableInput* input,
+    SubrangableOutput* output) {
+  const int len1 = input->GetLength1();
+  const int len2 = input->GetLength2();
+
+  int common_prefix_len;
+  int common_suffix_len;
+
+  {
+    common_prefix_len = 0;
+    int prefix_limit = min(len1, len2);
+    while (common_prefix_len < prefix_limit &&
+        input->Equals(common_prefix_len, common_prefix_len)) {
+      common_prefix_len++;
+    }
+
+    common_suffix_len = 0;
+    int suffix_limit = min(len1 - common_prefix_len, len2 - common_prefix_len);
+
+    while (common_suffix_len < suffix_limit &&
+        input->Equals(len1 - common_suffix_len - 1,
+        len2 - common_suffix_len - 1)) {
+      common_suffix_len++;
+    }
+  }
+
+  if (common_prefix_len > 0 || common_suffix_len > 0) {
+    int new_len1 = len1 - common_suffix_len - common_prefix_len;
+    int new_len2 = len2 - common_suffix_len - common_prefix_len;
+
+    input->SetSubrange1(common_prefix_len, new_len1);
+    input->SetSubrange2(common_prefix_len, new_len2);
+
+    output->SetSubrange1(common_prefix_len, new_len1);
+    output->SetSubrange2(common_prefix_len, new_len2);
+  }
+}
+
+
+// A helper class that writes chunk numbers into JSArray.
+// Each chunk is stored as 3 array elements: (pos1_begin, pos1_end, pos2_end).
+class CompareOutputArrayWriter {
+ public:
+  explicit CompareOutputArrayWriter(Isolate* isolate)
+      : array_(isolate->factory()->NewJSArray(10)), current_size_(0) {}
+
+  Handle<JSArray> GetResult() {
+    return array_;
+  }
+
+  void WriteChunk(int char_pos1, int char_pos2, int char_len1, int char_len2) {
+    Isolate* isolate = array_->GetIsolate();
+    SetElementSloppy(array_,
+                     current_size_,
+                     Handle<Object>(Smi::FromInt(char_pos1), isolate));
+    SetElementSloppy(array_,
+                     current_size_ + 1,
+                     Handle<Object>(Smi::FromInt(char_pos1 + char_len1),
+                                    isolate));
+    SetElementSloppy(array_,
+                     current_size_ + 2,
+                     Handle<Object>(Smi::FromInt(char_pos2 + char_len2),
+                                    isolate));
+    current_size_ += 3;
+  }
+
+ private:
+  Handle<JSArray> array_;
+  int current_size_;
+};
+
+
+// Represents 2 strings as 2 arrays of tokens.
+// TODO(LiveEdit): Currently it's actually an array of charactres.
+//     Make array of tokens instead.
+class TokensCompareInput : public Comparator::Input {
+ public:
+  TokensCompareInput(Handle<String> s1, int offset1, int len1,
+                       Handle<String> s2, int offset2, int len2)
+      : s1_(s1), offset1_(offset1), len1_(len1),
+        s2_(s2), offset2_(offset2), len2_(len2) {
+  }
+  virtual int GetLength1() {
+    return len1_;
+  }
+  virtual int GetLength2() {
+    return len2_;
+  }
+  bool Equals(int index1, int index2) {
+    return s1_->Get(offset1_ + index1) == s2_->Get(offset2_ + index2);
+  }
+
+ private:
+  Handle<String> s1_;
+  int offset1_;
+  int len1_;
+  Handle<String> s2_;
+  int offset2_;
+  int len2_;
+};
+
+
+// Stores compare result in JSArray. Converts substring positions
+// to absolute positions.
+class TokensCompareOutput : public Comparator::Output {
+ public:
+  TokensCompareOutput(CompareOutputArrayWriter* array_writer,
+                      int offset1, int offset2)
+        : array_writer_(array_writer), offset1_(offset1), offset2_(offset2) {
+  }
+
+  void AddChunk(int pos1, int pos2, int len1, int len2) {
+    array_writer_->WriteChunk(pos1 + offset1_, pos2 + offset2_, len1, len2);
+  }
+
+ private:
+  CompareOutputArrayWriter* array_writer_;
+  int offset1_;
+  int offset2_;
+};
+
+
+// Wraps raw n-elements line_ends array as a list of n+1 lines. The last line
+// never has terminating new line character.
+class LineEndsWrapper {
+ public:
+  explicit LineEndsWrapper(Handle<String> string)
+      : ends_array_(String::CalculateLineEnds(string, false)),
+        string_len_(string->length()) {
+  }
+  int length() {
+    return ends_array_->length() + 1;
+  }
+  // Returns start for any line including start of the imaginary line after
+  // the last line.
+  int GetLineStart(int index) {
+    if (index == 0) {
+      return 0;
+    } else {
+      return GetLineEnd(index - 1);
+    }
+  }
+  int GetLineEnd(int index) {
+    if (index == ends_array_->length()) {
+      // End of the last line is always an end of the whole string.
+      // If the string ends with a new line character, the last line is an
+      // empty string after this character.
+      return string_len_;
+    } else {
+      return GetPosAfterNewLine(index);
+    }
+  }
+
+ private:
+  Handle<FixedArray> ends_array_;
+  int string_len_;
+
+  int GetPosAfterNewLine(int index) {
+    return Smi::cast(ends_array_->get(index))->value() + 1;
+  }
+};
+
+
+// Represents 2 strings as 2 arrays of lines.
+class LineArrayCompareInput : public SubrangableInput {
+ public:
+  LineArrayCompareInput(Handle<String> s1, Handle<String> s2,
+                        LineEndsWrapper line_ends1, LineEndsWrapper line_ends2)
+      : s1_(s1), s2_(s2), line_ends1_(line_ends1),
+        line_ends2_(line_ends2),
+        subrange_offset1_(0), subrange_offset2_(0),
+        subrange_len1_(line_ends1_.length()),
+        subrange_len2_(line_ends2_.length()) {
+  }
+  int GetLength1() {
+    return subrange_len1_;
+  }
+  int GetLength2() {
+    return subrange_len2_;
+  }
+  bool Equals(int index1, int index2) {
+    index1 += subrange_offset1_;
+    index2 += subrange_offset2_;
+
+    int line_start1 = line_ends1_.GetLineStart(index1);
+    int line_start2 = line_ends2_.GetLineStart(index2);
+    int line_end1 = line_ends1_.GetLineEnd(index1);
+    int line_end2 = line_ends2_.GetLineEnd(index2);
+    int len1 = line_end1 - line_start1;
+    int len2 = line_end2 - line_start2;
+    if (len1 != len2) {
+      return false;
+    }
+    return CompareSubstrings(s1_, line_start1, s2_, line_start2,
+                             len1);
+  }
+  void SetSubrange1(int offset, int len) {
+    subrange_offset1_ = offset;
+    subrange_len1_ = len;
+  }
+  void SetSubrange2(int offset, int len) {
+    subrange_offset2_ = offset;
+    subrange_len2_ = len;
+  }
+
+ private:
+  Handle<String> s1_;
+  Handle<String> s2_;
+  LineEndsWrapper line_ends1_;
+  LineEndsWrapper line_ends2_;
+  int subrange_offset1_;
+  int subrange_offset2_;
+  int subrange_len1_;
+  int subrange_len2_;
+};
+
+
+// Stores compare result in JSArray. For each chunk tries to conduct
+// a fine-grained nested diff token-wise.
+class TokenizingLineArrayCompareOutput : public SubrangableOutput {
+ public:
+  TokenizingLineArrayCompareOutput(LineEndsWrapper line_ends1,
+                                   LineEndsWrapper line_ends2,
+                                   Handle<String> s1, Handle<String> s2)
+      : array_writer_(s1->GetIsolate()),
+        line_ends1_(line_ends1), line_ends2_(line_ends2), s1_(s1), s2_(s2),
+        subrange_offset1_(0), subrange_offset2_(0) {
+  }
+
+  void AddChunk(int line_pos1, int line_pos2, int line_len1, int line_len2) {
+    line_pos1 += subrange_offset1_;
+    line_pos2 += subrange_offset2_;
+
+    int char_pos1 = line_ends1_.GetLineStart(line_pos1);
+    int char_pos2 = line_ends2_.GetLineStart(line_pos2);
+    int char_len1 = line_ends1_.GetLineStart(line_pos1 + line_len1) - char_pos1;
+    int char_len2 = line_ends2_.GetLineStart(line_pos2 + line_len2) - char_pos2;
+
+    if (char_len1 < CHUNK_LEN_LIMIT && char_len2 < CHUNK_LEN_LIMIT) {
+      // Chunk is small enough to conduct a nested token-level diff.
+      HandleScope subTaskScope(s1_->GetIsolate());
+
+      TokensCompareInput tokens_input(s1_, char_pos1, char_len1,
+                                      s2_, char_pos2, char_len2);
+      TokensCompareOutput tokens_output(&array_writer_, char_pos1,
+                                          char_pos2);
+
+      Comparator::CalculateDifference(&tokens_input, &tokens_output);
+    } else {
+      array_writer_.WriteChunk(char_pos1, char_pos2, char_len1, char_len2);
+    }
+  }
+  void SetSubrange1(int offset, int len) {
+    subrange_offset1_ = offset;
+  }
+  void SetSubrange2(int offset, int len) {
+    subrange_offset2_ = offset;
+  }
+
+  Handle<JSArray> GetResult() {
+    return array_writer_.GetResult();
+  }
+
+ private:
+  static const int CHUNK_LEN_LIMIT = 800;
+
+  CompareOutputArrayWriter array_writer_;
+  LineEndsWrapper line_ends1_;
+  LineEndsWrapper line_ends2_;
+  Handle<String> s1_;
+  Handle<String> s2_;
+  int subrange_offset1_;
+  int subrange_offset2_;
+};
+
+
+Handle<JSArray> LiveEdit::CompareStrings(Handle<String> s1,
+                                         Handle<String> s2) {
+  s1 = String::Flatten(s1);
+  s2 = String::Flatten(s2);
+
+  LineEndsWrapper line_ends1(s1);
+  LineEndsWrapper line_ends2(s2);
+
+  LineArrayCompareInput input(s1, s2, line_ends1, line_ends2);
+  TokenizingLineArrayCompareOutput output(line_ends1, line_ends2, s1, s2);
+
+  NarrowDownInput(&input, &output);
+
+  Comparator::CalculateDifference(&input, &output);
+
+  return output.GetResult();
+}
+
+
+// Unwraps JSValue object, returning its field "value"
+static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) {
+  return Handle<Object>(jsValue->value(), jsValue->GetIsolate());
+}
+
+
+// Wraps any object into a OpaqueReference, that will hide the object
+// from JavaScript.
+static Handle<JSValue> WrapInJSValue(Handle<HeapObject> object) {
+  Isolate* isolate = object->GetIsolate();
+  Handle<JSFunction> constructor = isolate->opaque_reference_function();
+  Handle<JSValue> result =
+      Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
+  result->set_value(*object);
+  return result;
+}
+
+
+static Handle<SharedFunctionInfo> UnwrapSharedFunctionInfoFromJSValue(
+    Handle<JSValue> jsValue) {
+  Object* shared = jsValue->value();
+  CHECK(shared->IsSharedFunctionInfo());
+  return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(shared));
+}
+
+
+static int GetArrayLength(Handle<JSArray> array) {
+  Object* length = array->length();
+  CHECK(length->IsSmi());
+  return Smi::cast(length)->value();
+}
+
+
+void FunctionInfoWrapper::SetInitialProperties(Handle<String> name,
+                                               int start_position,
+                                               int end_position, int param_num,
+                                               int literal_count,
+                                               int parent_index) {
+  HandleScope scope(isolate());
+  this->SetField(kFunctionNameOffset_, name);
+  this->SetSmiValueField(kStartPositionOffset_, start_position);
+  this->SetSmiValueField(kEndPositionOffset_, end_position);
+  this->SetSmiValueField(kParamNumOffset_, param_num);
+  this->SetSmiValueField(kLiteralNumOffset_, literal_count);
+  this->SetSmiValueField(kParentIndexOffset_, parent_index);
+}
+
+
+void FunctionInfoWrapper::SetFunctionCode(Handle<Code> function_code,
+                                          Handle<HeapObject> code_scope_info) {
+  Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
+  this->SetField(kCodeOffset_, code_wrapper);
+
+  Handle<JSValue> scope_wrapper = WrapInJSValue(code_scope_info);
+  this->SetField(kCodeScopeInfoOffset_, scope_wrapper);
+}
+
+
+void FunctionInfoWrapper::SetSharedFunctionInfo(
+    Handle<SharedFunctionInfo> info) {
+  Handle<JSValue> info_holder = WrapInJSValue(info);
+  this->SetField(kSharedFunctionInfoOffset_, info_holder);
+}
+
+
+Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
+  Handle<Object> element = this->GetField(kCodeOffset_);
+  Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
+  Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
+  CHECK(raw_result->IsCode());
+  return Handle<Code>::cast(raw_result);
+}
+
+
+MaybeHandle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
+  Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
+  if (element->IsJSValue()) {
+    Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
+    Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
+    Handle<SharedFunctionInfo> shared =
+        Handle<SharedFunctionInfo>::cast(raw_result);
+    return Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
+  } else {
+    // Scripts may never have a SharedFunctionInfo created.
+    return MaybeHandle<TypeFeedbackVector>();
+  }
+}
+
+
+Handle<Object> FunctionInfoWrapper::GetCodeScopeInfo() {
+  Handle<Object> element = this->GetField(kCodeScopeInfoOffset_);
+  return UnwrapJSValue(Handle<JSValue>::cast(element));
+}
+
+
+void SharedInfoWrapper::SetProperties(Handle<String> name,
+                                      int start_position,
+                                      int end_position,
+                                      Handle<SharedFunctionInfo> info) {
+  HandleScope scope(isolate());
+  this->SetField(kFunctionNameOffset_, name);
+  Handle<JSValue> info_holder = WrapInJSValue(info);
+  this->SetField(kSharedInfoOffset_, info_holder);
+  this->SetSmiValueField(kStartPositionOffset_, start_position);
+  this->SetSmiValueField(kEndPositionOffset_, end_position);
+}
+
+
+Handle<SharedFunctionInfo> SharedInfoWrapper::GetInfo() {
+  Handle<Object> element = this->GetField(kSharedInfoOffset_);
+  Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
+  return UnwrapSharedFunctionInfoFromJSValue(value_wrapper);
+}
+
+
+class FunctionInfoListener {
+ public:
+  explicit FunctionInfoListener(Isolate* isolate) {
+    current_parent_index_ = -1;
+    len_ = 0;
+    result_ = isolate->factory()->NewJSArray(10);
+  }
+
+  void FunctionStarted(FunctionLiteral* fun) {
+    HandleScope scope(isolate());
+    FunctionInfoWrapper info = FunctionInfoWrapper::Create(isolate());
+    info.SetInitialProperties(fun->name(), fun->start_position(),
+                              fun->end_position(), fun->parameter_count(),
+                              fun->materialized_literal_count(),
+                              current_parent_index_);
+    current_parent_index_ = len_;
+    SetElementSloppy(result_, len_, info.GetJSArray());
+    len_++;
+  }
+
+  void FunctionDone() {
+    HandleScope scope(isolate());
+    FunctionInfoWrapper info =
+        FunctionInfoWrapper::cast(
+            *Object::GetElement(
+                isolate(), result_, current_parent_index_).ToHandleChecked());
+    current_parent_index_ = info.GetParentIndex();
+  }
+
+  // Saves only function code, because for a script function we
+  // may never create a SharedFunctionInfo object.
+  void FunctionCode(Handle<Code> function_code) {
+    FunctionInfoWrapper info =
+        FunctionInfoWrapper::cast(
+            *Object::GetElement(
+                isolate(), result_, current_parent_index_).ToHandleChecked());
+    info.SetFunctionCode(function_code,
+                         Handle<HeapObject>(isolate()->heap()->null_value()));
+  }
+
+  // Saves full information about a function: its code, its scope info
+  // and a SharedFunctionInfo object.
+  void FunctionInfo(Handle<SharedFunctionInfo> shared, Scope* scope,
+                    Zone* zone) {
+    if (!shared->IsSharedFunctionInfo()) {
+      return;
+    }
+    FunctionInfoWrapper info =
+        FunctionInfoWrapper::cast(
+            *Object::GetElement(
+                isolate(), result_, current_parent_index_).ToHandleChecked());
+    info.SetFunctionCode(Handle<Code>(shared->code()),
+                         Handle<HeapObject>(shared->scope_info()));
+    info.SetSharedFunctionInfo(shared);
+
+    Handle<Object> scope_info_list = SerializeFunctionScope(scope, zone);
+    info.SetFunctionScopeInfo(scope_info_list);
+  }
+
+  Handle<JSArray> GetResult() { return result_; }
+
+ private:
+  Isolate* isolate() const { return result_->GetIsolate(); }
+
+  Handle<Object> SerializeFunctionScope(Scope* scope, Zone* zone) {
+    Handle<JSArray> scope_info_list = isolate()->factory()->NewJSArray(10);
+    int scope_info_length = 0;
+
+    // Saves some description of scope. It stores name and indexes of
+    // variables in the whole scope chain. Null-named slots delimit
+    // scopes of this chain.
+    Scope* current_scope = scope;
+    while (current_scope != NULL) {
+      HandleScope handle_scope(isolate());
+      ZoneList<Variable*> stack_list(current_scope->StackLocalCount(), zone);
+      ZoneList<Variable*> context_list(
+          current_scope->ContextLocalCount(), zone);
+      ZoneList<Variable*> globals_list(current_scope->ContextGlobalCount(),
+                                       zone);
+      current_scope->CollectStackAndContextLocals(&stack_list, &context_list,
+                                                  &globals_list);
+      context_list.Sort(&Variable::CompareIndex);
+
+      for (int i = 0; i < context_list.length(); i++) {
+        SetElementSloppy(scope_info_list,
+                         scope_info_length,
+                         context_list[i]->name());
+        scope_info_length++;
+        SetElementSloppy(
+            scope_info_list,
+            scope_info_length,
+            Handle<Smi>(Smi::FromInt(context_list[i]->index()), isolate()));
+        scope_info_length++;
+      }
+      SetElementSloppy(scope_info_list,
+                       scope_info_length,
+                       Handle<Object>(isolate()->heap()->null_value(),
+                                      isolate()));
+      scope_info_length++;
+
+      current_scope = current_scope->outer_scope();
+    }
+
+    return scope_info_list;
+  }
+
+  Handle<JSArray> result_;
+  int len_;
+  int current_parent_index_;
+};
+
+
+void LiveEdit::InitializeThreadLocal(Debug* debug) {
+  debug->thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED;
+}
+
+
+bool LiveEdit::SetAfterBreakTarget(Debug* debug) {
+  Code* code = NULL;
+  Isolate* isolate = debug->isolate_;
+  switch (debug->thread_local_.frame_drop_mode_) {
+    case FRAMES_UNTOUCHED:
+      return false;
+    case FRAME_DROPPED_IN_IC_CALL:
+      // We must have been calling IC stub. Do not go there anymore.
+      code = isolate->builtins()->builtin(Builtins::kPlainReturn_LiveEdit);
+      break;
+    case FRAME_DROPPED_IN_DEBUG_SLOT_CALL:
+      // Debug break slot stub does not return normally, instead it manually
+      // cleans the stack and jumps. We should patch the jump address.
+      code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit);
+      break;
+    case FRAME_DROPPED_IN_DIRECT_CALL:
+      // Nothing to do, after_break_target is not used here.
+      return true;
+    case FRAME_DROPPED_IN_RETURN_CALL:
+      code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit);
+      break;
+    case CURRENTLY_SET_MODE:
+      UNREACHABLE();
+      break;
+  }
+  debug->after_break_target_ = code->entry();
+  return true;
+}
+
+
+MaybeHandle<JSArray> LiveEdit::GatherCompileInfo(Handle<Script> script,
+                                                 Handle<String> source) {
+  Isolate* isolate = script->GetIsolate();
+
+  FunctionInfoListener listener(isolate);
+  Handle<Object> original_source =
+      Handle<Object>(script->source(), isolate);
+  script->set_source(*source);
+  isolate->set_active_function_info_listener(&listener);
+
+  {
+    // Creating verbose TryCatch from public API is currently the only way to
+    // force code save location. We do not use this the object directly.
+    v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
+    try_catch.SetVerbose(true);
+
+    // A logical 'try' section.
+    Compiler::CompileForLiveEdit(script);
+  }
+
+  // A logical 'catch' section.
+  Handle<JSObject> rethrow_exception;
+  if (isolate->has_pending_exception()) {
+    Handle<Object> exception(isolate->pending_exception(), isolate);
+    MessageLocation message_location = isolate->GetMessageLocation();
+
+    isolate->clear_pending_message();
+    isolate->clear_pending_exception();
+
+    // If possible, copy positions from message object to exception object.
+    if (exception->IsJSObject() && !message_location.script().is_null()) {
+      rethrow_exception = Handle<JSObject>::cast(exception);
+
+      Factory* factory = isolate->factory();
+      Handle<String> start_pos_key = factory->InternalizeOneByteString(
+          STATIC_CHAR_VECTOR("startPosition"));
+      Handle<String> end_pos_key =
+          factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("endPosition"));
+      Handle<String> script_obj_key =
+          factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptObject"));
+      Handle<Smi> start_pos(
+          Smi::FromInt(message_location.start_pos()), isolate);
+      Handle<Smi> end_pos(Smi::FromInt(message_location.end_pos()), isolate);
+      Handle<JSObject> script_obj =
+          Script::GetWrapper(message_location.script());
+      Object::SetProperty(rethrow_exception, start_pos_key, start_pos, SLOPPY)
+          .Assert();
+      Object::SetProperty(rethrow_exception, end_pos_key, end_pos, SLOPPY)
+          .Assert();
+      Object::SetProperty(rethrow_exception, script_obj_key, script_obj, SLOPPY)
+          .Assert();
+    }
+  }
+
+  // A logical 'finally' section.
+  isolate->set_active_function_info_listener(NULL);
+  script->set_source(*original_source);
+
+  if (rethrow_exception.is_null()) {
+    return listener.GetResult();
+  } else {
+    return isolate->Throw<JSArray>(rethrow_exception);
+  }
+}
+
+
+void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) {
+  Isolate* isolate = array->GetIsolate();
+  HandleScope scope(isolate);
+  int len = GetArrayLength(array);
+  for (int i = 0; i < len; i++) {
+    Handle<SharedFunctionInfo> info(
+        SharedFunctionInfo::cast(
+            *Object::GetElement(isolate, array, i).ToHandleChecked()));
+    SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create(isolate);
+    Handle<String> name_handle(String::cast(info->name()));
+    info_wrapper.SetProperties(name_handle, info->start_position(),
+                               info->end_position(), info);
+    SetElementSloppy(array, i, info_wrapper.GetJSArray());
+  }
+}
+
+
+// Visitor that finds all references to a particular code object,
+// including "CODE_TARGET" references in other code objects and replaces
+// them on the fly.
+class ReplacingVisitor : public ObjectVisitor {
+ public:
+  explicit ReplacingVisitor(Code* original, Code* substitution)
+    : original_(original), substitution_(substitution) {
+  }
+
+  virtual void VisitPointers(Object** start, Object** end) {
+    for (Object** p = start; p < end; p++) {
+      if (*p == original_) {
+        *p = substitution_;
+      }
+    }
+  }
+
+  virtual void VisitCodeEntry(Address entry) {
+    if (Code::GetObjectFromEntryAddress(entry) == original_) {
+      Address substitution_entry = substitution_->instruction_start();
+      Memory::Address_at(entry) = substitution_entry;
+    }
+  }
+
+  virtual void VisitCodeTarget(RelocInfo* rinfo) {
+    if (RelocInfo::IsCodeTarget(rinfo->rmode()) &&
+        Code::GetCodeFromTargetAddress(rinfo->target_address()) == original_) {
+      Address substitution_entry = substitution_->instruction_start();
+      rinfo->set_target_address(substitution_entry);
+    }
+  }
+
+  virtual void VisitDebugTarget(RelocInfo* rinfo) {
+    VisitCodeTarget(rinfo);
+  }
+
+ private:
+  Code* original_;
+  Code* substitution_;
+};
+
+
+// Finds all references to original and replaces them with substitution.
+static void ReplaceCodeObject(Handle<Code> original,
+                              Handle<Code> substitution) {
+  // Perform a full GC in order to ensure that we are not in the middle of an
+  // incremental marking phase when we are replacing the code object.
+  // Since we are not in an incremental marking phase we can write pointers
+  // to code objects (that are never in new space) without worrying about
+  // write barriers.
+  Heap* heap = original->GetHeap();
+  HeapIterator iterator(heap);
+
+  DCHECK(!heap->InNewSpace(*substitution));
+
+  ReplacingVisitor visitor(*original, *substitution);
+
+  // Iterate over all roots. Stack frames may have pointer into original code,
+  // so temporary replace the pointers with offset numbers
+  // in prologue/epilogue.
+  heap->IterateRoots(&visitor, VISIT_ALL);
+
+  // Now iterate over all pointers of all objects, including code_target
+  // implicit pointers.
+  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
+    obj->Iterate(&visitor);
+  }
+}
+
+
+// Patch function literals.
+// Name 'literals' is a misnomer. Rather it's a cache for complex object
+// boilerplates and for a native context. We must clean cached values.
+// Additionally we may need to allocate a new array if number of literals
+// changed.
+class LiteralFixer {
+ public:
+  static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper,
+                            Handle<SharedFunctionInfo> shared_info,
+                            Isolate* isolate) {
+    int new_literal_count = compile_info_wrapper->GetLiteralCount();
+    int old_literal_count = shared_info->num_literals();
+
+    if (old_literal_count == new_literal_count) {
+      // If literal count didn't change, simply go over all functions
+      // and clear literal arrays.
+      ClearValuesVisitor visitor;
+      IterateJSFunctions(shared_info, &visitor);
+    } else {
+      // When literal count changes, we have to create new array instances.
+      // Since we cannot create instances when iterating heap, we should first
+      // collect all functions and fix their literal arrays.
+      Handle<FixedArray> function_instances =
+          CollectJSFunctions(shared_info, isolate);
+      for (int i = 0; i < function_instances->length(); i++) {
+        Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i)));
+        Handle<FixedArray> new_literals =
+            isolate->factory()->NewFixedArray(new_literal_count);
+        fun->set_literals(*new_literals);
+      }
+
+      shared_info->set_num_literals(new_literal_count);
+    }
+  }
+
+ private:
+  // Iterates all function instances in the HEAP that refers to the
+  // provided shared_info.
+  template<typename Visitor>
+  static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info,
+                                 Visitor* visitor) {
+    HeapIterator iterator(shared_info->GetHeap());
+    for (HeapObject* obj = iterator.next(); obj != NULL;
+        obj = iterator.next()) {
+      if (obj->IsJSFunction()) {
+        JSFunction* function = JSFunction::cast(obj);
+        if (function->shared() == *shared_info) {
+          visitor->visit(function);
+        }
+      }
+    }
+  }
+
+  // Finds all instances of JSFunction that refers to the provided shared_info
+  // and returns array with them.
+  static Handle<FixedArray> CollectJSFunctions(
+      Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
+    CountVisitor count_visitor;
+    count_visitor.count = 0;
+    IterateJSFunctions(shared_info, &count_visitor);
+    int size = count_visitor.count;
+
+    Handle<FixedArray> result = isolate->factory()->NewFixedArray(size);
+    if (size > 0) {
+      CollectVisitor collect_visitor(result);
+      IterateJSFunctions(shared_info, &collect_visitor);
+    }
+    return result;
+  }
+
+  class ClearValuesVisitor {
+   public:
+    void visit(JSFunction* fun) {
+      FixedArray* literals = fun->literals();
+      int len = literals->length();
+      for (int j = 0; j < len; j++) {
+        literals->set_undefined(j);
+      }
+    }
+  };
+
+  class CountVisitor {
+   public:
+    void visit(JSFunction* fun) {
+      count++;
+    }
+    int count;
+  };
+
+  class CollectVisitor {
+   public:
+    explicit CollectVisitor(Handle<FixedArray> output)
+        : m_output(output), m_pos(0) {}
+
+    void visit(JSFunction* fun) {
+      m_output->set(m_pos, fun);
+      m_pos++;
+    }
+   private:
+    Handle<FixedArray> m_output;
+    int m_pos;
+  };
+};
+
+
+// Marks code that shares the same shared function info or has inlined
+// code that shares the same function info.
+class DependentFunctionMarker: public OptimizedFunctionVisitor {
+ public:
+  SharedFunctionInfo* shared_info_;
+  bool found_;
+
+  explicit DependentFunctionMarker(SharedFunctionInfo* shared_info)
+    : shared_info_(shared_info), found_(false) { }
+
+  virtual void EnterContext(Context* context) { }  // Don't care.
+  virtual void LeaveContext(Context* context)  { }  // Don't care.
+  virtual void VisitFunction(JSFunction* function) {
+    // It should be guaranteed by the iterator that everything is optimized.
+    DCHECK(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
+    if (function->Inlines(shared_info_)) {
+      // Mark the code for deoptimization.
+      function->code()->set_marked_for_deoptimization(true);
+      found_ = true;
+    }
+  }
+};
+
+
+static void DeoptimizeDependentFunctions(SharedFunctionInfo* function_info) {
+  DisallowHeapAllocation no_allocation;
+  DependentFunctionMarker marker(function_info);
+  // TODO(titzer): need to traverse all optimized code to find OSR code here.
+  Deoptimizer::VisitAllOptimizedFunctions(function_info->GetIsolate(), &marker);
+
+  if (marker.found_) {
+    // Only go through with the deoptimization if something was found.
+    Deoptimizer::DeoptimizeMarkedCode(function_info->GetIsolate());
+  }
+}
+
+
+void LiveEdit::ReplaceFunctionCode(
+    Handle<JSArray> new_compile_info_array,
+    Handle<JSArray> shared_info_array) {
+  Isolate* isolate = new_compile_info_array->GetIsolate();
+
+  FunctionInfoWrapper compile_info_wrapper(new_compile_info_array);
+  SharedInfoWrapper shared_info_wrapper(shared_info_array);
+
+  Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
+
+  if (shared_info->code()->kind() == Code::FUNCTION) {
+    Handle<Code> code = compile_info_wrapper.GetFunctionCode();
+    ReplaceCodeObject(Handle<Code>(shared_info->code()), code);
+    Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo();
+    if (code_scope_info->IsFixedArray()) {
+      shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info));
+    }
+    shared_info->DisableOptimization(kLiveEdit);
+    // Update the type feedback vector, if needed.
+    MaybeHandle<TypeFeedbackVector> feedback_vector =
+        compile_info_wrapper.GetFeedbackVector();
+    if (!feedback_vector.is_null()) {
+      shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
+    }
+  }
+
+  int start_position = compile_info_wrapper.GetStartPosition();
+  int end_position = compile_info_wrapper.GetEndPosition();
+  shared_info->set_start_position(start_position);
+  shared_info->set_end_position(end_position);
+
+  LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, isolate);
+
+  shared_info->set_construct_stub(
+      isolate->builtins()->builtin(Builtins::kJSConstructStubGeneric));
+
+  DeoptimizeDependentFunctions(*shared_info);
+  isolate->compilation_cache()->Remove(shared_info);
+}
+
+
+void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array) {
+  SharedInfoWrapper shared_info_wrapper(shared_info_array);
+  Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
+
+  DeoptimizeDependentFunctions(*shared_info);
+  shared_info_array->GetIsolate()->compilation_cache()->Remove(shared_info);
+}
+
+
+void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
+                                 Handle<Object> script_handle) {
+  Handle<SharedFunctionInfo> shared_info =
+      UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
+  CHECK(script_handle->IsScript() || script_handle->IsUndefined());
+  SharedFunctionInfo::SetScript(shared_info, script_handle);
+  shared_info->DisableOptimization(kLiveEdit);
+
+  function_wrapper->GetIsolate()->compilation_cache()->Remove(shared_info);
+}
+
+
+// For a script text change (defined as position_change_array), translates
+// position in unchanged text to position in changed text.
+// Text change is a set of non-overlapping regions in text, that have changed
+// their contents and length. It is specified as array of groups of 3 numbers:
+// (change_begin, change_end, change_end_new_position).
+// Each group describes a change in text; groups are sorted by change_begin.
+// Only position in text beyond any changes may be successfully translated.
+// If a positions is inside some region that changed, result is currently
+// undefined.
+static int TranslatePosition(int original_position,
+                             Handle<JSArray> position_change_array) {
+  int position_diff = 0;
+  int array_len = GetArrayLength(position_change_array);
+  Isolate* isolate = position_change_array->GetIsolate();
+  // TODO(635): binary search may be used here
+  for (int i = 0; i < array_len; i += 3) {
+    HandleScope scope(isolate);
+    Handle<Object> element = Object::GetElement(
+        isolate, position_change_array, i).ToHandleChecked();
+    CHECK(element->IsSmi());
+    int chunk_start = Handle<Smi>::cast(element)->value();
+    if (original_position < chunk_start) {
+      break;
+    }
+    element = Object::GetElement(
+        isolate, position_change_array, i + 1).ToHandleChecked();
+    CHECK(element->IsSmi());
+    int chunk_end = Handle<Smi>::cast(element)->value();
+    // Position mustn't be inside a chunk.
+    DCHECK(original_position >= chunk_end);
+    element = Object::GetElement(
+        isolate, position_change_array, i + 2).ToHandleChecked();
+    CHECK(element->IsSmi());
+    int chunk_changed_end = Handle<Smi>::cast(element)->value();
+    position_diff = chunk_changed_end - chunk_end;
+  }
+
+  return original_position + position_diff;
+}
+
+
+// Auto-growing buffer for writing relocation info code section. This buffer
+// is a simplified version of buffer from Assembler. Unlike Assembler, this
+// class is platform-independent and it works without dealing with instructions.
+// As specified by RelocInfo format, the buffer is filled in reversed order:
+// from upper to lower addresses.
+// It uses NewArray/DeleteArray for memory management.
+class RelocInfoBuffer {
+ public:
+  RelocInfoBuffer(int buffer_initial_capicity, byte* pc) {
+    buffer_size_ = buffer_initial_capicity + kBufferGap;
+    buffer_ = NewArray<byte>(buffer_size_);
+
+    reloc_info_writer_.Reposition(buffer_ + buffer_size_, pc);
+  }
+  ~RelocInfoBuffer() {
+    DeleteArray(buffer_);
+  }
+
+  // As specified by RelocInfo format, the buffer is filled in reversed order:
+  // from upper to lower addresses.
+  void Write(const RelocInfo* rinfo) {
+    if (buffer_ + kBufferGap >= reloc_info_writer_.pos()) {
+      Grow();
+    }
+    reloc_info_writer_.Write(rinfo);
+  }
+
+  Vector<byte> GetResult() {
+    // Return the bytes from pos up to end of buffer.
+    int result_size =
+        static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer_.pos());
+    return Vector<byte>(reloc_info_writer_.pos(), result_size);
+  }
+
+ private:
+  void Grow() {
+    // Compute new buffer size.
+    int new_buffer_size;
+    if (buffer_size_ < 2 * KB) {
+      new_buffer_size = 4 * KB;
+    } else {
+      new_buffer_size = 2 * buffer_size_;
+    }
+    // Some internal data structures overflow for very large buffers,
+    // they must ensure that kMaximalBufferSize is not too large.
+    if (new_buffer_size > kMaximalBufferSize) {
+      V8::FatalProcessOutOfMemory("RelocInfoBuffer::GrowBuffer");
+    }
+
+    // Set up new buffer.
+    byte* new_buffer = NewArray<byte>(new_buffer_size);
+
+    // Copy the data.
+    int curently_used_size =
+        static_cast<int>(buffer_ + buffer_size_ - reloc_info_writer_.pos());
+    MemMove(new_buffer + new_buffer_size - curently_used_size,
+            reloc_info_writer_.pos(), curently_used_size);
+
+    reloc_info_writer_.Reposition(
+        new_buffer + new_buffer_size - curently_used_size,
+        reloc_info_writer_.last_pc());
+
+    DeleteArray(buffer_);
+    buffer_ = new_buffer;
+    buffer_size_ = new_buffer_size;
+  }
+
+  RelocInfoWriter reloc_info_writer_;
+  byte* buffer_;
+  int buffer_size_;
+
+  static const int kBufferGap = RelocInfoWriter::kMaxSize;
+  static const int kMaximalBufferSize = 512*MB;
+};
+
+
+// Patch positions in code (changes relocation info section) and possibly
+// returns new instance of code.
+static Handle<Code> PatchPositionsInCode(
+    Handle<Code> code,
+    Handle<JSArray> position_change_array) {
+  Isolate* isolate = code->GetIsolate();
+
+  RelocInfoBuffer buffer_writer(code->relocation_size(),
+                                code->instruction_start());
+
+  {
+    for (RelocIterator it(*code); !it.done(); it.next()) {
+      RelocInfo* rinfo = it.rinfo();
+      if (RelocInfo::IsPosition(rinfo->rmode())) {
+        int position = static_cast<int>(rinfo->data());
+        int new_position = TranslatePosition(position,
+                                             position_change_array);
+        if (position != new_position) {
+          RelocInfo info_copy(rinfo->pc(), rinfo->rmode(), new_position, NULL);
+          buffer_writer.Write(&info_copy);
+          continue;
+        }
+      }
+      if (RelocInfo::IsRealRelocMode(rinfo->rmode())) {
+        buffer_writer.Write(it.rinfo());
+      }
+    }
+  }
+
+  Vector<byte> buffer = buffer_writer.GetResult();
+
+  if (buffer.length() == code->relocation_size()) {
+    // Simply patch relocation area of code.
+    MemCopy(code->relocation_start(), buffer.start(), buffer.length());
+    return code;
+  } else {
+    // Relocation info section now has different size. We cannot simply
+    // rewrite it inside code object. Instead we have to create a new
+    // code object.
+    Handle<Code> result(isolate->factory()->CopyCode(code, buffer));
+    return result;
+  }
+}
+
+
+void LiveEdit::PatchFunctionPositions(Handle<JSArray> shared_info_array,
+                                      Handle<JSArray> position_change_array) {
+  SharedInfoWrapper shared_info_wrapper(shared_info_array);
+  Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo();
+
+  int old_function_start = info->start_position();
+  int new_function_start = TranslatePosition(old_function_start,
+                                             position_change_array);
+  int new_function_end = TranslatePosition(info->end_position(),
+                                           position_change_array);
+  int new_function_token_pos =
+      TranslatePosition(info->function_token_position(), position_change_array);
+
+  info->set_start_position(new_function_start);
+  info->set_end_position(new_function_end);
+  info->set_function_token_position(new_function_token_pos);
+
+  if (info->code()->kind() == Code::FUNCTION) {
+    // Patch relocation info section of the code.
+    Handle<Code> patched_code = PatchPositionsInCode(Handle<Code>(info->code()),
+                                                     position_change_array);
+    if (*patched_code != info->code()) {
+      // Replace all references to the code across the heap. In particular,
+      // some stubs may refer to this code and this code may be being executed
+      // on stack (it is safe to substitute the code object on stack, because
+      // we only change the structure of rinfo and leave instructions
+      // untouched).
+      ReplaceCodeObject(Handle<Code>(info->code()), patched_code);
+    }
+  }
+}
+
+
+static Handle<Script> CreateScriptCopy(Handle<Script> original) {
+  Isolate* isolate = original->GetIsolate();
+
+  Handle<String> original_source(String::cast(original->source()));
+  Handle<Script> copy = isolate->factory()->NewScript(original_source);
+
+  copy->set_name(original->name());
+  copy->set_line_offset(original->line_offset());
+  copy->set_column_offset(original->column_offset());
+  copy->set_type(original->type());
+  copy->set_context_data(original->context_data());
+  copy->set_eval_from_shared(original->eval_from_shared());
+  copy->set_eval_from_instructions_offset(
+      original->eval_from_instructions_offset());
+
+  // Copy all the flags, but clear compilation state.
+  copy->set_flags(original->flags());
+  copy->set_compilation_state(Script::COMPILATION_STATE_INITIAL);
+
+  return copy;
+}
+
+
+Handle<Object> LiveEdit::ChangeScriptSource(Handle<Script> original_script,
+                                            Handle<String> new_source,
+                                            Handle<Object> old_script_name) {
+  Isolate* isolate = original_script->GetIsolate();
+  Handle<Object> old_script_object;
+  if (old_script_name->IsString()) {
+    Handle<Script> old_script = CreateScriptCopy(original_script);
+    old_script->set_name(String::cast(*old_script_name));
+    old_script_object = old_script;
+    isolate->debug()->OnAfterCompile(old_script);
+  } else {
+    old_script_object = isolate->factory()->null_value();
+  }
+
+  original_script->set_source(*new_source);
+
+  // Drop line ends so that they will be recalculated.
+  original_script->set_line_ends(isolate->heap()->undefined_value());
+
+  return old_script_object;
+}
+
+
+
+void LiveEdit::ReplaceRefToNestedFunction(
+    Handle<JSValue> parent_function_wrapper,
+    Handle<JSValue> orig_function_wrapper,
+    Handle<JSValue> subst_function_wrapper) {
+
+  Handle<SharedFunctionInfo> parent_shared =
+      UnwrapSharedFunctionInfoFromJSValue(parent_function_wrapper);
+  Handle<SharedFunctionInfo> orig_shared =
+      UnwrapSharedFunctionInfoFromJSValue(orig_function_wrapper);
+  Handle<SharedFunctionInfo> subst_shared =
+      UnwrapSharedFunctionInfoFromJSValue(subst_function_wrapper);
+
+  for (RelocIterator it(parent_shared->code()); !it.done(); it.next()) {
+    if (it.rinfo()->rmode() == RelocInfo::EMBEDDED_OBJECT) {
+      if (it.rinfo()->target_object() == *orig_shared) {
+        it.rinfo()->set_target_object(*subst_shared);
+      }
+    }
+  }
+}
+
+
+// Check an activation against list of functions. If there is a function
+// that matches, its status in result array is changed to status argument value.
+static bool CheckActivation(Handle<JSArray> shared_info_array,
+                            Handle<JSArray> result,
+                            StackFrame* frame,
+                            LiveEdit::FunctionPatchabilityStatus status) {
+  if (!frame->is_java_script()) return false;
+
+  Handle<JSFunction> function(JavaScriptFrame::cast(frame)->function());
+
+  Isolate* isolate = shared_info_array->GetIsolate();
+  int len = GetArrayLength(shared_info_array);
+  for (int i = 0; i < len; i++) {
+    HandleScope scope(isolate);
+    Handle<Object> element =
+        Object::GetElement(isolate, shared_info_array, i).ToHandleChecked();
+    Handle<JSValue> jsvalue = Handle<JSValue>::cast(element);
+    Handle<SharedFunctionInfo> shared =
+        UnwrapSharedFunctionInfoFromJSValue(jsvalue);
+
+    if (function->Inlines(*shared)) {
+      SetElementSloppy(result, i, Handle<Smi>(Smi::FromInt(status), isolate));
+      return true;
+    }
+  }
+  return false;
+}
+
+
+// Iterates over handler chain and removes all elements that are inside
+// frames being dropped.
+static bool FixTryCatchHandler(StackFrame* top_frame,
+                               StackFrame* bottom_frame) {
+  Address* pointer_address =
+      &Memory::Address_at(top_frame->isolate()->get_address_from_id(
+          Isolate::kHandlerAddress));
+
+  while (*pointer_address < top_frame->sp()) {
+    pointer_address = &Memory::Address_at(*pointer_address);
+  }
+  Address* above_frame_address = pointer_address;
+  while (*pointer_address < bottom_frame->fp()) {
+    pointer_address = &Memory::Address_at(*pointer_address);
+  }
+  bool change = *above_frame_address != *pointer_address;
+  *above_frame_address = *pointer_address;
+  return change;
+}
+
+
+// Initializes an artificial stack frame. The data it contains is used for:
+//  a. successful work of frame dropper code which eventually gets control,
+//  b. being compatible with regular stack structure for various stack
+//     iterators.
+// Returns address of stack allocated pointer to restarted function,
+// the value that is called 'restarter_frame_function_pointer'. The value
+// at this address (possibly updated by GC) may be used later when preparing
+// 'step in' operation.
+// Frame structure (conforms InternalFrame structure):
+//   -- code
+//   -- SMI maker
+//   -- function (slot is called "context")
+//   -- frame base
+static Object** SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
+                                       Handle<Code> code) {
+  DCHECK(bottom_js_frame->is_java_script());
+
+  Address fp = bottom_js_frame->fp();
+
+  // Move function pointer into "context" slot.
+  Memory::Object_at(fp + StandardFrameConstants::kContextOffset) =
+      Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset);
+
+  Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code;
+  Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) =
+      Smi::FromInt(StackFrame::INTERNAL);
+
+  return reinterpret_cast<Object**>(&Memory::Object_at(
+      fp + StandardFrameConstants::kContextOffset));
+}
+
+
+// Removes specified range of frames from stack. There may be 1 or more
+// frames in range. Anyway the bottom frame is restarted rather than dropped,
+// and therefore has to be a JavaScript frame.
+// Returns error message or NULL.
+static const char* DropFrames(Vector<StackFrame*> frames,
+                              int top_frame_index,
+                              int bottom_js_frame_index,
+                              LiveEdit::FrameDropMode* mode,
+                              Object*** restarter_frame_function_pointer) {
+  if (!LiveEdit::kFrameDropperSupported) {
+    return "Stack manipulations are not supported in this architecture.";
+  }
+
+  StackFrame* pre_top_frame = frames[top_frame_index - 1];
+  StackFrame* top_frame = frames[top_frame_index];
+  StackFrame* bottom_js_frame = frames[bottom_js_frame_index];
+
+  DCHECK(bottom_js_frame->is_java_script());
+
+  // Check the nature of the top frame.
+  Isolate* isolate = bottom_js_frame->isolate();
+  Code* pre_top_frame_code = pre_top_frame->LookupCode();
+  bool frame_has_padding = true;
+  if (pre_top_frame_code->is_inline_cache_stub() &&
+      pre_top_frame_code->is_debug_stub()) {
+    // OK, we can drop inline cache calls.
+    *mode = LiveEdit::FRAME_DROPPED_IN_IC_CALL;
+  } else if (pre_top_frame_code ==
+             isolate->builtins()->builtin(Builtins::kSlot_DebugBreak)) {
+    // OK, we can drop debug break slot.
+    *mode = LiveEdit::FRAME_DROPPED_IN_DEBUG_SLOT_CALL;
+  } else if (pre_top_frame_code ==
+             isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)) {
+    // OK, we can drop our own code.
+    pre_top_frame = frames[top_frame_index - 2];
+    top_frame = frames[top_frame_index - 1];
+    *mode = LiveEdit::CURRENTLY_SET_MODE;
+    frame_has_padding = false;
+  } else if (pre_top_frame_code ==
+             isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) {
+    *mode = LiveEdit::FRAME_DROPPED_IN_RETURN_CALL;
+  } else if (pre_top_frame_code->kind() == Code::STUB &&
+             CodeStub::GetMajorKey(pre_top_frame_code) == CodeStub::CEntry) {
+    // Entry from our unit tests on 'debugger' statement.
+    // It's fine, we support this case.
+    *mode = LiveEdit::FRAME_DROPPED_IN_DIRECT_CALL;
+    // We don't have a padding from 'debugger' statement call.
+    // Here the stub is CEntry, it's not debug-only and can't be padded.
+    // If anyone would complain, a proxy padded stub could be added.
+    frame_has_padding = false;
+  } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) {
+    // This must be adaptor that remain from the frame dropping that
+    // is still on stack. A frame dropper frame must be above it.
+    DCHECK(frames[top_frame_index - 2]->LookupCode() ==
+           isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit));
+    pre_top_frame = frames[top_frame_index - 3];
+    top_frame = frames[top_frame_index - 2];
+    *mode = LiveEdit::CURRENTLY_SET_MODE;
+    frame_has_padding = false;
+  } else {
+    return "Unknown structure of stack above changing function";
+  }
+
+  Address unused_stack_top = top_frame->sp();
+  int new_frame_size = LiveEdit::kFrameDropperFrameSize * kPointerSize;
+  Address unused_stack_bottom = bottom_js_frame->fp()
+      - new_frame_size + kPointerSize;  // Bigger address end is exclusive.
+
+  Address* top_frame_pc_address = top_frame->pc_address();
+
+  // top_frame may be damaged below this point. Do not used it.
+  DCHECK(!(top_frame = NULL));
+
+  if (unused_stack_top > unused_stack_bottom) {
+    if (frame_has_padding) {
+      int shortage_bytes =
+          static_cast<int>(unused_stack_top - unused_stack_bottom);
+
+      Address padding_start = pre_top_frame->fp() -
+          LiveEdit::kFrameDropperFrameSize * kPointerSize;
+
+      Address padding_pointer = padding_start;
+      Smi* padding_object = Smi::FromInt(LiveEdit::kFramePaddingValue);
+      while (Memory::Object_at(padding_pointer) == padding_object) {
+        padding_pointer -= kPointerSize;
+      }
+      int padding_counter =
+          Smi::cast(Memory::Object_at(padding_pointer))->value();
+      if (padding_counter * kPointerSize < shortage_bytes) {
+        return "Not enough space for frame dropper frame "
+            "(even with padding frame)";
+      }
+      Memory::Object_at(padding_pointer) =
+          Smi::FromInt(padding_counter - shortage_bytes / kPointerSize);
+
+      StackFrame* pre_pre_frame = frames[top_frame_index - 2];
+
+      MemMove(padding_start + kPointerSize - shortage_bytes,
+              padding_start + kPointerSize,
+              LiveEdit::kFrameDropperFrameSize * kPointerSize);
+
+      pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes);
+      pre_pre_frame->SetCallerFp(pre_top_frame->fp());
+      unused_stack_top -= shortage_bytes;
+
+      STATIC_ASSERT(sizeof(Address) == kPointerSize);
+      top_frame_pc_address -= shortage_bytes / kPointerSize;
+    } else {
+      return "Not enough space for frame dropper frame";
+    }
+  }
+
+  // Committing now. After this point we should return only NULL value.
+
+  FixTryCatchHandler(pre_top_frame, bottom_js_frame);
+  // Make sure FixTryCatchHandler is idempotent.
+  DCHECK(!FixTryCatchHandler(pre_top_frame, bottom_js_frame));
+
+  Handle<Code> code = isolate->builtins()->FrameDropper_LiveEdit();
+  *top_frame_pc_address = code->entry();
+  pre_top_frame->SetCallerFp(bottom_js_frame->fp());
+
+  *restarter_frame_function_pointer =
+      SetUpFrameDropperFrame(bottom_js_frame, code);
+
+  DCHECK((**restarter_frame_function_pointer)->IsJSFunction());
+
+  for (Address a = unused_stack_top;
+      a < unused_stack_bottom;
+      a += kPointerSize) {
+    Memory::Object_at(a) = Smi::FromInt(0);
+  }
+
+  return NULL;
+}
+
+
+// Describes a set of call frames that execute any of listed functions.
+// Finding no such frames does not mean error.
+class MultipleFunctionTarget {
+ public:
+  MultipleFunctionTarget(Handle<JSArray> shared_info_array,
+      Handle<JSArray> result)
+      : m_shared_info_array(shared_info_array),
+        m_result(result) {}
+  bool MatchActivation(StackFrame* frame,
+      LiveEdit::FunctionPatchabilityStatus status) {
+    return CheckActivation(m_shared_info_array, m_result, frame, status);
+  }
+  const char* GetNotFoundMessage() const {
+    return NULL;
+  }
+ private:
+  Handle<JSArray> m_shared_info_array;
+  Handle<JSArray> m_result;
+};
+
+
+// Drops all call frame matched by target and all frames above them.
+template <typename TARGET>
+static const char* DropActivationsInActiveThreadImpl(Isolate* isolate,
+                                                     TARGET& target,  // NOLINT
+                                                     bool do_drop) {
+  Debug* debug = isolate->debug();
+  Zone zone;
+  Vector<StackFrame*> frames = CreateStackMap(isolate, &zone);
+
+
+  int top_frame_index = -1;
+  int frame_index = 0;
+  for (; frame_index < frames.length(); frame_index++) {
+    StackFrame* frame = frames[frame_index];
+    if (frame->id() == debug->break_frame_id()) {
+      top_frame_index = frame_index;
+      break;
+    }
+    if (target.MatchActivation(
+            frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
+      // We are still above break_frame. It is not a target frame,
+      // it is a problem.
+      return "Debugger mark-up on stack is not found";
+    }
+  }
+
+  if (top_frame_index == -1) {
+    // We haven't found break frame, but no function is blocking us anyway.
+    return target.GetNotFoundMessage();
+  }
+
+  bool target_frame_found = false;
+  int bottom_js_frame_index = top_frame_index;
+  bool non_droppable_frame_found = false;
+  LiveEdit::FunctionPatchabilityStatus non_droppable_reason;
+
+  for (; frame_index < frames.length(); frame_index++) {
+    StackFrame* frame = frames[frame_index];
+    if (frame->is_exit()) {
+      non_droppable_frame_found = true;
+      non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE;
+      break;
+    }
+    if (frame->is_java_script() &&
+        JavaScriptFrame::cast(frame)->function()->shared()->is_generator()) {
+      non_droppable_frame_found = true;
+      non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR;
+      break;
+    }
+    if (target.MatchActivation(
+            frame, LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
+      target_frame_found = true;
+      bottom_js_frame_index = frame_index;
+    }
+  }
+
+  if (non_droppable_frame_found) {
+    // There is a C or generator frame on stack.  We can't drop C frames, and we
+    // can't restart generators.  Check that there are no target frames below
+    // them.
+    for (; frame_index < frames.length(); frame_index++) {
+      StackFrame* frame = frames[frame_index];
+      if (frame->is_java_script()) {
+        if (target.MatchActivation(frame, non_droppable_reason)) {
+          // Fail.
+          return NULL;
+        }
+      }
+    }
+  }
+
+  if (!do_drop) {
+    // We are in check-only mode.
+    return NULL;
+  }
+
+  if (!target_frame_found) {
+    // Nothing to drop.
+    return target.GetNotFoundMessage();
+  }
+
+  LiveEdit::FrameDropMode drop_mode = LiveEdit::FRAMES_UNTOUCHED;
+  Object** restarter_frame_function_pointer = NULL;
+  const char* error_message = DropFrames(frames, top_frame_index,
+                                         bottom_js_frame_index, &drop_mode,
+                                         &restarter_frame_function_pointer);
+
+  if (error_message != NULL) {
+    return error_message;
+  }
+
+  // Adjust break_frame after some frames has been dropped.
+  StackFrame::Id new_id = StackFrame::NO_ID;
+  for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) {
+    if (frames[i]->type() == StackFrame::JAVA_SCRIPT) {
+      new_id = frames[i]->id();
+      break;
+    }
+  }
+  debug->FramesHaveBeenDropped(
+      new_id, drop_mode, restarter_frame_function_pointer);
+  return NULL;
+}
+
+
+// Fills result array with statuses of functions. Modifies the stack
+// removing all listed function if possible and if do_drop is true.
+static const char* DropActivationsInActiveThread(
+    Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop) {
+  MultipleFunctionTarget target(shared_info_array, result);
+  Isolate* isolate = shared_info_array->GetIsolate();
+
+  const char* message =
+      DropActivationsInActiveThreadImpl(isolate, target, do_drop);
+  if (message) {
+    return message;
+  }
+
+  int array_len = GetArrayLength(shared_info_array);
+
+  // Replace "blocked on active" with "replaced on active" status.
+  for (int i = 0; i < array_len; i++) {
+    Handle<Object> obj =
+        Object::GetElement(isolate, result, i).ToHandleChecked();
+    if (*obj == Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
+      Handle<Object> replaced(
+          Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK), isolate);
+      SetElementSloppy(result, i, replaced);
+    }
+  }
+  return NULL;
+}
+
+
+bool LiveEdit::FindActiveGenerators(Handle<FixedArray> shared_info_array,
+                                    Handle<FixedArray> result,
+                                    int len) {
+  Isolate* isolate = shared_info_array->GetIsolate();
+  bool found_suspended_activations = false;
+
+  DCHECK_LE(len, result->length());
+
+  FunctionPatchabilityStatus active = FUNCTION_BLOCKED_ACTIVE_GENERATOR;
+
+  Heap* heap = isolate->heap();
+  HeapIterator iterator(heap);
+  HeapObject* obj = NULL;
+  while ((obj = iterator.next()) != NULL) {
+    if (!obj->IsJSGeneratorObject()) continue;
+
+    JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
+    if (gen->is_closed()) continue;
+
+    HandleScope scope(isolate);
+
+    for (int i = 0; i < len; i++) {
+      Handle<JSValue> jsvalue =
+          Handle<JSValue>::cast(FixedArray::get(shared_info_array, i));
+      Handle<SharedFunctionInfo> shared =
+          UnwrapSharedFunctionInfoFromJSValue(jsvalue);
+
+      if (gen->function()->shared() == *shared) {
+        result->set(i, Smi::FromInt(active));
+        found_suspended_activations = true;
+      }
+    }
+  }
+
+  return found_suspended_activations;
+}
+
+
+class InactiveThreadActivationsChecker : public ThreadVisitor {
+ public:
+  InactiveThreadActivationsChecker(Handle<JSArray> shared_info_array,
+                                   Handle<JSArray> result)
+      : shared_info_array_(shared_info_array), result_(result),
+        has_blocked_functions_(false) {
+  }
+  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
+    for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) {
+      has_blocked_functions_ |= CheckActivation(
+          shared_info_array_, result_, it.frame(),
+          LiveEdit::FUNCTION_BLOCKED_ON_OTHER_STACK);
+    }
+  }
+  bool HasBlockedFunctions() {
+    return has_blocked_functions_;
+  }
+
+ private:
+  Handle<JSArray> shared_info_array_;
+  Handle<JSArray> result_;
+  bool has_blocked_functions_;
+};
+
+
+Handle<JSArray> LiveEdit::CheckAndDropActivations(
+    Handle<JSArray> shared_info_array, bool do_drop) {
+  Isolate* isolate = shared_info_array->GetIsolate();
+  int len = GetArrayLength(shared_info_array);
+
+  DCHECK(shared_info_array->HasFastElements());
+  Handle<FixedArray> shared_info_array_elements(
+      FixedArray::cast(shared_info_array->elements()));
+
+  Handle<JSArray> result = isolate->factory()->NewJSArray(len);
+  Handle<FixedArray> result_elements =
+      JSObject::EnsureWritableFastElements(result);
+
+  // Fill the default values.
+  for (int i = 0; i < len; i++) {
+    FunctionPatchabilityStatus status = FUNCTION_AVAILABLE_FOR_PATCH;
+    result_elements->set(i, Smi::FromInt(status));
+  }
+
+  // Scan the heap for active generators -- those that are either currently
+  // running (as we wouldn't want to restart them, because we don't know where
+  // to restart them from) or suspended.  Fail if any one corresponds to the set
+  // of functions being edited.
+  if (FindActiveGenerators(shared_info_array_elements, result_elements, len)) {
+    return result;
+  }
+
+  // Check inactive threads. Fail if some functions are blocked there.
+  InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array,
+                                                            result);
+  isolate->thread_manager()->IterateArchivedThreads(
+      &inactive_threads_checker);
+  if (inactive_threads_checker.HasBlockedFunctions()) {
+    return result;
+  }
+
+  // Try to drop activations from the current stack.
+  const char* error_message =
+      DropActivationsInActiveThread(shared_info_array, result, do_drop);
+  if (error_message != NULL) {
+    // Add error message as an array extra element.
+    Handle<String> str =
+        isolate->factory()->NewStringFromAsciiChecked(error_message);
+    SetElementSloppy(result, len, str);
+  }
+  return result;
+}
+
+
+// Describes a single callframe a target. Not finding this frame
+// means an error.
+class SingleFrameTarget {
+ public:
+  explicit SingleFrameTarget(JavaScriptFrame* frame)
+      : m_frame(frame),
+        m_saved_status(LiveEdit::FUNCTION_AVAILABLE_FOR_PATCH) {}
+
+  bool MatchActivation(StackFrame* frame,
+      LiveEdit::FunctionPatchabilityStatus status) {
+    if (frame->fp() == m_frame->fp()) {
+      m_saved_status = status;
+      return true;
+    }
+    return false;
+  }
+  const char* GetNotFoundMessage() const {
+    return "Failed to found requested frame";
+  }
+  LiveEdit::FunctionPatchabilityStatus saved_status() {
+    return m_saved_status;
+  }
+ private:
+  JavaScriptFrame* m_frame;
+  LiveEdit::FunctionPatchabilityStatus m_saved_status;
+};
+
+
+// Finds a drops required frame and all frames above.
+// Returns error message or NULL.
+const char* LiveEdit::RestartFrame(JavaScriptFrame* frame) {
+  SingleFrameTarget target(frame);
+
+  const char* result =
+      DropActivationsInActiveThreadImpl(frame->isolate(), target, true);
+  if (result != NULL) {
+    return result;
+  }
+  if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE) {
+    return "Function is blocked under native code";
+  }
+  if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR) {
+    return "Function is blocked under a generator activation";
+  }
+  return NULL;
+}
+
+
+LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate,
+                                                 FunctionLiteral* fun)
+    : isolate_(isolate) {
+  if (isolate_->active_function_info_listener() != NULL) {
+    isolate_->active_function_info_listener()->FunctionStarted(fun);
+  }
+}
+
+
+LiveEditFunctionTracker::~LiveEditFunctionTracker() {
+  if (isolate_->active_function_info_listener() != NULL) {
+    isolate_->active_function_info_listener()->FunctionDone();
+  }
+}
+
+
+void LiveEditFunctionTracker::RecordFunctionInfo(
+    Handle<SharedFunctionInfo> info, FunctionLiteral* lit,
+    Zone* zone) {
+  if (isolate_->active_function_info_listener() != NULL) {
+    isolate_->active_function_info_listener()->FunctionInfo(info, lit->scope(),
+                                                            zone);
+  }
+}
+
+
+void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) {
+  isolate_->active_function_info_listener()->FunctionCode(code);
+}
+
+
+bool LiveEditFunctionTracker::IsActive(Isolate* isolate) {
+  return isolate->active_function_info_listener() != NULL;
+}
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/debug/liveedit.h b/src/debug/liveedit.h
new file mode 100644 (file)
index 0000000..d576e82
--- /dev/null
@@ -0,0 +1,371 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_DEBUG_LIVEEDIT_H_
+#define V8_DEBUG_LIVEEDIT_H_
+
+
+// Live Edit feature implementation.
+// User should be able to change script on already running VM. This feature
+// matches hot swap features in other frameworks.
+//
+// The basic use-case is when user spots some mistake in function body
+// from debugger and wishes to change the algorithm without restart.
+//
+// A single change always has a form of a simple replacement (in pseudo-code):
+//   script.source[positions, positions+length] = new_string;
+// Implementation first determines, which function's body includes this
+// change area. Then both old and new versions of script are fully compiled
+// in order to analyze, whether the function changed its outer scope
+// expectations (or number of parameters). If it didn't, function's code is
+// patched with a newly compiled code. If it did change, enclosing function
+// gets patched. All inner functions are left untouched, whatever happened
+// to them in a new script version. However, new version of code will
+// instantiate newly compiled functions.
+
+
+#include "src/allocation.h"
+#include "src/compiler.h"
+
+namespace v8 {
+namespace internal {
+
+// This class collects some specific information on structure of functions
+// in a particular script. It gets called from compiler all the time, but
+// actually records any data only when liveedit operation is in process;
+// in any other time this class is very cheap.
+//
+// The primary interest of the Tracker is to record function scope structures
+// in order to analyze whether function code maybe safely patched (with new
+// code successfully reading existing data from function scopes). The Tracker
+// also collects compiled function codes.
+class LiveEditFunctionTracker {
+ public:
+  explicit LiveEditFunctionTracker(Isolate* isolate, FunctionLiteral* fun);
+  ~LiveEditFunctionTracker();
+  void RecordFunctionInfo(Handle<SharedFunctionInfo> info,
+                          FunctionLiteral* lit, Zone* zone);
+  void RecordRootFunctionInfo(Handle<Code> code);
+
+  static bool IsActive(Isolate* isolate);
+
+ private:
+  Isolate* isolate_;
+};
+
+
+class LiveEdit : AllStatic {
+ public:
+  // Describes how exactly a frame has been dropped from stack.
+  enum FrameDropMode {
+    // No frame has been dropped.
+    FRAMES_UNTOUCHED,
+    // The top JS frame had been calling IC stub. IC stub mustn't be called now.
+    FRAME_DROPPED_IN_IC_CALL,
+    // The top JS frame had been calling debug break slot stub. Patch the
+    // address this stub jumps to in the end.
+    FRAME_DROPPED_IN_DEBUG_SLOT_CALL,
+    // The top JS frame had been calling some C++ function. The return address
+    // gets patched automatically.
+    FRAME_DROPPED_IN_DIRECT_CALL,
+    FRAME_DROPPED_IN_RETURN_CALL,
+    CURRENTLY_SET_MODE
+  };
+
+  static void InitializeThreadLocal(Debug* debug);
+
+  static bool SetAfterBreakTarget(Debug* debug);
+
+  MUST_USE_RESULT static MaybeHandle<JSArray> GatherCompileInfo(
+      Handle<Script> script,
+      Handle<String> source);
+
+  static void WrapSharedFunctionInfos(Handle<JSArray> array);
+
+  static void ReplaceFunctionCode(Handle<JSArray> new_compile_info_array,
+                                  Handle<JSArray> shared_info_array);
+
+  static void FunctionSourceUpdated(Handle<JSArray> shared_info_array);
+
+  // Updates script field in FunctionSharedInfo.
+  static void SetFunctionScript(Handle<JSValue> function_wrapper,
+                                Handle<Object> script_handle);
+
+  static void PatchFunctionPositions(Handle<JSArray> shared_info_array,
+                                     Handle<JSArray> position_change_array);
+
+  // For a script updates its source field. If old_script_name is provided
+  // (i.e. is a String), also creates a copy of the script with its original
+  // source and sends notification to debugger.
+  static Handle<Object> ChangeScriptSource(Handle<Script> original_script,
+                                           Handle<String> new_source,
+                                           Handle<Object> old_script_name);
+
+  // In a code of a parent function replaces original function as embedded
+  // object with a substitution one.
+  static void ReplaceRefToNestedFunction(Handle<JSValue> parent_function_shared,
+                                         Handle<JSValue> orig_function_shared,
+                                         Handle<JSValue> subst_function_shared);
+
+  // Find open generator activations, and set corresponding "result" elements to
+  // FUNCTION_BLOCKED_ACTIVE_GENERATOR.
+  static bool FindActiveGenerators(Handle<FixedArray> shared_info_array,
+                                   Handle<FixedArray> result, int len);
+
+  // Checks listed functions on stack and return array with corresponding
+  // FunctionPatchabilityStatus statuses; extra array element may
+  // contain general error message. Modifies the current stack and
+  // has restart the lowest found frames and drops all other frames above
+  // if possible and if do_drop is true.
+  static Handle<JSArray> CheckAndDropActivations(
+      Handle<JSArray> shared_info_array, bool do_drop);
+
+  // Restarts the call frame and completely drops all frames above it.
+  // Return error message or NULL.
+  static const char* RestartFrame(JavaScriptFrame* frame);
+
+  // A copy of this is in liveedit.js.
+  enum FunctionPatchabilityStatus {
+    FUNCTION_AVAILABLE_FOR_PATCH = 1,
+    FUNCTION_BLOCKED_ON_ACTIVE_STACK = 2,
+    FUNCTION_BLOCKED_ON_OTHER_STACK = 3,
+    FUNCTION_BLOCKED_UNDER_NATIVE_CODE = 4,
+    FUNCTION_REPLACED_ON_ACTIVE_STACK = 5,
+    FUNCTION_BLOCKED_UNDER_GENERATOR = 6,
+    FUNCTION_BLOCKED_ACTIVE_GENERATOR = 7
+  };
+
+  // Compares 2 strings line-by-line, then token-wise and returns diff in form
+  // of array of triplets (pos1, pos1_end, pos2_end) describing list
+  // of diff chunks.
+  static Handle<JSArray> CompareStrings(Handle<String> s1,
+                                        Handle<String> s2);
+
+  // Architecture-specific constant.
+  static const bool kFrameDropperSupported;
+
+  /**
+   * Defines layout of a stack frame that supports padding. This is a regular
+   * internal frame that has a flexible stack structure. LiveEdit can shift
+   * its lower part up the stack, taking up the 'padding' space when additional
+   * stack memory is required.
+   * Such frame is expected immediately above the topmost JavaScript frame.
+   *
+   * Stack Layout:
+   *   --- Top
+   *   LiveEdit routine frames
+   *   ---
+   *   C frames of debug handler
+   *   ---
+   *   ...
+   *   ---
+   *      An internal frame that has n padding words:
+   *      - any number of words as needed by code -- upper part of frame
+   *      - padding size: a Smi storing n -- current size of padding
+   *      - padding: n words filled with kPaddingValue in form of Smi
+   *      - 3 context/type words of a regular InternalFrame
+   *      - fp
+   *   ---
+   *      Topmost JavaScript frame
+   *   ---
+   *   ...
+   *   --- Bottom
+   */
+  // A size of frame base including fp. Padding words starts right above
+  // the base.
+  static const int kFrameDropperFrameSize = 4;
+  // A number of words that should be reserved on stack for the LiveEdit use.
+  // Stored on stack in form of Smi.
+  static const int kFramePaddingInitialSize = 1;
+  // A value that padding words are filled with (in form of Smi). Going
+  // bottom-top, the first word not having this value is a counter word.
+  static const int kFramePaddingValue = kFramePaddingInitialSize + 1;
+};
+
+
+// A general-purpose comparator between 2 arrays.
+class Comparator {
+ public:
+  // Holds 2 arrays of some elements allowing to compare any pair of
+  // element from the first array and element from the second array.
+  class Input {
+   public:
+    virtual int GetLength1() = 0;
+    virtual int GetLength2() = 0;
+    virtual bool Equals(int index1, int index2) = 0;
+
+   protected:
+    virtual ~Input() {}
+  };
+
+  // Receives compare result as a series of chunks.
+  class Output {
+   public:
+    // Puts another chunk in result list. Note that technically speaking
+    // only 3 arguments actually needed with 4th being derivable.
+    virtual void AddChunk(int pos1, int pos2, int len1, int len2) = 0;
+
+   protected:
+    virtual ~Output() {}
+  };
+
+  // Finds the difference between 2 arrays of elements.
+  static void CalculateDifference(Input* input,
+                                  Output* result_writer);
+};
+
+
+
+// Simple helper class that creates more or less typed structures over
+// JSArray object. This is an adhoc method of passing structures from C++
+// to JavaScript.
+template<typename S>
+class JSArrayBasedStruct {
+ public:
+  static S Create(Isolate* isolate) {
+    Factory* factory = isolate->factory();
+    Handle<JSArray> array = factory->NewJSArray(S::kSize_);
+    return S(array);
+  }
+
+  static S cast(Object* object) {
+    JSArray* array = JSArray::cast(object);
+    Handle<JSArray> array_handle(array);
+    return S(array_handle);
+  }
+
+  explicit JSArrayBasedStruct(Handle<JSArray> array) : array_(array) {
+  }
+
+  Handle<JSArray> GetJSArray() {
+    return array_;
+  }
+
+  Isolate* isolate() const {
+    return array_->GetIsolate();
+  }
+
+ protected:
+  void SetField(int field_position, Handle<Object> value) {
+    Object::SetElement(isolate(), array_, field_position, value, SLOPPY)
+        .Assert();
+  }
+
+  void SetSmiValueField(int field_position, int value) {
+    SetField(field_position, Handle<Smi>(Smi::FromInt(value), isolate()));
+  }
+
+  Handle<Object> GetField(int field_position) {
+    return Object::GetElement(
+        isolate(), array_, field_position).ToHandleChecked();
+  }
+
+  int GetSmiValueField(int field_position) {
+    Handle<Object> res = GetField(field_position);
+    return Handle<Smi>::cast(res)->value();
+  }
+
+ private:
+  Handle<JSArray> array_;
+};
+
+
+// Represents some function compilation details. This structure will be used
+// from JavaScript. It contains Code object, which is kept wrapped
+// into a BlindReference for sanitizing reasons.
+class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
+ public:
+  explicit FunctionInfoWrapper(Handle<JSArray> array)
+      : JSArrayBasedStruct<FunctionInfoWrapper>(array) {
+  }
+
+  void SetInitialProperties(Handle<String> name, int start_position,
+                            int end_position, int param_num, int literal_count,
+                            int parent_index);
+
+  void SetFunctionCode(Handle<Code> function_code,
+                       Handle<HeapObject> code_scope_info);
+
+  void SetFunctionScopeInfo(Handle<Object> scope_info_array) {
+    this->SetField(kFunctionScopeInfoOffset_, scope_info_array);
+  }
+
+  void SetSharedFunctionInfo(Handle<SharedFunctionInfo> info);
+
+  int GetLiteralCount() {
+    return this->GetSmiValueField(kLiteralNumOffset_);
+  }
+
+  int GetParentIndex() {
+    return this->GetSmiValueField(kParentIndexOffset_);
+  }
+
+  Handle<Code> GetFunctionCode();
+
+  MaybeHandle<TypeFeedbackVector> GetFeedbackVector();
+
+  Handle<Object> GetCodeScopeInfo();
+
+  int GetStartPosition() {
+    return this->GetSmiValueField(kStartPositionOffset_);
+  }
+
+  int GetEndPosition() { return this->GetSmiValueField(kEndPositionOffset_); }
+
+ private:
+  static const int kFunctionNameOffset_ = 0;
+  static const int kStartPositionOffset_ = 1;
+  static const int kEndPositionOffset_ = 2;
+  static const int kParamNumOffset_ = 3;
+  static const int kCodeOffset_ = 4;
+  static const int kCodeScopeInfoOffset_ = 5;
+  static const int kFunctionScopeInfoOffset_ = 6;
+  static const int kParentIndexOffset_ = 7;
+  static const int kSharedFunctionInfoOffset_ = 8;
+  static const int kLiteralNumOffset_ = 9;
+  static const int kSize_ = 10;
+
+  friend class JSArrayBasedStruct<FunctionInfoWrapper>;
+};
+
+
+// Wraps SharedFunctionInfo along with some of its fields for passing it
+// back to JavaScript. SharedFunctionInfo object itself is additionally
+// wrapped into BlindReference for sanitizing reasons.
+class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> {
+ public:
+  static bool IsInstance(Handle<JSArray> array) {
+    if (array->length() != Smi::FromInt(kSize_)) return false;
+    Handle<Object> element(
+        Object::GetElement(array->GetIsolate(),
+                           array,
+                           kSharedInfoOffset_).ToHandleChecked());
+    if (!element->IsJSValue()) return false;
+    return Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo();
+  }
+
+  explicit SharedInfoWrapper(Handle<JSArray> array)
+      : JSArrayBasedStruct<SharedInfoWrapper>(array) {
+  }
+
+  void SetProperties(Handle<String> name,
+                     int start_position,
+                     int end_position,
+                     Handle<SharedFunctionInfo> info);
+
+  Handle<SharedFunctionInfo> GetInfo();
+
+ private:
+  static const int kFunctionNameOffset_ = 0;
+  static const int kStartPositionOffset_ = 1;
+  static const int kEndPositionOffset_ = 2;
+  static const int kSharedInfoOffset_ = 3;
+  static const int kSize_ = 4;
+
+  friend class JSArrayBasedStruct<SharedInfoWrapper>;
+};
+
+} }  // namespace v8::internal
+
+#endif /* V8_DEBUG_LIVEEDIT_H_ */
diff --git a/src/debug/liveedit.js b/src/debug/liveedit.js
new file mode 100644 (file)
index 0000000..26663bf
--- /dev/null
@@ -0,0 +1,1107 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// LiveEdit feature implementation. The script should be executed after
+// debug.js.
+
+// A LiveEdit namespace. It contains functions that modifies JavaScript code
+// according to changes of script source (if possible).
+//
+// When new script source is put in, the difference is calculated textually,
+// in form of list of delete/add/change chunks. The functions that include
+// change chunk(s) get recompiled, or their enclosing functions are
+// recompiled instead.
+// If the function may not be recompiled (e.g. it was completely erased in new
+// version of the script) it remains unchanged, but the code that could
+// create a new instance of this function goes away. An old version of script
+// is created to back up this obsolete function.
+// All unchanged functions have their positions updated accordingly.
+//
+// LiveEdit namespace is declared inside a single function constructor.
+
+"use strict";
+
+Debug.LiveEdit = new function() {
+
+  // Forward declaration for minifier.
+  var FunctionStatus;
+
+  // Applies the change to the script.
+  // The change is in form of list of chunks encoded in a single array as
+  // a series of triplets (pos1_start, pos1_end, pos2_end)
+  function ApplyPatchMultiChunk(script, diff_array, new_source, preview_only,
+      change_log) {
+
+    var old_source = script.source;
+
+    // Gather compile information about old version of script.
+    var old_compile_info = GatherCompileInfo(old_source, script);
+
+    // Build tree structures for old and new versions of the script.
+    var root_old_node = BuildCodeInfoTree(old_compile_info);
+
+    var pos_translator = new PosTranslator(diff_array);
+
+    // Analyze changes.
+    MarkChangedFunctions(root_old_node, pos_translator.GetChunks());
+
+    // Find all SharedFunctionInfo's that were compiled from this script.
+    FindLiveSharedInfos(root_old_node, script);
+
+    // Gather compile information about new version of script.
+    var new_compile_info;
+    try {
+      new_compile_info = GatherCompileInfo(new_source, script);
+    } catch (e) {
+      var failure =
+          new Failure("Failed to compile new version of script: " + e);
+      if (e instanceof SyntaxError) {
+        var details = {
+          type: "liveedit_compile_error",
+          syntaxErrorMessage: e.message
+        };
+        CopyErrorPositionToDetails(e, details);
+        failure.details = details;
+      }
+      throw failure;
+    }
+    var root_new_node = BuildCodeInfoTree(new_compile_info);
+
+    // Link recompiled script data with other data.
+    FindCorrespondingFunctions(root_old_node, root_new_node);
+
+    // Prepare to-do lists.
+    var replace_code_list = new Array();
+    var link_to_old_script_list = new Array();
+    var link_to_original_script_list = new Array();
+    var update_positions_list = new Array();
+
+    function HarvestTodo(old_node) {
+      function CollectDamaged(node) {
+        link_to_old_script_list.push(node);
+        for (var i = 0; i < node.children.length; i++) {
+          CollectDamaged(node.children[i]);
+        }
+      }
+
+      // Recursively collects all newly compiled functions that are going into
+      // business and should have link to the actual script updated.
+      function CollectNew(node_list) {
+        for (var i = 0; i < node_list.length; i++) {
+          link_to_original_script_list.push(node_list[i]);
+          CollectNew(node_list[i].children);
+        }
+      }
+
+      if (old_node.status == FunctionStatus.DAMAGED) {
+        CollectDamaged(old_node);
+        return;
+      }
+      if (old_node.status == FunctionStatus.UNCHANGED) {
+        update_positions_list.push(old_node);
+      } else if (old_node.status == FunctionStatus.SOURCE_CHANGED) {
+        update_positions_list.push(old_node);
+      } else if (old_node.status == FunctionStatus.CHANGED) {
+        replace_code_list.push(old_node);
+        CollectNew(old_node.unmatched_new_nodes);
+      }
+      for (var i = 0; i < old_node.children.length; i++) {
+        HarvestTodo(old_node.children[i]);
+      }
+    }
+
+    var preview_description = {
+        change_tree: DescribeChangeTree(root_old_node),
+        textual_diff: {
+          old_len: old_source.length,
+          new_len: new_source.length,
+          chunks: diff_array
+        },
+        updated: false
+    };
+
+    if (preview_only) {
+      return preview_description;
+    }
+
+    HarvestTodo(root_old_node);
+
+    // Collect shared infos for functions whose code need to be patched.
+    var replaced_function_infos = new Array();
+    for (var i = 0; i < replace_code_list.length; i++) {
+      var live_shared_function_infos =
+          replace_code_list[i].live_shared_function_infos;
+
+      if (live_shared_function_infos) {
+        for (var j = 0; j < live_shared_function_infos.length; j++) {
+          replaced_function_infos.push(live_shared_function_infos[j]);
+        }
+      }
+    }
+
+    // We haven't changed anything before this line yet.
+    // Committing all changes.
+
+    // Check that function being patched is not currently on stack or drop them.
+    var dropped_functions_number =
+        CheckStackActivations(replaced_function_infos, change_log);
+
+    // Our current implementation requires client to manually issue "step in"
+    // command for correct stack state if the stack was modified.
+    preview_description.stack_modified = dropped_functions_number != 0;
+
+    // Start with breakpoints. Convert their line/column positions and
+    // temporary remove.
+    var break_points_restorer = TemporaryRemoveBreakPoints(script, change_log);
+
+    var old_script;
+
+    // Create an old script only if there are function that should be linked
+    // to old version.
+    if (link_to_old_script_list.length == 0) {
+      %LiveEditReplaceScript(script, new_source, null);
+      old_script = UNDEFINED;
+    } else {
+      var old_script_name = CreateNameForOldScript(script);
+
+      // Update the script text and create a new script representing an old
+      // version of the script.
+      old_script = %LiveEditReplaceScript(script, new_source,
+          old_script_name);
+
+      var link_to_old_script_report = new Array();
+      change_log.push( { linked_to_old_script: link_to_old_script_report } );
+
+      // We need to link to old script all former nested functions.
+      for (var i = 0; i < link_to_old_script_list.length; i++) {
+        LinkToOldScript(link_to_old_script_list[i], old_script,
+            link_to_old_script_report);
+      }
+
+      preview_description.created_script_name = old_script_name;
+    }
+
+    // Link to an actual script all the functions that we are going to use.
+    for (var i = 0; i < link_to_original_script_list.length; i++) {
+      %LiveEditFunctionSetScript(
+          link_to_original_script_list[i].info.shared_function_info, script);
+    }
+
+    for (var i = 0; i < replace_code_list.length; i++) {
+      PatchFunctionCode(replace_code_list[i], change_log);
+    }
+
+    var position_patch_report = new Array();
+    change_log.push( {position_patched: position_patch_report} );
+
+    for (var i = 0; i < update_positions_list.length; i++) {
+      // TODO(LiveEdit): take into account whether it's source_changed or
+      // unchanged and whether positions changed at all.
+      PatchPositions(update_positions_list[i], diff_array,
+          position_patch_report);
+
+      if (update_positions_list[i].live_shared_function_infos) {
+        update_positions_list[i].live_shared_function_infos.
+            forEach(function (info) {
+                %LiveEditFunctionSourceUpdated(info.raw_array);
+              });
+      }
+    }
+
+    break_points_restorer(pos_translator, old_script);
+
+    preview_description.updated = true;
+    return preview_description;
+  }
+  // Function is public.
+  this.ApplyPatchMultiChunk = ApplyPatchMultiChunk;
+
+
+  // Fully compiles source string as a script. Returns Array of
+  // FunctionCompileInfo -- a descriptions of all functions of the script.
+  // Elements of array are ordered by start positions of functions (from top
+  // to bottom) in the source. Fields outer_index and next_sibling_index help
+  // to navigate the nesting structure of functions.
+  //
+  // All functions get compiled linked to script provided as parameter script.
+  // TODO(LiveEdit): consider not using actual scripts as script, because
+  // we have to manually erase all links right after compile.
+  function GatherCompileInfo(source, script) {
+    // Get function info, elements are partially sorted (it is a tree of
+    // nested functions serialized as parent followed by serialized children.
+    var raw_compile_info = %LiveEditGatherCompileInfo(script, source);
+
+    // Sort function infos by start position field.
+    var compile_info = new Array();
+    var old_index_map = new Array();
+    for (var i = 0; i < raw_compile_info.length; i++) {
+      var info = new FunctionCompileInfo(raw_compile_info[i]);
+      // Remove all links to the actual script. Breakpoints system and
+      // LiveEdit itself believe that any function in heap that points to a
+      // particular script is a regular function.
+      // For some functions we will restore this link later.
+      %LiveEditFunctionSetScript(info.shared_function_info, UNDEFINED);
+      compile_info.push(info);
+      old_index_map.push(i);
+    }
+
+    for (var i = 0; i < compile_info.length; i++) {
+      var k = i;
+      for (var j = i + 1; j < compile_info.length; j++) {
+        if (compile_info[k].start_position > compile_info[j].start_position) {
+          k = j;
+        }
+      }
+      if (k != i) {
+        var temp_info = compile_info[k];
+        var temp_index = old_index_map[k];
+        compile_info[k] = compile_info[i];
+        old_index_map[k] = old_index_map[i];
+        compile_info[i] = temp_info;
+        old_index_map[i] = temp_index;
+      }
+    }
+
+    // After sorting update outer_index field using old_index_map. Also
+    // set next_sibling_index field.
+    var current_index = 0;
+
+    // The recursive function, that goes over all children of a particular
+    // node (i.e. function info).
+    function ResetIndexes(new_parent_index, old_parent_index) {
+      var previous_sibling = -1;
+      while (current_index < compile_info.length &&
+          compile_info[current_index].outer_index == old_parent_index) {
+        var saved_index = current_index;
+        compile_info[saved_index].outer_index = new_parent_index;
+        if (previous_sibling != -1) {
+          compile_info[previous_sibling].next_sibling_index = saved_index;
+        }
+        previous_sibling = saved_index;
+        current_index++;
+        ResetIndexes(saved_index, old_index_map[saved_index]);
+      }
+      if (previous_sibling != -1) {
+        compile_info[previous_sibling].next_sibling_index = -1;
+      }
+    }
+
+    ResetIndexes(-1, -1);
+    Assert(current_index == compile_info.length);
+
+    return compile_info;
+  }
+
+
+  // Replaces function's Code.
+  function PatchFunctionCode(old_node, change_log) {
+    var new_info = old_node.corresponding_node.info;
+    if (old_node.live_shared_function_infos) {
+      old_node.live_shared_function_infos.forEach(function (old_info) {
+        %LiveEditReplaceFunctionCode(new_info.raw_array,
+                                     old_info.raw_array);
+
+        // The function got a new code. However, this new code brings all new
+        // instances of SharedFunctionInfo for nested functions. However,
+        // we want the original instances to be used wherever possible.
+        // (This is because old instances and new instances will be both
+        // linked to a script and breakpoints subsystem does not really
+        // expects this; neither does LiveEdit subsystem on next call).
+        for (var i = 0; i < old_node.children.length; i++) {
+          if (old_node.children[i].corresponding_node) {
+            var corresponding_child_info =
+                old_node.children[i].corresponding_node.info.
+                    shared_function_info;
+
+            if (old_node.children[i].live_shared_function_infos) {
+              old_node.children[i].live_shared_function_infos.
+                  forEach(function (old_child_info) {
+                    %LiveEditReplaceRefToNestedFunction(
+                        old_info.info,
+                        corresponding_child_info,
+                        old_child_info.info);
+                  });
+            }
+          }
+        }
+      });
+
+      change_log.push( {function_patched: new_info.function_name} );
+    } else {
+      change_log.push( {function_patched: new_info.function_name,
+          function_info_not_found: true} );
+    }
+  }
+
+
+  // Makes a function associated with another instance of a script (the
+  // one representing its old version). This way the function still
+  // may access its own text.
+  function LinkToOldScript(old_info_node, old_script, report_array) {
+    if (old_info_node.live_shared_function_infos) {
+      old_info_node.live_shared_function_infos.
+          forEach(function (info) {
+            %LiveEditFunctionSetScript(info.info, old_script);
+          });
+
+      report_array.push( { name: old_info_node.info.function_name } );
+    } else {
+      report_array.push(
+          { name: old_info_node.info.function_name, not_found: true } );
+    }
+  }
+
+
+  // Returns function that restores breakpoints.
+  function TemporaryRemoveBreakPoints(original_script, change_log) {
+    var script_break_points = GetScriptBreakPoints(original_script);
+
+    var break_points_update_report = [];
+    change_log.push( { break_points_update: break_points_update_report } );
+
+    var break_point_old_positions = [];
+    for (var i = 0; i < script_break_points.length; i++) {
+      var break_point = script_break_points[i];
+
+      break_point.clear();
+
+      // TODO(LiveEdit): be careful with resource offset here.
+      var break_point_position = Debug.findScriptSourcePosition(original_script,
+          break_point.line(), break_point.column());
+
+      var old_position_description = {
+          position: break_point_position,
+          line: break_point.line(),
+          column: break_point.column()
+      };
+      break_point_old_positions.push(old_position_description);
+    }
+
+
+    // Restores breakpoints and creates their copies in the "old" copy of
+    // the script.
+    return function (pos_translator, old_script_copy_opt) {
+      // Update breakpoints (change positions and restore them in old version
+      // of script.
+      for (var i = 0; i < script_break_points.length; i++) {
+        var break_point = script_break_points[i];
+        if (old_script_copy_opt) {
+          var clone = break_point.cloneForOtherScript(old_script_copy_opt);
+          clone.set(old_script_copy_opt);
+
+          break_points_update_report.push( {
+            type: "copied_to_old",
+            id: break_point.number(),
+            new_id: clone.number(),
+            positions: break_point_old_positions[i]
+            } );
+        }
+
+        var updated_position = pos_translator.Translate(
+            break_point_old_positions[i].position,
+            PosTranslator.ShiftWithTopInsideChunkHandler);
+
+        var new_location =
+            original_script.locationFromPosition(updated_position, false);
+
+        break_point.update_positions(new_location.line, new_location.column);
+
+        var new_position_description = {
+            position: updated_position,
+            line: new_location.line,
+            column: new_location.column
+        };
+
+        break_point.set(original_script);
+
+        break_points_update_report.push( { type: "position_changed",
+          id: break_point.number(),
+          old_positions: break_point_old_positions[i],
+          new_positions: new_position_description
+          } );
+      }
+    };
+  }
+
+
+  function Assert(condition, message) {
+    if (!condition) {
+      if (message) {
+        throw "Assert " + message;
+      } else {
+        throw "Assert";
+      }
+    }
+  }
+
+  function DiffChunk(pos1, pos2, len1, len2) {
+    this.pos1 = pos1;
+    this.pos2 = pos2;
+    this.len1 = len1;
+    this.len2 = len2;
+  }
+
+  function PosTranslator(diff_array) {
+    var chunks = new Array();
+    var current_diff = 0;
+    for (var i = 0; i < diff_array.length; i += 3) {
+      var pos1_begin = diff_array[i];
+      var pos2_begin = pos1_begin + current_diff;
+      var pos1_end = diff_array[i + 1];
+      var pos2_end = diff_array[i + 2];
+      chunks.push(new DiffChunk(pos1_begin, pos2_begin, pos1_end - pos1_begin,
+          pos2_end - pos2_begin));
+      current_diff = pos2_end - pos1_end;
+    }
+    this.chunks = chunks;
+  }
+  PosTranslator.prototype.GetChunks = function() {
+    return this.chunks;
+  };
+
+  PosTranslator.prototype.Translate = function(pos, inside_chunk_handler) {
+    var array = this.chunks;
+    if (array.length == 0 || pos < array[0].pos1) {
+      return pos;
+    }
+    var chunk_index1 = 0;
+    var chunk_index2 = array.length - 1;
+
+    while (chunk_index1 < chunk_index2) {
+      var middle_index = Math.floor((chunk_index1 + chunk_index2) / 2);
+      if (pos < array[middle_index + 1].pos1) {
+        chunk_index2 = middle_index;
+      } else {
+        chunk_index1 = middle_index + 1;
+      }
+    }
+    var chunk = array[chunk_index1];
+    if (pos >= chunk.pos1 + chunk.len1) {
+      return pos + chunk.pos2 + chunk.len2 - chunk.pos1 - chunk.len1;
+    }
+
+    if (!inside_chunk_handler) {
+      inside_chunk_handler = PosTranslator.DefaultInsideChunkHandler;
+    }
+    return inside_chunk_handler(pos, chunk);
+  };
+
+  PosTranslator.DefaultInsideChunkHandler = function(pos, diff_chunk) {
+    Assert(false, "Cannot translate position in changed area");
+  };
+
+  PosTranslator.ShiftWithTopInsideChunkHandler =
+      function(pos, diff_chunk) {
+    // We carelessly do not check whether we stay inside the chunk after
+    // translation.
+    return pos - diff_chunk.pos1 + diff_chunk.pos2;
+  };
+
+  var FunctionStatus = {
+      // No change to function or its inner functions; however its positions
+      // in script may have been shifted.
+      UNCHANGED: "unchanged",
+      // The code of a function remains unchanged, but something happened inside
+      // some inner functions.
+      SOURCE_CHANGED: "source changed",
+      // The code of a function is changed or some nested function cannot be
+      // properly patched so this function must be recompiled.
+      CHANGED: "changed",
+      // Function is changed but cannot be patched.
+      DAMAGED: "damaged"
+  };
+
+  function CodeInfoTreeNode(code_info, children, array_index) {
+    this.info = code_info;
+    this.children = children;
+    // an index in array of compile_info
+    this.array_index = array_index;
+    this.parent = UNDEFINED;
+
+    this.status = FunctionStatus.UNCHANGED;
+    // Status explanation is used for debugging purposes and will be shown
+    // in user UI if some explanations are needed.
+    this.status_explanation = UNDEFINED;
+    this.new_start_pos = UNDEFINED;
+    this.new_end_pos = UNDEFINED;
+    this.corresponding_node = UNDEFINED;
+    this.unmatched_new_nodes = UNDEFINED;
+
+    // 'Textual' correspondence/matching is weaker than 'pure'
+    // correspondence/matching. We need 'textual' level for visual presentation
+    // in UI, we use 'pure' level for actual code manipulation.
+    // Sometimes only function body is changed (functions in old and new script
+    // textually correspond), but we cannot patch the code, so we see them
+    // as an old function deleted and new function created.
+    this.textual_corresponding_node = UNDEFINED;
+    this.textually_unmatched_new_nodes = UNDEFINED;
+
+    this.live_shared_function_infos = UNDEFINED;
+  }
+
+  // From array of function infos that is implicitly a tree creates
+  // an actual tree of functions in script.
+  function BuildCodeInfoTree(code_info_array) {
+    // Throughtout all function we iterate over input array.
+    var index = 0;
+
+    // Recursive function that builds a branch of tree.
+    function BuildNode() {
+      var my_index = index;
+      index++;
+      var child_array = new Array();
+      while (index < code_info_array.length &&
+          code_info_array[index].outer_index == my_index) {
+        child_array.push(BuildNode());
+      }
+      var node = new CodeInfoTreeNode(code_info_array[my_index], child_array,
+          my_index);
+      for (var i = 0; i < child_array.length; i++) {
+        child_array[i].parent = node;
+      }
+      return node;
+    }
+
+    var root = BuildNode();
+    Assert(index == code_info_array.length);
+    return root;
+  }
+
+  // Applies a list of the textual diff chunks onto the tree of functions.
+  // Determines status of each function (from unchanged to damaged). However
+  // children of unchanged functions are ignored.
+  function MarkChangedFunctions(code_info_tree, chunks) {
+
+    // A convenient iterator over diff chunks that also translates
+    // positions from old to new in a current non-changed part of script.
+    var chunk_it = new function() {
+      var chunk_index = 0;
+      var pos_diff = 0;
+      this.current = function() { return chunks[chunk_index]; };
+      this.next = function() {
+        var chunk = chunks[chunk_index];
+        pos_diff = chunk.pos2 + chunk.len2 - (chunk.pos1 + chunk.len1);
+        chunk_index++;
+      };
+      this.done = function() { return chunk_index >= chunks.length; };
+      this.TranslatePos = function(pos) { return pos + pos_diff; };
+    };
+
+    // A recursive function that processes internals of a function and all its
+    // inner functions. Iterator chunk_it initially points to a chunk that is
+    // below function start.
+    function ProcessInternals(info_node) {
+      info_node.new_start_pos = chunk_it.TranslatePos(
+          info_node.info.start_position);
+      var child_index = 0;
+      var code_changed = false;
+      var source_changed = false;
+      // Simultaneously iterates over child functions and over chunks.
+      while (!chunk_it.done() &&
+          chunk_it.current().pos1 < info_node.info.end_position) {
+        if (child_index < info_node.children.length) {
+          var child = info_node.children[child_index];
+
+          if (child.info.end_position <= chunk_it.current().pos1) {
+            ProcessUnchangedChild(child);
+            child_index++;
+            continue;
+          } else if (child.info.start_position >=
+              chunk_it.current().pos1 + chunk_it.current().len1) {
+            code_changed = true;
+            chunk_it.next();
+            continue;
+          } else if (child.info.start_position <= chunk_it.current().pos1 &&
+              child.info.end_position >= chunk_it.current().pos1 +
+              chunk_it.current().len1) {
+            ProcessInternals(child);
+            source_changed = source_changed ||
+                ( child.status != FunctionStatus.UNCHANGED );
+            code_changed = code_changed ||
+                ( child.status == FunctionStatus.DAMAGED );
+            child_index++;
+            continue;
+          } else {
+            code_changed = true;
+            child.status = FunctionStatus.DAMAGED;
+            child.status_explanation =
+                "Text diff overlaps with function boundary";
+            child_index++;
+            continue;
+          }
+        } else {
+          if (chunk_it.current().pos1 + chunk_it.current().len1 <=
+              info_node.info.end_position) {
+            info_node.status = FunctionStatus.CHANGED;
+            chunk_it.next();
+            continue;
+          } else {
+            info_node.status = FunctionStatus.DAMAGED;
+            info_node.status_explanation =
+                "Text diff overlaps with function boundary";
+            return;
+          }
+        }
+        Assert("Unreachable", false);
+      }
+      while (child_index < info_node.children.length) {
+        var child = info_node.children[child_index];
+        ProcessUnchangedChild(child);
+        child_index++;
+      }
+      if (code_changed) {
+        info_node.status = FunctionStatus.CHANGED;
+      } else if (source_changed) {
+        info_node.status = FunctionStatus.SOURCE_CHANGED;
+      }
+      info_node.new_end_pos =
+          chunk_it.TranslatePos(info_node.info.end_position);
+    }
+
+    function ProcessUnchangedChild(node) {
+      node.new_start_pos = chunk_it.TranslatePos(node.info.start_position);
+      node.new_end_pos = chunk_it.TranslatePos(node.info.end_position);
+    }
+
+    ProcessInternals(code_info_tree);
+  }
+
+  // For each old function (if it is not damaged) tries to find a corresponding
+  // function in new script. Typically it should succeed (non-damaged functions
+  // by definition may only have changes inside their bodies). However there are
+  // reasons for correspondence not to be found; function with unmodified text
+  // in new script may become enclosed into other function; the innocent change
+  // inside function body may in fact be something like "} function B() {" that
+  // splits a function into 2 functions.
+  function FindCorrespondingFunctions(old_code_tree, new_code_tree) {
+
+    // A recursive function that tries to find a correspondence for all
+    // child functions and for their inner functions.
+    function ProcessNode(old_node, new_node) {
+      var scope_change_description =
+          IsFunctionContextLocalsChanged(old_node.info, new_node.info);
+      if (scope_change_description) {
+          old_node.status = FunctionStatus.CHANGED;
+      }
+
+      var old_children = old_node.children;
+      var new_children = new_node.children;
+
+      var unmatched_new_nodes_list = [];
+      var textually_unmatched_new_nodes_list = [];
+
+      var old_index = 0;
+      var new_index = 0;
+      while (old_index < old_children.length) {
+        if (old_children[old_index].status == FunctionStatus.DAMAGED) {
+          old_index++;
+        } else if (new_index < new_children.length) {
+          if (new_children[new_index].info.start_position <
+              old_children[old_index].new_start_pos) {
+            unmatched_new_nodes_list.push(new_children[new_index]);
+            textually_unmatched_new_nodes_list.push(new_children[new_index]);
+            new_index++;
+          } else if (new_children[new_index].info.start_position ==
+              old_children[old_index].new_start_pos) {
+            if (new_children[new_index].info.end_position ==
+                old_children[old_index].new_end_pos) {
+              old_children[old_index].corresponding_node =
+                  new_children[new_index];
+              old_children[old_index].textual_corresponding_node =
+                  new_children[new_index];
+              if (scope_change_description) {
+                old_children[old_index].status = FunctionStatus.DAMAGED;
+                old_children[old_index].status_explanation =
+                    "Enclosing function is now incompatible. " +
+                    scope_change_description;
+                old_children[old_index].corresponding_node = UNDEFINED;
+              } else if (old_children[old_index].status !=
+                  FunctionStatus.UNCHANGED) {
+                ProcessNode(old_children[old_index],
+                    new_children[new_index]);
+                if (old_children[old_index].status == FunctionStatus.DAMAGED) {
+                  unmatched_new_nodes_list.push(
+                      old_children[old_index].corresponding_node);
+                  old_children[old_index].corresponding_node = UNDEFINED;
+                  old_node.status = FunctionStatus.CHANGED;
+                }
+              }
+            } else {
+              old_children[old_index].status = FunctionStatus.DAMAGED;
+              old_children[old_index].status_explanation =
+                  "No corresponding function in new script found";
+              old_node.status = FunctionStatus.CHANGED;
+              unmatched_new_nodes_list.push(new_children[new_index]);
+              textually_unmatched_new_nodes_list.push(new_children[new_index]);
+            }
+            new_index++;
+            old_index++;
+          } else {
+            old_children[old_index].status = FunctionStatus.DAMAGED;
+            old_children[old_index].status_explanation =
+                "No corresponding function in new script found";
+            old_node.status = FunctionStatus.CHANGED;
+            old_index++;
+          }
+        } else {
+          old_children[old_index].status = FunctionStatus.DAMAGED;
+          old_children[old_index].status_explanation =
+              "No corresponding function in new script found";
+          old_node.status = FunctionStatus.CHANGED;
+          old_index++;
+        }
+      }
+
+      while (new_index < new_children.length) {
+        unmatched_new_nodes_list.push(new_children[new_index]);
+        textually_unmatched_new_nodes_list.push(new_children[new_index]);
+        new_index++;
+      }
+
+      if (old_node.status == FunctionStatus.CHANGED) {
+        if (old_node.info.param_num != new_node.info.param_num) {
+          old_node.status = FunctionStatus.DAMAGED;
+          old_node.status_explanation = "Changed parameter number: " +
+              old_node.info.param_num + " and " + new_node.info.param_num;
+        }
+      }
+      old_node.unmatched_new_nodes = unmatched_new_nodes_list;
+      old_node.textually_unmatched_new_nodes =
+          textually_unmatched_new_nodes_list;
+    }
+
+    ProcessNode(old_code_tree, new_code_tree);
+
+    old_code_tree.corresponding_node = new_code_tree;
+    old_code_tree.textual_corresponding_node = new_code_tree;
+
+    Assert(old_code_tree.status != FunctionStatus.DAMAGED,
+        "Script became damaged");
+  }
+
+  function FindLiveSharedInfos(old_code_tree, script) {
+    var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script);
+
+    var shared_infos = new Array();
+
+    for (var i = 0; i < shared_raw_list.length; i++) {
+      shared_infos.push(new SharedInfoWrapper(shared_raw_list[i]));
+    }
+
+    // Finds all SharedFunctionInfos that corresponds to compile info
+    // in old version of the script.
+    function FindFunctionInfos(compile_info) {
+      var wrappers = [];
+
+      for (var i = 0; i < shared_infos.length; i++) {
+        var wrapper = shared_infos[i];
+        if (wrapper.start_position == compile_info.start_position &&
+            wrapper.end_position == compile_info.end_position) {
+          wrappers.push(wrapper);
+        }
+      }
+
+      if (wrappers.length > 0) {
+        return wrappers;
+      }
+    }
+
+    function TraverseTree(node) {
+      node.live_shared_function_infos = FindFunctionInfos(node.info);
+
+      for (var i = 0; i < node.children.length; i++) {
+        TraverseTree(node.children[i]);
+      }
+    }
+
+    TraverseTree(old_code_tree);
+  }
+
+
+  // An object describing function compilation details. Its index fields
+  // apply to indexes inside array that stores these objects.
+  function FunctionCompileInfo(raw_array) {
+    this.function_name = raw_array[0];
+    this.start_position = raw_array[1];
+    this.end_position = raw_array[2];
+    this.param_num = raw_array[3];
+    this.code = raw_array[4];
+    this.code_scope_info = raw_array[5];
+    this.scope_info = raw_array[6];
+    this.outer_index = raw_array[7];
+    this.shared_function_info = raw_array[8];
+    this.next_sibling_index = null;
+    this.raw_array = raw_array;
+  }
+
+  function SharedInfoWrapper(raw_array) {
+    this.function_name = raw_array[0];
+    this.start_position = raw_array[1];
+    this.end_position = raw_array[2];
+    this.info = raw_array[3];
+    this.raw_array = raw_array;
+  }
+
+  // Changes positions (including all statements) in function.
+  function PatchPositions(old_info_node, diff_array, report_array) {
+    if (old_info_node.live_shared_function_infos) {
+      old_info_node.live_shared_function_infos.forEach(function (info) {
+          %LiveEditPatchFunctionPositions(info.raw_array,
+                                          diff_array);
+      });
+
+      report_array.push( { name: old_info_node.info.function_name } );
+    } else {
+      // TODO(LiveEdit): function is not compiled yet or is already collected.
+      report_array.push(
+          { name: old_info_node.info.function_name, info_not_found: true } );
+    }
+  }
+
+  // Adds a suffix to script name to mark that it is old version.
+  function CreateNameForOldScript(script) {
+    // TODO(635): try better than this; support several changes.
+    return script.name + " (old)";
+  }
+
+  // Compares a function scope heap structure, old and new version, whether it
+  // changed or not. Returns explanation if they differ.
+  function IsFunctionContextLocalsChanged(function_info1, function_info2) {
+    var scope_info1 = function_info1.scope_info;
+    var scope_info2 = function_info2.scope_info;
+
+    var scope_info1_text;
+    var scope_info2_text;
+
+    if (scope_info1) {
+      scope_info1_text = scope_info1.toString();
+    } else {
+      scope_info1_text = "";
+    }
+    if (scope_info2) {
+      scope_info2_text = scope_info2.toString();
+    } else {
+      scope_info2_text = "";
+    }
+
+    if (scope_info1_text != scope_info2_text) {
+      return "Variable map changed: [" + scope_info1_text +
+          "] => [" + scope_info2_text + "]";
+    }
+    // No differences. Return undefined.
+    return;
+  }
+
+  // Minifier forward declaration.
+  var FunctionPatchabilityStatus;
+
+  // For array of wrapped shared function infos checks that none of them
+  // have activations on stack (of any thread). Throws a Failure exception
+  // if this proves to be false.
+  function CheckStackActivations(shared_wrapper_list, change_log) {
+    var shared_list = new Array();
+    for (var i = 0; i < shared_wrapper_list.length; i++) {
+      shared_list[i] = shared_wrapper_list[i].info;
+    }
+    var result = %LiveEditCheckAndDropActivations(shared_list, true);
+    if (result[shared_list.length]) {
+      // Extra array element may contain error message.
+      throw new Failure(result[shared_list.length]);
+    }
+
+    var problems = new Array();
+    var dropped = new Array();
+    for (var i = 0; i < shared_list.length; i++) {
+      var shared = shared_wrapper_list[i];
+      if (result[i] == FunctionPatchabilityStatus.REPLACED_ON_ACTIVE_STACK) {
+        dropped.push({ name: shared.function_name } );
+      } else if (result[i] != FunctionPatchabilityStatus.AVAILABLE_FOR_PATCH) {
+        var description = {
+            name: shared.function_name,
+            start_pos: shared.start_position,
+            end_pos: shared.end_position,
+            replace_problem:
+                FunctionPatchabilityStatus.SymbolName(result[i])
+        };
+        problems.push(description);
+      }
+    }
+    if (dropped.length > 0) {
+      change_log.push({ dropped_from_stack: dropped });
+    }
+    if (problems.length > 0) {
+      change_log.push( { functions_on_stack: problems } );
+      throw new Failure("Blocked by functions on stack");
+    }
+
+    return dropped.length;
+  }
+
+  // A copy of the FunctionPatchabilityStatus enum from liveedit.h
+  var FunctionPatchabilityStatus = {
+      AVAILABLE_FOR_PATCH: 1,
+      BLOCKED_ON_ACTIVE_STACK: 2,
+      BLOCKED_ON_OTHER_STACK: 3,
+      BLOCKED_UNDER_NATIVE_CODE: 4,
+      REPLACED_ON_ACTIVE_STACK: 5,
+      BLOCKED_UNDER_GENERATOR: 6,
+      BLOCKED_ACTIVE_GENERATOR: 7
+  };
+
+  FunctionPatchabilityStatus.SymbolName = function(code) {
+    var enumeration = FunctionPatchabilityStatus;
+    for (var name in enumeration) {
+      if (enumeration[name] == code) {
+        return name;
+      }
+    }
+  };
+
+
+  // A logical failure in liveedit process. This means that change_log
+  // is valid and consistent description of what happened.
+  function Failure(message) {
+    this.message = message;
+  }
+  // Function (constructor) is public.
+  this.Failure = Failure;
+
+  Failure.prototype.toString = function() {
+    return "LiveEdit Failure: " + this.message;
+  };
+
+  function CopyErrorPositionToDetails(e, details) {
+    function createPositionStruct(script, position) {
+      if (position == -1) return;
+      var location = script.locationFromPosition(position, true);
+      if (location == null) return;
+      return {
+        line: location.line + 1,
+        column: location.column + 1,
+        position: position
+      };
+    }
+
+    if (!("scriptObject" in e) || !("startPosition" in e)) {
+      return;
+    }
+
+    var script = e.scriptObject;
+
+    var position_struct = {
+      start: createPositionStruct(script, e.startPosition),
+      end: createPositionStruct(script, e.endPosition)
+    };
+    details.position = position_struct;
+  }
+
+  // A testing entry.
+  function GetPcFromSourcePos(func, source_pos) {
+    return %GetFunctionCodePositionFromSource(func, source_pos);
+  }
+  // Function is public.
+  this.GetPcFromSourcePos = GetPcFromSourcePos;
+
+  // LiveEdit main entry point: changes a script text to a new string.
+  function SetScriptSource(script, new_source, preview_only, change_log) {
+    var old_source = script.source;
+    var diff = CompareStrings(old_source, new_source);
+    return ApplyPatchMultiChunk(script, diff, new_source, preview_only,
+        change_log);
+  }
+  // Function is public.
+  this.SetScriptSource = SetScriptSource;
+
+  function CompareStrings(s1, s2) {
+    return %LiveEditCompareStrings(s1, s2);
+  }
+
+  // Applies the change to the script.
+  // The change is always a substring (change_pos, change_pos + change_len)
+  // being replaced with a completely different string new_str.
+  // This API is a legacy and is obsolete.
+  //
+  // @param {Script} script that is being changed
+  // @param {Array} change_log a list that collects engineer-readable
+  //     description of what happened.
+  function ApplySingleChunkPatch(script, change_pos, change_len, new_str,
+      change_log) {
+    var old_source = script.source;
+
+    // Prepare new source string.
+    var new_source = old_source.substring(0, change_pos) +
+        new_str + old_source.substring(change_pos + change_len);
+
+    return ApplyPatchMultiChunk(script,
+        [ change_pos, change_pos + change_len, change_pos + new_str.length],
+        new_source, false, change_log);
+  }
+
+  // Creates JSON description for a change tree.
+  function DescribeChangeTree(old_code_tree) {
+
+    function ProcessOldNode(node) {
+      var child_infos = [];
+      for (var i = 0; i < node.children.length; i++) {
+        var child = node.children[i];
+        if (child.status != FunctionStatus.UNCHANGED) {
+          child_infos.push(ProcessOldNode(child));
+        }
+      }
+      var new_child_infos = [];
+      if (node.textually_unmatched_new_nodes) {
+        for (var i = 0; i < node.textually_unmatched_new_nodes.length; i++) {
+          var child = node.textually_unmatched_new_nodes[i];
+          new_child_infos.push(ProcessNewNode(child));
+        }
+      }
+      var res = {
+        name: node.info.function_name,
+        positions: DescribePositions(node),
+        status: node.status,
+        children: child_infos,
+        new_children: new_child_infos
+      };
+      if (node.status_explanation) {
+        res.status_explanation = node.status_explanation;
+      }
+      if (node.textual_corresponding_node) {
+        res.new_positions = DescribePositions(node.textual_corresponding_node);
+      }
+      return res;
+    }
+
+    function ProcessNewNode(node) {
+      var child_infos = [];
+      // Do not list ancestors.
+      if (false) {
+        for (var i = 0; i < node.children.length; i++) {
+          child_infos.push(ProcessNewNode(node.children[i]));
+        }
+      }
+      var res = {
+        name: node.info.function_name,
+        positions: DescribePositions(node),
+        children: child_infos,
+      };
+      return res;
+    }
+
+    function DescribePositions(node) {
+      return {
+        start_position: node.info.start_position,
+        end_position: node.info.end_position
+      };
+    }
+
+    return ProcessOldNode(old_code_tree);
+  }
+
+  // Functions are public for tests.
+  this.TestApi = {
+    PosTranslator: PosTranslator,
+    CompareStrings: CompareStrings,
+    ApplySingleChunkPatch: ApplySingleChunkPatch
+  };
+};
diff --git a/src/debug/mips/OWNERS b/src/debug/mips/OWNERS
new file mode 100644 (file)
index 0000000..5508ba6
--- /dev/null
@@ -0,0 +1,5 @@
+paul.lind@imgtec.com
+gergely.kis@imgtec.com
+akos.palfi@imgtec.com
+balazs.kilvady@imgtec.com
+dusan.milosavljevic@imgtec.com
diff --git a/src/debug/mips/debug-mips.cc b/src/debug/mips/debug-mips.cc
new file mode 100644 (file)
index 0000000..5c6208f
--- /dev/null
@@ -0,0 +1,152 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_MIPS
+
+#include "src/codegen.h"
+#include "src/debug/debug.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void EmitDebugBreakSlot(MacroAssembler* masm) {
+  Label check_size;
+  __ bind(&check_size);
+  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
+    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
+  }
+  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
+            masm->InstructionsGeneratedSince(&check_size));
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                                int call_argc) {
+  // Generate enough nop's to make space for a call instruction. Avoid emitting
+  // the trampoline pool in the debug break slot code.
+  Assembler::BlockTrampolinePoolScope block_pool(masm);
+  masm->RecordDebugBreakSlot(mode, call_argc);
+  EmitDebugBreakSlot(masm);
+}
+
+
+void DebugCodegen::ClearDebugBreakSlot(Address pc) {
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
+  EmitDebugBreakSlot(patcher.masm());
+}
+
+
+void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
+  DCHECK_EQ(Code::BUILTIN, code->kind());
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
+  // Patch the code changing the debug break slot code from:
+  //   nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1)
+  //   nop(DEBUG_BREAK_NOP)
+  //   nop(DEBUG_BREAK_NOP)
+  //   nop(DEBUG_BREAK_NOP)
+  // to a call to the debug break slot code.
+  //   li t9, address   (lui t9 / ori t9 instruction pair)
+  //   call t9          (jalr t9 / nop instruction pair)
+  patcher.masm()->li(v8::internal::t9,
+                     Operand(reinterpret_cast<int32_t>(code->entry())));
+  patcher.masm()->Call(v8::internal::t9);
+}
+
+
+void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
+                                          DebugBreakCallHelperMode mode) {
+  __ RecordComment("Debug break");
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue)));
+    __ Subu(sp, sp,
+            Operand(kPointerSize * LiveEdit::kFramePaddingInitialSize));
+    for (int i = LiveEdit::kFramePaddingInitialSize - 1; i >= 0; i--) {
+      __ sw(at, MemOperand(sp, kPointerSize * i));
+    }
+    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
+    __ push(at);
+
+    if (mode == SAVE_RESULT_REGISTER) __ push(v0);
+
+    __ PrepareCEntryArgs(0);  // No arguments.
+    __ PrepareCEntryFunction(ExternalReference(
+        Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()));
+
+    CEntryStub ceb(masm->isolate(), 1);
+    __ CallStub(&ceb);
+
+    if (FLAG_debug_code) {
+      for (int i = 0; i < kNumJSCallerSaved; i++) {
+        Register reg = {JSCallerSavedCode(i)};
+        __ li(reg, kDebugZapValue);
+      }
+    }
+
+    if (mode == SAVE_RESULT_REGISTER) __ pop(v0);
+
+    // Don't bother removing padding bytes pushed on the stack
+    // as the frame is going to be restored right away.
+
+    // Leave the internal frame.
+  }
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ li(t9, Operand(after_break_target));
+  __ lw(t9, MemOperand(t9));
+  __ Jump(t9);
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  __ Ret();
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  __ li(at, Operand(restarter_frame_function_slot));
+  __ sw(zero_reg, MemOperand(at, 0));
+
+  // We do not know our frame height, but set sp based on fp.
+  __ Subu(sp, fp, Operand(kPointerSize));
+
+  __ Pop(ra, fp, a1);  // Return address, Frame, Function.
+
+  // Load context from the function.
+  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
+
+  // Get function code.
+  __ lw(at, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
+  __ lw(at, FieldMemOperand(at, SharedFunctionInfo::kCodeOffset));
+  __ Addu(t9, at, Operand(Code::kHeaderSize - kHeapObjectTag));
+
+  // Re-run JSFunction, a1 is function, cp is context.
+  __ Jump(t9);
+}
+
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+#undef __
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_MIPS
diff --git a/src/debug/mips64/OWNERS b/src/debug/mips64/OWNERS
new file mode 100644 (file)
index 0000000..5508ba6
--- /dev/null
@@ -0,0 +1,5 @@
+paul.lind@imgtec.com
+gergely.kis@imgtec.com
+akos.palfi@imgtec.com
+balazs.kilvady@imgtec.com
+dusan.milosavljevic@imgtec.com
diff --git a/src/debug/mips64/debug-mips64.cc b/src/debug/mips64/debug-mips64.cc
new file mode 100644 (file)
index 0000000..2665334
--- /dev/null
@@ -0,0 +1,154 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_MIPS64
+
+#include "src/codegen.h"
+#include "src/debug/debug.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+void EmitDebugBreakSlot(MacroAssembler* masm) {
+  Label check_size;
+  __ bind(&check_size);
+  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
+    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
+  }
+  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
+            masm->InstructionsGeneratedSince(&check_size));
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                                int call_argc) {
+  // Generate enough nop's to make space for a call instruction. Avoid emitting
+  // the trampoline pool in the debug break slot code.
+  Assembler::BlockTrampolinePoolScope block_pool(masm);
+  masm->RecordDebugBreakSlot(mode, call_argc);
+  EmitDebugBreakSlot(masm);
+}
+
+
+void DebugCodegen::ClearDebugBreakSlot(Address pc) {
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
+  EmitDebugBreakSlot(patcher.masm());
+}
+
+
+void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
+  DCHECK_EQ(Code::BUILTIN, code->kind());
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
+  // Patch the code changing the debug break slot code from:
+  //   nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1)
+  //   nop(DEBUG_BREAK_NOP)
+  //   nop(DEBUG_BREAK_NOP)
+  //   nop(DEBUG_BREAK_NOP)
+  //   nop(DEBUG_BREAK_NOP)
+  //   nop(DEBUG_BREAK_NOP)
+  // to a call to the debug break slot code.
+  //   li t9, address   (4-instruction sequence on mips64)
+  //   call t9          (jalr t9 / nop instruction pair)
+  patcher.masm()->li(v8::internal::t9,
+                     Operand(reinterpret_cast<int64_t>(code->entry())),
+                     ADDRESS_LOAD);
+  patcher.masm()->Call(v8::internal::t9);
+}
+
+
+void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
+                                          DebugBreakCallHelperMode mode) {
+  __ RecordComment("Debug break");
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue)));
+    __ Dsubu(sp, sp,
+            Operand(kPointerSize * LiveEdit::kFramePaddingInitialSize));
+    for (int i = LiveEdit::kFramePaddingInitialSize - 1; i >= 0; i--) {
+      __ sd(at, MemOperand(sp, kPointerSize * i));
+    }
+    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
+    __ push(at);
+
+    if (mode == SAVE_RESULT_REGISTER) __ push(v0);
+
+    __ PrepareCEntryArgs(0);  // No arguments.
+    __ PrepareCEntryFunction(ExternalReference(
+        Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()));
+
+    CEntryStub ceb(masm->isolate(), 1);
+    __ CallStub(&ceb);
+
+    if (FLAG_debug_code) {
+      for (int i = 0; i < kNumJSCallerSaved; i++) {
+        Register reg = {JSCallerSavedCode(i)};
+        __ li(reg, kDebugZapValue);
+      }
+    }
+
+    if (mode == SAVE_RESULT_REGISTER) __ pop(v0);
+
+    // Don't bother removing padding bytes pushed on the stack
+    // as the frame is going to be restored right away.
+
+    // Leave the internal frame.
+  }
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ li(t9, Operand(after_break_target));
+  __ ld(t9, MemOperand(t9));
+  __ Jump(t9);
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  __ Ret();
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  __ li(at, Operand(restarter_frame_function_slot));
+  __ sw(zero_reg, MemOperand(at, 0));
+
+  // We do not know our frame height, but set sp based on fp.
+  __ Dsubu(sp, fp, Operand(kPointerSize));
+
+  __ Pop(ra, fp, a1);  // Return address, Frame, Function.
+
+  // Load context from the function.
+  __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
+
+  // Get function code.
+  __ ld(at, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
+  __ ld(at, FieldMemOperand(at, SharedFunctionInfo::kCodeOffset));
+  __ Daddu(t9, at, Operand(Code::kHeaderSize - kHeapObjectTag));
+
+  // Re-run JSFunction, a1 is function, cp is context.
+  __ Jump(t9);
+}
+
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+#undef __
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_MIPS64
diff --git a/src/debug/mirrors.js b/src/debug/mirrors.js
new file mode 100644 (file)
index 0000000..dbdc68e
--- /dev/null
@@ -0,0 +1,3026 @@
+// Copyright 2006-2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+"use strict";
+
+// Handle id counters.
+var next_handle_ = 0;
+var next_transient_handle_ = -1;
+
+// Mirror cache.
+var mirror_cache_ = [];
+var mirror_cache_enabled_ = true;
+
+
+function ToggleMirrorCache(value) {
+  mirror_cache_enabled_ = value;
+  next_handle_ = 0;
+  mirror_cache_ = [];
+}
+
+
+// Wrapper to check whether an object is a Promise.  The call may not work
+// if promises are not enabled.
+// TODO(yangguo): remove try-catch once promises are enabled by default.
+function ObjectIsPromise(value) {
+  try {
+    return IS_SPEC_OBJECT(value) &&
+           !IS_UNDEFINED(%DebugGetProperty(value, builtins.$promiseStatus));
+  } catch (e) {
+    return false;
+  }
+}
+
+
+/**
+ * Returns the mirror for a specified value or object.
+ *
+ * @param {value or Object} value the value or object to retreive the mirror for
+ * @param {boolean} transient indicate whether this object is transient and
+ *    should not be added to the mirror cache. The default is not transient.
+ * @returns {Mirror} the mirror reflects the passed value or object
+ */
+function MakeMirror(value, opt_transient) {
+  var mirror;
+
+  // Look for non transient mirrors in the mirror cache.
+  if (!opt_transient && mirror_cache_enabled_) {
+    for (var id in mirror_cache_) {
+      mirror = mirror_cache_[id];
+      if (mirror.value() === value) {
+        return mirror;
+      }
+      // Special check for NaN as NaN == NaN is false.
+      if (mirror.isNumber() && isNaN(mirror.value()) &&
+          typeof value == 'number' && isNaN(value)) {
+        return mirror;
+      }
+    }
+  }
+
+  if (IS_UNDEFINED(value)) {
+    mirror = new UndefinedMirror();
+  } else if (IS_NULL(value)) {
+    mirror = new NullMirror();
+  } else if (IS_BOOLEAN(value)) {
+    mirror = new BooleanMirror(value);
+  } else if (IS_NUMBER(value)) {
+    mirror = new NumberMirror(value);
+  } else if (IS_STRING(value)) {
+    mirror = new StringMirror(value);
+  } else if (IS_SYMBOL(value)) {
+    mirror = new SymbolMirror(value);
+  } else if (IS_ARRAY(value)) {
+    mirror = new ArrayMirror(value);
+  } else if (IS_DATE(value)) {
+    mirror = new DateMirror(value);
+  } else if (IS_FUNCTION(value)) {
+    mirror = new FunctionMirror(value);
+  } else if (IS_REGEXP(value)) {
+    mirror = new RegExpMirror(value);
+  } else if (IS_ERROR(value)) {
+    mirror = new ErrorMirror(value);
+  } else if (IS_SCRIPT(value)) {
+    mirror = new ScriptMirror(value);
+  } else if (IS_MAP(value) || IS_WEAKMAP(value)) {
+    mirror = new MapMirror(value);
+  } else if (IS_SET(value) || IS_WEAKSET(value)) {
+    mirror = new SetMirror(value);
+  } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) {
+    mirror = new IteratorMirror(value);
+  } else if (ObjectIsPromise(value)) {
+    mirror = new PromiseMirror(value);
+  } else if (IS_GENERATOR(value)) {
+    mirror = new GeneratorMirror(value);
+  } else {
+    mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient);
+  }
+
+  if (mirror_cache_enabled_) mirror_cache_[mirror.handle()] = mirror;
+  return mirror;
+}
+
+
+/**
+ * Returns the mirror for a specified mirror handle.
+ *
+ * @param {number} handle the handle to find the mirror for
+ * @returns {Mirror or undefiend} the mirror with the requested handle or
+ *     undefined if no mirror with the requested handle was found
+ */
+function LookupMirror(handle) {
+  if (!mirror_cache_enabled_) throw new Error("Mirror cache is disabled");
+  return mirror_cache_[handle];
+}
+
+
+/**
+ * Returns the mirror for the undefined value.
+ *
+ * @returns {Mirror} the mirror reflects the undefined value
+ */
+function GetUndefinedMirror() {
+  return MakeMirror(UNDEFINED);
+}
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be revritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ *
+ * @param {function} ctor Constructor function which needs to inherit the
+ *     prototype
+ * @param {function} superCtor Constructor function to inherit prototype from
+ */
+function inherits(ctor, superCtor) {
+  var tempCtor = function(){};
+  tempCtor.prototype = superCtor.prototype;
+  ctor.super_ = superCtor.prototype;
+  ctor.prototype = new tempCtor();
+  ctor.prototype.constructor = ctor;
+}
+
+
+// Type names of the different mirrors.
+var UNDEFINED_TYPE = 'undefined';
+var NULL_TYPE = 'null';
+var BOOLEAN_TYPE = 'boolean';
+var NUMBER_TYPE = 'number';
+var STRING_TYPE = 'string';
+var SYMBOL_TYPE = 'symbol';
+var OBJECT_TYPE = 'object';
+var FUNCTION_TYPE = 'function';
+var REGEXP_TYPE = 'regexp';
+var ERROR_TYPE = 'error';
+var PROPERTY_TYPE = 'property';
+var INTERNAL_PROPERTY_TYPE = 'internalProperty';
+var FRAME_TYPE = 'frame';
+var SCRIPT_TYPE = 'script';
+var CONTEXT_TYPE = 'context';
+var SCOPE_TYPE = 'scope';
+var PROMISE_TYPE = 'promise';
+var MAP_TYPE = 'map';
+var SET_TYPE = 'set';
+var ITERATOR_TYPE = 'iterator';
+var GENERATOR_TYPE = 'generator';
+
+// Maximum length when sending strings through the JSON protocol.
+var kMaxProtocolStringLength = 80;
+
+// Different kind of properties.
+var PropertyKind = {};
+PropertyKind.Named   = 1;
+PropertyKind.Indexed = 2;
+
+
+// A copy of the PropertyType enum from property-details.h
+var PropertyType = {};
+PropertyType.Data                        = 0;
+PropertyType.DataConstant                = 2;
+PropertyType.AccessorConstant            = 3;
+
+
+// Different attributes for a property.
+var PropertyAttribute = {};
+PropertyAttribute.None       = NONE;
+PropertyAttribute.ReadOnly   = READ_ONLY;
+PropertyAttribute.DontEnum   = DONT_ENUM;
+PropertyAttribute.DontDelete = DONT_DELETE;
+
+
+// A copy of the scope types from runtime-debug.cc.
+// NOTE: these constants should be backward-compatible, so
+// add new ones to the end of this list.
+var ScopeType = { Global: 0,
+                  Local: 1,
+                  With: 2,
+                  Closure: 3,
+                  Catch: 4,
+                  Block: 5,
+                  Script: 6 };
+
+
+// Mirror hierarchy:
+//   - Mirror
+//     - ValueMirror
+//       - UndefinedMirror
+//       - NullMirror
+//       - NumberMirror
+//       - StringMirror
+//       - SymbolMirror
+//       - ObjectMirror
+//         - FunctionMirror
+//           - UnresolvedFunctionMirror
+//         - ArrayMirror
+//         - DateMirror
+//         - RegExpMirror
+//         - ErrorMirror
+//         - PromiseMirror
+//         - MapMirror
+//         - SetMirror
+//         - IteratorMirror
+//         - GeneratorMirror
+//     - PropertyMirror
+//     - InternalPropertyMirror
+//     - FrameMirror
+//     - ScriptMirror
+
+
+/**
+ * Base class for all mirror objects.
+ * @param {string} type The type of the mirror
+ * @constructor
+ */
+function Mirror(type) {
+  this.type_ = type;
+}
+
+
+Mirror.prototype.type = function() {
+  return this.type_;
+};
+
+
+/**
+ * Check whether the mirror reflects a value.
+ * @returns {boolean} True if the mirror reflects a value.
+ */
+Mirror.prototype.isValue = function() {
+  return this instanceof ValueMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects the undefined value.
+ * @returns {boolean} True if the mirror reflects the undefined value.
+ */
+Mirror.prototype.isUndefined = function() {
+  return this instanceof UndefinedMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects the null value.
+ * @returns {boolean} True if the mirror reflects the null value
+ */
+Mirror.prototype.isNull = function() {
+  return this instanceof NullMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a boolean value.
+ * @returns {boolean} True if the mirror reflects a boolean value
+ */
+Mirror.prototype.isBoolean = function() {
+  return this instanceof BooleanMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a number value.
+ * @returns {boolean} True if the mirror reflects a number value
+ */
+Mirror.prototype.isNumber = function() {
+  return this instanceof NumberMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a string value.
+ * @returns {boolean} True if the mirror reflects a string value
+ */
+Mirror.prototype.isString = function() {
+  return this instanceof StringMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a symbol.
+ * @returns {boolean} True if the mirror reflects a symbol
+ */
+Mirror.prototype.isSymbol = function() {
+  return this instanceof SymbolMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects an object.
+ * @returns {boolean} True if the mirror reflects an object
+ */
+Mirror.prototype.isObject = function() {
+  return this instanceof ObjectMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a function.
+ * @returns {boolean} True if the mirror reflects a function
+ */
+Mirror.prototype.isFunction = function() {
+  return this instanceof FunctionMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects an unresolved function.
+ * @returns {boolean} True if the mirror reflects an unresolved function
+ */
+Mirror.prototype.isUnresolvedFunction = function() {
+  return this instanceof UnresolvedFunctionMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects an array.
+ * @returns {boolean} True if the mirror reflects an array
+ */
+Mirror.prototype.isArray = function() {
+  return this instanceof ArrayMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a date.
+ * @returns {boolean} True if the mirror reflects a date
+ */
+Mirror.prototype.isDate = function() {
+  return this instanceof DateMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a regular expression.
+ * @returns {boolean} True if the mirror reflects a regular expression
+ */
+Mirror.prototype.isRegExp = function() {
+  return this instanceof RegExpMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects an error.
+ * @returns {boolean} True if the mirror reflects an error
+ */
+Mirror.prototype.isError = function() {
+  return this instanceof ErrorMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a promise.
+ * @returns {boolean} True if the mirror reflects a promise
+ */
+Mirror.prototype.isPromise = function() {
+  return this instanceof PromiseMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a generator object.
+ * @returns {boolean} True if the mirror reflects a generator object
+ */
+Mirror.prototype.isGenerator = function() {
+  return this instanceof GeneratorMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a property.
+ * @returns {boolean} True if the mirror reflects a property
+ */
+Mirror.prototype.isProperty = function() {
+  return this instanceof PropertyMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects an internal property.
+ * @returns {boolean} True if the mirror reflects an internal property
+ */
+Mirror.prototype.isInternalProperty = function() {
+  return this instanceof InternalPropertyMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a stack frame.
+ * @returns {boolean} True if the mirror reflects a stack frame
+ */
+Mirror.prototype.isFrame = function() {
+  return this instanceof FrameMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a script.
+ * @returns {boolean} True if the mirror reflects a script
+ */
+Mirror.prototype.isScript = function() {
+  return this instanceof ScriptMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a context.
+ * @returns {boolean} True if the mirror reflects a context
+ */
+Mirror.prototype.isContext = function() {
+  return this instanceof ContextMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a scope.
+ * @returns {boolean} True if the mirror reflects a scope
+ */
+Mirror.prototype.isScope = function() {
+  return this instanceof ScopeMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a map.
+ * @returns {boolean} True if the mirror reflects a map
+ */
+Mirror.prototype.isMap = function() {
+  return this instanceof MapMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects a set.
+ * @returns {boolean} True if the mirror reflects a set
+ */
+Mirror.prototype.isSet = function() {
+  return this instanceof SetMirror;
+};
+
+
+/**
+ * Check whether the mirror reflects an iterator.
+ * @returns {boolean} True if the mirror reflects an iterator
+ */
+Mirror.prototype.isIterator = function() {
+  return this instanceof IteratorMirror;
+};
+
+
+/**
+ * Allocate a handle id for this object.
+ */
+Mirror.prototype.allocateHandle_ = function() {
+  if (mirror_cache_enabled_) this.handle_ = next_handle_++;
+};
+
+
+/**
+ * Allocate a transient handle id for this object. Transient handles are
+ * negative.
+ */
+Mirror.prototype.allocateTransientHandle_ = function() {
+  this.handle_ = next_transient_handle_--;
+};
+
+
+Mirror.prototype.toText = function() {
+  // Simpel to text which is used when on specialization in subclass.
+  return "#<" + this.constructor.name + ">";
+};
+
+
+/**
+ * Base class for all value mirror objects.
+ * @param {string} type The type of the mirror
+ * @param {value} value The value reflected by this mirror
+ * @param {boolean} transient indicate whether this object is transient with a
+ *    transient handle
+ * @constructor
+ * @extends Mirror
+ */
+function ValueMirror(type, value, transient) {
+  %_CallFunction(this, type, Mirror);
+  this.value_ = value;
+  if (!transient) {
+    this.allocateHandle_();
+  } else {
+    this.allocateTransientHandle_();
+  }
+}
+inherits(ValueMirror, Mirror);
+
+
+Mirror.prototype.handle = function() {
+  return this.handle_;
+};
+
+
+/**
+ * Check whether this is a primitive value.
+ * @return {boolean} True if the mirror reflects a primitive value
+ */
+ValueMirror.prototype.isPrimitive = function() {
+  var type = this.type();
+  return type === 'undefined' ||
+         type === 'null' ||
+         type === 'boolean' ||
+         type === 'number' ||
+         type === 'string' ||
+         type === 'symbol';
+};
+
+
+/**
+ * Get the actual value reflected by this mirror.
+ * @return {value} The value reflected by this mirror
+ */
+ValueMirror.prototype.value = function() {
+  return this.value_;
+};
+
+
+/**
+ * Mirror object for Undefined.
+ * @constructor
+ * @extends ValueMirror
+ */
+function UndefinedMirror() {
+  %_CallFunction(this, UNDEFINED_TYPE, UNDEFINED, ValueMirror);
+}
+inherits(UndefinedMirror, ValueMirror);
+
+
+UndefinedMirror.prototype.toText = function() {
+  return 'undefined';
+};
+
+
+/**
+ * Mirror object for null.
+ * @constructor
+ * @extends ValueMirror
+ */
+function NullMirror() {
+  %_CallFunction(this, NULL_TYPE, null, ValueMirror);
+}
+inherits(NullMirror, ValueMirror);
+
+
+NullMirror.prototype.toText = function() {
+  return 'null';
+};
+
+
+/**
+ * Mirror object for boolean values.
+ * @param {boolean} value The boolean value reflected by this mirror
+ * @constructor
+ * @extends ValueMirror
+ */
+function BooleanMirror(value) {
+  %_CallFunction(this, BOOLEAN_TYPE, value, ValueMirror);
+}
+inherits(BooleanMirror, ValueMirror);
+
+
+BooleanMirror.prototype.toText = function() {
+  return this.value_ ? 'true' : 'false';
+};
+
+
+/**
+ * Mirror object for number values.
+ * @param {number} value The number value reflected by this mirror
+ * @constructor
+ * @extends ValueMirror
+ */
+function NumberMirror(value) {
+  %_CallFunction(this, NUMBER_TYPE, value, ValueMirror);
+}
+inherits(NumberMirror, ValueMirror);
+
+
+NumberMirror.prototype.toText = function() {
+  return %_NumberToString(this.value_);
+};
+
+
+/**
+ * Mirror object for string values.
+ * @param {string} value The string value reflected by this mirror
+ * @constructor
+ * @extends ValueMirror
+ */
+function StringMirror(value) {
+  %_CallFunction(this, STRING_TYPE, value, ValueMirror);
+}
+inherits(StringMirror, ValueMirror);
+
+
+StringMirror.prototype.length = function() {
+  return this.value_.length;
+};
+
+StringMirror.prototype.getTruncatedValue = function(maxLength) {
+  if (maxLength != -1 && this.length() > maxLength) {
+    return this.value_.substring(0, maxLength) +
+           '... (length: ' + this.length() + ')';
+  }
+  return this.value_;
+};
+
+StringMirror.prototype.toText = function() {
+  return this.getTruncatedValue(kMaxProtocolStringLength);
+};
+
+
+/**
+ * Mirror object for a Symbol
+ * @param {Object} value The Symbol
+ * @constructor
+ * @extends Mirror
+ */
+function SymbolMirror(value) {
+  %_CallFunction(this, SYMBOL_TYPE, value, ValueMirror);
+}
+inherits(SymbolMirror, ValueMirror);
+
+
+SymbolMirror.prototype.description = function() {
+  return %SymbolDescription(%_ValueOf(this.value_));
+}
+
+
+SymbolMirror.prototype.toText = function() {
+  return %_CallFunction(this.value_, builtins.$symbolToString);
+}
+
+
+/**
+ * Mirror object for objects.
+ * @param {object} value The object reflected by this mirror
+ * @param {boolean} transient indicate whether this object is transient with a
+ *    transient handle
+ * @constructor
+ * @extends ValueMirror
+ */
+function ObjectMirror(value, type, transient) {
+  %_CallFunction(this, type || OBJECT_TYPE, value, transient, ValueMirror);
+}
+inherits(ObjectMirror, ValueMirror);
+
+
+ObjectMirror.prototype.className = function() {
+  return %_ClassOf(this.value_);
+};
+
+
+ObjectMirror.prototype.constructorFunction = function() {
+  return MakeMirror(%DebugGetProperty(this.value_, 'constructor'));
+};
+
+
+ObjectMirror.prototype.prototypeObject = function() {
+  return MakeMirror(%DebugGetProperty(this.value_, 'prototype'));
+};
+
+
+ObjectMirror.prototype.protoObject = function() {
+  return MakeMirror(%DebugGetPrototype(this.value_));
+};
+
+
+ObjectMirror.prototype.hasNamedInterceptor = function() {
+  // Get information on interceptors for this object.
+  var x = %GetInterceptorInfo(this.value_);
+  return (x & 2) != 0;
+};
+
+
+ObjectMirror.prototype.hasIndexedInterceptor = function() {
+  // Get information on interceptors for this object.
+  var x = %GetInterceptorInfo(this.value_);
+  return (x & 1) != 0;
+};
+
+
+// Get all own property names except for private symbols.
+function TryGetPropertyNames(object) {
+  try {
+    // TODO(yangguo): Should there be a special debugger implementation of
+    // %GetOwnPropertyNames that doesn't perform access checks?
+    return %GetOwnPropertyNames(object, PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL);
+  } catch (e) {
+    // Might have hit a failed access check.
+    return [];
+  }
+}
+
+
+/**
+ * Return the property names for this object.
+ * @param {number} kind Indicate whether named, indexed or both kinds of
+ *     properties are requested
+ * @param {number} limit Limit the number of names returend to the specified
+       value
+ * @return {Array} Property names for this object
+ */
+ObjectMirror.prototype.propertyNames = function(kind, limit) {
+  // Find kind and limit and allocate array for the result
+  kind = kind || PropertyKind.Named | PropertyKind.Indexed;
+
+  var propertyNames;
+  var elementNames;
+  var total = 0;
+
+  // Find all the named properties.
+  if (kind & PropertyKind.Named) {
+    propertyNames = TryGetPropertyNames(this.value_);
+    total += propertyNames.length;
+
+    // Get names for named interceptor properties if any.
+    if (this.hasNamedInterceptor() && (kind & PropertyKind.Named)) {
+      var namedInterceptorNames =
+          %GetNamedInterceptorPropertyNames(this.value_);
+      if (namedInterceptorNames) {
+        propertyNames = propertyNames.concat(namedInterceptorNames);
+        total += namedInterceptorNames.length;
+      }
+    }
+  }
+
+  // Find all the indexed properties.
+  if (kind & PropertyKind.Indexed) {
+    // Get own element names.
+    elementNames = %GetOwnElementNames(this.value_);
+    total += elementNames.length;
+
+    // Get names for indexed interceptor properties.
+    if (this.hasIndexedInterceptor() && (kind & PropertyKind.Indexed)) {
+      var indexedInterceptorNames =
+          %GetIndexedInterceptorElementNames(this.value_);
+      if (indexedInterceptorNames) {
+        elementNames = elementNames.concat(indexedInterceptorNames);
+        total += indexedInterceptorNames.length;
+      }
+    }
+  }
+  limit = Math.min(limit || total, total);
+
+  var names = new Array(limit);
+  var index = 0;
+
+  // Copy names for named properties.
+  if (kind & PropertyKind.Named) {
+    for (var i = 0; index < limit && i < propertyNames.length; i++) {
+      names[index++] = propertyNames[i];
+    }
+  }
+
+  // Copy names for indexed properties.
+  if (kind & PropertyKind.Indexed) {
+    for (var i = 0; index < limit && i < elementNames.length; i++) {
+      names[index++] = elementNames[i];
+    }
+  }
+
+  return names;
+};
+
+
+/**
+ * Return the properties for this object as an array of PropertyMirror objects.
+ * @param {number} kind Indicate whether named, indexed or both kinds of
+ *     properties are requested
+ * @param {number} limit Limit the number of properties returned to the
+       specified value
+ * @return {Array} Property mirrors for this object
+ */
+ObjectMirror.prototype.properties = function(kind, limit) {
+  var names = this.propertyNames(kind, limit);
+  var properties = new Array(names.length);
+  for (var i = 0; i < names.length; i++) {
+    properties[i] = this.property(names[i]);
+  }
+
+  return properties;
+};
+
+
+/**
+ * Return the internal properties for this object as an array of
+ * InternalPropertyMirror objects.
+ * @return {Array} Property mirrors for this object
+ */
+ObjectMirror.prototype.internalProperties = function() {
+  return ObjectMirror.GetInternalProperties(this.value_);
+}
+
+
+ObjectMirror.prototype.property = function(name) {
+  var details = %DebugGetPropertyDetails(this.value_, builtins.$toName(name));
+  if (details) {
+    return new PropertyMirror(this, name, details);
+  }
+
+  // Nothing found.
+  return GetUndefinedMirror();
+};
+
+
+
+/**
+ * Try to find a property from its value.
+ * @param {Mirror} value The property value to look for
+ * @return {PropertyMirror} The property with the specified value. If no
+ *     property was found with the specified value UndefinedMirror is returned
+ */
+ObjectMirror.prototype.lookupProperty = function(value) {
+  var properties = this.properties();
+
+  // Look for property value in properties.
+  for (var i = 0; i < properties.length; i++) {
+
+    // Skip properties which are defined through assessors.
+    var property = properties[i];
+    if (property.propertyType() != PropertyType.AccessorConstant) {
+      if (%_ObjectEquals(property.value_, value.value_)) {
+        return property;
+      }
+    }
+  }
+
+  // Nothing found.
+  return GetUndefinedMirror();
+};
+
+
+/**
+ * Returns objects which has direct references to this object
+ * @param {number} opt_max_objects Optional parameter specifying the maximum
+ *     number of referencing objects to return.
+ * @return {Array} The objects which has direct references to this object.
+ */
+ObjectMirror.prototype.referencedBy = function(opt_max_objects) {
+  // Find all objects with direct references to this object.
+  var result = %DebugReferencedBy(this.value_,
+                                  Mirror.prototype, opt_max_objects || 0);
+
+  // Make mirrors for all the references found.
+  for (var i = 0; i < result.length; i++) {
+    result[i] = MakeMirror(result[i]);
+  }
+
+  return result;
+};
+
+
+ObjectMirror.prototype.toText = function() {
+  var name;
+  var ctor = this.constructorFunction();
+  if (!ctor.isFunction()) {
+    name = this.className();
+  } else {
+    name = ctor.name();
+    if (!name) {
+      name = this.className();
+    }
+  }
+  return '#<' + name + '>';
+};
+
+
+/**
+ * Return the internal properties of the value, such as [[PrimitiveValue]] of
+ * scalar wrapper objects, properties of the bound function and properties of
+ * the promise.
+ * This method is done static to be accessible from Debug API with the bare
+ * values without mirrors.
+ * @return {Array} array (possibly empty) of InternalProperty instances
+ */
+ObjectMirror.GetInternalProperties = function(value) {
+  var properties = %DebugGetInternalProperties(value);
+  var result = [];
+  for (var i = 0; i < properties.length; i += 2) {
+    result.push(new InternalPropertyMirror(properties[i], properties[i + 1]));
+  }
+  return result;
+}
+
+
+/**
+ * Mirror object for functions.
+ * @param {function} value The function object reflected by this mirror.
+ * @constructor
+ * @extends ObjectMirror
+ */
+function FunctionMirror(value) {
+  %_CallFunction(this, value, FUNCTION_TYPE, ObjectMirror);
+  this.resolved_ = true;
+}
+inherits(FunctionMirror, ObjectMirror);
+
+
+/**
+ * Returns whether the function is resolved.
+ * @return {boolean} True if the function is resolved. Unresolved functions can
+ *     only originate as functions from stack frames
+ */
+FunctionMirror.prototype.resolved = function() {
+  return this.resolved_;
+};
+
+
+/**
+ * Returns the name of the function.
+ * @return {string} Name of the function
+ */
+FunctionMirror.prototype.name = function() {
+  return %FunctionGetName(this.value_);
+};
+
+
+/**
+ * Returns the inferred name of the function.
+ * @return {string} Name of the function
+ */
+FunctionMirror.prototype.inferredName = function() {
+  return %FunctionGetInferredName(this.value_);
+};
+
+
+/**
+ * Returns the source code for the function.
+ * @return {string or undefined} The source code for the function. If the
+ *     function is not resolved undefined will be returned.
+ */
+FunctionMirror.prototype.source = function() {
+  // Return source if function is resolved. Otherwise just fall through to
+  // return undefined.
+  if (this.resolved()) {
+    return builtins.$functionSourceString(this.value_);
+  }
+};
+
+
+/**
+ * Returns the script object for the function.
+ * @return {ScriptMirror or undefined} Script object for the function or
+ *     undefined if the function has no script
+ */
+FunctionMirror.prototype.script = function() {
+  // Return script if function is resolved. Otherwise just fall through
+  // to return undefined.
+  if (this.resolved()) {
+    if (this.script_) {
+      return this.script_;
+    }
+    var script = %FunctionGetScript(this.value_);
+    if (script) {
+      return this.script_ = MakeMirror(script);
+    }
+  }
+};
+
+
+/**
+ * Returns the script source position for the function. Only makes sense
+ * for functions which has a script defined.
+ * @return {Number or undefined} in-script position for the function
+ */
+FunctionMirror.prototype.sourcePosition_ = function() {
+  // Return position if function is resolved. Otherwise just fall
+  // through to return undefined.
+  if (this.resolved()) {
+    return %FunctionGetScriptSourcePosition(this.value_);
+  }
+};
+
+
+/**
+ * Returns the script source location object for the function. Only makes sense
+ * for functions which has a script defined.
+ * @return {Location or undefined} in-script location for the function begin
+ */
+FunctionMirror.prototype.sourceLocation = function() {
+  if (this.resolved()) {
+    var script = this.script();
+    if (script) {
+      return script.locationFromPosition(this.sourcePosition_(), true);
+    }
+  }
+};
+
+
+/**
+ * Returns objects constructed by this function.
+ * @param {number} opt_max_instances Optional parameter specifying the maximum
+ *     number of instances to return.
+ * @return {Array or undefined} The objects constructed by this function.
+ */
+FunctionMirror.prototype.constructedBy = function(opt_max_instances) {
+  if (this.resolved()) {
+    // Find all objects constructed from this function.
+    var result = %DebugConstructedBy(this.value_, opt_max_instances || 0);
+
+    // Make mirrors for all the instances found.
+    for (var i = 0; i < result.length; i++) {
+      result[i] = MakeMirror(result[i]);
+    }
+
+    return result;
+  } else {
+    return [];
+  }
+};
+
+
+FunctionMirror.prototype.scopeCount = function() {
+  if (this.resolved()) {
+    if (IS_UNDEFINED(this.scopeCount_)) {
+      this.scopeCount_ = %GetFunctionScopeCount(this.value());
+    }
+    return this.scopeCount_;
+  } else {
+    return 0;
+  }
+};
+
+
+FunctionMirror.prototype.scope = function(index) {
+  if (this.resolved()) {
+    return new ScopeMirror(UNDEFINED, this, index);
+  }
+};
+
+
+FunctionMirror.prototype.toText = function() {
+  return this.source();
+};
+
+
+/**
+ * Mirror object for unresolved functions.
+ * @param {string} value The name for the unresolved function reflected by this
+ *     mirror.
+ * @constructor
+ * @extends ObjectMirror
+ */
+function UnresolvedFunctionMirror(value) {
+  // Construct this using the ValueMirror as an unresolved function is not a
+  // real object but just a string.
+  %_CallFunction(this, FUNCTION_TYPE, value, ValueMirror);
+  this.propertyCount_ = 0;
+  this.elementCount_ = 0;
+  this.resolved_ = false;
+}
+inherits(UnresolvedFunctionMirror, FunctionMirror);
+
+
+UnresolvedFunctionMirror.prototype.className = function() {
+  return 'Function';
+};
+
+
+UnresolvedFunctionMirror.prototype.constructorFunction = function() {
+  return GetUndefinedMirror();
+};
+
+
+UnresolvedFunctionMirror.prototype.prototypeObject = function() {
+  return GetUndefinedMirror();
+};
+
+
+UnresolvedFunctionMirror.prototype.protoObject = function() {
+  return GetUndefinedMirror();
+};
+
+
+UnresolvedFunctionMirror.prototype.name = function() {
+  return this.value_;
+};
+
+
+UnresolvedFunctionMirror.prototype.inferredName = function() {
+  return undefined;
+};
+
+
+UnresolvedFunctionMirror.prototype.propertyNames = function(kind, limit) {
+  return [];
+};
+
+
+/**
+ * Mirror object for arrays.
+ * @param {Array} value The Array object reflected by this mirror
+ * @constructor
+ * @extends ObjectMirror
+ */
+function ArrayMirror(value) {
+  %_CallFunction(this, value, ObjectMirror);
+}
+inherits(ArrayMirror, ObjectMirror);
+
+
+ArrayMirror.prototype.length = function() {
+  return this.value_.length;
+};
+
+
+ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index,
+                                                            opt_to_index) {
+  var from_index = opt_from_index || 0;
+  var to_index = opt_to_index || this.length() - 1;
+  if (from_index > to_index) return new Array();
+  var values = new Array(to_index - from_index + 1);
+  for (var i = from_index; i <= to_index; i++) {
+    var details = %DebugGetPropertyDetails(this.value_, builtins.$toString(i));
+    var value;
+    if (details) {
+      value = new PropertyMirror(this, i, details);
+    } else {
+      value = GetUndefinedMirror();
+    }
+    values[i - from_index] = value;
+  }
+  return values;
+};
+
+
+/**
+ * Mirror object for dates.
+ * @param {Date} value The Date object reflected by this mirror
+ * @constructor
+ * @extends ObjectMirror
+ */
+function DateMirror(value) {
+  %_CallFunction(this, value, ObjectMirror);
+}
+inherits(DateMirror, ObjectMirror);
+
+
+DateMirror.prototype.toText = function() {
+  var s = JSON.stringify(this.value_);
+  return s.substring(1, s.length - 1);  // cut quotes
+};
+
+
+/**
+ * Mirror object for regular expressions.
+ * @param {RegExp} value The RegExp object reflected by this mirror
+ * @constructor
+ * @extends ObjectMirror
+ */
+function RegExpMirror(value) {
+  %_CallFunction(this, value, REGEXP_TYPE, ObjectMirror);
+}
+inherits(RegExpMirror, ObjectMirror);
+
+
+/**
+ * Returns the source to the regular expression.
+ * @return {string or undefined} The source to the regular expression
+ */
+RegExpMirror.prototype.source = function() {
+  return this.value_.source;
+};
+
+
+/**
+ * Returns whether this regular expression has the global (g) flag set.
+ * @return {boolean} Value of the global flag
+ */
+RegExpMirror.prototype.global = function() {
+  return this.value_.global;
+};
+
+
+/**
+ * Returns whether this regular expression has the ignore case (i) flag set.
+ * @return {boolean} Value of the ignore case flag
+ */
+RegExpMirror.prototype.ignoreCase = function() {
+  return this.value_.ignoreCase;
+};
+
+
+/**
+ * Returns whether this regular expression has the multiline (m) flag set.
+ * @return {boolean} Value of the multiline flag
+ */
+RegExpMirror.prototype.multiline = function() {
+  return this.value_.multiline;
+};
+
+
+/**
+ * Returns whether this regular expression has the sticky (y) flag set.
+ * @return {boolean} Value of the sticky flag
+ */
+RegExpMirror.prototype.sticky = function() {
+  return this.value_.sticky;
+};
+
+
+/**
+ * Returns whether this regular expression has the unicode (u) flag set.
+ * @return {boolean} Value of the unicode flag
+ */
+RegExpMirror.prototype.unicode = function() {
+  return this.value_.unicode;
+};
+
+
+RegExpMirror.prototype.toText = function() {
+  // Simpel to text which is used when on specialization in subclass.
+  return "/" + this.source() + "/";
+};
+
+
+/**
+ * Mirror object for error objects.
+ * @param {Error} value The error object reflected by this mirror
+ * @constructor
+ * @extends ObjectMirror
+ */
+function ErrorMirror(value) {
+  %_CallFunction(this, value, ERROR_TYPE, ObjectMirror);
+}
+inherits(ErrorMirror, ObjectMirror);
+
+
+/**
+ * Returns the message for this eror object.
+ * @return {string or undefined} The message for this eror object
+ */
+ErrorMirror.prototype.message = function() {
+  return this.value_.message;
+};
+
+
+ErrorMirror.prototype.toText = function() {
+  // Use the same text representation as in messages.js.
+  var text;
+  try {
+    text = %_CallFunction(this.value_, builtins.$errorToString);
+  } catch (e) {
+    text = '#<Error>';
+  }
+  return text;
+};
+
+
+/**
+ * Mirror object for a Promise object.
+ * @param {Object} value The Promise object
+ * @constructor
+ * @extends ObjectMirror
+ */
+function PromiseMirror(value) {
+  %_CallFunction(this, value, PROMISE_TYPE, ObjectMirror);
+}
+inherits(PromiseMirror, ObjectMirror);
+
+
+function PromiseGetStatus_(value) {
+  var status = %DebugGetProperty(value, builtins.$promiseStatus);
+  if (status == 0) return "pending";
+  if (status == 1) return "resolved";
+  return "rejected";
+}
+
+
+function PromiseGetValue_(value) {
+  return %DebugGetProperty(value, builtins.$promiseValue);
+}
+
+
+PromiseMirror.prototype.status = function() {
+  return PromiseGetStatus_(this.value_);
+};
+
+
+PromiseMirror.prototype.promiseValue = function() {
+  return MakeMirror(PromiseGetValue_(this.value_));
+};
+
+
+function MapMirror(value) {
+  %_CallFunction(this, value, MAP_TYPE, ObjectMirror);
+}
+inherits(MapMirror, ObjectMirror);
+
+
+/**
+ * Returns an array of key/value pairs of a map.
+ * This will keep keys alive for WeakMaps.
+ *
+ * @param {number=} opt_limit Max elements to return.
+ * @returns {Array.<Object>} Array of key/value pairs of a map.
+ */
+MapMirror.prototype.entries = function(opt_limit) {
+  var result = [];
+
+  if (IS_WEAKMAP(this.value_)) {
+    var entries = %GetWeakMapEntries(this.value_, opt_limit || 0);
+    for (var i = 0; i < entries.length; i += 2) {
+      result.push({
+        key: entries[i],
+        value: entries[i + 1]
+      });
+    }
+    return result;
+  }
+
+  var iter = %_CallFunction(this.value_, builtins.$mapEntries);
+  var next;
+  while ((!opt_limit || result.length < opt_limit) &&
+         !(next = iter.next()).done) {
+    result.push({
+      key: next.value[0],
+      value: next.value[1]
+    });
+  }
+  return result;
+};
+
+
+function SetMirror(value) {
+  %_CallFunction(this, value, SET_TYPE, ObjectMirror);
+}
+inherits(SetMirror, ObjectMirror);
+
+
+function IteratorGetValues_(iter, next_function, opt_limit) {
+  var result = [];
+  var next;
+  while ((!opt_limit || result.length < opt_limit) &&
+         !(next = %_CallFunction(iter, next_function)).done) {
+    result.push(next.value);
+  }
+  return result;
+}
+
+
+/**
+ * Returns an array of elements of a set.
+ * This will keep elements alive for WeakSets.
+ *
+ * @param {number=} opt_limit Max elements to return.
+ * @returns {Array.<Object>} Array of elements of a set.
+ */
+SetMirror.prototype.values = function(opt_limit) {
+  if (IS_WEAKSET(this.value_)) {
+    return %GetWeakSetValues(this.value_, opt_limit || 0);
+  }
+
+  var iter = %_CallFunction(this.value_, builtins.$setValues);
+  return IteratorGetValues_(iter, builtins.$setIteratorNext, opt_limit);
+};
+
+
+function IteratorMirror(value) {
+  %_CallFunction(this, value, ITERATOR_TYPE, ObjectMirror);
+}
+inherits(IteratorMirror, ObjectMirror);
+
+
+/**
+ * Returns a preview of elements of an iterator.
+ * Does not change the backing iterator state.
+ *
+ * @param {number=} opt_limit Max elements to return.
+ * @returns {Array.<Object>} Array of elements of an iterator.
+ */
+IteratorMirror.prototype.preview = function(opt_limit) {
+  if (IS_MAP_ITERATOR(this.value_)) {
+    return IteratorGetValues_(%MapIteratorClone(this.value_),
+                              builtins.$mapIteratorNext,
+                              opt_limit);
+  } else if (IS_SET_ITERATOR(this.value_)) {
+    return IteratorGetValues_(%SetIteratorClone(this.value_),
+                              builtins.$setIteratorNext,
+                              opt_limit);
+  }
+};
+
+
+/**
+ * Mirror object for a Generator object.
+ * @param {Object} data The Generator object
+ * @constructor
+ * @extends Mirror
+ */
+function GeneratorMirror(value) {
+  %_CallFunction(this, value, GENERATOR_TYPE, ObjectMirror);
+}
+inherits(GeneratorMirror, ObjectMirror);
+
+
+function GeneratorGetStatus_(value) {
+  var continuation = %GeneratorGetContinuation(value);
+  if (continuation < 0) return "running";
+  if (continuation == 0) return "closed";
+  return "suspended";
+}
+
+
+GeneratorMirror.prototype.status = function() {
+  return GeneratorGetStatus_(this.value_);
+};
+
+
+GeneratorMirror.prototype.sourcePosition_ = function() {
+  return %GeneratorGetSourcePosition(this.value_);
+};
+
+
+GeneratorMirror.prototype.sourceLocation = function() {
+  var pos = this.sourcePosition_();
+  if (!IS_UNDEFINED(pos)) {
+    var script = this.func().script();
+    if (script) {
+      return script.locationFromPosition(pos, true);
+    }
+  }
+};
+
+
+GeneratorMirror.prototype.func = function() {
+  if (!this.func_) {
+    this.func_ = MakeMirror(%GeneratorGetFunction(this.value_));
+  }
+  return this.func_;
+};
+
+
+GeneratorMirror.prototype.context = function() {
+  if (!this.context_) {
+    this.context_ = new ContextMirror(%GeneratorGetContext(this.value_));
+  }
+  return this.context_;
+};
+
+
+GeneratorMirror.prototype.receiver = function() {
+  if (!this.receiver_) {
+    this.receiver_ = MakeMirror(%GeneratorGetReceiver(this.value_));
+  }
+  return this.receiver_;
+};
+
+
+/**
+ * Base mirror object for properties.
+ * @param {ObjectMirror} mirror The mirror object having this property
+ * @param {string} name The name of the property
+ * @param {Array} details Details about the property
+ * @constructor
+ * @extends Mirror
+ */
+function PropertyMirror(mirror, name, details) {
+  %_CallFunction(this, PROPERTY_TYPE, Mirror);
+  this.mirror_ = mirror;
+  this.name_ = name;
+  this.value_ = details[0];
+  this.details_ = details[1];
+  this.is_interceptor_ = details[2];
+  if (details.length > 3) {
+    this.exception_ = details[3];
+    this.getter_ = details[4];
+    this.setter_ = details[5];
+  }
+}
+inherits(PropertyMirror, Mirror);
+
+
+PropertyMirror.prototype.isReadOnly = function() {
+  return (this.attributes() & PropertyAttribute.ReadOnly) != 0;
+};
+
+
+PropertyMirror.prototype.isEnum = function() {
+  return (this.attributes() & PropertyAttribute.DontEnum) == 0;
+};
+
+
+PropertyMirror.prototype.canDelete = function() {
+  return (this.attributes() & PropertyAttribute.DontDelete) == 0;
+};
+
+
+PropertyMirror.prototype.name = function() {
+  return this.name_;
+};
+
+
+PropertyMirror.prototype.isIndexed = function() {
+  for (var i = 0; i < this.name_.length; i++) {
+    if (this.name_[i] < '0' || '9' < this.name_[i]) {
+      return false;
+    }
+  }
+  return true;
+};
+
+
+PropertyMirror.prototype.value = function() {
+  return MakeMirror(this.value_, false);
+};
+
+
+/**
+ * Returns whether this property value is an exception.
+ * @return {booolean} True if this property value is an exception
+ */
+PropertyMirror.prototype.isException = function() {
+  return this.exception_ ? true : false;
+};
+
+
+PropertyMirror.prototype.attributes = function() {
+  return %DebugPropertyAttributesFromDetails(this.details_);
+};
+
+
+PropertyMirror.prototype.propertyType = function() {
+  return %DebugPropertyTypeFromDetails(this.details_);
+};
+
+
+PropertyMirror.prototype.insertionIndex = function() {
+  return %DebugPropertyIndexFromDetails(this.details_);
+};
+
+
+/**
+ * Returns whether this property has a getter defined through __defineGetter__.
+ * @return {booolean} True if this property has a getter
+ */
+PropertyMirror.prototype.hasGetter = function() {
+  return this.getter_ ? true : false;
+};
+
+
+/**
+ * Returns whether this property has a setter defined through __defineSetter__.
+ * @return {booolean} True if this property has a setter
+ */
+PropertyMirror.prototype.hasSetter = function() {
+  return this.setter_ ? true : false;
+};
+
+
+/**
+ * Returns the getter for this property defined through __defineGetter__.
+ * @return {Mirror} FunctionMirror reflecting the getter function or
+ *     UndefinedMirror if there is no getter for this property
+ */
+PropertyMirror.prototype.getter = function() {
+  if (this.hasGetter()) {
+    return MakeMirror(this.getter_);
+  } else {
+    return GetUndefinedMirror();
+  }
+};
+
+
+/**
+ * Returns the setter for this property defined through __defineSetter__.
+ * @return {Mirror} FunctionMirror reflecting the setter function or
+ *     UndefinedMirror if there is no setter for this property
+ */
+PropertyMirror.prototype.setter = function() {
+  if (this.hasSetter()) {
+    return MakeMirror(this.setter_);
+  } else {
+    return GetUndefinedMirror();
+  }
+};
+
+
+/**
+ * Returns whether this property is natively implemented by the host or a set
+ * through JavaScript code.
+ * @return {boolean} True if the property is
+ *     UndefinedMirror if there is no setter for this property
+ */
+PropertyMirror.prototype.isNative = function() {
+  return this.is_interceptor_ ||
+         ((this.propertyType() == PropertyType.AccessorConstant) &&
+          !this.hasGetter() && !this.hasSetter());
+};
+
+
+/**
+ * Mirror object for internal properties. Internal property reflects properties
+ * not accessible from user code such as [[BoundThis]] in bound function.
+ * Their names are merely symbolic.
+ * @param {string} name The name of the property
+ * @param {value} property value
+ * @constructor
+ * @extends Mirror
+ */
+function InternalPropertyMirror(name, value) {
+  %_CallFunction(this, INTERNAL_PROPERTY_TYPE, Mirror);
+  this.name_ = name;
+  this.value_ = value;
+}
+inherits(InternalPropertyMirror, Mirror);
+
+
+InternalPropertyMirror.prototype.name = function() {
+  return this.name_;
+};
+
+
+InternalPropertyMirror.prototype.value = function() {
+  return MakeMirror(this.value_, false);
+};
+
+
+var kFrameDetailsFrameIdIndex = 0;
+var kFrameDetailsReceiverIndex = 1;
+var kFrameDetailsFunctionIndex = 2;
+var kFrameDetailsArgumentCountIndex = 3;
+var kFrameDetailsLocalCountIndex = 4;
+var kFrameDetailsSourcePositionIndex = 5;
+var kFrameDetailsConstructCallIndex = 6;
+var kFrameDetailsAtReturnIndex = 7;
+var kFrameDetailsFlagsIndex = 8;
+var kFrameDetailsFirstDynamicIndex = 9;
+
+var kFrameDetailsNameIndex = 0;
+var kFrameDetailsValueIndex = 1;
+var kFrameDetailsNameValueSize = 2;
+
+var kFrameDetailsFlagDebuggerFrameMask = 1 << 0;
+var kFrameDetailsFlagOptimizedFrameMask = 1 << 1;
+var kFrameDetailsFlagInlinedFrameIndexMask = 7 << 2;
+
+/**
+ * Wrapper for the frame details information retreived from the VM. The frame
+ * details from the VM is an array with the following content. See runtime.cc
+ * Runtime_GetFrameDetails.
+ *     0: Id
+ *     1: Receiver
+ *     2: Function
+ *     3: Argument count
+ *     4: Local count
+ *     5: Source position
+ *     6: Construct call
+ *     7: Is at return
+ *     8: Flags (debugger frame, optimized frame, inlined frame index)
+ *     Arguments name, value
+ *     Locals name, value
+ *     Return value if any
+ * @param {number} break_id Current break id
+ * @param {number} index Frame number
+ * @constructor
+ */
+function FrameDetails(break_id, index) {
+  this.break_id_ = break_id;
+  this.details_ = %GetFrameDetails(break_id, index);
+}
+
+
+FrameDetails.prototype.frameId = function() {
+  %CheckExecutionState(this.break_id_);
+  return this.details_[kFrameDetailsFrameIdIndex];
+};
+
+
+FrameDetails.prototype.receiver = function() {
+  %CheckExecutionState(this.break_id_);
+  return this.details_[kFrameDetailsReceiverIndex];
+};
+
+
+FrameDetails.prototype.func = function() {
+  %CheckExecutionState(this.break_id_);
+  return this.details_[kFrameDetailsFunctionIndex];
+};
+
+
+FrameDetails.prototype.isConstructCall = function() {
+  %CheckExecutionState(this.break_id_);
+  return this.details_[kFrameDetailsConstructCallIndex];
+};
+
+
+FrameDetails.prototype.isAtReturn = function() {
+  %CheckExecutionState(this.break_id_);
+  return this.details_[kFrameDetailsAtReturnIndex];
+};
+
+
+FrameDetails.prototype.isDebuggerFrame = function() {
+  %CheckExecutionState(this.break_id_);
+  var f = kFrameDetailsFlagDebuggerFrameMask;
+  return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
+};
+
+
+FrameDetails.prototype.isOptimizedFrame = function() {
+  %CheckExecutionState(this.break_id_);
+  var f = kFrameDetailsFlagOptimizedFrameMask;
+  return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
+};
+
+
+FrameDetails.prototype.isInlinedFrame = function() {
+  return this.inlinedFrameIndex() > 0;
+};
+
+
+FrameDetails.prototype.inlinedFrameIndex = function() {
+  %CheckExecutionState(this.break_id_);
+  var f = kFrameDetailsFlagInlinedFrameIndexMask;
+  return (this.details_[kFrameDetailsFlagsIndex] & f) >> 2;
+};
+
+
+FrameDetails.prototype.argumentCount = function() {
+  %CheckExecutionState(this.break_id_);
+  return this.details_[kFrameDetailsArgumentCountIndex];
+};
+
+
+FrameDetails.prototype.argumentName = function(index) {
+  %CheckExecutionState(this.break_id_);
+  if (index >= 0 && index < this.argumentCount()) {
+    return this.details_[kFrameDetailsFirstDynamicIndex +
+                         index * kFrameDetailsNameValueSize +
+                         kFrameDetailsNameIndex];
+  }
+};
+
+
+FrameDetails.prototype.argumentValue = function(index) {
+  %CheckExecutionState(this.break_id_);
+  if (index >= 0 && index < this.argumentCount()) {
+    return this.details_[kFrameDetailsFirstDynamicIndex +
+                         index * kFrameDetailsNameValueSize +
+                         kFrameDetailsValueIndex];
+  }
+};
+
+
+FrameDetails.prototype.localCount = function() {
+  %CheckExecutionState(this.break_id_);
+  return this.details_[kFrameDetailsLocalCountIndex];
+};
+
+
+FrameDetails.prototype.sourcePosition = function() {
+  %CheckExecutionState(this.break_id_);
+  return this.details_[kFrameDetailsSourcePositionIndex];
+};
+
+
+FrameDetails.prototype.localName = function(index) {
+  %CheckExecutionState(this.break_id_);
+  if (index >= 0 && index < this.localCount()) {
+    var locals_offset = kFrameDetailsFirstDynamicIndex +
+                        this.argumentCount() * kFrameDetailsNameValueSize;
+    return this.details_[locals_offset +
+                         index * kFrameDetailsNameValueSize +
+                         kFrameDetailsNameIndex];
+  }
+};
+
+
+FrameDetails.prototype.localValue = function(index) {
+  %CheckExecutionState(this.break_id_);
+  if (index >= 0 && index < this.localCount()) {
+    var locals_offset = kFrameDetailsFirstDynamicIndex +
+                        this.argumentCount() * kFrameDetailsNameValueSize;
+    return this.details_[locals_offset +
+                         index * kFrameDetailsNameValueSize +
+                         kFrameDetailsValueIndex];
+  }
+};
+
+
+FrameDetails.prototype.returnValue = function() {
+  %CheckExecutionState(this.break_id_);
+  var return_value_offset =
+      kFrameDetailsFirstDynamicIndex +
+      (this.argumentCount() + this.localCount()) * kFrameDetailsNameValueSize;
+  if (this.details_[kFrameDetailsAtReturnIndex]) {
+    return this.details_[return_value_offset];
+  }
+};
+
+
+FrameDetails.prototype.scopeCount = function() {
+  if (IS_UNDEFINED(this.scopeCount_)) {
+    this.scopeCount_ = %GetScopeCount(this.break_id_, this.frameId());
+  }
+  return this.scopeCount_;
+};
+
+
+FrameDetails.prototype.stepInPositionsImpl = function() {
+  return %GetStepInPositions(this.break_id_, this.frameId());
+};
+
+
+/**
+ * Mirror object for stack frames.
+ * @param {number} break_id The break id in the VM for which this frame is
+       valid
+ * @param {number} index The frame index (top frame is index 0)
+ * @constructor
+ * @extends Mirror
+ */
+function FrameMirror(break_id, index) {
+  %_CallFunction(this, FRAME_TYPE, Mirror);
+  this.break_id_ = break_id;
+  this.index_ = index;
+  this.details_ = new FrameDetails(break_id, index);
+}
+inherits(FrameMirror, Mirror);
+
+
+FrameMirror.prototype.details = function() {
+  return this.details_;
+};
+
+
+FrameMirror.prototype.index = function() {
+  return this.index_;
+};
+
+
+FrameMirror.prototype.func = function() {
+  if (this.func_) {
+    return this.func_;
+  }
+
+  // Get the function for this frame from the VM.
+  var f = this.details_.func();
+
+  // Create a function mirror. NOTE: MakeMirror cannot be used here as the
+  // value returned from the VM might be a string if the function for the
+  // frame is unresolved.
+  if (IS_FUNCTION(f)) {
+    return this.func_ = MakeMirror(f);
+  } else {
+    return new UnresolvedFunctionMirror(f);
+  }
+};
+
+
+FrameMirror.prototype.receiver = function() {
+  return MakeMirror(this.details_.receiver());
+};
+
+
+FrameMirror.prototype.isConstructCall = function() {
+  return this.details_.isConstructCall();
+};
+
+
+FrameMirror.prototype.isAtReturn = function() {
+  return this.details_.isAtReturn();
+};
+
+
+FrameMirror.prototype.isDebuggerFrame = function() {
+  return this.details_.isDebuggerFrame();
+};
+
+
+FrameMirror.prototype.isOptimizedFrame = function() {
+  return this.details_.isOptimizedFrame();
+};
+
+
+FrameMirror.prototype.isInlinedFrame = function() {
+  return this.details_.isInlinedFrame();
+};
+
+
+FrameMirror.prototype.inlinedFrameIndex = function() {
+  return this.details_.inlinedFrameIndex();
+};
+
+
+FrameMirror.prototype.argumentCount = function() {
+  return this.details_.argumentCount();
+};
+
+
+FrameMirror.prototype.argumentName = function(index) {
+  return this.details_.argumentName(index);
+};
+
+
+FrameMirror.prototype.argumentValue = function(index) {
+  return MakeMirror(this.details_.argumentValue(index));
+};
+
+
+FrameMirror.prototype.localCount = function() {
+  return this.details_.localCount();
+};
+
+
+FrameMirror.prototype.localName = function(index) {
+  return this.details_.localName(index);
+};
+
+
+FrameMirror.prototype.localValue = function(index) {
+  return MakeMirror(this.details_.localValue(index));
+};
+
+
+FrameMirror.prototype.returnValue = function() {
+  return MakeMirror(this.details_.returnValue());
+};
+
+
+FrameMirror.prototype.sourcePosition = function() {
+  return this.details_.sourcePosition();
+};
+
+
+FrameMirror.prototype.sourceLocation = function() {
+  var func = this.func();
+  if (func.resolved()) {
+    var script = func.script();
+    if (script) {
+      return script.locationFromPosition(this.sourcePosition(), true);
+    }
+  }
+};
+
+
+FrameMirror.prototype.sourceLine = function() {
+  var location = this.sourceLocation();
+  if (location) {
+    return location.line;
+  }
+};
+
+
+FrameMirror.prototype.sourceColumn = function() {
+  var location = this.sourceLocation();
+  if (location) {
+    return location.column;
+  }
+};
+
+
+FrameMirror.prototype.sourceLineText = function() {
+  var location = this.sourceLocation();
+  if (location) {
+    return location.sourceText();
+  }
+};
+
+
+FrameMirror.prototype.scopeCount = function() {
+  return this.details_.scopeCount();
+};
+
+
+FrameMirror.prototype.scope = function(index) {
+  return new ScopeMirror(this, UNDEFINED, index);
+};
+
+
+FrameMirror.prototype.allScopes = function(opt_ignore_nested_scopes) {
+  var scopeDetails = %GetAllScopesDetails(this.break_id_,
+                                          this.details_.frameId(),
+                                          this.details_.inlinedFrameIndex(),
+                                          !!opt_ignore_nested_scopes);
+  var result = [];
+  for (var i = 0; i < scopeDetails.length; ++i) {
+    result.push(new ScopeMirror(this, UNDEFINED, i, scopeDetails[i]));
+  }
+  return result;
+};
+
+
+FrameMirror.prototype.stepInPositions = function() {
+  var script = this.func().script();
+  var funcOffset = this.func().sourcePosition_();
+
+  var stepInRaw = this.details_.stepInPositionsImpl();
+  var result = [];
+  if (stepInRaw) {
+    for (var i = 0; i < stepInRaw.length; i++) {
+      var posStruct = {};
+      var offset = script.locationFromPosition(funcOffset + stepInRaw[i],
+                                               true);
+      serializeLocationFields(offset, posStruct);
+      var item = {
+        position: posStruct
+      };
+      result.push(item);
+    }
+  }
+
+  return result;
+};
+
+
+FrameMirror.prototype.evaluate = function(source, disable_break,
+                                          opt_context_object) {
+  return MakeMirror(%DebugEvaluate(this.break_id_,
+                                   this.details_.frameId(),
+                                   this.details_.inlinedFrameIndex(),
+                                   source,
+                                   Boolean(disable_break),
+                                   opt_context_object));
+};
+
+
+FrameMirror.prototype.invocationText = function() {
+  // Format frame invoaction (receiver, function and arguments).
+  var result = '';
+  var func = this.func();
+  var receiver = this.receiver();
+  if (this.isConstructCall()) {
+    // For constructor frames display new followed by the function name.
+    result += 'new ';
+    result += func.name() ? func.name() : '[anonymous]';
+  } else if (this.isDebuggerFrame()) {
+    result += '[debugger]';
+  } else {
+    // If the receiver has a className which is 'global' don't display it.
+    var display_receiver =
+      !receiver.className || (receiver.className() != 'global');
+    if (display_receiver) {
+      result += receiver.toText();
+    }
+    // Try to find the function as a property in the receiver. Include the
+    // prototype chain in the lookup.
+    var property = GetUndefinedMirror();
+    if (receiver.isObject()) {
+      for (var r = receiver;
+           !r.isNull() && property.isUndefined();
+           r = r.protoObject()) {
+        property = r.lookupProperty(func);
+      }
+    }
+    if (!property.isUndefined()) {
+      // The function invoked was found on the receiver. Use the property name
+      // for the backtrace.
+      if (!property.isIndexed()) {
+        if (display_receiver) {
+          result += '.';
+        }
+        result += property.name();
+      } else {
+        result += '[';
+        result += property.name();
+        result += ']';
+      }
+      // Also known as - if the name in the function doesn't match the name
+      // under which it was looked up.
+      if (func.name() && func.name() != property.name()) {
+        result += '(aka ' + func.name() + ')';
+      }
+    } else {
+      // The function invoked was not found on the receiver. Use the function
+      // name if available for the backtrace.
+      if (display_receiver) {
+        result += '.';
+      }
+      result += func.name() ? func.name() : '[anonymous]';
+    }
+  }
+
+  // Render arguments for normal frames.
+  if (!this.isDebuggerFrame()) {
+    result += '(';
+    for (var i = 0; i < this.argumentCount(); i++) {
+      if (i != 0) result += ', ';
+      if (this.argumentName(i)) {
+        result += this.argumentName(i);
+        result += '=';
+      }
+      result += this.argumentValue(i).toText();
+    }
+    result += ')';
+  }
+
+  if (this.isAtReturn()) {
+    result += ' returning ';
+    result += this.returnValue().toText();
+  }
+
+  return result;
+};
+
+
+FrameMirror.prototype.sourceAndPositionText = function() {
+  // Format source and position.
+  var result = '';
+  var func = this.func();
+  if (func.resolved()) {
+    var script = func.script();
+    if (script) {
+      if (script.name()) {
+        result += script.name();
+      } else {
+        result += '[unnamed]';
+      }
+      if (!this.isDebuggerFrame()) {
+        var location = this.sourceLocation();
+        result += ' line ';
+        result += !IS_UNDEFINED(location) ? (location.line + 1) : '?';
+        result += ' column ';
+        result += !IS_UNDEFINED(location) ? (location.column + 1) : '?';
+        if (!IS_UNDEFINED(this.sourcePosition())) {
+          result += ' (position ' + (this.sourcePosition() + 1) + ')';
+        }
+      }
+    } else {
+      result += '[no source]';
+    }
+  } else {
+    result += '[unresolved]';
+  }
+
+  return result;
+};
+
+
+FrameMirror.prototype.localsText = function() {
+  // Format local variables.
+  var result = '';
+  var locals_count = this.localCount();
+  if (locals_count > 0) {
+    for (var i = 0; i < locals_count; ++i) {
+      result += '      var ';
+      result += this.localName(i);
+      result += ' = ';
+      result += this.localValue(i).toText();
+      if (i < locals_count - 1) result += '\n';
+    }
+  }
+
+  return result;
+};
+
+
+FrameMirror.prototype.restart = function() {
+  var result = %LiveEditRestartFrame(this.break_id_, this.index_);
+  if (IS_UNDEFINED(result)) {
+    result = "Failed to find requested frame";
+  }
+  return result;
+};
+
+
+FrameMirror.prototype.toText = function(opt_locals) {
+  var result = '';
+  result += '#' + (this.index() <= 9 ? '0' : '') + this.index();
+  result += ' ';
+  result += this.invocationText();
+  result += ' ';
+  result += this.sourceAndPositionText();
+  if (opt_locals) {
+    result += '\n';
+    result += this.localsText();
+  }
+  return result;
+};
+
+
+var kScopeDetailsTypeIndex = 0;
+var kScopeDetailsObjectIndex = 1;
+
+function ScopeDetails(frame, fun, index, opt_details) {
+  if (frame) {
+    this.break_id_ = frame.break_id_;
+    this.details_ = opt_details ||
+                    %GetScopeDetails(frame.break_id_,
+                                     frame.details_.frameId(),
+                                     frame.details_.inlinedFrameIndex(),
+                                     index);
+    this.frame_id_ = frame.details_.frameId();
+    this.inlined_frame_id_ = frame.details_.inlinedFrameIndex();
+  } else {
+    this.details_ = opt_details || %GetFunctionScopeDetails(fun.value(), index);
+    this.fun_value_ = fun.value();
+    this.break_id_ = undefined;
+  }
+  this.index_ = index;
+}
+
+
+ScopeDetails.prototype.type = function() {
+  if (!IS_UNDEFINED(this.break_id_)) {
+    %CheckExecutionState(this.break_id_);
+  }
+  return this.details_[kScopeDetailsTypeIndex];
+};
+
+
+ScopeDetails.prototype.object = function() {
+  if (!IS_UNDEFINED(this.break_id_)) {
+    %CheckExecutionState(this.break_id_);
+  }
+  return this.details_[kScopeDetailsObjectIndex];
+};
+
+
+ScopeDetails.prototype.setVariableValueImpl = function(name, new_value) {
+  var raw_res;
+  if (!IS_UNDEFINED(this.break_id_)) {
+    %CheckExecutionState(this.break_id_);
+    raw_res = %SetScopeVariableValue(this.break_id_, this.frame_id_,
+        this.inlined_frame_id_, this.index_, name, new_value);
+  } else {
+    raw_res = %SetScopeVariableValue(this.fun_value_, null, null, this.index_,
+        name, new_value);
+  }
+  if (!raw_res) {
+    throw new Error("Failed to set variable value");
+  }
+};
+
+
+/**
+ * Mirror object for scope of frame or function. Either frame or function must
+ * be specified.
+ * @param {FrameMirror} frame The frame this scope is a part of
+ * @param {FunctionMirror} function The function this scope is a part of
+ * @param {number} index The scope index in the frame
+ * @param {Array=} opt_details Raw scope details data
+ * @constructor
+ * @extends Mirror
+ */
+function ScopeMirror(frame, function, index, opt_details) {
+  %_CallFunction(this, SCOPE_TYPE, Mirror);
+  if (frame) {
+    this.frame_index_ = frame.index_;
+  } else {
+    this.frame_index_ = undefined;
+  }
+  this.scope_index_ = index;
+  this.details_ = new ScopeDetails(frame, function, index, opt_details);
+}
+inherits(ScopeMirror, Mirror);
+
+
+ScopeMirror.prototype.details = function() {
+  return this.details_;
+};
+
+
+ScopeMirror.prototype.frameIndex = function() {
+  return this.frame_index_;
+};
+
+
+ScopeMirror.prototype.scopeIndex = function() {
+  return this.scope_index_;
+};
+
+
+ScopeMirror.prototype.scopeType = function() {
+  return this.details_.type();
+};
+
+
+ScopeMirror.prototype.scopeObject = function() {
+  // For local, closure and script scopes create a transient mirror
+  // as these objects are created on the fly materializing the local
+  // or closure scopes and therefore will not preserve identity.
+  var transient = this.scopeType() == ScopeType.Local ||
+                  this.scopeType() == ScopeType.Closure ||
+                  this.scopeType() == ScopeType.Script;
+  return MakeMirror(this.details_.object(), transient);
+};
+
+
+ScopeMirror.prototype.setVariableValue = function(name, new_value) {
+  this.details_.setVariableValueImpl(name, new_value);
+};
+
+
+/**
+ * Mirror object for script source.
+ * @param {Script} script The script object
+ * @constructor
+ * @extends Mirror
+ */
+function ScriptMirror(script) {
+  %_CallFunction(this, SCRIPT_TYPE, Mirror);
+  this.script_ = script;
+  this.context_ = new ContextMirror(script.context_data);
+  this.allocateHandle_();
+}
+inherits(ScriptMirror, Mirror);
+
+
+ScriptMirror.prototype.value = function() {
+  return this.script_;
+};
+
+
+ScriptMirror.prototype.name = function() {
+  return this.script_.name || this.script_.nameOrSourceURL();
+};
+
+
+ScriptMirror.prototype.id = function() {
+  return this.script_.id;
+};
+
+
+ScriptMirror.prototype.source = function() {
+  return this.script_.source;
+};
+
+
+ScriptMirror.prototype.setSource = function(source) {
+  %DebugSetScriptSource(this.script_, source);
+};
+
+
+ScriptMirror.prototype.lineOffset = function() {
+  return this.script_.line_offset;
+};
+
+
+ScriptMirror.prototype.columnOffset = function() {
+  return this.script_.column_offset;
+};
+
+
+ScriptMirror.prototype.data = function() {
+  return this.script_.data;
+};
+
+
+ScriptMirror.prototype.scriptType = function() {
+  return this.script_.type;
+};
+
+
+ScriptMirror.prototype.compilationType = function() {
+  return this.script_.compilation_type;
+};
+
+
+ScriptMirror.prototype.lineCount = function() {
+  return this.script_.lineCount();
+};
+
+
+ScriptMirror.prototype.locationFromPosition = function(
+    position, include_resource_offset) {
+  return this.script_.locationFromPosition(position, include_resource_offset);
+};
+
+
+ScriptMirror.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
+  return this.script_.sourceSlice(opt_from_line, opt_to_line);
+};
+
+
+ScriptMirror.prototype.context = function() {
+  return this.context_;
+};
+
+
+ScriptMirror.prototype.evalFromScript = function() {
+  return MakeMirror(this.script_.eval_from_script);
+};
+
+
+ScriptMirror.prototype.evalFromFunctionName = function() {
+  return MakeMirror(this.script_.eval_from_function_name);
+};
+
+
+ScriptMirror.prototype.evalFromLocation = function() {
+  var eval_from_script = this.evalFromScript();
+  if (!eval_from_script.isUndefined()) {
+    var position = this.script_.eval_from_script_position;
+    return eval_from_script.locationFromPosition(position, true);
+  }
+};
+
+
+ScriptMirror.prototype.toText = function() {
+  var result = '';
+  result += this.name();
+  result += ' (lines: ';
+  if (this.lineOffset() > 0) {
+    result += this.lineOffset();
+    result += '-';
+    result += this.lineOffset() + this.lineCount() - 1;
+  } else {
+    result += this.lineCount();
+  }
+  result += ')';
+  return result;
+};
+
+
+/**
+ * Mirror object for context.
+ * @param {Object} data The context data
+ * @constructor
+ * @extends Mirror
+ */
+function ContextMirror(data) {
+  %_CallFunction(this, CONTEXT_TYPE, Mirror);
+  this.data_ = data;
+  this.allocateHandle_();
+}
+inherits(ContextMirror, Mirror);
+
+
+ContextMirror.prototype.data = function() {
+  return this.data_;
+};
+
+
+/**
+ * Returns a mirror serializer
+ *
+ * @param {boolean} details Set to true to include details
+ * @param {Object} options Options comtrolling the serialization
+ *     The following options can be set:
+ *       includeSource: include ths full source of scripts
+ * @returns {MirrorSerializer} mirror serializer
+ */
+function MakeMirrorSerializer(details, options) {
+  return new JSONProtocolSerializer(details, options);
+}
+
+
+/**
+ * Object for serializing a mirror objects and its direct references.
+ * @param {boolean} details Indicates whether to include details for the mirror
+ *     serialized
+ * @constructor
+ */
+function JSONProtocolSerializer(details, options) {
+  this.details_ = details;
+  this.options_ = options;
+  this.mirrors_ = [ ];
+}
+
+
+/**
+ * Returns a serialization of an object reference. The referenced object are
+ * added to the serialization state.
+ *
+ * @param {Mirror} mirror The mirror to serialize
+ * @returns {String} JSON serialization
+ */
+JSONProtocolSerializer.prototype.serializeReference = function(mirror) {
+  return this.serialize_(mirror, true, true);
+};
+
+
+/**
+ * Returns a serialization of an object value. The referenced objects are
+ * added to the serialization state.
+ *
+ * @param {Mirror} mirror The mirror to serialize
+ * @returns {String} JSON serialization
+ */
+JSONProtocolSerializer.prototype.serializeValue = function(mirror) {
+  var json = this.serialize_(mirror, false, true);
+  return json;
+};
+
+
+/**
+ * Returns a serialization of all the objects referenced.
+ *
+ * @param {Mirror} mirror The mirror to serialize.
+ * @returns {Array.<Object>} Array of the referenced objects converted to
+ *     protcol objects.
+ */
+JSONProtocolSerializer.prototype.serializeReferencedObjects = function() {
+  // Collect the protocol representation of the referenced objects in an array.
+  var content = [];
+
+  // Get the number of referenced objects.
+  var count = this.mirrors_.length;
+
+  for (var i = 0; i < count; i++) {
+    content.push(this.serialize_(this.mirrors_[i], false, false));
+  }
+
+  return content;
+};
+
+
+JSONProtocolSerializer.prototype.includeSource_ = function() {
+  return this.options_ && this.options_.includeSource;
+};
+
+
+JSONProtocolSerializer.prototype.inlineRefs_ = function() {
+  return this.options_ && this.options_.inlineRefs;
+};
+
+
+JSONProtocolSerializer.prototype.maxStringLength_ = function() {
+  if (IS_UNDEFINED(this.options_) ||
+      IS_UNDEFINED(this.options_.maxStringLength)) {
+    return kMaxProtocolStringLength;
+  }
+  return this.options_.maxStringLength;
+};
+
+
+JSONProtocolSerializer.prototype.add_ = function(mirror) {
+  // If this mirror is already in the list just return.
+  for (var i = 0; i < this.mirrors_.length; i++) {
+    if (this.mirrors_[i] === mirror) {
+      return;
+    }
+  }
+
+  // Add the mirror to the list of mirrors to be serialized.
+  this.mirrors_.push(mirror);
+};
+
+
+/**
+ * Formats mirror object to protocol reference object with some data that can
+ * be used to display the value in debugger.
+ * @param {Mirror} mirror Mirror to serialize.
+ * @return {Object} Protocol reference object.
+ */
+JSONProtocolSerializer.prototype.serializeReferenceWithDisplayData_ =
+    function(mirror) {
+  var o = {};
+  o.ref = mirror.handle();
+  o.type = mirror.type();
+  switch (mirror.type()) {
+    case UNDEFINED_TYPE:
+    case NULL_TYPE:
+    case BOOLEAN_TYPE:
+    case NUMBER_TYPE:
+      o.value = mirror.value();
+      break;
+    case STRING_TYPE:
+      o.value = mirror.getTruncatedValue(this.maxStringLength_());
+      break;
+    case SYMBOL_TYPE:
+      o.description = mirror.description();
+      break;
+    case FUNCTION_TYPE:
+      o.name = mirror.name();
+      o.inferredName = mirror.inferredName();
+      if (mirror.script()) {
+        o.scriptId = mirror.script().id();
+      }
+      break;
+    case ERROR_TYPE:
+    case REGEXP_TYPE:
+      o.value = mirror.toText();
+      break;
+    case OBJECT_TYPE:
+      o.className = mirror.className();
+      break;
+  }
+  return o;
+};
+
+
+JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
+                                                       details) {
+  // If serializing a reference to a mirror just return the reference and add
+  // the mirror to the referenced mirrors.
+  if (reference &&
+      (mirror.isValue() || mirror.isScript() || mirror.isContext())) {
+    if (this.inlineRefs_() && mirror.isValue()) {
+      return this.serializeReferenceWithDisplayData_(mirror);
+    } else {
+      this.add_(mirror);
+      return {'ref' : mirror.handle()};
+    }
+  }
+
+  // Collect the JSON property/value pairs.
+  var content = {};
+
+  // Add the mirror handle.
+  if (mirror.isValue() || mirror.isScript() || mirror.isContext()) {
+    content.handle = mirror.handle();
+  }
+
+  // Always add the type.
+  content.type = mirror.type();
+
+  switch (mirror.type()) {
+    case UNDEFINED_TYPE:
+    case NULL_TYPE:
+      // Undefined and null are represented just by their type.
+      break;
+
+    case BOOLEAN_TYPE:
+      // Boolean values are simply represented by their value.
+      content.value = mirror.value();
+      break;
+
+    case NUMBER_TYPE:
+      // Number values are simply represented by their value.
+      content.value = NumberToJSON_(mirror.value());
+      break;
+
+    case STRING_TYPE:
+      // String values might have their value cropped to keep down size.
+      if (this.maxStringLength_() != -1 &&
+          mirror.length() > this.maxStringLength_()) {
+        var str = mirror.getTruncatedValue(this.maxStringLength_());
+        content.value = str;
+        content.fromIndex = 0;
+        content.toIndex = this.maxStringLength_();
+      } else {
+        content.value = mirror.value();
+      }
+      content.length = mirror.length();
+      break;
+
+    case SYMBOL_TYPE:
+      content.description = mirror.description();
+      break;
+
+    case OBJECT_TYPE:
+    case FUNCTION_TYPE:
+    case ERROR_TYPE:
+    case REGEXP_TYPE:
+    case PROMISE_TYPE:
+    case GENERATOR_TYPE:
+      // Add object representation.
+      this.serializeObject_(mirror, content, details);
+      break;
+
+    case PROPERTY_TYPE:
+    case INTERNAL_PROPERTY_TYPE:
+      throw new Error('PropertyMirror cannot be serialized independently');
+      break;
+
+    case FRAME_TYPE:
+      // Add object representation.
+      this.serializeFrame_(mirror, content);
+      break;
+
+    case SCOPE_TYPE:
+      // Add object representation.
+      this.serializeScope_(mirror, content);
+      break;
+
+    case SCRIPT_TYPE:
+      // Script is represented by id, name and source attributes.
+      if (mirror.name()) {
+        content.name = mirror.name();
+      }
+      content.id = mirror.id();
+      content.lineOffset = mirror.lineOffset();
+      content.columnOffset = mirror.columnOffset();
+      content.lineCount = mirror.lineCount();
+      if (mirror.data()) {
+        content.data = mirror.data();
+      }
+      if (this.includeSource_()) {
+        content.source = mirror.source();
+      } else {
+        var sourceStart = mirror.source().substring(0, 80);
+        content.sourceStart = sourceStart;
+      }
+      content.sourceLength = mirror.source().length;
+      content.scriptType = mirror.scriptType();
+      content.compilationType = mirror.compilationType();
+      // For compilation type eval emit information on the script from which
+      // eval was called if a script is present.
+      if (mirror.compilationType() == 1 &&
+          mirror.evalFromScript()) {
+        content.evalFromScript =
+            this.serializeReference(mirror.evalFromScript());
+        var evalFromLocation = mirror.evalFromLocation();
+        if (evalFromLocation) {
+          content.evalFromLocation = { line: evalFromLocation.line,
+                                       column: evalFromLocation.column };
+        }
+        if (mirror.evalFromFunctionName()) {
+          content.evalFromFunctionName = mirror.evalFromFunctionName();
+        }
+      }
+      if (mirror.context()) {
+        content.context = this.serializeReference(mirror.context());
+      }
+      break;
+
+    case CONTEXT_TYPE:
+      content.data = mirror.data();
+      break;
+  }
+
+  // Always add the text representation.
+  content.text = mirror.toText();
+
+  // Create and return the JSON string.
+  return content;
+};
+
+
+/**
+ * Serialize object information to the following JSON format.
+ *
+ *   {"className":"<class name>",
+ *    "constructorFunction":{"ref":<number>},
+ *    "protoObject":{"ref":<number>},
+ *    "prototypeObject":{"ref":<number>},
+ *    "namedInterceptor":<boolean>,
+ *    "indexedInterceptor":<boolean>,
+ *    "properties":[<properties>],
+ *    "internalProperties":[<internal properties>]}
+ */
+JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
+                                                             details) {
+  // Add general object properties.
+  content.className = mirror.className();
+  content.constructorFunction =
+      this.serializeReference(mirror.constructorFunction());
+  content.protoObject = this.serializeReference(mirror.protoObject());
+  content.prototypeObject = this.serializeReference(mirror.prototypeObject());
+
+  // Add flags to indicate whether there are interceptors.
+  if (mirror.hasNamedInterceptor()) {
+    content.namedInterceptor = true;
+  }
+  if (mirror.hasIndexedInterceptor()) {
+    content.indexedInterceptor = true;
+  }
+
+  if (mirror.isFunction()) {
+    // Add function specific properties.
+    content.name = mirror.name();
+    if (!IS_UNDEFINED(mirror.inferredName())) {
+      content.inferredName = mirror.inferredName();
+    }
+    content.resolved = mirror.resolved();
+    if (mirror.resolved()) {
+      content.source = mirror.source();
+    }
+    if (mirror.script()) {
+      content.script = this.serializeReference(mirror.script());
+      content.scriptId = mirror.script().id();
+
+      serializeLocationFields(mirror.sourceLocation(), content);
+    }
+
+    content.scopes = [];
+    for (var i = 0; i < mirror.scopeCount(); i++) {
+      var scope = mirror.scope(i);
+      content.scopes.push({
+        type: scope.scopeType(),
+        index: i
+      });
+    }
+  }
+
+  if (mirror.isGenerator()) {
+    // Add generator specific properties.
+
+    // Either 'running', 'closed', or 'suspended'.
+    content.status = mirror.status();
+
+    content.func = this.serializeReference(mirror.func())
+    content.receiver = this.serializeReference(mirror.receiver())
+
+    // If the generator is suspended, the content add line/column properties.
+    serializeLocationFields(mirror.sourceLocation(), content);
+
+    // TODO(wingo): Also serialize a reference to the context (scope chain).
+  }
+
+  if (mirror.isDate()) {
+    // Add date specific properties.
+    content.value = mirror.value();
+  }
+
+  if (mirror.isPromise()) {
+    // Add promise specific properties.
+    content.status = mirror.status();
+    content.promiseValue = this.serializeReference(mirror.promiseValue());
+  }
+
+  // Add actual properties - named properties followed by indexed properties.
+  var propertyNames = mirror.propertyNames(PropertyKind.Named);
+  var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed);
+  var p = new Array(propertyNames.length + propertyIndexes.length);
+  for (var i = 0; i < propertyNames.length; i++) {
+    var propertyMirror = mirror.property(propertyNames[i]);
+    p[i] = this.serializeProperty_(propertyMirror);
+    if (details) {
+      this.add_(propertyMirror.value());
+    }
+  }
+  for (var i = 0; i < propertyIndexes.length; i++) {
+    var propertyMirror = mirror.property(propertyIndexes[i]);
+    p[propertyNames.length + i] = this.serializeProperty_(propertyMirror);
+    if (details) {
+      this.add_(propertyMirror.value());
+    }
+  }
+  content.properties = p;
+
+  var internalProperties = mirror.internalProperties();
+  if (internalProperties.length > 0) {
+    var ip = [];
+    for (var i = 0; i < internalProperties.length; i++) {
+      ip.push(this.serializeInternalProperty_(internalProperties[i]));
+    }
+    content.internalProperties = ip;
+  }
+};
+
+
+/**
+ * Serialize location information to the following JSON format:
+ *
+ *   "position":"<position>",
+ *   "line":"<line>",
+ *   "column":"<column>",
+ *
+ * @param {SourceLocation} location The location to serialize, may be undefined.
+ */
+function serializeLocationFields (location, content) {
+  if (!location) {
+    return;
+  }
+  content.position = location.position;
+  var line = location.line;
+  if (!IS_UNDEFINED(line)) {
+    content.line = line;
+  }
+  var column = location.column;
+  if (!IS_UNDEFINED(column)) {
+    content.column = column;
+  }
+}
+
+
+/**
+ * Serialize property information to the following JSON format for building the
+ * array of properties.
+ *
+ *   {"name":"<property name>",
+ *    "attributes":<number>,
+ *    "propertyType":<number>,
+ *    "ref":<number>}
+ *
+ * If the attribute for the property is PropertyAttribute.None it is not added.
+ * Here are a couple of examples.
+ *
+ *   {"name":"hello","propertyType":0,"ref":1}
+ *   {"name":"length","attributes":7,"propertyType":3,"ref":2}
+ *
+ * @param {PropertyMirror} propertyMirror The property to serialize.
+ * @returns {Object} Protocol object representing the property.
+ */
+JSONProtocolSerializer.prototype.serializeProperty_ = function(propertyMirror) {
+  var result = {};
+
+  result.name = propertyMirror.name();
+  var propertyValue = propertyMirror.value();
+  if (this.inlineRefs_() && propertyValue.isValue()) {
+    result.value = this.serializeReferenceWithDisplayData_(propertyValue);
+  } else {
+    if (propertyMirror.attributes() != PropertyAttribute.None) {
+      result.attributes = propertyMirror.attributes();
+    }
+    result.propertyType = propertyMirror.propertyType();
+    result.ref = propertyValue.handle();
+  }
+  return result;
+};
+
+
+/**
+ * Serialize internal property information to the following JSON format for
+ * building the array of properties.
+ *
+ *   {"name":"<property name>",
+ *    "ref":<number>}
+ *
+ *   {"name":"[[BoundThis]]","ref":117}
+ *
+ * @param {InternalPropertyMirror} propertyMirror The property to serialize.
+ * @returns {Object} Protocol object representing the property.
+ */
+JSONProtocolSerializer.prototype.serializeInternalProperty_ =
+    function(propertyMirror) {
+  var result = {};
+
+  result.name = propertyMirror.name();
+  var propertyValue = propertyMirror.value();
+  if (this.inlineRefs_() && propertyValue.isValue()) {
+    result.value = this.serializeReferenceWithDisplayData_(propertyValue);
+  } else {
+    result.ref = propertyValue.handle();
+  }
+  return result;
+};
+
+
+JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) {
+  content.index = mirror.index();
+  content.receiver = this.serializeReference(mirror.receiver());
+  var func = mirror.func();
+  content.func = this.serializeReference(func);
+  var script = func.script();
+  if (script) {
+    content.script = this.serializeReference(script);
+  }
+  content.constructCall = mirror.isConstructCall();
+  content.atReturn = mirror.isAtReturn();
+  if (mirror.isAtReturn()) {
+    content.returnValue = this.serializeReference(mirror.returnValue());
+  }
+  content.debuggerFrame = mirror.isDebuggerFrame();
+  var x = new Array(mirror.argumentCount());
+  for (var i = 0; i < mirror.argumentCount(); i++) {
+    var arg = {};
+    var argument_name = mirror.argumentName(i);
+    if (argument_name) {
+      arg.name = argument_name;
+    }
+    arg.value = this.serializeReference(mirror.argumentValue(i));
+    x[i] = arg;
+  }
+  content.arguments = x;
+  var x = new Array(mirror.localCount());
+  for (var i = 0; i < mirror.localCount(); i++) {
+    var local = {};
+    local.name = mirror.localName(i);
+    local.value = this.serializeReference(mirror.localValue(i));
+    x[i] = local;
+  }
+  content.locals = x;
+  serializeLocationFields(mirror.sourceLocation(), content);
+  var source_line_text = mirror.sourceLineText();
+  if (!IS_UNDEFINED(source_line_text)) {
+    content.sourceLineText = source_line_text;
+  }
+
+  content.scopes = [];
+  for (var i = 0; i < mirror.scopeCount(); i++) {
+    var scope = mirror.scope(i);
+    content.scopes.push({
+      type: scope.scopeType(),
+      index: i
+    });
+  }
+};
+
+
+JSONProtocolSerializer.prototype.serializeScope_ = function(mirror, content) {
+  content.index = mirror.scopeIndex();
+  content.frameIndex = mirror.frameIndex();
+  content.type = mirror.scopeType();
+  content.object = this.inlineRefs_() ?
+                   this.serializeValue(mirror.scopeObject()) :
+                   this.serializeReference(mirror.scopeObject());
+};
+
+
+/**
+ * Convert a number to a protocol value. For all finite numbers the number
+ * itself is returned. For non finite numbers NaN, Infinite and
+ * -Infinite the string representation "NaN", "Infinite" or "-Infinite"
+ * (not including the quotes) is returned.
+ *
+ * @param {number} value The number value to convert to a protocol value.
+ * @returns {number|string} Protocol value.
+ */
+function NumberToJSON_(value) {
+  if (isNaN(value)) {
+    return 'NaN';
+  }
+  if (!NUMBER_IS_FINITE(value)) {
+    if (value > 0) {
+      return 'Infinity';
+    } else {
+      return '-Infinity';
+    }
+  }
+  return value;
+}
diff --git a/src/debug/ppc/OWNERS b/src/debug/ppc/OWNERS
new file mode 100644 (file)
index 0000000..eb007cb
--- /dev/null
@@ -0,0 +1,5 @@
+jyan@ca.ibm.com
+dstence@us.ibm.com
+joransiu@ca.ibm.com
+mbrandy@us.ibm.com
+michael_dawson@ca.ibm.com
diff --git a/src/debug/ppc/debug-ppc.cc b/src/debug/ppc/debug-ppc.cc
new file mode 100644 (file)
index 0000000..a23782a
--- /dev/null
@@ -0,0 +1,159 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/codegen.h"
+#include "src/debug/debug.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void EmitDebugBreakSlot(MacroAssembler* masm) {
+  Label check_size;
+  __ bind(&check_size);
+  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
+    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
+  }
+  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
+            masm->InstructionsGeneratedSince(&check_size));
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                                int call_argc) {
+  // Generate enough nop's to make space for a call instruction. Avoid emitting
+  // the trampoline pool in the debug break slot code.
+  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
+  masm->RecordDebugBreakSlot(mode, call_argc);
+  EmitDebugBreakSlot(masm);
+}
+
+
+void DebugCodegen::ClearDebugBreakSlot(Address pc) {
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
+  EmitDebugBreakSlot(patcher.masm());
+}
+
+
+void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
+  DCHECK_EQ(Code::BUILTIN, code->kind());
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
+  // Patch the code changing the debug break slot code from
+  //
+  //   ori r3, r3, 0
+  //   ori r3, r3, 0
+  //   ori r3, r3, 0
+  //   ori r3, r3, 0
+  //   ori r3, r3, 0
+  //
+  // to a call to the debug break code, using a FIXED_SEQUENCE.
+  //
+  //   mov r0, <address>
+  //   mtlr r0
+  //   blrl
+  //
+  Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm());
+  patcher.masm()->mov(v8::internal::r0,
+                      Operand(reinterpret_cast<intptr_t>(code->entry())));
+  patcher.masm()->mtctr(v8::internal::r0);
+  patcher.masm()->bctrl();
+}
+
+
+void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
+                                          DebugBreakCallHelperMode mode) {
+  __ RecordComment("Debug break");
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingValue));
+    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
+      __ push(ip);
+    }
+    __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
+    __ push(ip);
+
+    if (mode == SAVE_RESULT_REGISTER) __ push(r3);
+
+    __ mov(r3, Operand::Zero());  // no arguments
+    __ mov(r4,
+           Operand(ExternalReference(
+               Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
+
+    CEntryStub ceb(masm->isolate(), 1);
+    __ CallStub(&ceb);
+
+    if (FLAG_debug_code) {
+      for (int i = 0; i < kNumJSCallerSaved; i++) {
+        Register reg = {JSCallerSavedCode(i)};
+        __ mov(reg, Operand(kDebugZapValue));
+      }
+    }
+
+    if (mode == SAVE_RESULT_REGISTER) __ pop(r3);
+
+    // Don't bother removing padding bytes pushed on the stack
+    // as the frame is going to be restored right away.
+
+    // Leave the internal frame.
+  }
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ mov(ip, Operand(after_break_target));
+  __ LoadP(ip, MemOperand(ip));
+  __ JumpToJSEntry(ip);
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  __ Ret();
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  __ mov(ip, Operand(restarter_frame_function_slot));
+  __ li(r4, Operand::Zero());
+  __ StoreP(r4, MemOperand(ip, 0));
+
+  // Load the function pointer off of our current stack frame.
+  __ LoadP(r4, MemOperand(fp, StandardFrameConstants::kConstantPoolOffset -
+                                  kPointerSize));
+
+  // Pop return address and frame
+  __ LeaveFrame(StackFrame::INTERNAL);
+
+  // Load context from the function.
+  __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+
+  // Get function code.
+  __ LoadP(ip, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadP(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset));
+  __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
+
+  // Re-run JSFunction, r4 is function, cp is context.
+  __ Jump(ip);
+}
+
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+#undef __
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/debug/x64/debug-x64.cc b/src/debug/x64/debug-x64.cc
new file mode 100644 (file)
index 0000000..6cb653d
--- /dev/null
@@ -0,0 +1,148 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_X64
+
+#include "src/assembler.h"
+#include "src/codegen.h"
+#include "src/debug/debug.h"
+
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void EmitDebugBreakSlot(MacroAssembler* masm) {
+  Label check_codesize;
+  __ bind(&check_codesize);
+  __ Nop(Assembler::kDebugBreakSlotLength);
+  DCHECK_EQ(Assembler::kDebugBreakSlotLength,
+            masm->SizeOfCodeGeneratedSince(&check_codesize));
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                                int call_argc) {
+  // Generate enough nop's to make space for a call instruction.
+  masm->RecordDebugBreakSlot(mode, call_argc);
+  EmitDebugBreakSlot(masm);
+}
+
+
+void DebugCodegen::ClearDebugBreakSlot(Address pc) {
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotLength);
+  EmitDebugBreakSlot(patcher.masm());
+}
+
+
+void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
+  DCHECK_EQ(Code::BUILTIN, code->kind());
+  static const int kSize = Assembler::kDebugBreakSlotLength;
+  CodePatcher patcher(pc, kSize);
+  Label check_codesize;
+  patcher.masm()->bind(&check_codesize);
+  patcher.masm()->movp(kScratchRegister, reinterpret_cast<void*>(code->entry()),
+                       Assembler::RelocInfoNone());
+  patcher.masm()->call(kScratchRegister);
+  // Check that the size of the code generated is as expected.
+  DCHECK_EQ(kSize, patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
+}
+
+
+void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
+                                          DebugBreakCallHelperMode mode) {
+  __ RecordComment("Debug break");
+
+  // Enter an internal frame.
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
+      __ Push(Smi::FromInt(LiveEdit::kFramePaddingValue));
+    }
+    __ Push(Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
+
+    if (mode == SAVE_RESULT_REGISTER) __ Push(rax);
+
+    __ Set(rax, 0);  // No arguments (argc == 0).
+    __ Move(rbx, ExternalReference(Runtime::FunctionForId(Runtime::kDebugBreak),
+                                   masm->isolate()));
+
+    CEntryStub ceb(masm->isolate(), 1);
+    __ CallStub(&ceb);
+
+    if (FLAG_debug_code) {
+      for (int i = 0; i < kNumJSCallerSaved; ++i) {
+        Register reg = {JSCallerSavedCode(i)};
+        __ Set(reg, kDebugZapValue);
+      }
+    }
+
+    if (mode == SAVE_RESULT_REGISTER) __ Pop(rax);
+
+    // Read current padding counter and skip corresponding number of words.
+    __ Pop(kScratchRegister);
+    __ SmiToInteger32(kScratchRegister, kScratchRegister);
+    __ leap(rsp, Operand(rsp, kScratchRegister, times_pointer_size, 0));
+
+    // Get rid of the internal frame.
+  }
+
+  // This call did not replace a call , so there will be an unwanted
+  // return address left on the stack. Here we get rid of that.
+  __ addp(rsp, Immediate(kPCOnStackSize));
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ Move(kScratchRegister, after_break_target);
+  __ Jump(Operand(kScratchRegister, 0));
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  masm->ret(0);
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  __ Move(rax, restarter_frame_function_slot);
+  __ movp(Operand(rax, 0), Immediate(0));
+
+  // We do not know our frame height, but set rsp based on rbp.
+  __ leap(rsp, Operand(rbp, -1 * kPointerSize));
+
+  __ Pop(rdi);  // Function.
+  __ popq(rbp);
+
+  // Load context from the function.
+  __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
+
+  // Get function code.
+  __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+  __ movp(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
+  __ leap(rdx, FieldOperand(rdx, Code::kHeaderSize));
+
+  // Re-run JSFunction, rdi is function, rsi is context.
+  __ jmp(rdx);
+}
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+#undef __
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_X64
diff --git a/src/debug/x87/OWNERS b/src/debug/x87/OWNERS
new file mode 100644 (file)
index 0000000..dd9998b
--- /dev/null
@@ -0,0 +1 @@
+weiliang.lin@intel.com
diff --git a/src/debug/x87/debug-x87.cc b/src/debug/x87/debug-x87.cc
new file mode 100644 (file)
index 0000000..f0e39af
--- /dev/null
@@ -0,0 +1,147 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_X87
+
+#include "src/codegen.h"
+#include "src/debug/debug.h"
+
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void EmitDebugBreakSlot(MacroAssembler* masm) {
+  Label check_codesize;
+  __ bind(&check_codesize);
+  __ Nop(Assembler::kDebugBreakSlotLength);
+  DCHECK_EQ(Assembler::kDebugBreakSlotLength,
+            masm->SizeOfCodeGeneratedSince(&check_codesize));
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
+                                int call_argc) {
+  // Generate enough nop's to make space for a call instruction.
+  masm->RecordDebugBreakSlot(mode, call_argc);
+  EmitDebugBreakSlot(masm);
+}
+
+
+void DebugCodegen::ClearDebugBreakSlot(Address pc) {
+  CodePatcher patcher(pc, Assembler::kDebugBreakSlotLength);
+  EmitDebugBreakSlot(patcher.masm());
+}
+
+
+void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
+  DCHECK_EQ(Code::BUILTIN, code->kind());
+  static const int kSize = Assembler::kDebugBreakSlotLength;
+  CodePatcher patcher(pc, kSize);
+
+  // Add a label for checking the size of the code used for returning.
+  Label check_codesize;
+  patcher.masm()->bind(&check_codesize);
+  patcher.masm()->call(code->entry(), RelocInfo::NONE32);
+  // Check that the size of the code generated is as expected.
+  DCHECK_EQ(kSize, patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
+}
+
+
+void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
+                                          DebugBreakCallHelperMode mode) {
+  __ RecordComment("Debug break");
+
+  // Enter an internal frame.
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
+      __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue)));
+    }
+    __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
+
+    if (mode == SAVE_RESULT_REGISTER) __ push(eax);
+
+    __ Move(eax, Immediate(0));  // No arguments.
+    __ mov(ebx,
+           Immediate(ExternalReference(
+               Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
+
+    CEntryStub ceb(masm->isolate(), 1);
+    __ CallStub(&ceb);
+
+    if (FLAG_debug_code) {
+      for (int i = 0; i < kNumJSCallerSaved; ++i) {
+        Register reg = {JSCallerSavedCode(i)};
+        __ Move(reg, Immediate(kDebugZapValue));
+      }
+    }
+
+    if (mode == SAVE_RESULT_REGISTER) __ pop(eax);
+
+    __ pop(ebx);
+    // We divide stored value by 2 (untagging) and multiply it by word's size.
+    STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0);
+    __ lea(esp, Operand(esp, ebx, times_half_pointer_size, 0));
+
+    // Get rid of the internal frame.
+  }
+
+  // This call did not replace a call , so there will be an unwanted
+  // return address left on the stack. Here we get rid of that.
+  __ add(esp, Immediate(kPointerSize));
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ jmp(Operand::StaticVariable(after_break_target));
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  masm->ret(0);
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
+
+  // We do not know our frame height, but set esp based on ebp.
+  __ lea(esp, Operand(ebp, -1 * kPointerSize));
+
+  __ pop(edi);  // Function.
+  __ pop(ebp);
+
+  // Load context from the function.
+  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
+
+  // Get function code.
+  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+  __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
+  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
+
+  // Re-run JSFunction, edi is function, esi is context.
+  __ jmp(edx);
+}
+
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+#undef __
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_X87
index 8d77d226deb7947df00f2212d210bf12a724911b..2f6e67ce25728568f626c73dfb85518a9701892e 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "src/code-stubs.h"
 #include "src/codegen.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
index 43d9aed55bc5d93182db7252e1bf4d914dfe1d3f..a4d017e0119e4e0a6ce0a480214eeb4169d42244 100644 (file)
@@ -10,7 +10,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ic/ic.h"
 #include "src/parser.h"
index 1465731ec43af1ddc747a83c20f4bb999b33ef07..205af1e092aeeadbe4beff5f6a5175c0604039c8 100644 (file)
@@ -10,7 +10,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ic/ic.h"
 #include "src/parser.h"
index 137b2463e80888b78bba7650efa2f82007584be6..4c7df3fe4890e669ab478a8bd95eadb7346dbbb2 100644 (file)
@@ -9,9 +9,9 @@
 #include "src/code-factory.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
+#include "src/debug/liveedit.h"
 #include "src/full-codegen/full-codegen.h"
-#include "src/liveedit.h"
 #include "src/macro-assembler.h"
 #include "src/prettyprinter.h"
 #include "src/scopeinfo.h"
index 67998c012e5e60d3c8d113c16d54f13000a7386e..93f11ccd63e4e0681a15d172bf1aedd970c69df2 100644 (file)
@@ -10,7 +10,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ic/ic.h"
 #include "src/parser.h"
index bf526280a6f29c633f0bcb7b03156ee881876eb6..62bc93576b001501e41be6ce3d068293f719fcc8 100644 (file)
@@ -18,7 +18,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ic/ic.h"
 #include "src/parser.h"
index bcec8b1fe62237b6457f482957a427b7f564486d..21426b78dcf2c3e4c2dcdef76b46b8b1e523f94e 100644 (file)
@@ -18,7 +18,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ic/ic.h"
 #include "src/parser.h"
index 904b0106c747d446ccbde2c3829048b0f514436f..7a754df0b57e239fe71a917709c1e9a560352e5c 100644 (file)
@@ -10,7 +10,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ic/ic.h"
 #include "src/parser.h"
index 6fe3062f2ebe72176d6a364ae061949449d39725..d8c60ad445fb89c6698e9ab0f9886fdaf8002a82 100644 (file)
@@ -10,7 +10,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ic/ic.h"
 #include "src/parser.h"
index 88ac788be49dc301f410d8cbc41e0efa4863e701..d4ef7018d6cc354d907a1add3eeef6c75e42979e 100644 (file)
@@ -10,7 +10,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ic/ic.h"
 #include "src/parser.h"
index 34936fb8e8f72dfb43e4c2562d76f57560e7a8f9..693361ce0443486891798f1caca4b9e4d8440ba6 100644 (file)
@@ -9,7 +9,7 @@
 #include "src/allocation-tracker.h"
 #include "src/code-stubs.h"
 #include "src/conversions.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/heap-profiler.h"
 #include "src/types.h"
 
index 49c327be29557ee33e59bc040ba6ea61bdd4bab7..45c35859fadd9c2d40f21a8288b7fb32e32bfd5b 100644 (file)
@@ -14,7 +14,7 @@
 #include "src/compilation-cache.h"
 #include "src/conversions.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/global-handles.h"
 #include "src/heap/gc-idle-time-handler.h"
index e70f2eed2c638df308ebf23d422e3a4941e09252..70b7a6727bdf3aadeb7be819a60cad7937a6676c 100644 (file)
@@ -40,7 +40,7 @@
 #include "src/ia32/assembler-ia32.h"
 
 #include "src/assembler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc
deleted file mode 100644 (file)
index 345ad3d..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#if V8_TARGET_ARCH_IA32
-
-#include "src/codegen.h"
-#include "src/debug.h"
-
-
-namespace v8 {
-namespace internal {
-
-#define __ ACCESS_MASM(masm)
-
-
-void EmitDebugBreakSlot(MacroAssembler* masm) {
-  Label check_codesize;
-  __ bind(&check_codesize);
-  __ Nop(Assembler::kDebugBreakSlotLength);
-  DCHECK_EQ(Assembler::kDebugBreakSlotLength,
-            masm->SizeOfCodeGeneratedSince(&check_codesize));
-}
-
-
-void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                                int call_argc) {
-  // Generate enough nop's to make space for a call instruction.
-  masm->RecordDebugBreakSlot(mode, call_argc);
-  EmitDebugBreakSlot(masm);
-}
-
-
-void DebugCodegen::ClearDebugBreakSlot(Address pc) {
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotLength);
-  EmitDebugBreakSlot(patcher.masm());
-}
-
-
-void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
-  DCHECK_EQ(Code::BUILTIN, code->kind());
-  static const int kSize = Assembler::kDebugBreakSlotLength;
-  CodePatcher patcher(pc, kSize);
-
-  // Add a label for checking the size of the code used for returning.
-  Label check_codesize;
-  patcher.masm()->bind(&check_codesize);
-  patcher.masm()->call(code->entry(), RelocInfo::NONE32);
-  // Check that the size of the code generated is as expected.
-  DCHECK_EQ(kSize, patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
-}
-
-
-void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
-                                          DebugBreakCallHelperMode mode) {
-  __ RecordComment("Debug break");
-
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Load padding words on stack.
-    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
-      __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue)));
-    }
-    __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
-
-    if (mode == SAVE_RESULT_REGISTER) __ push(eax);
-
-    __ Move(eax, Immediate(0));  // No arguments.
-    __ mov(ebx,
-           Immediate(ExternalReference(
-               Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
-
-    CEntryStub ceb(masm->isolate(), 1);
-    __ CallStub(&ceb);
-
-    if (FLAG_debug_code) {
-      for (int i = 0; i < kNumJSCallerSaved; ++i) {
-        Register reg = {JSCallerSavedCode(i)};
-        __ Move(reg, Immediate(kDebugZapValue));
-      }
-    }
-
-    if (mode == SAVE_RESULT_REGISTER) __ pop(eax);
-
-    __ pop(ebx);
-    // We divide stored value by 2 (untagging) and multiply it by word's size.
-    STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0);
-    __ lea(esp, Operand(esp, ebx, times_half_pointer_size, 0));
-
-    // Get rid of the internal frame.
-  }
-
-  // This call did not replace a call , so there will be an unwanted
-  // return address left on the stack. Here we get rid of that.
-  __ add(esp, Immediate(kPointerSize));
-
-  // Now that the break point has been handled, resume normal execution by
-  // jumping to the target address intended by the caller and that was
-  // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target =
-      ExternalReference::debug_after_break_target_address(masm->isolate());
-  __ jmp(Operand::StaticVariable(after_break_target));
-}
-
-
-void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
-  masm->ret(0);
-}
-
-
-void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
-  ExternalReference restarter_frame_function_slot =
-      ExternalReference::debug_restarter_frame_function_pointer_address(
-          masm->isolate());
-  __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
-
-  // We do not know our frame height, but set esp based on ebp.
-  __ lea(esp, Operand(ebp, -1 * kPointerSize));
-
-  __ pop(edi);  // Function.
-  __ pop(ebp);
-
-  // Load context from the function.
-  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-
-  // Get function code.
-  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
-  __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
-  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
-
-  // Re-run JSFunction, edi is function, esi is context.
-  __ jmp(edx);
-}
-
-
-const bool LiveEdit::kFrameDropperSupported = true;
-
-#undef __
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TARGET_ARCH_IA32
index 4648c5f7ae6fc1af91583a498d9b4dac9321ce13..5e62cd1acab7bef759537a68042e0b52e963cc1f 100644 (file)
@@ -11,7 +11,7 @@
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
index 85c6edb13f8bc90171f92cefca2509350ecafd74..f123595dd14e7417af7a916951760987ee0094b8 100644 (file)
@@ -8,7 +8,7 @@
 #include "src/ic/ic.h"
 
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/macro-assembler.h"
 #include "src/prototype.h"
 
index aa67185e26fda26d87447525921694c4f7bad6ae..f7916ed7fc5baecba2bdb5152b93991d21c4252a 100644 (file)
@@ -19,7 +19,7 @@
 #include "src/compilation-cache.h"
 #include "src/compilation-statistics.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/heap/spaces.h"
 #include "src/heap-profiler.h"
diff --git a/src/liveedit-debugger.js b/src/liveedit-debugger.js
deleted file mode 100644 (file)
index af7712d..0000000
+++ /dev/null
@@ -1,1107 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// LiveEdit feature implementation. The script should be executed after
-// debug-debugger.js.
-
-// A LiveEdit namespace. It contains functions that modifies JavaScript code
-// according to changes of script source (if possible).
-//
-// When new script source is put in, the difference is calculated textually,
-// in form of list of delete/add/change chunks. The functions that include
-// change chunk(s) get recompiled, or their enclosing functions are
-// recompiled instead.
-// If the function may not be recompiled (e.g. it was completely erased in new
-// version of the script) it remains unchanged, but the code that could
-// create a new instance of this function goes away. An old version of script
-// is created to back up this obsolete function.
-// All unchanged functions have their positions updated accordingly.
-//
-// LiveEdit namespace is declared inside a single function constructor.
-
-"use strict";
-
-Debug.LiveEdit = new function() {
-
-  // Forward declaration for minifier.
-  var FunctionStatus;
-
-  // Applies the change to the script.
-  // The change is in form of list of chunks encoded in a single array as
-  // a series of triplets (pos1_start, pos1_end, pos2_end)
-  function ApplyPatchMultiChunk(script, diff_array, new_source, preview_only,
-      change_log) {
-
-    var old_source = script.source;
-
-    // Gather compile information about old version of script.
-    var old_compile_info = GatherCompileInfo(old_source, script);
-
-    // Build tree structures for old and new versions of the script.
-    var root_old_node = BuildCodeInfoTree(old_compile_info);
-
-    var pos_translator = new PosTranslator(diff_array);
-
-    // Analyze changes.
-    MarkChangedFunctions(root_old_node, pos_translator.GetChunks());
-
-    // Find all SharedFunctionInfo's that were compiled from this script.
-    FindLiveSharedInfos(root_old_node, script);
-
-    // Gather compile information about new version of script.
-    var new_compile_info;
-    try {
-      new_compile_info = GatherCompileInfo(new_source, script);
-    } catch (e) {
-      var failure =
-          new Failure("Failed to compile new version of script: " + e);
-      if (e instanceof SyntaxError) {
-        var details = {
-          type: "liveedit_compile_error",
-          syntaxErrorMessage: e.message
-        };
-        CopyErrorPositionToDetails(e, details);
-        failure.details = details;
-      }
-      throw failure;
-    }
-    var root_new_node = BuildCodeInfoTree(new_compile_info);
-
-    // Link recompiled script data with other data.
-    FindCorrespondingFunctions(root_old_node, root_new_node);
-
-    // Prepare to-do lists.
-    var replace_code_list = new Array();
-    var link_to_old_script_list = new Array();
-    var link_to_original_script_list = new Array();
-    var update_positions_list = new Array();
-
-    function HarvestTodo(old_node) {
-      function CollectDamaged(node) {
-        link_to_old_script_list.push(node);
-        for (var i = 0; i < node.children.length; i++) {
-          CollectDamaged(node.children[i]);
-        }
-      }
-
-      // Recursively collects all newly compiled functions that are going into
-      // business and should have link to the actual script updated.
-      function CollectNew(node_list) {
-        for (var i = 0; i < node_list.length; i++) {
-          link_to_original_script_list.push(node_list[i]);
-          CollectNew(node_list[i].children);
-        }
-      }
-
-      if (old_node.status == FunctionStatus.DAMAGED) {
-        CollectDamaged(old_node);
-        return;
-      }
-      if (old_node.status == FunctionStatus.UNCHANGED) {
-        update_positions_list.push(old_node);
-      } else if (old_node.status == FunctionStatus.SOURCE_CHANGED) {
-        update_positions_list.push(old_node);
-      } else if (old_node.status == FunctionStatus.CHANGED) {
-        replace_code_list.push(old_node);
-        CollectNew(old_node.unmatched_new_nodes);
-      }
-      for (var i = 0; i < old_node.children.length; i++) {
-        HarvestTodo(old_node.children[i]);
-      }
-    }
-
-    var preview_description = {
-        change_tree: DescribeChangeTree(root_old_node),
-        textual_diff: {
-          old_len: old_source.length,
-          new_len: new_source.length,
-          chunks: diff_array
-        },
-        updated: false
-    };
-
-    if (preview_only) {
-      return preview_description;
-    }
-
-    HarvestTodo(root_old_node);
-
-    // Collect shared infos for functions whose code need to be patched.
-    var replaced_function_infos = new Array();
-    for (var i = 0; i < replace_code_list.length; i++) {
-      var live_shared_function_infos =
-          replace_code_list[i].live_shared_function_infos;
-
-      if (live_shared_function_infos) {
-        for (var j = 0; j < live_shared_function_infos.length; j++) {
-          replaced_function_infos.push(live_shared_function_infos[j]);
-        }
-      }
-    }
-
-    // We haven't changed anything before this line yet.
-    // Committing all changes.
-
-    // Check that function being patched is not currently on stack or drop them.
-    var dropped_functions_number =
-        CheckStackActivations(replaced_function_infos, change_log);
-
-    // Our current implementation requires client to manually issue "step in"
-    // command for correct stack state if the stack was modified.
-    preview_description.stack_modified = dropped_functions_number != 0;
-
-    // Start with breakpoints. Convert their line/column positions and
-    // temporary remove.
-    var break_points_restorer = TemporaryRemoveBreakPoints(script, change_log);
-
-    var old_script;
-
-    // Create an old script only if there are function that should be linked
-    // to old version.
-    if (link_to_old_script_list.length == 0) {
-      %LiveEditReplaceScript(script, new_source, null);
-      old_script = UNDEFINED;
-    } else {
-      var old_script_name = CreateNameForOldScript(script);
-
-      // Update the script text and create a new script representing an old
-      // version of the script.
-      old_script = %LiveEditReplaceScript(script, new_source,
-          old_script_name);
-
-      var link_to_old_script_report = new Array();
-      change_log.push( { linked_to_old_script: link_to_old_script_report } );
-
-      // We need to link to old script all former nested functions.
-      for (var i = 0; i < link_to_old_script_list.length; i++) {
-        LinkToOldScript(link_to_old_script_list[i], old_script,
-            link_to_old_script_report);
-      }
-
-      preview_description.created_script_name = old_script_name;
-    }
-
-    // Link to an actual script all the functions that we are going to use.
-    for (var i = 0; i < link_to_original_script_list.length; i++) {
-      %LiveEditFunctionSetScript(
-          link_to_original_script_list[i].info.shared_function_info, script);
-    }
-
-    for (var i = 0; i < replace_code_list.length; i++) {
-      PatchFunctionCode(replace_code_list[i], change_log);
-    }
-
-    var position_patch_report = new Array();
-    change_log.push( {position_patched: position_patch_report} );
-
-    for (var i = 0; i < update_positions_list.length; i++) {
-      // TODO(LiveEdit): take into account whether it's source_changed or
-      // unchanged and whether positions changed at all.
-      PatchPositions(update_positions_list[i], diff_array,
-          position_patch_report);
-
-      if (update_positions_list[i].live_shared_function_infos) {
-        update_positions_list[i].live_shared_function_infos.
-            forEach(function (info) {
-                %LiveEditFunctionSourceUpdated(info.raw_array);
-              });
-      }
-    }
-
-    break_points_restorer(pos_translator, old_script);
-
-    preview_description.updated = true;
-    return preview_description;
-  }
-  // Function is public.
-  this.ApplyPatchMultiChunk = ApplyPatchMultiChunk;
-
-
-  // Fully compiles source string as a script. Returns Array of
-  // FunctionCompileInfo -- a descriptions of all functions of the script.
-  // Elements of array are ordered by start positions of functions (from top
-  // to bottom) in the source. Fields outer_index and next_sibling_index help
-  // to navigate the nesting structure of functions.
-  //
-  // All functions get compiled linked to script provided as parameter script.
-  // TODO(LiveEdit): consider not using actual scripts as script, because
-  // we have to manually erase all links right after compile.
-  function GatherCompileInfo(source, script) {
-    // Get function info, elements are partially sorted (it is a tree of
-    // nested functions serialized as parent followed by serialized children.
-    var raw_compile_info = %LiveEditGatherCompileInfo(script, source);
-
-    // Sort function infos by start position field.
-    var compile_info = new Array();
-    var old_index_map = new Array();
-    for (var i = 0; i < raw_compile_info.length; i++) {
-      var info = new FunctionCompileInfo(raw_compile_info[i]);
-      // Remove all links to the actual script. Breakpoints system and
-      // LiveEdit itself believe that any function in heap that points to a
-      // particular script is a regular function.
-      // For some functions we will restore this link later.
-      %LiveEditFunctionSetScript(info.shared_function_info, UNDEFINED);
-      compile_info.push(info);
-      old_index_map.push(i);
-    }
-
-    for (var i = 0; i < compile_info.length; i++) {
-      var k = i;
-      for (var j = i + 1; j < compile_info.length; j++) {
-        if (compile_info[k].start_position > compile_info[j].start_position) {
-          k = j;
-        }
-      }
-      if (k != i) {
-        var temp_info = compile_info[k];
-        var temp_index = old_index_map[k];
-        compile_info[k] = compile_info[i];
-        old_index_map[k] = old_index_map[i];
-        compile_info[i] = temp_info;
-        old_index_map[i] = temp_index;
-      }
-    }
-
-    // After sorting update outer_index field using old_index_map. Also
-    // set next_sibling_index field.
-    var current_index = 0;
-
-    // The recursive function, that goes over all children of a particular
-    // node (i.e. function info).
-    function ResetIndexes(new_parent_index, old_parent_index) {
-      var previous_sibling = -1;
-      while (current_index < compile_info.length &&
-          compile_info[current_index].outer_index == old_parent_index) {
-        var saved_index = current_index;
-        compile_info[saved_index].outer_index = new_parent_index;
-        if (previous_sibling != -1) {
-          compile_info[previous_sibling].next_sibling_index = saved_index;
-        }
-        previous_sibling = saved_index;
-        current_index++;
-        ResetIndexes(saved_index, old_index_map[saved_index]);
-      }
-      if (previous_sibling != -1) {
-        compile_info[previous_sibling].next_sibling_index = -1;
-      }
-    }
-
-    ResetIndexes(-1, -1);
-    Assert(current_index == compile_info.length);
-
-    return compile_info;
-  }
-
-
-  // Replaces function's Code.
-  function PatchFunctionCode(old_node, change_log) {
-    var new_info = old_node.corresponding_node.info;
-    if (old_node.live_shared_function_infos) {
-      old_node.live_shared_function_infos.forEach(function (old_info) {
-        %LiveEditReplaceFunctionCode(new_info.raw_array,
-                                     old_info.raw_array);
-
-        // The function got a new code. However, this new code brings all new
-        // instances of SharedFunctionInfo for nested functions. However,
-        // we want the original instances to be used wherever possible.
-        // (This is because old instances and new instances will be both
-        // linked to a script and breakpoints subsystem does not really
-        // expects this; neither does LiveEdit subsystem on next call).
-        for (var i = 0; i < old_node.children.length; i++) {
-          if (old_node.children[i].corresponding_node) {
-            var corresponding_child_info =
-                old_node.children[i].corresponding_node.info.
-                    shared_function_info;
-
-            if (old_node.children[i].live_shared_function_infos) {
-              old_node.children[i].live_shared_function_infos.
-                  forEach(function (old_child_info) {
-                    %LiveEditReplaceRefToNestedFunction(
-                        old_info.info,
-                        corresponding_child_info,
-                        old_child_info.info);
-                  });
-            }
-          }
-        }
-      });
-
-      change_log.push( {function_patched: new_info.function_name} );
-    } else {
-      change_log.push( {function_patched: new_info.function_name,
-          function_info_not_found: true} );
-    }
-  }
-
-
-  // Makes a function associated with another instance of a script (the
-  // one representing its old version). This way the function still
-  // may access its own text.
-  function LinkToOldScript(old_info_node, old_script, report_array) {
-    if (old_info_node.live_shared_function_infos) {
-      old_info_node.live_shared_function_infos.
-          forEach(function (info) {
-            %LiveEditFunctionSetScript(info.info, old_script);
-          });
-
-      report_array.push( { name: old_info_node.info.function_name } );
-    } else {
-      report_array.push(
-          { name: old_info_node.info.function_name, not_found: true } );
-    }
-  }
-
-
-  // Returns function that restores breakpoints.
-  function TemporaryRemoveBreakPoints(original_script, change_log) {
-    var script_break_points = GetScriptBreakPoints(original_script);
-
-    var break_points_update_report = [];
-    change_log.push( { break_points_update: break_points_update_report } );
-
-    var break_point_old_positions = [];
-    for (var i = 0; i < script_break_points.length; i++) {
-      var break_point = script_break_points[i];
-
-      break_point.clear();
-
-      // TODO(LiveEdit): be careful with resource offset here.
-      var break_point_position = Debug.findScriptSourcePosition(original_script,
-          break_point.line(), break_point.column());
-
-      var old_position_description = {
-          position: break_point_position,
-          line: break_point.line(),
-          column: break_point.column()
-      };
-      break_point_old_positions.push(old_position_description);
-    }
-
-
-    // Restores breakpoints and creates their copies in the "old" copy of
-    // the script.
-    return function (pos_translator, old_script_copy_opt) {
-      // Update breakpoints (change positions and restore them in old version
-      // of script.
-      for (var i = 0; i < script_break_points.length; i++) {
-        var break_point = script_break_points[i];
-        if (old_script_copy_opt) {
-          var clone = break_point.cloneForOtherScript(old_script_copy_opt);
-          clone.set(old_script_copy_opt);
-
-          break_points_update_report.push( {
-            type: "copied_to_old",
-            id: break_point.number(),
-            new_id: clone.number(),
-            positions: break_point_old_positions[i]
-            } );
-        }
-
-        var updated_position = pos_translator.Translate(
-            break_point_old_positions[i].position,
-            PosTranslator.ShiftWithTopInsideChunkHandler);
-
-        var new_location =
-            original_script.locationFromPosition(updated_position, false);
-
-        break_point.update_positions(new_location.line, new_location.column);
-
-        var new_position_description = {
-            position: updated_position,
-            line: new_location.line,
-            column: new_location.column
-        };
-
-        break_point.set(original_script);
-
-        break_points_update_report.push( { type: "position_changed",
-          id: break_point.number(),
-          old_positions: break_point_old_positions[i],
-          new_positions: new_position_description
-          } );
-      }
-    };
-  }
-
-
-  function Assert(condition, message) {
-    if (!condition) {
-      if (message) {
-        throw "Assert " + message;
-      } else {
-        throw "Assert";
-      }
-    }
-  }
-
-  function DiffChunk(pos1, pos2, len1, len2) {
-    this.pos1 = pos1;
-    this.pos2 = pos2;
-    this.len1 = len1;
-    this.len2 = len2;
-  }
-
-  function PosTranslator(diff_array) {
-    var chunks = new Array();
-    var current_diff = 0;
-    for (var i = 0; i < diff_array.length; i += 3) {
-      var pos1_begin = diff_array[i];
-      var pos2_begin = pos1_begin + current_diff;
-      var pos1_end = diff_array[i + 1];
-      var pos2_end = diff_array[i + 2];
-      chunks.push(new DiffChunk(pos1_begin, pos2_begin, pos1_end - pos1_begin,
-          pos2_end - pos2_begin));
-      current_diff = pos2_end - pos1_end;
-    }
-    this.chunks = chunks;
-  }
-  PosTranslator.prototype.GetChunks = function() {
-    return this.chunks;
-  };
-
-  PosTranslator.prototype.Translate = function(pos, inside_chunk_handler) {
-    var array = this.chunks;
-    if (array.length == 0 || pos < array[0].pos1) {
-      return pos;
-    }
-    var chunk_index1 = 0;
-    var chunk_index2 = array.length - 1;
-
-    while (chunk_index1 < chunk_index2) {
-      var middle_index = Math.floor((chunk_index1 + chunk_index2) / 2);
-      if (pos < array[middle_index + 1].pos1) {
-        chunk_index2 = middle_index;
-      } else {
-        chunk_index1 = middle_index + 1;
-      }
-    }
-    var chunk = array[chunk_index1];
-    if (pos >= chunk.pos1 + chunk.len1) {
-      return pos + chunk.pos2 + chunk.len2 - chunk.pos1 - chunk.len1;
-    }
-
-    if (!inside_chunk_handler) {
-      inside_chunk_handler = PosTranslator.DefaultInsideChunkHandler;
-    }
-    return inside_chunk_handler(pos, chunk);
-  };
-
-  PosTranslator.DefaultInsideChunkHandler = function(pos, diff_chunk) {
-    Assert(false, "Cannot translate position in changed area");
-  };
-
-  PosTranslator.ShiftWithTopInsideChunkHandler =
-      function(pos, diff_chunk) {
-    // We carelessly do not check whether we stay inside the chunk after
-    // translation.
-    return pos - diff_chunk.pos1 + diff_chunk.pos2;
-  };
-
-  var FunctionStatus = {
-      // No change to function or its inner functions; however its positions
-      // in script may have been shifted.
-      UNCHANGED: "unchanged",
-      // The code of a function remains unchanged, but something happened inside
-      // some inner functions.
-      SOURCE_CHANGED: "source changed",
-      // The code of a function is changed or some nested function cannot be
-      // properly patched so this function must be recompiled.
-      CHANGED: "changed",
-      // Function is changed but cannot be patched.
-      DAMAGED: "damaged"
-  };
-
-  function CodeInfoTreeNode(code_info, children, array_index) {
-    this.info = code_info;
-    this.children = children;
-    // an index in array of compile_info
-    this.array_index = array_index;
-    this.parent = UNDEFINED;
-
-    this.status = FunctionStatus.UNCHANGED;
-    // Status explanation is used for debugging purposes and will be shown
-    // in user UI if some explanations are needed.
-    this.status_explanation = UNDEFINED;
-    this.new_start_pos = UNDEFINED;
-    this.new_end_pos = UNDEFINED;
-    this.corresponding_node = UNDEFINED;
-    this.unmatched_new_nodes = UNDEFINED;
-
-    // 'Textual' correspondence/matching is weaker than 'pure'
-    // correspondence/matching. We need 'textual' level for visual presentation
-    // in UI, we use 'pure' level for actual code manipulation.
-    // Sometimes only function body is changed (functions in old and new script
-    // textually correspond), but we cannot patch the code, so we see them
-    // as an old function deleted and new function created.
-    this.textual_corresponding_node = UNDEFINED;
-    this.textually_unmatched_new_nodes = UNDEFINED;
-
-    this.live_shared_function_infos = UNDEFINED;
-  }
-
-  // From array of function infos that is implicitly a tree creates
-  // an actual tree of functions in script.
-  function BuildCodeInfoTree(code_info_array) {
-    // Throughtout all function we iterate over input array.
-    var index = 0;
-
-    // Recursive function that builds a branch of tree.
-    function BuildNode() {
-      var my_index = index;
-      index++;
-      var child_array = new Array();
-      while (index < code_info_array.length &&
-          code_info_array[index].outer_index == my_index) {
-        child_array.push(BuildNode());
-      }
-      var node = new CodeInfoTreeNode(code_info_array[my_index], child_array,
-          my_index);
-      for (var i = 0; i < child_array.length; i++) {
-        child_array[i].parent = node;
-      }
-      return node;
-    }
-
-    var root = BuildNode();
-    Assert(index == code_info_array.length);
-    return root;
-  }
-
-  // Applies a list of the textual diff chunks onto the tree of functions.
-  // Determines status of each function (from unchanged to damaged). However
-  // children of unchanged functions are ignored.
-  function MarkChangedFunctions(code_info_tree, chunks) {
-
-    // A convenient iterator over diff chunks that also translates
-    // positions from old to new in a current non-changed part of script.
-    var chunk_it = new function() {
-      var chunk_index = 0;
-      var pos_diff = 0;
-      this.current = function() { return chunks[chunk_index]; };
-      this.next = function() {
-        var chunk = chunks[chunk_index];
-        pos_diff = chunk.pos2 + chunk.len2 - (chunk.pos1 + chunk.len1);
-        chunk_index++;
-      };
-      this.done = function() { return chunk_index >= chunks.length; };
-      this.TranslatePos = function(pos) { return pos + pos_diff; };
-    };
-
-    // A recursive function that processes internals of a function and all its
-    // inner functions. Iterator chunk_it initially points to a chunk that is
-    // below function start.
-    function ProcessInternals(info_node) {
-      info_node.new_start_pos = chunk_it.TranslatePos(
-          info_node.info.start_position);
-      var child_index = 0;
-      var code_changed = false;
-      var source_changed = false;
-      // Simultaneously iterates over child functions and over chunks.
-      while (!chunk_it.done() &&
-          chunk_it.current().pos1 < info_node.info.end_position) {
-        if (child_index < info_node.children.length) {
-          var child = info_node.children[child_index];
-
-          if (child.info.end_position <= chunk_it.current().pos1) {
-            ProcessUnchangedChild(child);
-            child_index++;
-            continue;
-          } else if (child.info.start_position >=
-              chunk_it.current().pos1 + chunk_it.current().len1) {
-            code_changed = true;
-            chunk_it.next();
-            continue;
-          } else if (child.info.start_position <= chunk_it.current().pos1 &&
-              child.info.end_position >= chunk_it.current().pos1 +
-              chunk_it.current().len1) {
-            ProcessInternals(child);
-            source_changed = source_changed ||
-                ( child.status != FunctionStatus.UNCHANGED );
-            code_changed = code_changed ||
-                ( child.status == FunctionStatus.DAMAGED );
-            child_index++;
-            continue;
-          } else {
-            code_changed = true;
-            child.status = FunctionStatus.DAMAGED;
-            child.status_explanation =
-                "Text diff overlaps with function boundary";
-            child_index++;
-            continue;
-          }
-        } else {
-          if (chunk_it.current().pos1 + chunk_it.current().len1 <=
-              info_node.info.end_position) {
-            info_node.status = FunctionStatus.CHANGED;
-            chunk_it.next();
-            continue;
-          } else {
-            info_node.status = FunctionStatus.DAMAGED;
-            info_node.status_explanation =
-                "Text diff overlaps with function boundary";
-            return;
-          }
-        }
-        Assert("Unreachable", false);
-      }
-      while (child_index < info_node.children.length) {
-        var child = info_node.children[child_index];
-        ProcessUnchangedChild(child);
-        child_index++;
-      }
-      if (code_changed) {
-        info_node.status = FunctionStatus.CHANGED;
-      } else if (source_changed) {
-        info_node.status = FunctionStatus.SOURCE_CHANGED;
-      }
-      info_node.new_end_pos =
-          chunk_it.TranslatePos(info_node.info.end_position);
-    }
-
-    function ProcessUnchangedChild(node) {
-      node.new_start_pos = chunk_it.TranslatePos(node.info.start_position);
-      node.new_end_pos = chunk_it.TranslatePos(node.info.end_position);
-    }
-
-    ProcessInternals(code_info_tree);
-  }
-
-  // For each old function (if it is not damaged) tries to find a corresponding
-  // function in new script. Typically it should succeed (non-damaged functions
-  // by definition may only have changes inside their bodies). However there are
-  // reasons for correspondence not to be found; function with unmodified text
-  // in new script may become enclosed into other function; the innocent change
-  // inside function body may in fact be something like "} function B() {" that
-  // splits a function into 2 functions.
-  function FindCorrespondingFunctions(old_code_tree, new_code_tree) {
-
-    // A recursive function that tries to find a correspondence for all
-    // child functions and for their inner functions.
-    function ProcessNode(old_node, new_node) {
-      var scope_change_description =
-          IsFunctionContextLocalsChanged(old_node.info, new_node.info);
-      if (scope_change_description) {
-          old_node.status = FunctionStatus.CHANGED;
-      }
-
-      var old_children = old_node.children;
-      var new_children = new_node.children;
-
-      var unmatched_new_nodes_list = [];
-      var textually_unmatched_new_nodes_list = [];
-
-      var old_index = 0;
-      var new_index = 0;
-      while (old_index < old_children.length) {
-        if (old_children[old_index].status == FunctionStatus.DAMAGED) {
-          old_index++;
-        } else if (new_index < new_children.length) {
-          if (new_children[new_index].info.start_position <
-              old_children[old_index].new_start_pos) {
-            unmatched_new_nodes_list.push(new_children[new_index]);
-            textually_unmatched_new_nodes_list.push(new_children[new_index]);
-            new_index++;
-          } else if (new_children[new_index].info.start_position ==
-              old_children[old_index].new_start_pos) {
-            if (new_children[new_index].info.end_position ==
-                old_children[old_index].new_end_pos) {
-              old_children[old_index].corresponding_node =
-                  new_children[new_index];
-              old_children[old_index].textual_corresponding_node =
-                  new_children[new_index];
-              if (scope_change_description) {
-                old_children[old_index].status = FunctionStatus.DAMAGED;
-                old_children[old_index].status_explanation =
-                    "Enclosing function is now incompatible. " +
-                    scope_change_description;
-                old_children[old_index].corresponding_node = UNDEFINED;
-              } else if (old_children[old_index].status !=
-                  FunctionStatus.UNCHANGED) {
-                ProcessNode(old_children[old_index],
-                    new_children[new_index]);
-                if (old_children[old_index].status == FunctionStatus.DAMAGED) {
-                  unmatched_new_nodes_list.push(
-                      old_children[old_index].corresponding_node);
-                  old_children[old_index].corresponding_node = UNDEFINED;
-                  old_node.status = FunctionStatus.CHANGED;
-                }
-              }
-            } else {
-              old_children[old_index].status = FunctionStatus.DAMAGED;
-              old_children[old_index].status_explanation =
-                  "No corresponding function in new script found";
-              old_node.status = FunctionStatus.CHANGED;
-              unmatched_new_nodes_list.push(new_children[new_index]);
-              textually_unmatched_new_nodes_list.push(new_children[new_index]);
-            }
-            new_index++;
-            old_index++;
-          } else {
-            old_children[old_index].status = FunctionStatus.DAMAGED;
-            old_children[old_index].status_explanation =
-                "No corresponding function in new script found";
-            old_node.status = FunctionStatus.CHANGED;
-            old_index++;
-          }
-        } else {
-          old_children[old_index].status = FunctionStatus.DAMAGED;
-          old_children[old_index].status_explanation =
-              "No corresponding function in new script found";
-          old_node.status = FunctionStatus.CHANGED;
-          old_index++;
-        }
-      }
-
-      while (new_index < new_children.length) {
-        unmatched_new_nodes_list.push(new_children[new_index]);
-        textually_unmatched_new_nodes_list.push(new_children[new_index]);
-        new_index++;
-      }
-
-      if (old_node.status == FunctionStatus.CHANGED) {
-        if (old_node.info.param_num != new_node.info.param_num) {
-          old_node.status = FunctionStatus.DAMAGED;
-          old_node.status_explanation = "Changed parameter number: " +
-              old_node.info.param_num + " and " + new_node.info.param_num;
-        }
-      }
-      old_node.unmatched_new_nodes = unmatched_new_nodes_list;
-      old_node.textually_unmatched_new_nodes =
-          textually_unmatched_new_nodes_list;
-    }
-
-    ProcessNode(old_code_tree, new_code_tree);
-
-    old_code_tree.corresponding_node = new_code_tree;
-    old_code_tree.textual_corresponding_node = new_code_tree;
-
-    Assert(old_code_tree.status != FunctionStatus.DAMAGED,
-        "Script became damaged");
-  }
-
-  function FindLiveSharedInfos(old_code_tree, script) {
-    var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script);
-
-    var shared_infos = new Array();
-
-    for (var i = 0; i < shared_raw_list.length; i++) {
-      shared_infos.push(new SharedInfoWrapper(shared_raw_list[i]));
-    }
-
-    // Finds all SharedFunctionInfos that corresponds to compile info
-    // in old version of the script.
-    function FindFunctionInfos(compile_info) {
-      var wrappers = [];
-
-      for (var i = 0; i < shared_infos.length; i++) {
-        var wrapper = shared_infos[i];
-        if (wrapper.start_position == compile_info.start_position &&
-            wrapper.end_position == compile_info.end_position) {
-          wrappers.push(wrapper);
-        }
-      }
-
-      if (wrappers.length > 0) {
-        return wrappers;
-      }
-    }
-
-    function TraverseTree(node) {
-      node.live_shared_function_infos = FindFunctionInfos(node.info);
-
-      for (var i = 0; i < node.children.length; i++) {
-        TraverseTree(node.children[i]);
-      }
-    }
-
-    TraverseTree(old_code_tree);
-  }
-
-
-  // An object describing function compilation details. Its index fields
-  // apply to indexes inside array that stores these objects.
-  function FunctionCompileInfo(raw_array) {
-    this.function_name = raw_array[0];
-    this.start_position = raw_array[1];
-    this.end_position = raw_array[2];
-    this.param_num = raw_array[3];
-    this.code = raw_array[4];
-    this.code_scope_info = raw_array[5];
-    this.scope_info = raw_array[6];
-    this.outer_index = raw_array[7];
-    this.shared_function_info = raw_array[8];
-    this.next_sibling_index = null;
-    this.raw_array = raw_array;
-  }
-
-  function SharedInfoWrapper(raw_array) {
-    this.function_name = raw_array[0];
-    this.start_position = raw_array[1];
-    this.end_position = raw_array[2];
-    this.info = raw_array[3];
-    this.raw_array = raw_array;
-  }
-
-  // Changes positions (including all statements) in function.
-  function PatchPositions(old_info_node, diff_array, report_array) {
-    if (old_info_node.live_shared_function_infos) {
-      old_info_node.live_shared_function_infos.forEach(function (info) {
-          %LiveEditPatchFunctionPositions(info.raw_array,
-                                          diff_array);
-      });
-
-      report_array.push( { name: old_info_node.info.function_name } );
-    } else {
-      // TODO(LiveEdit): function is not compiled yet or is already collected.
-      report_array.push(
-          { name: old_info_node.info.function_name, info_not_found: true } );
-    }
-  }
-
-  // Adds a suffix to script name to mark that it is old version.
-  function CreateNameForOldScript(script) {
-    // TODO(635): try better than this; support several changes.
-    return script.name + " (old)";
-  }
-
-  // Compares a function scope heap structure, old and new version, whether it
-  // changed or not. Returns explanation if they differ.
-  function IsFunctionContextLocalsChanged(function_info1, function_info2) {
-    var scope_info1 = function_info1.scope_info;
-    var scope_info2 = function_info2.scope_info;
-
-    var scope_info1_text;
-    var scope_info2_text;
-
-    if (scope_info1) {
-      scope_info1_text = scope_info1.toString();
-    } else {
-      scope_info1_text = "";
-    }
-    if (scope_info2) {
-      scope_info2_text = scope_info2.toString();
-    } else {
-      scope_info2_text = "";
-    }
-
-    if (scope_info1_text != scope_info2_text) {
-      return "Variable map changed: [" + scope_info1_text +
-          "] => [" + scope_info2_text + "]";
-    }
-    // No differences. Return undefined.
-    return;
-  }
-
-  // Minifier forward declaration.
-  var FunctionPatchabilityStatus;
-
-  // For array of wrapped shared function infos checks that none of them
-  // have activations on stack (of any thread). Throws a Failure exception
-  // if this proves to be false.
-  function CheckStackActivations(shared_wrapper_list, change_log) {
-    var shared_list = new Array();
-    for (var i = 0; i < shared_wrapper_list.length; i++) {
-      shared_list[i] = shared_wrapper_list[i].info;
-    }
-    var result = %LiveEditCheckAndDropActivations(shared_list, true);
-    if (result[shared_list.length]) {
-      // Extra array element may contain error message.
-      throw new Failure(result[shared_list.length]);
-    }
-
-    var problems = new Array();
-    var dropped = new Array();
-    for (var i = 0; i < shared_list.length; i++) {
-      var shared = shared_wrapper_list[i];
-      if (result[i] == FunctionPatchabilityStatus.REPLACED_ON_ACTIVE_STACK) {
-        dropped.push({ name: shared.function_name } );
-      } else if (result[i] != FunctionPatchabilityStatus.AVAILABLE_FOR_PATCH) {
-        var description = {
-            name: shared.function_name,
-            start_pos: shared.start_position,
-            end_pos: shared.end_position,
-            replace_problem:
-                FunctionPatchabilityStatus.SymbolName(result[i])
-        };
-        problems.push(description);
-      }
-    }
-    if (dropped.length > 0) {
-      change_log.push({ dropped_from_stack: dropped });
-    }
-    if (problems.length > 0) {
-      change_log.push( { functions_on_stack: problems } );
-      throw new Failure("Blocked by functions on stack");
-    }
-
-    return dropped.length;
-  }
-
-  // A copy of the FunctionPatchabilityStatus enum from liveedit.h
-  var FunctionPatchabilityStatus = {
-      AVAILABLE_FOR_PATCH: 1,
-      BLOCKED_ON_ACTIVE_STACK: 2,
-      BLOCKED_ON_OTHER_STACK: 3,
-      BLOCKED_UNDER_NATIVE_CODE: 4,
-      REPLACED_ON_ACTIVE_STACK: 5,
-      BLOCKED_UNDER_GENERATOR: 6,
-      BLOCKED_ACTIVE_GENERATOR: 7
-  };
-
-  FunctionPatchabilityStatus.SymbolName = function(code) {
-    var enumeration = FunctionPatchabilityStatus;
-    for (var name in enumeration) {
-      if (enumeration[name] == code) {
-        return name;
-      }
-    }
-  };
-
-
-  // A logical failure in liveedit process. This means that change_log
-  // is valid and consistent description of what happened.
-  function Failure(message) {
-    this.message = message;
-  }
-  // Function (constructor) is public.
-  this.Failure = Failure;
-
-  Failure.prototype.toString = function() {
-    return "LiveEdit Failure: " + this.message;
-  };
-
-  function CopyErrorPositionToDetails(e, details) {
-    function createPositionStruct(script, position) {
-      if (position == -1) return;
-      var location = script.locationFromPosition(position, true);
-      if (location == null) return;
-      return {
-        line: location.line + 1,
-        column: location.column + 1,
-        position: position
-      };
-    }
-
-    if (!("scriptObject" in e) || !("startPosition" in e)) {
-      return;
-    }
-
-    var script = e.scriptObject;
-
-    var position_struct = {
-      start: createPositionStruct(script, e.startPosition),
-      end: createPositionStruct(script, e.endPosition)
-    };
-    details.position = position_struct;
-  }
-
-  // A testing entry.
-  function GetPcFromSourcePos(func, source_pos) {
-    return %GetFunctionCodePositionFromSource(func, source_pos);
-  }
-  // Function is public.
-  this.GetPcFromSourcePos = GetPcFromSourcePos;
-
-  // LiveEdit main entry point: changes a script text to a new string.
-  function SetScriptSource(script, new_source, preview_only, change_log) {
-    var old_source = script.source;
-    var diff = CompareStrings(old_source, new_source);
-    return ApplyPatchMultiChunk(script, diff, new_source, preview_only,
-        change_log);
-  }
-  // Function is public.
-  this.SetScriptSource = SetScriptSource;
-
-  function CompareStrings(s1, s2) {
-    return %LiveEditCompareStrings(s1, s2);
-  }
-
-  // Applies the change to the script.
-  // The change is always a substring (change_pos, change_pos + change_len)
-  // being replaced with a completely different string new_str.
-  // This API is a legacy and is obsolete.
-  //
-  // @param {Script} script that is being changed
-  // @param {Array} change_log a list that collects engineer-readable
-  //     description of what happened.
-  function ApplySingleChunkPatch(script, change_pos, change_len, new_str,
-      change_log) {
-    var old_source = script.source;
-
-    // Prepare new source string.
-    var new_source = old_source.substring(0, change_pos) +
-        new_str + old_source.substring(change_pos + change_len);
-
-    return ApplyPatchMultiChunk(script,
-        [ change_pos, change_pos + change_len, change_pos + new_str.length],
-        new_source, false, change_log);
-  }
-
-  // Creates JSON description for a change tree.
-  function DescribeChangeTree(old_code_tree) {
-
-    function ProcessOldNode(node) {
-      var child_infos = [];
-      for (var i = 0; i < node.children.length; i++) {
-        var child = node.children[i];
-        if (child.status != FunctionStatus.UNCHANGED) {
-          child_infos.push(ProcessOldNode(child));
-        }
-      }
-      var new_child_infos = [];
-      if (node.textually_unmatched_new_nodes) {
-        for (var i = 0; i < node.textually_unmatched_new_nodes.length; i++) {
-          var child = node.textually_unmatched_new_nodes[i];
-          new_child_infos.push(ProcessNewNode(child));
-        }
-      }
-      var res = {
-        name: node.info.function_name,
-        positions: DescribePositions(node),
-        status: node.status,
-        children: child_infos,
-        new_children: new_child_infos
-      };
-      if (node.status_explanation) {
-        res.status_explanation = node.status_explanation;
-      }
-      if (node.textual_corresponding_node) {
-        res.new_positions = DescribePositions(node.textual_corresponding_node);
-      }
-      return res;
-    }
-
-    function ProcessNewNode(node) {
-      var child_infos = [];
-      // Do not list ancestors.
-      if (false) {
-        for (var i = 0; i < node.children.length; i++) {
-          child_infos.push(ProcessNewNode(node.children[i]));
-        }
-      }
-      var res = {
-        name: node.info.function_name,
-        positions: DescribePositions(node),
-        children: child_infos,
-      };
-      return res;
-    }
-
-    function DescribePositions(node) {
-      return {
-        start_position: node.info.start_position,
-        end_position: node.info.end_position
-      };
-    }
-
-    return ProcessOldNode(old_code_tree);
-  }
-
-  // Functions are public for tests.
-  this.TestApi = {
-    PosTranslator: PosTranslator,
-    CompareStrings: CompareStrings,
-    ApplySingleChunkPatch: ApplySingleChunkPatch
-  };
-};
diff --git a/src/liveedit.cc b/src/liveedit.cc
deleted file mode 100644 (file)
index d03a24e..0000000
+++ /dev/null
@@ -1,2029 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-#include "src/v8.h"
-
-#include "src/liveedit.h"
-
-#include "src/code-stubs.h"
-#include "src/compilation-cache.h"
-#include "src/compiler.h"
-#include "src/debug.h"
-#include "src/deoptimizer.h"
-#include "src/global-handles.h"
-#include "src/messages.h"
-#include "src/parser.h"
-#include "src/scopeinfo.h"
-#include "src/scopes.h"
-#include "src/v8memory.h"
-
-namespace v8 {
-namespace internal {
-
-void SetElementSloppy(Handle<JSObject> object,
-                      uint32_t index,
-                      Handle<Object> value) {
-  // Ignore return value from SetElement. It can only be a failure if there
-  // are element setters causing exceptions and the debugger context has none
-  // of these.
-  Object::SetElement(object->GetIsolate(), object, index, value, SLOPPY)
-      .Assert();
-}
-
-
-// A simple implementation of dynamic programming algorithm. It solves
-// the problem of finding the difference of 2 arrays. It uses a table of results
-// of subproblems. Each cell contains a number together with 2-bit flag
-// that helps building the chunk list.
-class Differencer {
- public:
-  explicit Differencer(Comparator::Input* input)
-      : input_(input), len1_(input->GetLength1()), len2_(input->GetLength2()) {
-    buffer_ = NewArray<int>(len1_ * len2_);
-  }
-  ~Differencer() {
-    DeleteArray(buffer_);
-  }
-
-  void Initialize() {
-    int array_size = len1_ * len2_;
-    for (int i = 0; i < array_size; i++) {
-      buffer_[i] = kEmptyCellValue;
-    }
-  }
-
-  // Makes sure that result for the full problem is calculated and stored
-  // in the table together with flags showing a path through subproblems.
-  void FillTable() {
-    CompareUpToTail(0, 0);
-  }
-
-  void SaveResult(Comparator::Output* chunk_writer) {
-    ResultWriter writer(chunk_writer);
-
-    int pos1 = 0;
-    int pos2 = 0;
-    while (true) {
-      if (pos1 < len1_) {
-        if (pos2 < len2_) {
-          Direction dir = get_direction(pos1, pos2);
-          switch (dir) {
-            case EQ:
-              writer.eq();
-              pos1++;
-              pos2++;
-              break;
-            case SKIP1:
-              writer.skip1(1);
-              pos1++;
-              break;
-            case SKIP2:
-            case SKIP_ANY:
-              writer.skip2(1);
-              pos2++;
-              break;
-            default:
-              UNREACHABLE();
-          }
-        } else {
-          writer.skip1(len1_ - pos1);
-          break;
-        }
-      } else {
-        if (len2_ != pos2) {
-          writer.skip2(len2_ - pos2);
-        }
-        break;
-      }
-    }
-    writer.close();
-  }
-
- private:
-  Comparator::Input* input_;
-  int* buffer_;
-  int len1_;
-  int len2_;
-
-  enum Direction {
-    EQ = 0,
-    SKIP1,
-    SKIP2,
-    SKIP_ANY,
-
-    MAX_DIRECTION_FLAG_VALUE = SKIP_ANY
-  };
-
-  // Computes result for a subtask and optionally caches it in the buffer table.
-  // All results values are shifted to make space for flags in the lower bits.
-  int CompareUpToTail(int pos1, int pos2) {
-    if (pos1 < len1_) {
-      if (pos2 < len2_) {
-        int cached_res = get_value4(pos1, pos2);
-        if (cached_res == kEmptyCellValue) {
-          Direction dir;
-          int res;
-          if (input_->Equals(pos1, pos2)) {
-            res = CompareUpToTail(pos1 + 1, pos2 + 1);
-            dir = EQ;
-          } else {
-            int res1 = CompareUpToTail(pos1 + 1, pos2) +
-                (1 << kDirectionSizeBits);
-            int res2 = CompareUpToTail(pos1, pos2 + 1) +
-                (1 << kDirectionSizeBits);
-            if (res1 == res2) {
-              res = res1;
-              dir = SKIP_ANY;
-            } else if (res1 < res2) {
-              res = res1;
-              dir = SKIP1;
-            } else {
-              res = res2;
-              dir = SKIP2;
-            }
-          }
-          set_value4_and_dir(pos1, pos2, res, dir);
-          cached_res = res;
-        }
-        return cached_res;
-      } else {
-        return (len1_ - pos1) << kDirectionSizeBits;
-      }
-    } else {
-      return (len2_ - pos2) << kDirectionSizeBits;
-    }
-  }
-
-  inline int& get_cell(int i1, int i2) {
-    return buffer_[i1 + i2 * len1_];
-  }
-
-  // Each cell keeps a value plus direction. Value is multiplied by 4.
-  void set_value4_and_dir(int i1, int i2, int value4, Direction dir) {
-    DCHECK((value4 & kDirectionMask) == 0);
-    get_cell(i1, i2) = value4 | dir;
-  }
-
-  int get_value4(int i1, int i2) {
-    return get_cell(i1, i2) & (kMaxUInt32 ^ kDirectionMask);
-  }
-  Direction get_direction(int i1, int i2) {
-    return static_cast<Direction>(get_cell(i1, i2) & kDirectionMask);
-  }
-
-  static const int kDirectionSizeBits = 2;
-  static const int kDirectionMask = (1 << kDirectionSizeBits) - 1;
-  static const int kEmptyCellValue = ~0u << kDirectionSizeBits;
-
-  // This method only holds static assert statement (unfortunately you cannot
-  // place one in class scope).
-  void StaticAssertHolder() {
-    STATIC_ASSERT(MAX_DIRECTION_FLAG_VALUE < (1 << kDirectionSizeBits));
-  }
-
-  class ResultWriter {
-   public:
-    explicit ResultWriter(Comparator::Output* chunk_writer)
-        : chunk_writer_(chunk_writer), pos1_(0), pos2_(0),
-          pos1_begin_(-1), pos2_begin_(-1), has_open_chunk_(false) {
-    }
-    void eq() {
-      FlushChunk();
-      pos1_++;
-      pos2_++;
-    }
-    void skip1(int len1) {
-      StartChunk();
-      pos1_ += len1;
-    }
-    void skip2(int len2) {
-      StartChunk();
-      pos2_ += len2;
-    }
-    void close() {
-      FlushChunk();
-    }
-
-   private:
-    Comparator::Output* chunk_writer_;
-    int pos1_;
-    int pos2_;
-    int pos1_begin_;
-    int pos2_begin_;
-    bool has_open_chunk_;
-
-    void StartChunk() {
-      if (!has_open_chunk_) {
-        pos1_begin_ = pos1_;
-        pos2_begin_ = pos2_;
-        has_open_chunk_ = true;
-      }
-    }
-
-    void FlushChunk() {
-      if (has_open_chunk_) {
-        chunk_writer_->AddChunk(pos1_begin_, pos2_begin_,
-                                pos1_ - pos1_begin_, pos2_ - pos2_begin_);
-        has_open_chunk_ = false;
-      }
-    }
-  };
-};
-
-
-void Comparator::CalculateDifference(Comparator::Input* input,
-                                     Comparator::Output* result_writer) {
-  Differencer differencer(input);
-  differencer.Initialize();
-  differencer.FillTable();
-  differencer.SaveResult(result_writer);
-}
-
-
-static bool CompareSubstrings(Handle<String> s1, int pos1,
-                              Handle<String> s2, int pos2, int len) {
-  for (int i = 0; i < len; i++) {
-    if (s1->Get(i + pos1) != s2->Get(i + pos2)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-
-// Additional to Input interface. Lets switch Input range to subrange.
-// More elegant way would be to wrap one Input as another Input object
-// and translate positions there, but that would cost us additional virtual
-// call per comparison.
-class SubrangableInput : public Comparator::Input {
- public:
-  virtual void SetSubrange1(int offset, int len) = 0;
-  virtual void SetSubrange2(int offset, int len) = 0;
-};
-
-
-class SubrangableOutput : public Comparator::Output {
- public:
-  virtual void SetSubrange1(int offset, int len) = 0;
-  virtual void SetSubrange2(int offset, int len) = 0;
-};
-
-
-static int min(int a, int b) {
-  return a < b ? a : b;
-}
-
-
-// Finds common prefix and suffix in input. This parts shouldn't take space in
-// linear programming table. Enable subranging in input and output.
-static void NarrowDownInput(SubrangableInput* input,
-    SubrangableOutput* output) {
-  const int len1 = input->GetLength1();
-  const int len2 = input->GetLength2();
-
-  int common_prefix_len;
-  int common_suffix_len;
-
-  {
-    common_prefix_len = 0;
-    int prefix_limit = min(len1, len2);
-    while (common_prefix_len < prefix_limit &&
-        input->Equals(common_prefix_len, common_prefix_len)) {
-      common_prefix_len++;
-    }
-
-    common_suffix_len = 0;
-    int suffix_limit = min(len1 - common_prefix_len, len2 - common_prefix_len);
-
-    while (common_suffix_len < suffix_limit &&
-        input->Equals(len1 - common_suffix_len - 1,
-        len2 - common_suffix_len - 1)) {
-      common_suffix_len++;
-    }
-  }
-
-  if (common_prefix_len > 0 || common_suffix_len > 0) {
-    int new_len1 = len1 - common_suffix_len - common_prefix_len;
-    int new_len2 = len2 - common_suffix_len - common_prefix_len;
-
-    input->SetSubrange1(common_prefix_len, new_len1);
-    input->SetSubrange2(common_prefix_len, new_len2);
-
-    output->SetSubrange1(common_prefix_len, new_len1);
-    output->SetSubrange2(common_prefix_len, new_len2);
-  }
-}
-
-
-// A helper class that writes chunk numbers into JSArray.
-// Each chunk is stored as 3 array elements: (pos1_begin, pos1_end, pos2_end).
-class CompareOutputArrayWriter {
- public:
-  explicit CompareOutputArrayWriter(Isolate* isolate)
-      : array_(isolate->factory()->NewJSArray(10)), current_size_(0) {}
-
-  Handle<JSArray> GetResult() {
-    return array_;
-  }
-
-  void WriteChunk(int char_pos1, int char_pos2, int char_len1, int char_len2) {
-    Isolate* isolate = array_->GetIsolate();
-    SetElementSloppy(array_,
-                     current_size_,
-                     Handle<Object>(Smi::FromInt(char_pos1), isolate));
-    SetElementSloppy(array_,
-                     current_size_ + 1,
-                     Handle<Object>(Smi::FromInt(char_pos1 + char_len1),
-                                    isolate));
-    SetElementSloppy(array_,
-                     current_size_ + 2,
-                     Handle<Object>(Smi::FromInt(char_pos2 + char_len2),
-                                    isolate));
-    current_size_ += 3;
-  }
-
- private:
-  Handle<JSArray> array_;
-  int current_size_;
-};
-
-
-// Represents 2 strings as 2 arrays of tokens.
-// TODO(LiveEdit): Currently it's actually an array of charactres.
-//     Make array of tokens instead.
-class TokensCompareInput : public Comparator::Input {
- public:
-  TokensCompareInput(Handle<String> s1, int offset1, int len1,
-                       Handle<String> s2, int offset2, int len2)
-      : s1_(s1), offset1_(offset1), len1_(len1),
-        s2_(s2), offset2_(offset2), len2_(len2) {
-  }
-  virtual int GetLength1() {
-    return len1_;
-  }
-  virtual int GetLength2() {
-    return len2_;
-  }
-  bool Equals(int index1, int index2) {
-    return s1_->Get(offset1_ + index1) == s2_->Get(offset2_ + index2);
-  }
-
- private:
-  Handle<String> s1_;
-  int offset1_;
-  int len1_;
-  Handle<String> s2_;
-  int offset2_;
-  int len2_;
-};
-
-
-// Stores compare result in JSArray. Converts substring positions
-// to absolute positions.
-class TokensCompareOutput : public Comparator::Output {
- public:
-  TokensCompareOutput(CompareOutputArrayWriter* array_writer,
-                      int offset1, int offset2)
-        : array_writer_(array_writer), offset1_(offset1), offset2_(offset2) {
-  }
-
-  void AddChunk(int pos1, int pos2, int len1, int len2) {
-    array_writer_->WriteChunk(pos1 + offset1_, pos2 + offset2_, len1, len2);
-  }
-
- private:
-  CompareOutputArrayWriter* array_writer_;
-  int offset1_;
-  int offset2_;
-};
-
-
-// Wraps raw n-elements line_ends array as a list of n+1 lines. The last line
-// never has terminating new line character.
-class LineEndsWrapper {
- public:
-  explicit LineEndsWrapper(Handle<String> string)
-      : ends_array_(String::CalculateLineEnds(string, false)),
-        string_len_(string->length()) {
-  }
-  int length() {
-    return ends_array_->length() + 1;
-  }
-  // Returns start for any line including start of the imaginary line after
-  // the last line.
-  int GetLineStart(int index) {
-    if (index == 0) {
-      return 0;
-    } else {
-      return GetLineEnd(index - 1);
-    }
-  }
-  int GetLineEnd(int index) {
-    if (index == ends_array_->length()) {
-      // End of the last line is always an end of the whole string.
-      // If the string ends with a new line character, the last line is an
-      // empty string after this character.
-      return string_len_;
-    } else {
-      return GetPosAfterNewLine(index);
-    }
-  }
-
- private:
-  Handle<FixedArray> ends_array_;
-  int string_len_;
-
-  int GetPosAfterNewLine(int index) {
-    return Smi::cast(ends_array_->get(index))->value() + 1;
-  }
-};
-
-
-// Represents 2 strings as 2 arrays of lines.
-class LineArrayCompareInput : public SubrangableInput {
- public:
-  LineArrayCompareInput(Handle<String> s1, Handle<String> s2,
-                        LineEndsWrapper line_ends1, LineEndsWrapper line_ends2)
-      : s1_(s1), s2_(s2), line_ends1_(line_ends1),
-        line_ends2_(line_ends2),
-        subrange_offset1_(0), subrange_offset2_(0),
-        subrange_len1_(line_ends1_.length()),
-        subrange_len2_(line_ends2_.length()) {
-  }
-  int GetLength1() {
-    return subrange_len1_;
-  }
-  int GetLength2() {
-    return subrange_len2_;
-  }
-  bool Equals(int index1, int index2) {
-    index1 += subrange_offset1_;
-    index2 += subrange_offset2_;
-
-    int line_start1 = line_ends1_.GetLineStart(index1);
-    int line_start2 = line_ends2_.GetLineStart(index2);
-    int line_end1 = line_ends1_.GetLineEnd(index1);
-    int line_end2 = line_ends2_.GetLineEnd(index2);
-    int len1 = line_end1 - line_start1;
-    int len2 = line_end2 - line_start2;
-    if (len1 != len2) {
-      return false;
-    }
-    return CompareSubstrings(s1_, line_start1, s2_, line_start2,
-                             len1);
-  }
-  void SetSubrange1(int offset, int len) {
-    subrange_offset1_ = offset;
-    subrange_len1_ = len;
-  }
-  void SetSubrange2(int offset, int len) {
-    subrange_offset2_ = offset;
-    subrange_len2_ = len;
-  }
-
- private:
-  Handle<String> s1_;
-  Handle<String> s2_;
-  LineEndsWrapper line_ends1_;
-  LineEndsWrapper line_ends2_;
-  int subrange_offset1_;
-  int subrange_offset2_;
-  int subrange_len1_;
-  int subrange_len2_;
-};
-
-
-// Stores compare result in JSArray. For each chunk tries to conduct
-// a fine-grained nested diff token-wise.
-class TokenizingLineArrayCompareOutput : public SubrangableOutput {
- public:
-  TokenizingLineArrayCompareOutput(LineEndsWrapper line_ends1,
-                                   LineEndsWrapper line_ends2,
-                                   Handle<String> s1, Handle<String> s2)
-      : array_writer_(s1->GetIsolate()),
-        line_ends1_(line_ends1), line_ends2_(line_ends2), s1_(s1), s2_(s2),
-        subrange_offset1_(0), subrange_offset2_(0) {
-  }
-
-  void AddChunk(int line_pos1, int line_pos2, int line_len1, int line_len2) {
-    line_pos1 += subrange_offset1_;
-    line_pos2 += subrange_offset2_;
-
-    int char_pos1 = line_ends1_.GetLineStart(line_pos1);
-    int char_pos2 = line_ends2_.GetLineStart(line_pos2);
-    int char_len1 = line_ends1_.GetLineStart(line_pos1 + line_len1) - char_pos1;
-    int char_len2 = line_ends2_.GetLineStart(line_pos2 + line_len2) - char_pos2;
-
-    if (char_len1 < CHUNK_LEN_LIMIT && char_len2 < CHUNK_LEN_LIMIT) {
-      // Chunk is small enough to conduct a nested token-level diff.
-      HandleScope subTaskScope(s1_->GetIsolate());
-
-      TokensCompareInput tokens_input(s1_, char_pos1, char_len1,
-                                      s2_, char_pos2, char_len2);
-      TokensCompareOutput tokens_output(&array_writer_, char_pos1,
-                                          char_pos2);
-
-      Comparator::CalculateDifference(&tokens_input, &tokens_output);
-    } else {
-      array_writer_.WriteChunk(char_pos1, char_pos2, char_len1, char_len2);
-    }
-  }
-  void SetSubrange1(int offset, int len) {
-    subrange_offset1_ = offset;
-  }
-  void SetSubrange2(int offset, int len) {
-    subrange_offset2_ = offset;
-  }
-
-  Handle<JSArray> GetResult() {
-    return array_writer_.GetResult();
-  }
-
- private:
-  static const int CHUNK_LEN_LIMIT = 800;
-
-  CompareOutputArrayWriter array_writer_;
-  LineEndsWrapper line_ends1_;
-  LineEndsWrapper line_ends2_;
-  Handle<String> s1_;
-  Handle<String> s2_;
-  int subrange_offset1_;
-  int subrange_offset2_;
-};
-
-
-Handle<JSArray> LiveEdit::CompareStrings(Handle<String> s1,
-                                         Handle<String> s2) {
-  s1 = String::Flatten(s1);
-  s2 = String::Flatten(s2);
-
-  LineEndsWrapper line_ends1(s1);
-  LineEndsWrapper line_ends2(s2);
-
-  LineArrayCompareInput input(s1, s2, line_ends1, line_ends2);
-  TokenizingLineArrayCompareOutput output(line_ends1, line_ends2, s1, s2);
-
-  NarrowDownInput(&input, &output);
-
-  Comparator::CalculateDifference(&input, &output);
-
-  return output.GetResult();
-}
-
-
-// Unwraps JSValue object, returning its field "value"
-static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) {
-  return Handle<Object>(jsValue->value(), jsValue->GetIsolate());
-}
-
-
-// Wraps any object into a OpaqueReference, that will hide the object
-// from JavaScript.
-static Handle<JSValue> WrapInJSValue(Handle<HeapObject> object) {
-  Isolate* isolate = object->GetIsolate();
-  Handle<JSFunction> constructor = isolate->opaque_reference_function();
-  Handle<JSValue> result =
-      Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
-  result->set_value(*object);
-  return result;
-}
-
-
-static Handle<SharedFunctionInfo> UnwrapSharedFunctionInfoFromJSValue(
-    Handle<JSValue> jsValue) {
-  Object* shared = jsValue->value();
-  CHECK(shared->IsSharedFunctionInfo());
-  return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(shared));
-}
-
-
-static int GetArrayLength(Handle<JSArray> array) {
-  Object* length = array->length();
-  CHECK(length->IsSmi());
-  return Smi::cast(length)->value();
-}
-
-
-void FunctionInfoWrapper::SetInitialProperties(Handle<String> name,
-                                               int start_position,
-                                               int end_position, int param_num,
-                                               int literal_count,
-                                               int parent_index) {
-  HandleScope scope(isolate());
-  this->SetField(kFunctionNameOffset_, name);
-  this->SetSmiValueField(kStartPositionOffset_, start_position);
-  this->SetSmiValueField(kEndPositionOffset_, end_position);
-  this->SetSmiValueField(kParamNumOffset_, param_num);
-  this->SetSmiValueField(kLiteralNumOffset_, literal_count);
-  this->SetSmiValueField(kParentIndexOffset_, parent_index);
-}
-
-
-void FunctionInfoWrapper::SetFunctionCode(Handle<Code> function_code,
-                                          Handle<HeapObject> code_scope_info) {
-  Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
-  this->SetField(kCodeOffset_, code_wrapper);
-
-  Handle<JSValue> scope_wrapper = WrapInJSValue(code_scope_info);
-  this->SetField(kCodeScopeInfoOffset_, scope_wrapper);
-}
-
-
-void FunctionInfoWrapper::SetSharedFunctionInfo(
-    Handle<SharedFunctionInfo> info) {
-  Handle<JSValue> info_holder = WrapInJSValue(info);
-  this->SetField(kSharedFunctionInfoOffset_, info_holder);
-}
-
-
-Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
-  Handle<Object> element = this->GetField(kCodeOffset_);
-  Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
-  Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
-  CHECK(raw_result->IsCode());
-  return Handle<Code>::cast(raw_result);
-}
-
-
-MaybeHandle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
-  Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
-  if (element->IsJSValue()) {
-    Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
-    Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
-    Handle<SharedFunctionInfo> shared =
-        Handle<SharedFunctionInfo>::cast(raw_result);
-    return Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
-  } else {
-    // Scripts may never have a SharedFunctionInfo created.
-    return MaybeHandle<TypeFeedbackVector>();
-  }
-}
-
-
-Handle<Object> FunctionInfoWrapper::GetCodeScopeInfo() {
-  Handle<Object> element = this->GetField(kCodeScopeInfoOffset_);
-  return UnwrapJSValue(Handle<JSValue>::cast(element));
-}
-
-
-void SharedInfoWrapper::SetProperties(Handle<String> name,
-                                      int start_position,
-                                      int end_position,
-                                      Handle<SharedFunctionInfo> info) {
-  HandleScope scope(isolate());
-  this->SetField(kFunctionNameOffset_, name);
-  Handle<JSValue> info_holder = WrapInJSValue(info);
-  this->SetField(kSharedInfoOffset_, info_holder);
-  this->SetSmiValueField(kStartPositionOffset_, start_position);
-  this->SetSmiValueField(kEndPositionOffset_, end_position);
-}
-
-
-Handle<SharedFunctionInfo> SharedInfoWrapper::GetInfo() {
-  Handle<Object> element = this->GetField(kSharedInfoOffset_);
-  Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
-  return UnwrapSharedFunctionInfoFromJSValue(value_wrapper);
-}
-
-
-class FunctionInfoListener {
- public:
-  explicit FunctionInfoListener(Isolate* isolate) {
-    current_parent_index_ = -1;
-    len_ = 0;
-    result_ = isolate->factory()->NewJSArray(10);
-  }
-
-  void FunctionStarted(FunctionLiteral* fun) {
-    HandleScope scope(isolate());
-    FunctionInfoWrapper info = FunctionInfoWrapper::Create(isolate());
-    info.SetInitialProperties(fun->name(), fun->start_position(),
-                              fun->end_position(), fun->parameter_count(),
-                              fun->materialized_literal_count(),
-                              current_parent_index_);
-    current_parent_index_ = len_;
-    SetElementSloppy(result_, len_, info.GetJSArray());
-    len_++;
-  }
-
-  void FunctionDone() {
-    HandleScope scope(isolate());
-    FunctionInfoWrapper info =
-        FunctionInfoWrapper::cast(
-            *Object::GetElement(
-                isolate(), result_, current_parent_index_).ToHandleChecked());
-    current_parent_index_ = info.GetParentIndex();
-  }
-
-  // Saves only function code, because for a script function we
-  // may never create a SharedFunctionInfo object.
-  void FunctionCode(Handle<Code> function_code) {
-    FunctionInfoWrapper info =
-        FunctionInfoWrapper::cast(
-            *Object::GetElement(
-                isolate(), result_, current_parent_index_).ToHandleChecked());
-    info.SetFunctionCode(function_code,
-                         Handle<HeapObject>(isolate()->heap()->null_value()));
-  }
-
-  // Saves full information about a function: its code, its scope info
-  // and a SharedFunctionInfo object.
-  void FunctionInfo(Handle<SharedFunctionInfo> shared, Scope* scope,
-                    Zone* zone) {
-    if (!shared->IsSharedFunctionInfo()) {
-      return;
-    }
-    FunctionInfoWrapper info =
-        FunctionInfoWrapper::cast(
-            *Object::GetElement(
-                isolate(), result_, current_parent_index_).ToHandleChecked());
-    info.SetFunctionCode(Handle<Code>(shared->code()),
-                         Handle<HeapObject>(shared->scope_info()));
-    info.SetSharedFunctionInfo(shared);
-
-    Handle<Object> scope_info_list = SerializeFunctionScope(scope, zone);
-    info.SetFunctionScopeInfo(scope_info_list);
-  }
-
-  Handle<JSArray> GetResult() { return result_; }
-
- private:
-  Isolate* isolate() const { return result_->GetIsolate(); }
-
-  Handle<Object> SerializeFunctionScope(Scope* scope, Zone* zone) {
-    Handle<JSArray> scope_info_list = isolate()->factory()->NewJSArray(10);
-    int scope_info_length = 0;
-
-    // Saves some description of scope. It stores name and indexes of
-    // variables in the whole scope chain. Null-named slots delimit
-    // scopes of this chain.
-    Scope* current_scope = scope;
-    while (current_scope != NULL) {
-      HandleScope handle_scope(isolate());
-      ZoneList<Variable*> stack_list(current_scope->StackLocalCount(), zone);
-      ZoneList<Variable*> context_list(
-          current_scope->ContextLocalCount(), zone);
-      ZoneList<Variable*> globals_list(current_scope->ContextGlobalCount(),
-                                       zone);
-      current_scope->CollectStackAndContextLocals(&stack_list, &context_list,
-                                                  &globals_list);
-      context_list.Sort(&Variable::CompareIndex);
-
-      for (int i = 0; i < context_list.length(); i++) {
-        SetElementSloppy(scope_info_list,
-                         scope_info_length,
-                         context_list[i]->name());
-        scope_info_length++;
-        SetElementSloppy(
-            scope_info_list,
-            scope_info_length,
-            Handle<Smi>(Smi::FromInt(context_list[i]->index()), isolate()));
-        scope_info_length++;
-      }
-      SetElementSloppy(scope_info_list,
-                       scope_info_length,
-                       Handle<Object>(isolate()->heap()->null_value(),
-                                      isolate()));
-      scope_info_length++;
-
-      current_scope = current_scope->outer_scope();
-    }
-
-    return scope_info_list;
-  }
-
-  Handle<JSArray> result_;
-  int len_;
-  int current_parent_index_;
-};
-
-
-void LiveEdit::InitializeThreadLocal(Debug* debug) {
-  debug->thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED;
-}
-
-
-bool LiveEdit::SetAfterBreakTarget(Debug* debug) {
-  Code* code = NULL;
-  Isolate* isolate = debug->isolate_;
-  switch (debug->thread_local_.frame_drop_mode_) {
-    case FRAMES_UNTOUCHED:
-      return false;
-    case FRAME_DROPPED_IN_IC_CALL:
-      // We must have been calling IC stub. Do not go there anymore.
-      code = isolate->builtins()->builtin(Builtins::kPlainReturn_LiveEdit);
-      break;
-    case FRAME_DROPPED_IN_DEBUG_SLOT_CALL:
-      // Debug break slot stub does not return normally, instead it manually
-      // cleans the stack and jumps. We should patch the jump address.
-      code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit);
-      break;
-    case FRAME_DROPPED_IN_DIRECT_CALL:
-      // Nothing to do, after_break_target is not used here.
-      return true;
-    case FRAME_DROPPED_IN_RETURN_CALL:
-      code = isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit);
-      break;
-    case CURRENTLY_SET_MODE:
-      UNREACHABLE();
-      break;
-  }
-  debug->after_break_target_ = code->entry();
-  return true;
-}
-
-
-MaybeHandle<JSArray> LiveEdit::GatherCompileInfo(Handle<Script> script,
-                                                 Handle<String> source) {
-  Isolate* isolate = script->GetIsolate();
-
-  FunctionInfoListener listener(isolate);
-  Handle<Object> original_source =
-      Handle<Object>(script->source(), isolate);
-  script->set_source(*source);
-  isolate->set_active_function_info_listener(&listener);
-
-  {
-    // Creating verbose TryCatch from public API is currently the only way to
-    // force code save location. We do not use this the object directly.
-    v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
-    try_catch.SetVerbose(true);
-
-    // A logical 'try' section.
-    Compiler::CompileForLiveEdit(script);
-  }
-
-  // A logical 'catch' section.
-  Handle<JSObject> rethrow_exception;
-  if (isolate->has_pending_exception()) {
-    Handle<Object> exception(isolate->pending_exception(), isolate);
-    MessageLocation message_location = isolate->GetMessageLocation();
-
-    isolate->clear_pending_message();
-    isolate->clear_pending_exception();
-
-    // If possible, copy positions from message object to exception object.
-    if (exception->IsJSObject() && !message_location.script().is_null()) {
-      rethrow_exception = Handle<JSObject>::cast(exception);
-
-      Factory* factory = isolate->factory();
-      Handle<String> start_pos_key = factory->InternalizeOneByteString(
-          STATIC_CHAR_VECTOR("startPosition"));
-      Handle<String> end_pos_key =
-          factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("endPosition"));
-      Handle<String> script_obj_key =
-          factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptObject"));
-      Handle<Smi> start_pos(
-          Smi::FromInt(message_location.start_pos()), isolate);
-      Handle<Smi> end_pos(Smi::FromInt(message_location.end_pos()), isolate);
-      Handle<JSObject> script_obj =
-          Script::GetWrapper(message_location.script());
-      Object::SetProperty(rethrow_exception, start_pos_key, start_pos, SLOPPY)
-          .Assert();
-      Object::SetProperty(rethrow_exception, end_pos_key, end_pos, SLOPPY)
-          .Assert();
-      Object::SetProperty(rethrow_exception, script_obj_key, script_obj, SLOPPY)
-          .Assert();
-    }
-  }
-
-  // A logical 'finally' section.
-  isolate->set_active_function_info_listener(NULL);
-  script->set_source(*original_source);
-
-  if (rethrow_exception.is_null()) {
-    return listener.GetResult();
-  } else {
-    return isolate->Throw<JSArray>(rethrow_exception);
-  }
-}
-
-
-void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) {
-  Isolate* isolate = array->GetIsolate();
-  HandleScope scope(isolate);
-  int len = GetArrayLength(array);
-  for (int i = 0; i < len; i++) {
-    Handle<SharedFunctionInfo> info(
-        SharedFunctionInfo::cast(
-            *Object::GetElement(isolate, array, i).ToHandleChecked()));
-    SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create(isolate);
-    Handle<String> name_handle(String::cast(info->name()));
-    info_wrapper.SetProperties(name_handle, info->start_position(),
-                               info->end_position(), info);
-    SetElementSloppy(array, i, info_wrapper.GetJSArray());
-  }
-}
-
-
-// Visitor that finds all references to a particular code object,
-// including "CODE_TARGET" references in other code objects and replaces
-// them on the fly.
-class ReplacingVisitor : public ObjectVisitor {
- public:
-  explicit ReplacingVisitor(Code* original, Code* substitution)
-    : original_(original), substitution_(substitution) {
-  }
-
-  virtual void VisitPointers(Object** start, Object** end) {
-    for (Object** p = start; p < end; p++) {
-      if (*p == original_) {
-        *p = substitution_;
-      }
-    }
-  }
-
-  virtual void VisitCodeEntry(Address entry) {
-    if (Code::GetObjectFromEntryAddress(entry) == original_) {
-      Address substitution_entry = substitution_->instruction_start();
-      Memory::Address_at(entry) = substitution_entry;
-    }
-  }
-
-  virtual void VisitCodeTarget(RelocInfo* rinfo) {
-    if (RelocInfo::IsCodeTarget(rinfo->rmode()) &&
-        Code::GetCodeFromTargetAddress(rinfo->target_address()) == original_) {
-      Address substitution_entry = substitution_->instruction_start();
-      rinfo->set_target_address(substitution_entry);
-    }
-  }
-
-  virtual void VisitDebugTarget(RelocInfo* rinfo) {
-    VisitCodeTarget(rinfo);
-  }
-
- private:
-  Code* original_;
-  Code* substitution_;
-};
-
-
-// Finds all references to original and replaces them with substitution.
-static void ReplaceCodeObject(Handle<Code> original,
-                              Handle<Code> substitution) {
-  // Perform a full GC in order to ensure that we are not in the middle of an
-  // incremental marking phase when we are replacing the code object.
-  // Since we are not in an incremental marking phase we can write pointers
-  // to code objects (that are never in new space) without worrying about
-  // write barriers.
-  Heap* heap = original->GetHeap();
-  HeapIterator iterator(heap);
-
-  DCHECK(!heap->InNewSpace(*substitution));
-
-  ReplacingVisitor visitor(*original, *substitution);
-
-  // Iterate over all roots. Stack frames may have pointer into original code,
-  // so temporary replace the pointers with offset numbers
-  // in prologue/epilogue.
-  heap->IterateRoots(&visitor, VISIT_ALL);
-
-  // Now iterate over all pointers of all objects, including code_target
-  // implicit pointers.
-  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
-    obj->Iterate(&visitor);
-  }
-}
-
-
-// Patch function literals.
-// Name 'literals' is a misnomer. Rather it's a cache for complex object
-// boilerplates and for a native context. We must clean cached values.
-// Additionally we may need to allocate a new array if number of literals
-// changed.
-class LiteralFixer {
- public:
-  static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper,
-                            Handle<SharedFunctionInfo> shared_info,
-                            Isolate* isolate) {
-    int new_literal_count = compile_info_wrapper->GetLiteralCount();
-    int old_literal_count = shared_info->num_literals();
-
-    if (old_literal_count == new_literal_count) {
-      // If literal count didn't change, simply go over all functions
-      // and clear literal arrays.
-      ClearValuesVisitor visitor;
-      IterateJSFunctions(shared_info, &visitor);
-    } else {
-      // When literal count changes, we have to create new array instances.
-      // Since we cannot create instances when iterating heap, we should first
-      // collect all functions and fix their literal arrays.
-      Handle<FixedArray> function_instances =
-          CollectJSFunctions(shared_info, isolate);
-      for (int i = 0; i < function_instances->length(); i++) {
-        Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i)));
-        Handle<FixedArray> new_literals =
-            isolate->factory()->NewFixedArray(new_literal_count);
-        fun->set_literals(*new_literals);
-      }
-
-      shared_info->set_num_literals(new_literal_count);
-    }
-  }
-
- private:
-  // Iterates all function instances in the HEAP that refers to the
-  // provided shared_info.
-  template<typename Visitor>
-  static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info,
-                                 Visitor* visitor) {
-    HeapIterator iterator(shared_info->GetHeap());
-    for (HeapObject* obj = iterator.next(); obj != NULL;
-        obj = iterator.next()) {
-      if (obj->IsJSFunction()) {
-        JSFunction* function = JSFunction::cast(obj);
-        if (function->shared() == *shared_info) {
-          visitor->visit(function);
-        }
-      }
-    }
-  }
-
-  // Finds all instances of JSFunction that refers to the provided shared_info
-  // and returns array with them.
-  static Handle<FixedArray> CollectJSFunctions(
-      Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
-    CountVisitor count_visitor;
-    count_visitor.count = 0;
-    IterateJSFunctions(shared_info, &count_visitor);
-    int size = count_visitor.count;
-
-    Handle<FixedArray> result = isolate->factory()->NewFixedArray(size);
-    if (size > 0) {
-      CollectVisitor collect_visitor(result);
-      IterateJSFunctions(shared_info, &collect_visitor);
-    }
-    return result;
-  }
-
-  class ClearValuesVisitor {
-   public:
-    void visit(JSFunction* fun) {
-      FixedArray* literals = fun->literals();
-      int len = literals->length();
-      for (int j = 0; j < len; j++) {
-        literals->set_undefined(j);
-      }
-    }
-  };
-
-  class CountVisitor {
-   public:
-    void visit(JSFunction* fun) {
-      count++;
-    }
-    int count;
-  };
-
-  class CollectVisitor {
-   public:
-    explicit CollectVisitor(Handle<FixedArray> output)
-        : m_output(output), m_pos(0) {}
-
-    void visit(JSFunction* fun) {
-      m_output->set(m_pos, fun);
-      m_pos++;
-    }
-   private:
-    Handle<FixedArray> m_output;
-    int m_pos;
-  };
-};
-
-
-// Marks code that shares the same shared function info or has inlined
-// code that shares the same function info.
-class DependentFunctionMarker: public OptimizedFunctionVisitor {
- public:
-  SharedFunctionInfo* shared_info_;
-  bool found_;
-
-  explicit DependentFunctionMarker(SharedFunctionInfo* shared_info)
-    : shared_info_(shared_info), found_(false) { }
-
-  virtual void EnterContext(Context* context) { }  // Don't care.
-  virtual void LeaveContext(Context* context)  { }  // Don't care.
-  virtual void VisitFunction(JSFunction* function) {
-    // It should be guaranteed by the iterator that everything is optimized.
-    DCHECK(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
-    if (function->Inlines(shared_info_)) {
-      // Mark the code for deoptimization.
-      function->code()->set_marked_for_deoptimization(true);
-      found_ = true;
-    }
-  }
-};
-
-
-static void DeoptimizeDependentFunctions(SharedFunctionInfo* function_info) {
-  DisallowHeapAllocation no_allocation;
-  DependentFunctionMarker marker(function_info);
-  // TODO(titzer): need to traverse all optimized code to find OSR code here.
-  Deoptimizer::VisitAllOptimizedFunctions(function_info->GetIsolate(), &marker);
-
-  if (marker.found_) {
-    // Only go through with the deoptimization if something was found.
-    Deoptimizer::DeoptimizeMarkedCode(function_info->GetIsolate());
-  }
-}
-
-
-void LiveEdit::ReplaceFunctionCode(
-    Handle<JSArray> new_compile_info_array,
-    Handle<JSArray> shared_info_array) {
-  Isolate* isolate = new_compile_info_array->GetIsolate();
-
-  FunctionInfoWrapper compile_info_wrapper(new_compile_info_array);
-  SharedInfoWrapper shared_info_wrapper(shared_info_array);
-
-  Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
-
-  if (shared_info->code()->kind() == Code::FUNCTION) {
-    Handle<Code> code = compile_info_wrapper.GetFunctionCode();
-    ReplaceCodeObject(Handle<Code>(shared_info->code()), code);
-    Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo();
-    if (code_scope_info->IsFixedArray()) {
-      shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info));
-    }
-    shared_info->DisableOptimization(kLiveEdit);
-    // Update the type feedback vector, if needed.
-    MaybeHandle<TypeFeedbackVector> feedback_vector =
-        compile_info_wrapper.GetFeedbackVector();
-    if (!feedback_vector.is_null()) {
-      shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
-    }
-  }
-
-  int start_position = compile_info_wrapper.GetStartPosition();
-  int end_position = compile_info_wrapper.GetEndPosition();
-  shared_info->set_start_position(start_position);
-  shared_info->set_end_position(end_position);
-
-  LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, isolate);
-
-  shared_info->set_construct_stub(
-      isolate->builtins()->builtin(Builtins::kJSConstructStubGeneric));
-
-  DeoptimizeDependentFunctions(*shared_info);
-  isolate->compilation_cache()->Remove(shared_info);
-}
-
-
-void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array) {
-  SharedInfoWrapper shared_info_wrapper(shared_info_array);
-  Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
-
-  DeoptimizeDependentFunctions(*shared_info);
-  shared_info_array->GetIsolate()->compilation_cache()->Remove(shared_info);
-}
-
-
-void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
-                                 Handle<Object> script_handle) {
-  Handle<SharedFunctionInfo> shared_info =
-      UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
-  CHECK(script_handle->IsScript() || script_handle->IsUndefined());
-  SharedFunctionInfo::SetScript(shared_info, script_handle);
-  shared_info->DisableOptimization(kLiveEdit);
-
-  function_wrapper->GetIsolate()->compilation_cache()->Remove(shared_info);
-}
-
-
-// For a script text change (defined as position_change_array), translates
-// position in unchanged text to position in changed text.
-// Text change is a set of non-overlapping regions in text, that have changed
-// their contents and length. It is specified as array of groups of 3 numbers:
-// (change_begin, change_end, change_end_new_position).
-// Each group describes a change in text; groups are sorted by change_begin.
-// Only position in text beyond any changes may be successfully translated.
-// If a positions is inside some region that changed, result is currently
-// undefined.
-static int TranslatePosition(int original_position,
-                             Handle<JSArray> position_change_array) {
-  int position_diff = 0;
-  int array_len = GetArrayLength(position_change_array);
-  Isolate* isolate = position_change_array->GetIsolate();
-  // TODO(635): binary search may be used here
-  for (int i = 0; i < array_len; i += 3) {
-    HandleScope scope(isolate);
-    Handle<Object> element = Object::GetElement(
-        isolate, position_change_array, i).ToHandleChecked();
-    CHECK(element->IsSmi());
-    int chunk_start = Handle<Smi>::cast(element)->value();
-    if (original_position < chunk_start) {
-      break;
-    }
-    element = Object::GetElement(
-        isolate, position_change_array, i + 1).ToHandleChecked();
-    CHECK(element->IsSmi());
-    int chunk_end = Handle<Smi>::cast(element)->value();
-    // Position mustn't be inside a chunk.
-    DCHECK(original_position >= chunk_end);
-    element = Object::GetElement(
-        isolate, position_change_array, i + 2).ToHandleChecked();
-    CHECK(element->IsSmi());
-    int chunk_changed_end = Handle<Smi>::cast(element)->value();
-    position_diff = chunk_changed_end - chunk_end;
-  }
-
-  return original_position + position_diff;
-}
-
-
-// Auto-growing buffer for writing relocation info code section. This buffer
-// is a simplified version of buffer from Assembler. Unlike Assembler, this
-// class is platform-independent and it works without dealing with instructions.
-// As specified by RelocInfo format, the buffer is filled in reversed order:
-// from upper to lower addresses.
-// It uses NewArray/DeleteArray for memory management.
-class RelocInfoBuffer {
- public:
-  RelocInfoBuffer(int buffer_initial_capicity, byte* pc) {
-    buffer_size_ = buffer_initial_capicity + kBufferGap;
-    buffer_ = NewArray<byte>(buffer_size_);
-
-    reloc_info_writer_.Reposition(buffer_ + buffer_size_, pc);
-  }
-  ~RelocInfoBuffer() {
-    DeleteArray(buffer_);
-  }
-
-  // As specified by RelocInfo format, the buffer is filled in reversed order:
-  // from upper to lower addresses.
-  void Write(const RelocInfo* rinfo) {
-    if (buffer_ + kBufferGap >= reloc_info_writer_.pos()) {
-      Grow();
-    }
-    reloc_info_writer_.Write(rinfo);
-  }
-
-  Vector<byte> GetResult() {
-    // Return the bytes from pos up to end of buffer.
-    int result_size =
-        static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer_.pos());
-    return Vector<byte>(reloc_info_writer_.pos(), result_size);
-  }
-
- private:
-  void Grow() {
-    // Compute new buffer size.
-    int new_buffer_size;
-    if (buffer_size_ < 2 * KB) {
-      new_buffer_size = 4 * KB;
-    } else {
-      new_buffer_size = 2 * buffer_size_;
-    }
-    // Some internal data structures overflow for very large buffers,
-    // they must ensure that kMaximalBufferSize is not too large.
-    if (new_buffer_size > kMaximalBufferSize) {
-      V8::FatalProcessOutOfMemory("RelocInfoBuffer::GrowBuffer");
-    }
-
-    // Set up new buffer.
-    byte* new_buffer = NewArray<byte>(new_buffer_size);
-
-    // Copy the data.
-    int curently_used_size =
-        static_cast<int>(buffer_ + buffer_size_ - reloc_info_writer_.pos());
-    MemMove(new_buffer + new_buffer_size - curently_used_size,
-            reloc_info_writer_.pos(), curently_used_size);
-
-    reloc_info_writer_.Reposition(
-        new_buffer + new_buffer_size - curently_used_size,
-        reloc_info_writer_.last_pc());
-
-    DeleteArray(buffer_);
-    buffer_ = new_buffer;
-    buffer_size_ = new_buffer_size;
-  }
-
-  RelocInfoWriter reloc_info_writer_;
-  byte* buffer_;
-  int buffer_size_;
-
-  static const int kBufferGap = RelocInfoWriter::kMaxSize;
-  static const int kMaximalBufferSize = 512*MB;
-};
-
-
-// Patch positions in code (changes relocation info section) and possibly
-// returns new instance of code.
-static Handle<Code> PatchPositionsInCode(
-    Handle<Code> code,
-    Handle<JSArray> position_change_array) {
-  Isolate* isolate = code->GetIsolate();
-
-  RelocInfoBuffer buffer_writer(code->relocation_size(),
-                                code->instruction_start());
-
-  {
-    for (RelocIterator it(*code); !it.done(); it.next()) {
-      RelocInfo* rinfo = it.rinfo();
-      if (RelocInfo::IsPosition(rinfo->rmode())) {
-        int position = static_cast<int>(rinfo->data());
-        int new_position = TranslatePosition(position,
-                                             position_change_array);
-        if (position != new_position) {
-          RelocInfo info_copy(rinfo->pc(), rinfo->rmode(), new_position, NULL);
-          buffer_writer.Write(&info_copy);
-          continue;
-        }
-      }
-      if (RelocInfo::IsRealRelocMode(rinfo->rmode())) {
-        buffer_writer.Write(it.rinfo());
-      }
-    }
-  }
-
-  Vector<byte> buffer = buffer_writer.GetResult();
-
-  if (buffer.length() == code->relocation_size()) {
-    // Simply patch relocation area of code.
-    MemCopy(code->relocation_start(), buffer.start(), buffer.length());
-    return code;
-  } else {
-    // Relocation info section now has different size. We cannot simply
-    // rewrite it inside code object. Instead we have to create a new
-    // code object.
-    Handle<Code> result(isolate->factory()->CopyCode(code, buffer));
-    return result;
-  }
-}
-
-
-void LiveEdit::PatchFunctionPositions(Handle<JSArray> shared_info_array,
-                                      Handle<JSArray> position_change_array) {
-  SharedInfoWrapper shared_info_wrapper(shared_info_array);
-  Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo();
-
-  int old_function_start = info->start_position();
-  int new_function_start = TranslatePosition(old_function_start,
-                                             position_change_array);
-  int new_function_end = TranslatePosition(info->end_position(),
-                                           position_change_array);
-  int new_function_token_pos =
-      TranslatePosition(info->function_token_position(), position_change_array);
-
-  info->set_start_position(new_function_start);
-  info->set_end_position(new_function_end);
-  info->set_function_token_position(new_function_token_pos);
-
-  if (info->code()->kind() == Code::FUNCTION) {
-    // Patch relocation info section of the code.
-    Handle<Code> patched_code = PatchPositionsInCode(Handle<Code>(info->code()),
-                                                     position_change_array);
-    if (*patched_code != info->code()) {
-      // Replace all references to the code across the heap. In particular,
-      // some stubs may refer to this code and this code may be being executed
-      // on stack (it is safe to substitute the code object on stack, because
-      // we only change the structure of rinfo and leave instructions
-      // untouched).
-      ReplaceCodeObject(Handle<Code>(info->code()), patched_code);
-    }
-  }
-}
-
-
-static Handle<Script> CreateScriptCopy(Handle<Script> original) {
-  Isolate* isolate = original->GetIsolate();
-
-  Handle<String> original_source(String::cast(original->source()));
-  Handle<Script> copy = isolate->factory()->NewScript(original_source);
-
-  copy->set_name(original->name());
-  copy->set_line_offset(original->line_offset());
-  copy->set_column_offset(original->column_offset());
-  copy->set_type(original->type());
-  copy->set_context_data(original->context_data());
-  copy->set_eval_from_shared(original->eval_from_shared());
-  copy->set_eval_from_instructions_offset(
-      original->eval_from_instructions_offset());
-
-  // Copy all the flags, but clear compilation state.
-  copy->set_flags(original->flags());
-  copy->set_compilation_state(Script::COMPILATION_STATE_INITIAL);
-
-  return copy;
-}
-
-
-Handle<Object> LiveEdit::ChangeScriptSource(Handle<Script> original_script,
-                                            Handle<String> new_source,
-                                            Handle<Object> old_script_name) {
-  Isolate* isolate = original_script->GetIsolate();
-  Handle<Object> old_script_object;
-  if (old_script_name->IsString()) {
-    Handle<Script> old_script = CreateScriptCopy(original_script);
-    old_script->set_name(String::cast(*old_script_name));
-    old_script_object = old_script;
-    isolate->debug()->OnAfterCompile(old_script);
-  } else {
-    old_script_object = isolate->factory()->null_value();
-  }
-
-  original_script->set_source(*new_source);
-
-  // Drop line ends so that they will be recalculated.
-  original_script->set_line_ends(isolate->heap()->undefined_value());
-
-  return old_script_object;
-}
-
-
-
-void LiveEdit::ReplaceRefToNestedFunction(
-    Handle<JSValue> parent_function_wrapper,
-    Handle<JSValue> orig_function_wrapper,
-    Handle<JSValue> subst_function_wrapper) {
-
-  Handle<SharedFunctionInfo> parent_shared =
-      UnwrapSharedFunctionInfoFromJSValue(parent_function_wrapper);
-  Handle<SharedFunctionInfo> orig_shared =
-      UnwrapSharedFunctionInfoFromJSValue(orig_function_wrapper);
-  Handle<SharedFunctionInfo> subst_shared =
-      UnwrapSharedFunctionInfoFromJSValue(subst_function_wrapper);
-
-  for (RelocIterator it(parent_shared->code()); !it.done(); it.next()) {
-    if (it.rinfo()->rmode() == RelocInfo::EMBEDDED_OBJECT) {
-      if (it.rinfo()->target_object() == *orig_shared) {
-        it.rinfo()->set_target_object(*subst_shared);
-      }
-    }
-  }
-}
-
-
-// Check an activation against list of functions. If there is a function
-// that matches, its status in result array is changed to status argument value.
-static bool CheckActivation(Handle<JSArray> shared_info_array,
-                            Handle<JSArray> result,
-                            StackFrame* frame,
-                            LiveEdit::FunctionPatchabilityStatus status) {
-  if (!frame->is_java_script()) return false;
-
-  Handle<JSFunction> function(JavaScriptFrame::cast(frame)->function());
-
-  Isolate* isolate = shared_info_array->GetIsolate();
-  int len = GetArrayLength(shared_info_array);
-  for (int i = 0; i < len; i++) {
-    HandleScope scope(isolate);
-    Handle<Object> element =
-        Object::GetElement(isolate, shared_info_array, i).ToHandleChecked();
-    Handle<JSValue> jsvalue = Handle<JSValue>::cast(element);
-    Handle<SharedFunctionInfo> shared =
-        UnwrapSharedFunctionInfoFromJSValue(jsvalue);
-
-    if (function->Inlines(*shared)) {
-      SetElementSloppy(result, i, Handle<Smi>(Smi::FromInt(status), isolate));
-      return true;
-    }
-  }
-  return false;
-}
-
-
-// Iterates over handler chain and removes all elements that are inside
-// frames being dropped.
-static bool FixTryCatchHandler(StackFrame* top_frame,
-                               StackFrame* bottom_frame) {
-  Address* pointer_address =
-      &Memory::Address_at(top_frame->isolate()->get_address_from_id(
-          Isolate::kHandlerAddress));
-
-  while (*pointer_address < top_frame->sp()) {
-    pointer_address = &Memory::Address_at(*pointer_address);
-  }
-  Address* above_frame_address = pointer_address;
-  while (*pointer_address < bottom_frame->fp()) {
-    pointer_address = &Memory::Address_at(*pointer_address);
-  }
-  bool change = *above_frame_address != *pointer_address;
-  *above_frame_address = *pointer_address;
-  return change;
-}
-
-
-// Initializes an artificial stack frame. The data it contains is used for:
-//  a. successful work of frame dropper code which eventually gets control,
-//  b. being compatible with regular stack structure for various stack
-//     iterators.
-// Returns address of stack allocated pointer to restarted function,
-// the value that is called 'restarter_frame_function_pointer'. The value
-// at this address (possibly updated by GC) may be used later when preparing
-// 'step in' operation.
-// Frame structure (conforms InternalFrame structure):
-//   -- code
-//   -- SMI maker
-//   -- function (slot is called "context")
-//   -- frame base
-static Object** SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
-                                       Handle<Code> code) {
-  DCHECK(bottom_js_frame->is_java_script());
-
-  Address fp = bottom_js_frame->fp();
-
-  // Move function pointer into "context" slot.
-  Memory::Object_at(fp + StandardFrameConstants::kContextOffset) =
-      Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset);
-
-  Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code;
-  Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) =
-      Smi::FromInt(StackFrame::INTERNAL);
-
-  return reinterpret_cast<Object**>(&Memory::Object_at(
-      fp + StandardFrameConstants::kContextOffset));
-}
-
-
-// Removes specified range of frames from stack. There may be 1 or more
-// frames in range. Anyway the bottom frame is restarted rather than dropped,
-// and therefore has to be a JavaScript frame.
-// Returns error message or NULL.
-static const char* DropFrames(Vector<StackFrame*> frames,
-                              int top_frame_index,
-                              int bottom_js_frame_index,
-                              LiveEdit::FrameDropMode* mode,
-                              Object*** restarter_frame_function_pointer) {
-  if (!LiveEdit::kFrameDropperSupported) {
-    return "Stack manipulations are not supported in this architecture.";
-  }
-
-  StackFrame* pre_top_frame = frames[top_frame_index - 1];
-  StackFrame* top_frame = frames[top_frame_index];
-  StackFrame* bottom_js_frame = frames[bottom_js_frame_index];
-
-  DCHECK(bottom_js_frame->is_java_script());
-
-  // Check the nature of the top frame.
-  Isolate* isolate = bottom_js_frame->isolate();
-  Code* pre_top_frame_code = pre_top_frame->LookupCode();
-  bool frame_has_padding = true;
-  if (pre_top_frame_code->is_inline_cache_stub() &&
-      pre_top_frame_code->is_debug_stub()) {
-    // OK, we can drop inline cache calls.
-    *mode = LiveEdit::FRAME_DROPPED_IN_IC_CALL;
-  } else if (pre_top_frame_code ==
-             isolate->builtins()->builtin(Builtins::kSlot_DebugBreak)) {
-    // OK, we can drop debug break slot.
-    *mode = LiveEdit::FRAME_DROPPED_IN_DEBUG_SLOT_CALL;
-  } else if (pre_top_frame_code ==
-             isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit)) {
-    // OK, we can drop our own code.
-    pre_top_frame = frames[top_frame_index - 2];
-    top_frame = frames[top_frame_index - 1];
-    *mode = LiveEdit::CURRENTLY_SET_MODE;
-    frame_has_padding = false;
-  } else if (pre_top_frame_code ==
-             isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) {
-    *mode = LiveEdit::FRAME_DROPPED_IN_RETURN_CALL;
-  } else if (pre_top_frame_code->kind() == Code::STUB &&
-             CodeStub::GetMajorKey(pre_top_frame_code) == CodeStub::CEntry) {
-    // Entry from our unit tests on 'debugger' statement.
-    // It's fine, we support this case.
-    *mode = LiveEdit::FRAME_DROPPED_IN_DIRECT_CALL;
-    // We don't have a padding from 'debugger' statement call.
-    // Here the stub is CEntry, it's not debug-only and can't be padded.
-    // If anyone would complain, a proxy padded stub could be added.
-    frame_has_padding = false;
-  } else if (pre_top_frame->type() == StackFrame::ARGUMENTS_ADAPTOR) {
-    // This must be adaptor that remain from the frame dropping that
-    // is still on stack. A frame dropper frame must be above it.
-    DCHECK(frames[top_frame_index - 2]->LookupCode() ==
-           isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit));
-    pre_top_frame = frames[top_frame_index - 3];
-    top_frame = frames[top_frame_index - 2];
-    *mode = LiveEdit::CURRENTLY_SET_MODE;
-    frame_has_padding = false;
-  } else {
-    return "Unknown structure of stack above changing function";
-  }
-
-  Address unused_stack_top = top_frame->sp();
-  int new_frame_size = LiveEdit::kFrameDropperFrameSize * kPointerSize;
-  Address unused_stack_bottom = bottom_js_frame->fp()
-      - new_frame_size + kPointerSize;  // Bigger address end is exclusive.
-
-  Address* top_frame_pc_address = top_frame->pc_address();
-
-  // top_frame may be damaged below this point. Do not used it.
-  DCHECK(!(top_frame = NULL));
-
-  if (unused_stack_top > unused_stack_bottom) {
-    if (frame_has_padding) {
-      int shortage_bytes =
-          static_cast<int>(unused_stack_top - unused_stack_bottom);
-
-      Address padding_start = pre_top_frame->fp() -
-          LiveEdit::kFrameDropperFrameSize * kPointerSize;
-
-      Address padding_pointer = padding_start;
-      Smi* padding_object = Smi::FromInt(LiveEdit::kFramePaddingValue);
-      while (Memory::Object_at(padding_pointer) == padding_object) {
-        padding_pointer -= kPointerSize;
-      }
-      int padding_counter =
-          Smi::cast(Memory::Object_at(padding_pointer))->value();
-      if (padding_counter * kPointerSize < shortage_bytes) {
-        return "Not enough space for frame dropper frame "
-            "(even with padding frame)";
-      }
-      Memory::Object_at(padding_pointer) =
-          Smi::FromInt(padding_counter - shortage_bytes / kPointerSize);
-
-      StackFrame* pre_pre_frame = frames[top_frame_index - 2];
-
-      MemMove(padding_start + kPointerSize - shortage_bytes,
-              padding_start + kPointerSize,
-              LiveEdit::kFrameDropperFrameSize * kPointerSize);
-
-      pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes);
-      pre_pre_frame->SetCallerFp(pre_top_frame->fp());
-      unused_stack_top -= shortage_bytes;
-
-      STATIC_ASSERT(sizeof(Address) == kPointerSize);
-      top_frame_pc_address -= shortage_bytes / kPointerSize;
-    } else {
-      return "Not enough space for frame dropper frame";
-    }
-  }
-
-  // Committing now. After this point we should return only NULL value.
-
-  FixTryCatchHandler(pre_top_frame, bottom_js_frame);
-  // Make sure FixTryCatchHandler is idempotent.
-  DCHECK(!FixTryCatchHandler(pre_top_frame, bottom_js_frame));
-
-  Handle<Code> code = isolate->builtins()->FrameDropper_LiveEdit();
-  *top_frame_pc_address = code->entry();
-  pre_top_frame->SetCallerFp(bottom_js_frame->fp());
-
-  *restarter_frame_function_pointer =
-      SetUpFrameDropperFrame(bottom_js_frame, code);
-
-  DCHECK((**restarter_frame_function_pointer)->IsJSFunction());
-
-  for (Address a = unused_stack_top;
-      a < unused_stack_bottom;
-      a += kPointerSize) {
-    Memory::Object_at(a) = Smi::FromInt(0);
-  }
-
-  return NULL;
-}
-
-
-// Describes a set of call frames that execute any of listed functions.
-// Finding no such frames does not mean error.
-class MultipleFunctionTarget {
- public:
-  MultipleFunctionTarget(Handle<JSArray> shared_info_array,
-      Handle<JSArray> result)
-      : m_shared_info_array(shared_info_array),
-        m_result(result) {}
-  bool MatchActivation(StackFrame* frame,
-      LiveEdit::FunctionPatchabilityStatus status) {
-    return CheckActivation(m_shared_info_array, m_result, frame, status);
-  }
-  const char* GetNotFoundMessage() const {
-    return NULL;
-  }
- private:
-  Handle<JSArray> m_shared_info_array;
-  Handle<JSArray> m_result;
-};
-
-
-// Drops all call frame matched by target and all frames above them.
-template <typename TARGET>
-static const char* DropActivationsInActiveThreadImpl(Isolate* isolate,
-                                                     TARGET& target,  // NOLINT
-                                                     bool do_drop) {
-  Debug* debug = isolate->debug();
-  Zone zone;
-  Vector<StackFrame*> frames = CreateStackMap(isolate, &zone);
-
-
-  int top_frame_index = -1;
-  int frame_index = 0;
-  for (; frame_index < frames.length(); frame_index++) {
-    StackFrame* frame = frames[frame_index];
-    if (frame->id() == debug->break_frame_id()) {
-      top_frame_index = frame_index;
-      break;
-    }
-    if (target.MatchActivation(
-            frame, LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE)) {
-      // We are still above break_frame. It is not a target frame,
-      // it is a problem.
-      return "Debugger mark-up on stack is not found";
-    }
-  }
-
-  if (top_frame_index == -1) {
-    // We haven't found break frame, but no function is blocking us anyway.
-    return target.GetNotFoundMessage();
-  }
-
-  bool target_frame_found = false;
-  int bottom_js_frame_index = top_frame_index;
-  bool non_droppable_frame_found = false;
-  LiveEdit::FunctionPatchabilityStatus non_droppable_reason;
-
-  for (; frame_index < frames.length(); frame_index++) {
-    StackFrame* frame = frames[frame_index];
-    if (frame->is_exit()) {
-      non_droppable_frame_found = true;
-      non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE;
-      break;
-    }
-    if (frame->is_java_script() &&
-        JavaScriptFrame::cast(frame)->function()->shared()->is_generator()) {
-      non_droppable_frame_found = true;
-      non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR;
-      break;
-    }
-    if (target.MatchActivation(
-            frame, LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
-      target_frame_found = true;
-      bottom_js_frame_index = frame_index;
-    }
-  }
-
-  if (non_droppable_frame_found) {
-    // There is a C or generator frame on stack.  We can't drop C frames, and we
-    // can't restart generators.  Check that there are no target frames below
-    // them.
-    for (; frame_index < frames.length(); frame_index++) {
-      StackFrame* frame = frames[frame_index];
-      if (frame->is_java_script()) {
-        if (target.MatchActivation(frame, non_droppable_reason)) {
-          // Fail.
-          return NULL;
-        }
-      }
-    }
-  }
-
-  if (!do_drop) {
-    // We are in check-only mode.
-    return NULL;
-  }
-
-  if (!target_frame_found) {
-    // Nothing to drop.
-    return target.GetNotFoundMessage();
-  }
-
-  LiveEdit::FrameDropMode drop_mode = LiveEdit::FRAMES_UNTOUCHED;
-  Object** restarter_frame_function_pointer = NULL;
-  const char* error_message = DropFrames(frames, top_frame_index,
-                                         bottom_js_frame_index, &drop_mode,
-                                         &restarter_frame_function_pointer);
-
-  if (error_message != NULL) {
-    return error_message;
-  }
-
-  // Adjust break_frame after some frames has been dropped.
-  StackFrame::Id new_id = StackFrame::NO_ID;
-  for (int i = bottom_js_frame_index + 1; i < frames.length(); i++) {
-    if (frames[i]->type() == StackFrame::JAVA_SCRIPT) {
-      new_id = frames[i]->id();
-      break;
-    }
-  }
-  debug->FramesHaveBeenDropped(
-      new_id, drop_mode, restarter_frame_function_pointer);
-  return NULL;
-}
-
-
-// Fills result array with statuses of functions. Modifies the stack
-// removing all listed function if possible and if do_drop is true.
-static const char* DropActivationsInActiveThread(
-    Handle<JSArray> shared_info_array, Handle<JSArray> result, bool do_drop) {
-  MultipleFunctionTarget target(shared_info_array, result);
-  Isolate* isolate = shared_info_array->GetIsolate();
-
-  const char* message =
-      DropActivationsInActiveThreadImpl(isolate, target, do_drop);
-  if (message) {
-    return message;
-  }
-
-  int array_len = GetArrayLength(shared_info_array);
-
-  // Replace "blocked on active" with "replaced on active" status.
-  for (int i = 0; i < array_len; i++) {
-    Handle<Object> obj =
-        Object::GetElement(isolate, result, i).ToHandleChecked();
-    if (*obj == Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
-      Handle<Object> replaced(
-          Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK), isolate);
-      SetElementSloppy(result, i, replaced);
-    }
-  }
-  return NULL;
-}
-
-
-bool LiveEdit::FindActiveGenerators(Handle<FixedArray> shared_info_array,
-                                    Handle<FixedArray> result,
-                                    int len) {
-  Isolate* isolate = shared_info_array->GetIsolate();
-  bool found_suspended_activations = false;
-
-  DCHECK_LE(len, result->length());
-
-  FunctionPatchabilityStatus active = FUNCTION_BLOCKED_ACTIVE_GENERATOR;
-
-  Heap* heap = isolate->heap();
-  HeapIterator iterator(heap);
-  HeapObject* obj = NULL;
-  while ((obj = iterator.next()) != NULL) {
-    if (!obj->IsJSGeneratorObject()) continue;
-
-    JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
-    if (gen->is_closed()) continue;
-
-    HandleScope scope(isolate);
-
-    for (int i = 0; i < len; i++) {
-      Handle<JSValue> jsvalue =
-          Handle<JSValue>::cast(FixedArray::get(shared_info_array, i));
-      Handle<SharedFunctionInfo> shared =
-          UnwrapSharedFunctionInfoFromJSValue(jsvalue);
-
-      if (gen->function()->shared() == *shared) {
-        result->set(i, Smi::FromInt(active));
-        found_suspended_activations = true;
-      }
-    }
-  }
-
-  return found_suspended_activations;
-}
-
-
-class InactiveThreadActivationsChecker : public ThreadVisitor {
- public:
-  InactiveThreadActivationsChecker(Handle<JSArray> shared_info_array,
-                                   Handle<JSArray> result)
-      : shared_info_array_(shared_info_array), result_(result),
-        has_blocked_functions_(false) {
-  }
-  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
-    for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) {
-      has_blocked_functions_ |= CheckActivation(
-          shared_info_array_, result_, it.frame(),
-          LiveEdit::FUNCTION_BLOCKED_ON_OTHER_STACK);
-    }
-  }
-  bool HasBlockedFunctions() {
-    return has_blocked_functions_;
-  }
-
- private:
-  Handle<JSArray> shared_info_array_;
-  Handle<JSArray> result_;
-  bool has_blocked_functions_;
-};
-
-
-Handle<JSArray> LiveEdit::CheckAndDropActivations(
-    Handle<JSArray> shared_info_array, bool do_drop) {
-  Isolate* isolate = shared_info_array->GetIsolate();
-  int len = GetArrayLength(shared_info_array);
-
-  DCHECK(shared_info_array->HasFastElements());
-  Handle<FixedArray> shared_info_array_elements(
-      FixedArray::cast(shared_info_array->elements()));
-
-  Handle<JSArray> result = isolate->factory()->NewJSArray(len);
-  Handle<FixedArray> result_elements =
-      JSObject::EnsureWritableFastElements(result);
-
-  // Fill the default values.
-  for (int i = 0; i < len; i++) {
-    FunctionPatchabilityStatus status = FUNCTION_AVAILABLE_FOR_PATCH;
-    result_elements->set(i, Smi::FromInt(status));
-  }
-
-  // Scan the heap for active generators -- those that are either currently
-  // running (as we wouldn't want to restart them, because we don't know where
-  // to restart them from) or suspended.  Fail if any one corresponds to the set
-  // of functions being edited.
-  if (FindActiveGenerators(shared_info_array_elements, result_elements, len)) {
-    return result;
-  }
-
-  // Check inactive threads. Fail if some functions are blocked there.
-  InactiveThreadActivationsChecker inactive_threads_checker(shared_info_array,
-                                                            result);
-  isolate->thread_manager()->IterateArchivedThreads(
-      &inactive_threads_checker);
-  if (inactive_threads_checker.HasBlockedFunctions()) {
-    return result;
-  }
-
-  // Try to drop activations from the current stack.
-  const char* error_message =
-      DropActivationsInActiveThread(shared_info_array, result, do_drop);
-  if (error_message != NULL) {
-    // Add error message as an array extra element.
-    Handle<String> str =
-        isolate->factory()->NewStringFromAsciiChecked(error_message);
-    SetElementSloppy(result, len, str);
-  }
-  return result;
-}
-
-
-// Describes a single callframe a target. Not finding this frame
-// means an error.
-class SingleFrameTarget {
- public:
-  explicit SingleFrameTarget(JavaScriptFrame* frame)
-      : m_frame(frame),
-        m_saved_status(LiveEdit::FUNCTION_AVAILABLE_FOR_PATCH) {}
-
-  bool MatchActivation(StackFrame* frame,
-      LiveEdit::FunctionPatchabilityStatus status) {
-    if (frame->fp() == m_frame->fp()) {
-      m_saved_status = status;
-      return true;
-    }
-    return false;
-  }
-  const char* GetNotFoundMessage() const {
-    return "Failed to found requested frame";
-  }
-  LiveEdit::FunctionPatchabilityStatus saved_status() {
-    return m_saved_status;
-  }
- private:
-  JavaScriptFrame* m_frame;
-  LiveEdit::FunctionPatchabilityStatus m_saved_status;
-};
-
-
-// Finds a drops required frame and all frames above.
-// Returns error message or NULL.
-const char* LiveEdit::RestartFrame(JavaScriptFrame* frame) {
-  SingleFrameTarget target(frame);
-
-  const char* result =
-      DropActivationsInActiveThreadImpl(frame->isolate(), target, true);
-  if (result != NULL) {
-    return result;
-  }
-  if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_NATIVE_CODE) {
-    return "Function is blocked under native code";
-  }
-  if (target.saved_status() == LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR) {
-    return "Function is blocked under a generator activation";
-  }
-  return NULL;
-}
-
-
-LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate,
-                                                 FunctionLiteral* fun)
-    : isolate_(isolate) {
-  if (isolate_->active_function_info_listener() != NULL) {
-    isolate_->active_function_info_listener()->FunctionStarted(fun);
-  }
-}
-
-
-LiveEditFunctionTracker::~LiveEditFunctionTracker() {
-  if (isolate_->active_function_info_listener() != NULL) {
-    isolate_->active_function_info_listener()->FunctionDone();
-  }
-}
-
-
-void LiveEditFunctionTracker::RecordFunctionInfo(
-    Handle<SharedFunctionInfo> info, FunctionLiteral* lit,
-    Zone* zone) {
-  if (isolate_->active_function_info_listener() != NULL) {
-    isolate_->active_function_info_listener()->FunctionInfo(info, lit->scope(),
-                                                            zone);
-  }
-}
-
-
-void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) {
-  isolate_->active_function_info_listener()->FunctionCode(code);
-}
-
-
-bool LiveEditFunctionTracker::IsActive(Isolate* isolate) {
-  return isolate->active_function_info_listener() != NULL;
-}
-
-}  // namespace internal
-}  // namespace v8
diff --git a/src/liveedit.h b/src/liveedit.h
deleted file mode 100644 (file)
index 58204b6..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_LIVEEDIT_H_
-#define V8_LIVEEDIT_H_
-
-
-
-// Live Edit feature implementation.
-// User should be able to change script on already running VM. This feature
-// matches hot swap features in other frameworks.
-//
-// The basic use-case is when user spots some mistake in function body
-// from debugger and wishes to change the algorithm without restart.
-//
-// A single change always has a form of a simple replacement (in pseudo-code):
-//   script.source[positions, positions+length] = new_string;
-// Implementation first determines, which function's body includes this
-// change area. Then both old and new versions of script are fully compiled
-// in order to analyze, whether the function changed its outer scope
-// expectations (or number of parameters). If it didn't, function's code is
-// patched with a newly compiled code. If it did change, enclosing function
-// gets patched. All inner functions are left untouched, whatever happened
-// to them in a new script version. However, new version of code will
-// instantiate newly compiled functions.
-
-
-#include "src/allocation.h"
-#include "src/compiler.h"
-
-namespace v8 {
-namespace internal {
-
-// This class collects some specific information on structure of functions
-// in a particular script. It gets called from compiler all the time, but
-// actually records any data only when liveedit operation is in process;
-// in any other time this class is very cheap.
-//
-// The primary interest of the Tracker is to record function scope structures
-// in order to analyze whether function code maybe safely patched (with new
-// code successfully reading existing data from function scopes). The Tracker
-// also collects compiled function codes.
-class LiveEditFunctionTracker {
- public:
-  explicit LiveEditFunctionTracker(Isolate* isolate, FunctionLiteral* fun);
-  ~LiveEditFunctionTracker();
-  void RecordFunctionInfo(Handle<SharedFunctionInfo> info,
-                          FunctionLiteral* lit, Zone* zone);
-  void RecordRootFunctionInfo(Handle<Code> code);
-
-  static bool IsActive(Isolate* isolate);
-
- private:
-  Isolate* isolate_;
-};
-
-
-class LiveEdit : AllStatic {
- public:
-  // Describes how exactly a frame has been dropped from stack.
-  enum FrameDropMode {
-    // No frame has been dropped.
-    FRAMES_UNTOUCHED,
-    // The top JS frame had been calling IC stub. IC stub mustn't be called now.
-    FRAME_DROPPED_IN_IC_CALL,
-    // The top JS frame had been calling debug break slot stub. Patch the
-    // address this stub jumps to in the end.
-    FRAME_DROPPED_IN_DEBUG_SLOT_CALL,
-    // The top JS frame had been calling some C++ function. The return address
-    // gets patched automatically.
-    FRAME_DROPPED_IN_DIRECT_CALL,
-    FRAME_DROPPED_IN_RETURN_CALL,
-    CURRENTLY_SET_MODE
-  };
-
-  static void InitializeThreadLocal(Debug* debug);
-
-  static bool SetAfterBreakTarget(Debug* debug);
-
-  MUST_USE_RESULT static MaybeHandle<JSArray> GatherCompileInfo(
-      Handle<Script> script,
-      Handle<String> source);
-
-  static void WrapSharedFunctionInfos(Handle<JSArray> array);
-
-  static void ReplaceFunctionCode(Handle<JSArray> new_compile_info_array,
-                                  Handle<JSArray> shared_info_array);
-
-  static void FunctionSourceUpdated(Handle<JSArray> shared_info_array);
-
-  // Updates script field in FunctionSharedInfo.
-  static void SetFunctionScript(Handle<JSValue> function_wrapper,
-                                Handle<Object> script_handle);
-
-  static void PatchFunctionPositions(Handle<JSArray> shared_info_array,
-                                     Handle<JSArray> position_change_array);
-
-  // For a script updates its source field. If old_script_name is provided
-  // (i.e. is a String), also creates a copy of the script with its original
-  // source and sends notification to debugger.
-  static Handle<Object> ChangeScriptSource(Handle<Script> original_script,
-                                           Handle<String> new_source,
-                                           Handle<Object> old_script_name);
-
-  // In a code of a parent function replaces original function as embedded
-  // object with a substitution one.
-  static void ReplaceRefToNestedFunction(Handle<JSValue> parent_function_shared,
-                                         Handle<JSValue> orig_function_shared,
-                                         Handle<JSValue> subst_function_shared);
-
-  // Find open generator activations, and set corresponding "result" elements to
-  // FUNCTION_BLOCKED_ACTIVE_GENERATOR.
-  static bool FindActiveGenerators(Handle<FixedArray> shared_info_array,
-                                   Handle<FixedArray> result, int len);
-
-  // Checks listed functions on stack and return array with corresponding
-  // FunctionPatchabilityStatus statuses; extra array element may
-  // contain general error message. Modifies the current stack and
-  // has restart the lowest found frames and drops all other frames above
-  // if possible and if do_drop is true.
-  static Handle<JSArray> CheckAndDropActivations(
-      Handle<JSArray> shared_info_array, bool do_drop);
-
-  // Restarts the call frame and completely drops all frames above it.
-  // Return error message or NULL.
-  static const char* RestartFrame(JavaScriptFrame* frame);
-
-  // A copy of this is in liveedit-debugger.js.
-  enum FunctionPatchabilityStatus {
-    FUNCTION_AVAILABLE_FOR_PATCH = 1,
-    FUNCTION_BLOCKED_ON_ACTIVE_STACK = 2,
-    FUNCTION_BLOCKED_ON_OTHER_STACK = 3,
-    FUNCTION_BLOCKED_UNDER_NATIVE_CODE = 4,
-    FUNCTION_REPLACED_ON_ACTIVE_STACK = 5,
-    FUNCTION_BLOCKED_UNDER_GENERATOR = 6,
-    FUNCTION_BLOCKED_ACTIVE_GENERATOR = 7
-  };
-
-  // Compares 2 strings line-by-line, then token-wise and returns diff in form
-  // of array of triplets (pos1, pos1_end, pos2_end) describing list
-  // of diff chunks.
-  static Handle<JSArray> CompareStrings(Handle<String> s1,
-                                        Handle<String> s2);
-
-  // Architecture-specific constant.
-  static const bool kFrameDropperSupported;
-
-  /**
-   * Defines layout of a stack frame that supports padding. This is a regular
-   * internal frame that has a flexible stack structure. LiveEdit can shift
-   * its lower part up the stack, taking up the 'padding' space when additional
-   * stack memory is required.
-   * Such frame is expected immediately above the topmost JavaScript frame.
-   *
-   * Stack Layout:
-   *   --- Top
-   *   LiveEdit routine frames
-   *   ---
-   *   C frames of debug handler
-   *   ---
-   *   ...
-   *   ---
-   *      An internal frame that has n padding words:
-   *      - any number of words as needed by code -- upper part of frame
-   *      - padding size: a Smi storing n -- current size of padding
-   *      - padding: n words filled with kPaddingValue in form of Smi
-   *      - 3 context/type words of a regular InternalFrame
-   *      - fp
-   *   ---
-   *      Topmost JavaScript frame
-   *   ---
-   *   ...
-   *   --- Bottom
-   */
-  // A size of frame base including fp. Padding words starts right above
-  // the base.
-  static const int kFrameDropperFrameSize = 4;
-  // A number of words that should be reserved on stack for the LiveEdit use.
-  // Stored on stack in form of Smi.
-  static const int kFramePaddingInitialSize = 1;
-  // A value that padding words are filled with (in form of Smi). Going
-  // bottom-top, the first word not having this value is a counter word.
-  static const int kFramePaddingValue = kFramePaddingInitialSize + 1;
-};
-
-
-// A general-purpose comparator between 2 arrays.
-class Comparator {
- public:
-  // Holds 2 arrays of some elements allowing to compare any pair of
-  // element from the first array and element from the second array.
-  class Input {
-   public:
-    virtual int GetLength1() = 0;
-    virtual int GetLength2() = 0;
-    virtual bool Equals(int index1, int index2) = 0;
-
-   protected:
-    virtual ~Input() {}
-  };
-
-  // Receives compare result as a series of chunks.
-  class Output {
-   public:
-    // Puts another chunk in result list. Note that technically speaking
-    // only 3 arguments actually needed with 4th being derivable.
-    virtual void AddChunk(int pos1, int pos2, int len1, int len2) = 0;
-
-   protected:
-    virtual ~Output() {}
-  };
-
-  // Finds the difference between 2 arrays of elements.
-  static void CalculateDifference(Input* input,
-                                  Output* result_writer);
-};
-
-
-
-// Simple helper class that creates more or less typed structures over
-// JSArray object. This is an adhoc method of passing structures from C++
-// to JavaScript.
-template<typename S>
-class JSArrayBasedStruct {
- public:
-  static S Create(Isolate* isolate) {
-    Factory* factory = isolate->factory();
-    Handle<JSArray> array = factory->NewJSArray(S::kSize_);
-    return S(array);
-  }
-
-  static S cast(Object* object) {
-    JSArray* array = JSArray::cast(object);
-    Handle<JSArray> array_handle(array);
-    return S(array_handle);
-  }
-
-  explicit JSArrayBasedStruct(Handle<JSArray> array) : array_(array) {
-  }
-
-  Handle<JSArray> GetJSArray() {
-    return array_;
-  }
-
-  Isolate* isolate() const {
-    return array_->GetIsolate();
-  }
-
- protected:
-  void SetField(int field_position, Handle<Object> value) {
-    Object::SetElement(isolate(), array_, field_position, value, SLOPPY)
-        .Assert();
-  }
-
-  void SetSmiValueField(int field_position, int value) {
-    SetField(field_position, Handle<Smi>(Smi::FromInt(value), isolate()));
-  }
-
-  Handle<Object> GetField(int field_position) {
-    return Object::GetElement(
-        isolate(), array_, field_position).ToHandleChecked();
-  }
-
-  int GetSmiValueField(int field_position) {
-    Handle<Object> res = GetField(field_position);
-    return Handle<Smi>::cast(res)->value();
-  }
-
- private:
-  Handle<JSArray> array_;
-};
-
-
-// Represents some function compilation details. This structure will be used
-// from JavaScript. It contains Code object, which is kept wrapped
-// into a BlindReference for sanitizing reasons.
-class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
- public:
-  explicit FunctionInfoWrapper(Handle<JSArray> array)
-      : JSArrayBasedStruct<FunctionInfoWrapper>(array) {
-  }
-
-  void SetInitialProperties(Handle<String> name, int start_position,
-                            int end_position, int param_num, int literal_count,
-                            int parent_index);
-
-  void SetFunctionCode(Handle<Code> function_code,
-                       Handle<HeapObject> code_scope_info);
-
-  void SetFunctionScopeInfo(Handle<Object> scope_info_array) {
-    this->SetField(kFunctionScopeInfoOffset_, scope_info_array);
-  }
-
-  void SetSharedFunctionInfo(Handle<SharedFunctionInfo> info);
-
-  int GetLiteralCount() {
-    return this->GetSmiValueField(kLiteralNumOffset_);
-  }
-
-  int GetParentIndex() {
-    return this->GetSmiValueField(kParentIndexOffset_);
-  }
-
-  Handle<Code> GetFunctionCode();
-
-  MaybeHandle<TypeFeedbackVector> GetFeedbackVector();
-
-  Handle<Object> GetCodeScopeInfo();
-
-  int GetStartPosition() {
-    return this->GetSmiValueField(kStartPositionOffset_);
-  }
-
-  int GetEndPosition() { return this->GetSmiValueField(kEndPositionOffset_); }
-
- private:
-  static const int kFunctionNameOffset_ = 0;
-  static const int kStartPositionOffset_ = 1;
-  static const int kEndPositionOffset_ = 2;
-  static const int kParamNumOffset_ = 3;
-  static const int kCodeOffset_ = 4;
-  static const int kCodeScopeInfoOffset_ = 5;
-  static const int kFunctionScopeInfoOffset_ = 6;
-  static const int kParentIndexOffset_ = 7;
-  static const int kSharedFunctionInfoOffset_ = 8;
-  static const int kLiteralNumOffset_ = 9;
-  static const int kSize_ = 10;
-
-  friend class JSArrayBasedStruct<FunctionInfoWrapper>;
-};
-
-
-// Wraps SharedFunctionInfo along with some of its fields for passing it
-// back to JavaScript. SharedFunctionInfo object itself is additionally
-// wrapped into BlindReference for sanitizing reasons.
-class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> {
- public:
-  static bool IsInstance(Handle<JSArray> array) {
-    if (array->length() != Smi::FromInt(kSize_)) return false;
-    Handle<Object> element(
-        Object::GetElement(array->GetIsolate(),
-                           array,
-                           kSharedInfoOffset_).ToHandleChecked());
-    if (!element->IsJSValue()) return false;
-    return Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo();
-  }
-
-  explicit SharedInfoWrapper(Handle<JSArray> array)
-      : JSArrayBasedStruct<SharedInfoWrapper>(array) {
-  }
-
-  void SetProperties(Handle<String> name,
-                     int start_position,
-                     int end_position,
-                     Handle<SharedFunctionInfo> info);
-
-  Handle<SharedFunctionInfo> GetInfo();
-
- private:
-  static const int kFunctionNameOffset_ = 0;
-  static const int kStartPositionOffset_ = 1;
-  static const int kEndPositionOffset_ = 2;
-  static const int kSharedInfoOffset_ = 3;
-  static const int kSize_ = 4;
-
-  friend class JSArrayBasedStruct<SharedInfoWrapper>;
-};
-
-} }  // namespace v8::internal
-
-#endif /* V*_LIVEEDIT_H_ */
index 87335cba093245b36b00d6a81c654919d52f3aa1..f4bddf54613731d9d5a002e09412bf3c62fd1ef3 100644 (file)
@@ -40,7 +40,7 @@
 #include "src/mips/assembler-mips.h"
 
 #include "src/assembler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 
 
 namespace v8 {
index 93a10ce098394cfb4c62ff8978746926ec3d106b..711277d1e01717a1515058837d177fee596a4cc3 100644 (file)
@@ -9,7 +9,7 @@
 #if V8_TARGET_ARCH_MIPS
 
 #include "src/codegen.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/interpreter/bytecodes.h"
diff --git a/src/mips/debug-mips.cc b/src/mips/debug-mips.cc
deleted file mode 100644 (file)
index 9a7f143..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-
-#include "src/v8.h"
-
-#if V8_TARGET_ARCH_MIPS
-
-#include "src/codegen.h"
-#include "src/debug.h"
-
-namespace v8 {
-namespace internal {
-
-#define __ ACCESS_MASM(masm)
-
-
-void EmitDebugBreakSlot(MacroAssembler* masm) {
-  Label check_size;
-  __ bind(&check_size);
-  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
-    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
-  }
-  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
-            masm->InstructionsGeneratedSince(&check_size));
-}
-
-
-void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                                int call_argc) {
-  // Generate enough nop's to make space for a call instruction. Avoid emitting
-  // the trampoline pool in the debug break slot code.
-  Assembler::BlockTrampolinePoolScope block_pool(masm);
-  masm->RecordDebugBreakSlot(mode, call_argc);
-  EmitDebugBreakSlot(masm);
-}
-
-
-void DebugCodegen::ClearDebugBreakSlot(Address pc) {
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
-  EmitDebugBreakSlot(patcher.masm());
-}
-
-
-void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
-  DCHECK_EQ(Code::BUILTIN, code->kind());
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
-  // Patch the code changing the debug break slot code from:
-  //   nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1)
-  //   nop(DEBUG_BREAK_NOP)
-  //   nop(DEBUG_BREAK_NOP)
-  //   nop(DEBUG_BREAK_NOP)
-  // to a call to the debug break slot code.
-  //   li t9, address   (lui t9 / ori t9 instruction pair)
-  //   call t9          (jalr t9 / nop instruction pair)
-  patcher.masm()->li(v8::internal::t9,
-                     Operand(reinterpret_cast<int32_t>(code->entry())));
-  patcher.masm()->Call(v8::internal::t9);
-}
-
-
-void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
-                                          DebugBreakCallHelperMode mode) {
-  __ RecordComment("Debug break");
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Load padding words on stack.
-    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue)));
-    __ Subu(sp, sp,
-            Operand(kPointerSize * LiveEdit::kFramePaddingInitialSize));
-    for (int i = LiveEdit::kFramePaddingInitialSize - 1; i >= 0; i--) {
-      __ sw(at, MemOperand(sp, kPointerSize * i));
-    }
-    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
-    __ push(at);
-
-    if (mode == SAVE_RESULT_REGISTER) __ push(v0);
-
-    __ PrepareCEntryArgs(0);  // No arguments.
-    __ PrepareCEntryFunction(ExternalReference(
-        Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()));
-
-    CEntryStub ceb(masm->isolate(), 1);
-    __ CallStub(&ceb);
-
-    if (FLAG_debug_code) {
-      for (int i = 0; i < kNumJSCallerSaved; i++) {
-        Register reg = {JSCallerSavedCode(i)};
-        __ li(reg, kDebugZapValue);
-      }
-    }
-
-    if (mode == SAVE_RESULT_REGISTER) __ pop(v0);
-
-    // Don't bother removing padding bytes pushed on the stack
-    // as the frame is going to be restored right away.
-
-    // Leave the internal frame.
-  }
-
-  // Now that the break point has been handled, resume normal execution by
-  // jumping to the target address intended by the caller and that was
-  // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target =
-      ExternalReference::debug_after_break_target_address(masm->isolate());
-  __ li(t9, Operand(after_break_target));
-  __ lw(t9, MemOperand(t9));
-  __ Jump(t9);
-}
-
-
-void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
-  __ Ret();
-}
-
-
-void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
-  ExternalReference restarter_frame_function_slot =
-      ExternalReference::debug_restarter_frame_function_pointer_address(
-          masm->isolate());
-  __ li(at, Operand(restarter_frame_function_slot));
-  __ sw(zero_reg, MemOperand(at, 0));
-
-  // We do not know our frame height, but set sp based on fp.
-  __ Subu(sp, fp, Operand(kPointerSize));
-
-  __ Pop(ra, fp, a1);  // Return address, Frame, Function.
-
-  // Load context from the function.
-  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
-
-  // Get function code.
-  __ lw(at, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
-  __ lw(at, FieldMemOperand(at, SharedFunctionInfo::kCodeOffset));
-  __ Addu(t9, at, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-  // Re-run JSFunction, a1 is function, cp is context.
-  __ Jump(t9);
-}
-
-
-const bool LiveEdit::kFrameDropperSupported = true;
-
-#undef __
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TARGET_ARCH_MIPS
index 16a8c1e10700ca20761582587b46025926d9372d..0cda201e9c0e8bdab99e91deeb161c4fc890412d 100644 (file)
@@ -13,7 +13,7 @@
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
index 36c4158eddeebab92220d17bf6cd68c3f4ab4812..16ca33a9f3440c6de6a40f2d266c2eecf21af456 100644 (file)
@@ -40,7 +40,7 @@
 #include "src/mips64/assembler-mips64.h"
 
 #include "src/assembler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 
 
 namespace v8 {
index 1426f15858b896dcac70c392f612b97ffeb431ca..0888939106bb14a4def78c221db206555a737bb8 100644 (file)
@@ -9,7 +9,7 @@
 #if V8_TARGET_ARCH_MIPS64
 
 #include "src/codegen.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/runtime/runtime.h"
diff --git a/src/mips64/debug-mips64.cc b/src/mips64/debug-mips64.cc
deleted file mode 100644 (file)
index a34908b..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-
-#include "src/v8.h"
-
-#if V8_TARGET_ARCH_MIPS64
-
-#include "src/codegen.h"
-#include "src/debug.h"
-
-namespace v8 {
-namespace internal {
-
-#define __ ACCESS_MASM(masm)
-
-void EmitDebugBreakSlot(MacroAssembler* masm) {
-  Label check_size;
-  __ bind(&check_size);
-  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
-    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
-  }
-  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
-            masm->InstructionsGeneratedSince(&check_size));
-}
-
-
-void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                                int call_argc) {
-  // Generate enough nop's to make space for a call instruction. Avoid emitting
-  // the trampoline pool in the debug break slot code.
-  Assembler::BlockTrampolinePoolScope block_pool(masm);
-  masm->RecordDebugBreakSlot(mode, call_argc);
-  EmitDebugBreakSlot(masm);
-}
-
-
-void DebugCodegen::ClearDebugBreakSlot(Address pc) {
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
-  EmitDebugBreakSlot(patcher.masm());
-}
-
-
-void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
-  DCHECK_EQ(Code::BUILTIN, code->kind());
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
-  // Patch the code changing the debug break slot code from:
-  //   nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1)
-  //   nop(DEBUG_BREAK_NOP)
-  //   nop(DEBUG_BREAK_NOP)
-  //   nop(DEBUG_BREAK_NOP)
-  //   nop(DEBUG_BREAK_NOP)
-  //   nop(DEBUG_BREAK_NOP)
-  // to a call to the debug break slot code.
-  //   li t9, address   (4-instruction sequence on mips64)
-  //   call t9          (jalr t9 / nop instruction pair)
-  patcher.masm()->li(v8::internal::t9,
-                     Operand(reinterpret_cast<int64_t>(code->entry())),
-                     ADDRESS_LOAD);
-  patcher.masm()->Call(v8::internal::t9);
-}
-
-
-void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
-                                          DebugBreakCallHelperMode mode) {
-  __ RecordComment("Debug break");
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Load padding words on stack.
-    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue)));
-    __ Dsubu(sp, sp,
-            Operand(kPointerSize * LiveEdit::kFramePaddingInitialSize));
-    for (int i = LiveEdit::kFramePaddingInitialSize - 1; i >= 0; i--) {
-      __ sd(at, MemOperand(sp, kPointerSize * i));
-    }
-    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
-    __ push(at);
-
-    if (mode == SAVE_RESULT_REGISTER) __ push(v0);
-
-    __ PrepareCEntryArgs(0);  // No arguments.
-    __ PrepareCEntryFunction(ExternalReference(
-        Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()));
-
-    CEntryStub ceb(masm->isolate(), 1);
-    __ CallStub(&ceb);
-
-    if (FLAG_debug_code) {
-      for (int i = 0; i < kNumJSCallerSaved; i++) {
-        Register reg = {JSCallerSavedCode(i)};
-        __ li(reg, kDebugZapValue);
-      }
-    }
-
-    if (mode == SAVE_RESULT_REGISTER) __ pop(v0);
-
-    // Don't bother removing padding bytes pushed on the stack
-    // as the frame is going to be restored right away.
-
-    // Leave the internal frame.
-  }
-
-  // Now that the break point has been handled, resume normal execution by
-  // jumping to the target address intended by the caller and that was
-  // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target =
-      ExternalReference::debug_after_break_target_address(masm->isolate());
-  __ li(t9, Operand(after_break_target));
-  __ ld(t9, MemOperand(t9));
-  __ Jump(t9);
-}
-
-
-void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
-  __ Ret();
-}
-
-
-void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
-  ExternalReference restarter_frame_function_slot =
-      ExternalReference::debug_restarter_frame_function_pointer_address(
-          masm->isolate());
-  __ li(at, Operand(restarter_frame_function_slot));
-  __ sw(zero_reg, MemOperand(at, 0));
-
-  // We do not know our frame height, but set sp based on fp.
-  __ Dsubu(sp, fp, Operand(kPointerSize));
-
-  __ Pop(ra, fp, a1);  // Return address, Frame, Function.
-
-  // Load context from the function.
-  __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
-
-  // Get function code.
-  __ ld(at, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
-  __ ld(at, FieldMemOperand(at, SharedFunctionInfo::kCodeOffset));
-  __ Daddu(t9, at, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-  // Re-run JSFunction, a1 is function, cp is context.
-  __ Jump(t9);
-}
-
-
-const bool LiveEdit::kFrameDropperSupported = true;
-
-#undef __
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TARGET_ARCH_MIPS64
index a0925dd6ebee3ba5259e02ce0b203d5d7750b0b0..d0236a0ef33960fb37ea90822a972fbd0dc8eb26 100644 (file)
@@ -12,7 +12,7 @@
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
deleted file mode 100644 (file)
index dbdc68e..0000000
+++ /dev/null
@@ -1,3026 +0,0 @@
-// Copyright 2006-2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-"use strict";
-
-// Handle id counters.
-var next_handle_ = 0;
-var next_transient_handle_ = -1;
-
-// Mirror cache.
-var mirror_cache_ = [];
-var mirror_cache_enabled_ = true;
-
-
-function ToggleMirrorCache(value) {
-  mirror_cache_enabled_ = value;
-  next_handle_ = 0;
-  mirror_cache_ = [];
-}
-
-
-// Wrapper to check whether an object is a Promise.  The call may not work
-// if promises are not enabled.
-// TODO(yangguo): remove try-catch once promises are enabled by default.
-function ObjectIsPromise(value) {
-  try {
-    return IS_SPEC_OBJECT(value) &&
-           !IS_UNDEFINED(%DebugGetProperty(value, builtins.$promiseStatus));
-  } catch (e) {
-    return false;
-  }
-}
-
-
-/**
- * Returns the mirror for a specified value or object.
- *
- * @param {value or Object} value the value or object to retreive the mirror for
- * @param {boolean} transient indicate whether this object is transient and
- *    should not be added to the mirror cache. The default is not transient.
- * @returns {Mirror} the mirror reflects the passed value or object
- */
-function MakeMirror(value, opt_transient) {
-  var mirror;
-
-  // Look for non transient mirrors in the mirror cache.
-  if (!opt_transient && mirror_cache_enabled_) {
-    for (var id in mirror_cache_) {
-      mirror = mirror_cache_[id];
-      if (mirror.value() === value) {
-        return mirror;
-      }
-      // Special check for NaN as NaN == NaN is false.
-      if (mirror.isNumber() && isNaN(mirror.value()) &&
-          typeof value == 'number' && isNaN(value)) {
-        return mirror;
-      }
-    }
-  }
-
-  if (IS_UNDEFINED(value)) {
-    mirror = new UndefinedMirror();
-  } else if (IS_NULL(value)) {
-    mirror = new NullMirror();
-  } else if (IS_BOOLEAN(value)) {
-    mirror = new BooleanMirror(value);
-  } else if (IS_NUMBER(value)) {
-    mirror = new NumberMirror(value);
-  } else if (IS_STRING(value)) {
-    mirror = new StringMirror(value);
-  } else if (IS_SYMBOL(value)) {
-    mirror = new SymbolMirror(value);
-  } else if (IS_ARRAY(value)) {
-    mirror = new ArrayMirror(value);
-  } else if (IS_DATE(value)) {
-    mirror = new DateMirror(value);
-  } else if (IS_FUNCTION(value)) {
-    mirror = new FunctionMirror(value);
-  } else if (IS_REGEXP(value)) {
-    mirror = new RegExpMirror(value);
-  } else if (IS_ERROR(value)) {
-    mirror = new ErrorMirror(value);
-  } else if (IS_SCRIPT(value)) {
-    mirror = new ScriptMirror(value);
-  } else if (IS_MAP(value) || IS_WEAKMAP(value)) {
-    mirror = new MapMirror(value);
-  } else if (IS_SET(value) || IS_WEAKSET(value)) {
-    mirror = new SetMirror(value);
-  } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) {
-    mirror = new IteratorMirror(value);
-  } else if (ObjectIsPromise(value)) {
-    mirror = new PromiseMirror(value);
-  } else if (IS_GENERATOR(value)) {
-    mirror = new GeneratorMirror(value);
-  } else {
-    mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient);
-  }
-
-  if (mirror_cache_enabled_) mirror_cache_[mirror.handle()] = mirror;
-  return mirror;
-}
-
-
-/**
- * Returns the mirror for a specified mirror handle.
- *
- * @param {number} handle the handle to find the mirror for
- * @returns {Mirror or undefiend} the mirror with the requested handle or
- *     undefined if no mirror with the requested handle was found
- */
-function LookupMirror(handle) {
-  if (!mirror_cache_enabled_) throw new Error("Mirror cache is disabled");
-  return mirror_cache_[handle];
-}
-
-
-/**
- * Returns the mirror for the undefined value.
- *
- * @returns {Mirror} the mirror reflects the undefined value
- */
-function GetUndefinedMirror() {
-  return MakeMirror(UNDEFINED);
-}
-
-
-/**
- * Inherit the prototype methods from one constructor into another.
- *
- * The Function.prototype.inherits from lang.js rewritten as a standalone
- * function (not on Function.prototype). NOTE: If this file is to be loaded
- * during bootstrapping this function needs to be revritten using some native
- * functions as prototype setup using normal JavaScript does not work as
- * expected during bootstrapping (see mirror.js in r114903).
- *
- * @param {function} ctor Constructor function which needs to inherit the
- *     prototype
- * @param {function} superCtor Constructor function to inherit prototype from
- */
-function inherits(ctor, superCtor) {
-  var tempCtor = function(){};
-  tempCtor.prototype = superCtor.prototype;
-  ctor.super_ = superCtor.prototype;
-  ctor.prototype = new tempCtor();
-  ctor.prototype.constructor = ctor;
-}
-
-
-// Type names of the different mirrors.
-var UNDEFINED_TYPE = 'undefined';
-var NULL_TYPE = 'null';
-var BOOLEAN_TYPE = 'boolean';
-var NUMBER_TYPE = 'number';
-var STRING_TYPE = 'string';
-var SYMBOL_TYPE = 'symbol';
-var OBJECT_TYPE = 'object';
-var FUNCTION_TYPE = 'function';
-var REGEXP_TYPE = 'regexp';
-var ERROR_TYPE = 'error';
-var PROPERTY_TYPE = 'property';
-var INTERNAL_PROPERTY_TYPE = 'internalProperty';
-var FRAME_TYPE = 'frame';
-var SCRIPT_TYPE = 'script';
-var CONTEXT_TYPE = 'context';
-var SCOPE_TYPE = 'scope';
-var PROMISE_TYPE = 'promise';
-var MAP_TYPE = 'map';
-var SET_TYPE = 'set';
-var ITERATOR_TYPE = 'iterator';
-var GENERATOR_TYPE = 'generator';
-
-// Maximum length when sending strings through the JSON protocol.
-var kMaxProtocolStringLength = 80;
-
-// Different kind of properties.
-var PropertyKind = {};
-PropertyKind.Named   = 1;
-PropertyKind.Indexed = 2;
-
-
-// A copy of the PropertyType enum from property-details.h
-var PropertyType = {};
-PropertyType.Data                        = 0;
-PropertyType.DataConstant                = 2;
-PropertyType.AccessorConstant            = 3;
-
-
-// Different attributes for a property.
-var PropertyAttribute = {};
-PropertyAttribute.None       = NONE;
-PropertyAttribute.ReadOnly   = READ_ONLY;
-PropertyAttribute.DontEnum   = DONT_ENUM;
-PropertyAttribute.DontDelete = DONT_DELETE;
-
-
-// A copy of the scope types from runtime-debug.cc.
-// NOTE: these constants should be backward-compatible, so
-// add new ones to the end of this list.
-var ScopeType = { Global: 0,
-                  Local: 1,
-                  With: 2,
-                  Closure: 3,
-                  Catch: 4,
-                  Block: 5,
-                  Script: 6 };
-
-
-// Mirror hierarchy:
-//   - Mirror
-//     - ValueMirror
-//       - UndefinedMirror
-//       - NullMirror
-//       - NumberMirror
-//       - StringMirror
-//       - SymbolMirror
-//       - ObjectMirror
-//         - FunctionMirror
-//           - UnresolvedFunctionMirror
-//         - ArrayMirror
-//         - DateMirror
-//         - RegExpMirror
-//         - ErrorMirror
-//         - PromiseMirror
-//         - MapMirror
-//         - SetMirror
-//         - IteratorMirror
-//         - GeneratorMirror
-//     - PropertyMirror
-//     - InternalPropertyMirror
-//     - FrameMirror
-//     - ScriptMirror
-
-
-/**
- * Base class for all mirror objects.
- * @param {string} type The type of the mirror
- * @constructor
- */
-function Mirror(type) {
-  this.type_ = type;
-}
-
-
-Mirror.prototype.type = function() {
-  return this.type_;
-};
-
-
-/**
- * Check whether the mirror reflects a value.
- * @returns {boolean} True if the mirror reflects a value.
- */
-Mirror.prototype.isValue = function() {
-  return this instanceof ValueMirror;
-};
-
-
-/**
- * Check whether the mirror reflects the undefined value.
- * @returns {boolean} True if the mirror reflects the undefined value.
- */
-Mirror.prototype.isUndefined = function() {
-  return this instanceof UndefinedMirror;
-};
-
-
-/**
- * Check whether the mirror reflects the null value.
- * @returns {boolean} True if the mirror reflects the null value
- */
-Mirror.prototype.isNull = function() {
-  return this instanceof NullMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a boolean value.
- * @returns {boolean} True if the mirror reflects a boolean value
- */
-Mirror.prototype.isBoolean = function() {
-  return this instanceof BooleanMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a number value.
- * @returns {boolean} True if the mirror reflects a number value
- */
-Mirror.prototype.isNumber = function() {
-  return this instanceof NumberMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a string value.
- * @returns {boolean} True if the mirror reflects a string value
- */
-Mirror.prototype.isString = function() {
-  return this instanceof StringMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a symbol.
- * @returns {boolean} True if the mirror reflects a symbol
- */
-Mirror.prototype.isSymbol = function() {
-  return this instanceof SymbolMirror;
-};
-
-
-/**
- * Check whether the mirror reflects an object.
- * @returns {boolean} True if the mirror reflects an object
- */
-Mirror.prototype.isObject = function() {
-  return this instanceof ObjectMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a function.
- * @returns {boolean} True if the mirror reflects a function
- */
-Mirror.prototype.isFunction = function() {
-  return this instanceof FunctionMirror;
-};
-
-
-/**
- * Check whether the mirror reflects an unresolved function.
- * @returns {boolean} True if the mirror reflects an unresolved function
- */
-Mirror.prototype.isUnresolvedFunction = function() {
-  return this instanceof UnresolvedFunctionMirror;
-};
-
-
-/**
- * Check whether the mirror reflects an array.
- * @returns {boolean} True if the mirror reflects an array
- */
-Mirror.prototype.isArray = function() {
-  return this instanceof ArrayMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a date.
- * @returns {boolean} True if the mirror reflects a date
- */
-Mirror.prototype.isDate = function() {
-  return this instanceof DateMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a regular expression.
- * @returns {boolean} True if the mirror reflects a regular expression
- */
-Mirror.prototype.isRegExp = function() {
-  return this instanceof RegExpMirror;
-};
-
-
-/**
- * Check whether the mirror reflects an error.
- * @returns {boolean} True if the mirror reflects an error
- */
-Mirror.prototype.isError = function() {
-  return this instanceof ErrorMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a promise.
- * @returns {boolean} True if the mirror reflects a promise
- */
-Mirror.prototype.isPromise = function() {
-  return this instanceof PromiseMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a generator object.
- * @returns {boolean} True if the mirror reflects a generator object
- */
-Mirror.prototype.isGenerator = function() {
-  return this instanceof GeneratorMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a property.
- * @returns {boolean} True if the mirror reflects a property
- */
-Mirror.prototype.isProperty = function() {
-  return this instanceof PropertyMirror;
-};
-
-
-/**
- * Check whether the mirror reflects an internal property.
- * @returns {boolean} True if the mirror reflects an internal property
- */
-Mirror.prototype.isInternalProperty = function() {
-  return this instanceof InternalPropertyMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a stack frame.
- * @returns {boolean} True if the mirror reflects a stack frame
- */
-Mirror.prototype.isFrame = function() {
-  return this instanceof FrameMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a script.
- * @returns {boolean} True if the mirror reflects a script
- */
-Mirror.prototype.isScript = function() {
-  return this instanceof ScriptMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a context.
- * @returns {boolean} True if the mirror reflects a context
- */
-Mirror.prototype.isContext = function() {
-  return this instanceof ContextMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a scope.
- * @returns {boolean} True if the mirror reflects a scope
- */
-Mirror.prototype.isScope = function() {
-  return this instanceof ScopeMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a map.
- * @returns {boolean} True if the mirror reflects a map
- */
-Mirror.prototype.isMap = function() {
-  return this instanceof MapMirror;
-};
-
-
-/**
- * Check whether the mirror reflects a set.
- * @returns {boolean} True if the mirror reflects a set
- */
-Mirror.prototype.isSet = function() {
-  return this instanceof SetMirror;
-};
-
-
-/**
- * Check whether the mirror reflects an iterator.
- * @returns {boolean} True if the mirror reflects an iterator
- */
-Mirror.prototype.isIterator = function() {
-  return this instanceof IteratorMirror;
-};
-
-
-/**
- * Allocate a handle id for this object.
- */
-Mirror.prototype.allocateHandle_ = function() {
-  if (mirror_cache_enabled_) this.handle_ = next_handle_++;
-};
-
-
-/**
- * Allocate a transient handle id for this object. Transient handles are
- * negative.
- */
-Mirror.prototype.allocateTransientHandle_ = function() {
-  this.handle_ = next_transient_handle_--;
-};
-
-
-Mirror.prototype.toText = function() {
-  // Simpel to text which is used when on specialization in subclass.
-  return "#<" + this.constructor.name + ">";
-};
-
-
-/**
- * Base class for all value mirror objects.
- * @param {string} type The type of the mirror
- * @param {value} value The value reflected by this mirror
- * @param {boolean} transient indicate whether this object is transient with a
- *    transient handle
- * @constructor
- * @extends Mirror
- */
-function ValueMirror(type, value, transient) {
-  %_CallFunction(this, type, Mirror);
-  this.value_ = value;
-  if (!transient) {
-    this.allocateHandle_();
-  } else {
-    this.allocateTransientHandle_();
-  }
-}
-inherits(ValueMirror, Mirror);
-
-
-Mirror.prototype.handle = function() {
-  return this.handle_;
-};
-
-
-/**
- * Check whether this is a primitive value.
- * @return {boolean} True if the mirror reflects a primitive value
- */
-ValueMirror.prototype.isPrimitive = function() {
-  var type = this.type();
-  return type === 'undefined' ||
-         type === 'null' ||
-         type === 'boolean' ||
-         type === 'number' ||
-         type === 'string' ||
-         type === 'symbol';
-};
-
-
-/**
- * Get the actual value reflected by this mirror.
- * @return {value} The value reflected by this mirror
- */
-ValueMirror.prototype.value = function() {
-  return this.value_;
-};
-
-
-/**
- * Mirror object for Undefined.
- * @constructor
- * @extends ValueMirror
- */
-function UndefinedMirror() {
-  %_CallFunction(this, UNDEFINED_TYPE, UNDEFINED, ValueMirror);
-}
-inherits(UndefinedMirror, ValueMirror);
-
-
-UndefinedMirror.prototype.toText = function() {
-  return 'undefined';
-};
-
-
-/**
- * Mirror object for null.
- * @constructor
- * @extends ValueMirror
- */
-function NullMirror() {
-  %_CallFunction(this, NULL_TYPE, null, ValueMirror);
-}
-inherits(NullMirror, ValueMirror);
-
-
-NullMirror.prototype.toText = function() {
-  return 'null';
-};
-
-
-/**
- * Mirror object for boolean values.
- * @param {boolean} value The boolean value reflected by this mirror
- * @constructor
- * @extends ValueMirror
- */
-function BooleanMirror(value) {
-  %_CallFunction(this, BOOLEAN_TYPE, value, ValueMirror);
-}
-inherits(BooleanMirror, ValueMirror);
-
-
-BooleanMirror.prototype.toText = function() {
-  return this.value_ ? 'true' : 'false';
-};
-
-
-/**
- * Mirror object for number values.
- * @param {number} value The number value reflected by this mirror
- * @constructor
- * @extends ValueMirror
- */
-function NumberMirror(value) {
-  %_CallFunction(this, NUMBER_TYPE, value, ValueMirror);
-}
-inherits(NumberMirror, ValueMirror);
-
-
-NumberMirror.prototype.toText = function() {
-  return %_NumberToString(this.value_);
-};
-
-
-/**
- * Mirror object for string values.
- * @param {string} value The string value reflected by this mirror
- * @constructor
- * @extends ValueMirror
- */
-function StringMirror(value) {
-  %_CallFunction(this, STRING_TYPE, value, ValueMirror);
-}
-inherits(StringMirror, ValueMirror);
-
-
-StringMirror.prototype.length = function() {
-  return this.value_.length;
-};
-
-StringMirror.prototype.getTruncatedValue = function(maxLength) {
-  if (maxLength != -1 && this.length() > maxLength) {
-    return this.value_.substring(0, maxLength) +
-           '... (length: ' + this.length() + ')';
-  }
-  return this.value_;
-};
-
-StringMirror.prototype.toText = function() {
-  return this.getTruncatedValue(kMaxProtocolStringLength);
-};
-
-
-/**
- * Mirror object for a Symbol
- * @param {Object} value The Symbol
- * @constructor
- * @extends Mirror
- */
-function SymbolMirror(value) {
-  %_CallFunction(this, SYMBOL_TYPE, value, ValueMirror);
-}
-inherits(SymbolMirror, ValueMirror);
-
-
-SymbolMirror.prototype.description = function() {
-  return %SymbolDescription(%_ValueOf(this.value_));
-}
-
-
-SymbolMirror.prototype.toText = function() {
-  return %_CallFunction(this.value_, builtins.$symbolToString);
-}
-
-
-/**
- * Mirror object for objects.
- * @param {object} value The object reflected by this mirror
- * @param {boolean} transient indicate whether this object is transient with a
- *    transient handle
- * @constructor
- * @extends ValueMirror
- */
-function ObjectMirror(value, type, transient) {
-  %_CallFunction(this, type || OBJECT_TYPE, value, transient, ValueMirror);
-}
-inherits(ObjectMirror, ValueMirror);
-
-
-ObjectMirror.prototype.className = function() {
-  return %_ClassOf(this.value_);
-};
-
-
-ObjectMirror.prototype.constructorFunction = function() {
-  return MakeMirror(%DebugGetProperty(this.value_, 'constructor'));
-};
-
-
-ObjectMirror.prototype.prototypeObject = function() {
-  return MakeMirror(%DebugGetProperty(this.value_, 'prototype'));
-};
-
-
-ObjectMirror.prototype.protoObject = function() {
-  return MakeMirror(%DebugGetPrototype(this.value_));
-};
-
-
-ObjectMirror.prototype.hasNamedInterceptor = function() {
-  // Get information on interceptors for this object.
-  var x = %GetInterceptorInfo(this.value_);
-  return (x & 2) != 0;
-};
-
-
-ObjectMirror.prototype.hasIndexedInterceptor = function() {
-  // Get information on interceptors for this object.
-  var x = %GetInterceptorInfo(this.value_);
-  return (x & 1) != 0;
-};
-
-
-// Get all own property names except for private symbols.
-function TryGetPropertyNames(object) {
-  try {
-    // TODO(yangguo): Should there be a special debugger implementation of
-    // %GetOwnPropertyNames that doesn't perform access checks?
-    return %GetOwnPropertyNames(object, PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL);
-  } catch (e) {
-    // Might have hit a failed access check.
-    return [];
-  }
-}
-
-
-/**
- * Return the property names for this object.
- * @param {number} kind Indicate whether named, indexed or both kinds of
- *     properties are requested
- * @param {number} limit Limit the number of names returend to the specified
-       value
- * @return {Array} Property names for this object
- */
-ObjectMirror.prototype.propertyNames = function(kind, limit) {
-  // Find kind and limit and allocate array for the result
-  kind = kind || PropertyKind.Named | PropertyKind.Indexed;
-
-  var propertyNames;
-  var elementNames;
-  var total = 0;
-
-  // Find all the named properties.
-  if (kind & PropertyKind.Named) {
-    propertyNames = TryGetPropertyNames(this.value_);
-    total += propertyNames.length;
-
-    // Get names for named interceptor properties if any.
-    if (this.hasNamedInterceptor() && (kind & PropertyKind.Named)) {
-      var namedInterceptorNames =
-          %GetNamedInterceptorPropertyNames(this.value_);
-      if (namedInterceptorNames) {
-        propertyNames = propertyNames.concat(namedInterceptorNames);
-        total += namedInterceptorNames.length;
-      }
-    }
-  }
-
-  // Find all the indexed properties.
-  if (kind & PropertyKind.Indexed) {
-    // Get own element names.
-    elementNames = %GetOwnElementNames(this.value_);
-    total += elementNames.length;
-
-    // Get names for indexed interceptor properties.
-    if (this.hasIndexedInterceptor() && (kind & PropertyKind.Indexed)) {
-      var indexedInterceptorNames =
-          %GetIndexedInterceptorElementNames(this.value_);
-      if (indexedInterceptorNames) {
-        elementNames = elementNames.concat(indexedInterceptorNames);
-        total += indexedInterceptorNames.length;
-      }
-    }
-  }
-  limit = Math.min(limit || total, total);
-
-  var names = new Array(limit);
-  var index = 0;
-
-  // Copy names for named properties.
-  if (kind & PropertyKind.Named) {
-    for (var i = 0; index < limit && i < propertyNames.length; i++) {
-      names[index++] = propertyNames[i];
-    }
-  }
-
-  // Copy names for indexed properties.
-  if (kind & PropertyKind.Indexed) {
-    for (var i = 0; index < limit && i < elementNames.length; i++) {
-      names[index++] = elementNames[i];
-    }
-  }
-
-  return names;
-};
-
-
-/**
- * Return the properties for this object as an array of PropertyMirror objects.
- * @param {number} kind Indicate whether named, indexed or both kinds of
- *     properties are requested
- * @param {number} limit Limit the number of properties returned to the
-       specified value
- * @return {Array} Property mirrors for this object
- */
-ObjectMirror.prototype.properties = function(kind, limit) {
-  var names = this.propertyNames(kind, limit);
-  var properties = new Array(names.length);
-  for (var i = 0; i < names.length; i++) {
-    properties[i] = this.property(names[i]);
-  }
-
-  return properties;
-};
-
-
-/**
- * Return the internal properties for this object as an array of
- * InternalPropertyMirror objects.
- * @return {Array} Property mirrors for this object
- */
-ObjectMirror.prototype.internalProperties = function() {
-  return ObjectMirror.GetInternalProperties(this.value_);
-}
-
-
-ObjectMirror.prototype.property = function(name) {
-  var details = %DebugGetPropertyDetails(this.value_, builtins.$toName(name));
-  if (details) {
-    return new PropertyMirror(this, name, details);
-  }
-
-  // Nothing found.
-  return GetUndefinedMirror();
-};
-
-
-
-/**
- * Try to find a property from its value.
- * @param {Mirror} value The property value to look for
- * @return {PropertyMirror} The property with the specified value. If no
- *     property was found with the specified value UndefinedMirror is returned
- */
-ObjectMirror.prototype.lookupProperty = function(value) {
-  var properties = this.properties();
-
-  // Look for property value in properties.
-  for (var i = 0; i < properties.length; i++) {
-
-    // Skip properties which are defined through assessors.
-    var property = properties[i];
-    if (property.propertyType() != PropertyType.AccessorConstant) {
-      if (%_ObjectEquals(property.value_, value.value_)) {
-        return property;
-      }
-    }
-  }
-
-  // Nothing found.
-  return GetUndefinedMirror();
-};
-
-
-/**
- * Returns objects which has direct references to this object
- * @param {number} opt_max_objects Optional parameter specifying the maximum
- *     number of referencing objects to return.
- * @return {Array} The objects which has direct references to this object.
- */
-ObjectMirror.prototype.referencedBy = function(opt_max_objects) {
-  // Find all objects with direct references to this object.
-  var result = %DebugReferencedBy(this.value_,
-                                  Mirror.prototype, opt_max_objects || 0);
-
-  // Make mirrors for all the references found.
-  for (var i = 0; i < result.length; i++) {
-    result[i] = MakeMirror(result[i]);
-  }
-
-  return result;
-};
-
-
-ObjectMirror.prototype.toText = function() {
-  var name;
-  var ctor = this.constructorFunction();
-  if (!ctor.isFunction()) {
-    name = this.className();
-  } else {
-    name = ctor.name();
-    if (!name) {
-      name = this.className();
-    }
-  }
-  return '#<' + name + '>';
-};
-
-
-/**
- * Return the internal properties of the value, such as [[PrimitiveValue]] of
- * scalar wrapper objects, properties of the bound function and properties of
- * the promise.
- * This method is done static to be accessible from Debug API with the bare
- * values without mirrors.
- * @return {Array} array (possibly empty) of InternalProperty instances
- */
-ObjectMirror.GetInternalProperties = function(value) {
-  var properties = %DebugGetInternalProperties(value);
-  var result = [];
-  for (var i = 0; i < properties.length; i += 2) {
-    result.push(new InternalPropertyMirror(properties[i], properties[i + 1]));
-  }
-  return result;
-}
-
-
-/**
- * Mirror object for functions.
- * @param {function} value The function object reflected by this mirror.
- * @constructor
- * @extends ObjectMirror
- */
-function FunctionMirror(value) {
-  %_CallFunction(this, value, FUNCTION_TYPE, ObjectMirror);
-  this.resolved_ = true;
-}
-inherits(FunctionMirror, ObjectMirror);
-
-
-/**
- * Returns whether the function is resolved.
- * @return {boolean} True if the function is resolved. Unresolved functions can
- *     only originate as functions from stack frames
- */
-FunctionMirror.prototype.resolved = function() {
-  return this.resolved_;
-};
-
-
-/**
- * Returns the name of the function.
- * @return {string} Name of the function
- */
-FunctionMirror.prototype.name = function() {
-  return %FunctionGetName(this.value_);
-};
-
-
-/**
- * Returns the inferred name of the function.
- * @return {string} Name of the function
- */
-FunctionMirror.prototype.inferredName = function() {
-  return %FunctionGetInferredName(this.value_);
-};
-
-
-/**
- * Returns the source code for the function.
- * @return {string or undefined} The source code for the function. If the
- *     function is not resolved undefined will be returned.
- */
-FunctionMirror.prototype.source = function() {
-  // Return source if function is resolved. Otherwise just fall through to
-  // return undefined.
-  if (this.resolved()) {
-    return builtins.$functionSourceString(this.value_);
-  }
-};
-
-
-/**
- * Returns the script object for the function.
- * @return {ScriptMirror or undefined} Script object for the function or
- *     undefined if the function has no script
- */
-FunctionMirror.prototype.script = function() {
-  // Return script if function is resolved. Otherwise just fall through
-  // to return undefined.
-  if (this.resolved()) {
-    if (this.script_) {
-      return this.script_;
-    }
-    var script = %FunctionGetScript(this.value_);
-    if (script) {
-      return this.script_ = MakeMirror(script);
-    }
-  }
-};
-
-
-/**
- * Returns the script source position for the function. Only makes sense
- * for functions which has a script defined.
- * @return {Number or undefined} in-script position for the function
- */
-FunctionMirror.prototype.sourcePosition_ = function() {
-  // Return position if function is resolved. Otherwise just fall
-  // through to return undefined.
-  if (this.resolved()) {
-    return %FunctionGetScriptSourcePosition(this.value_);
-  }
-};
-
-
-/**
- * Returns the script source location object for the function. Only makes sense
- * for functions which has a script defined.
- * @return {Location or undefined} in-script location for the function begin
- */
-FunctionMirror.prototype.sourceLocation = function() {
-  if (this.resolved()) {
-    var script = this.script();
-    if (script) {
-      return script.locationFromPosition(this.sourcePosition_(), true);
-    }
-  }
-};
-
-
-/**
- * Returns objects constructed by this function.
- * @param {number} opt_max_instances Optional parameter specifying the maximum
- *     number of instances to return.
- * @return {Array or undefined} The objects constructed by this function.
- */
-FunctionMirror.prototype.constructedBy = function(opt_max_instances) {
-  if (this.resolved()) {
-    // Find all objects constructed from this function.
-    var result = %DebugConstructedBy(this.value_, opt_max_instances || 0);
-
-    // Make mirrors for all the instances found.
-    for (var i = 0; i < result.length; i++) {
-      result[i] = MakeMirror(result[i]);
-    }
-
-    return result;
-  } else {
-    return [];
-  }
-};
-
-
-FunctionMirror.prototype.scopeCount = function() {
-  if (this.resolved()) {
-    if (IS_UNDEFINED(this.scopeCount_)) {
-      this.scopeCount_ = %GetFunctionScopeCount(this.value());
-    }
-    return this.scopeCount_;
-  } else {
-    return 0;
-  }
-};
-
-
-FunctionMirror.prototype.scope = function(index) {
-  if (this.resolved()) {
-    return new ScopeMirror(UNDEFINED, this, index);
-  }
-};
-
-
-FunctionMirror.prototype.toText = function() {
-  return this.source();
-};
-
-
-/**
- * Mirror object for unresolved functions.
- * @param {string} value The name for the unresolved function reflected by this
- *     mirror.
- * @constructor
- * @extends ObjectMirror
- */
-function UnresolvedFunctionMirror(value) {
-  // Construct this using the ValueMirror as an unresolved function is not a
-  // real object but just a string.
-  %_CallFunction(this, FUNCTION_TYPE, value, ValueMirror);
-  this.propertyCount_ = 0;
-  this.elementCount_ = 0;
-  this.resolved_ = false;
-}
-inherits(UnresolvedFunctionMirror, FunctionMirror);
-
-
-UnresolvedFunctionMirror.prototype.className = function() {
-  return 'Function';
-};
-
-
-UnresolvedFunctionMirror.prototype.constructorFunction = function() {
-  return GetUndefinedMirror();
-};
-
-
-UnresolvedFunctionMirror.prototype.prototypeObject = function() {
-  return GetUndefinedMirror();
-};
-
-
-UnresolvedFunctionMirror.prototype.protoObject = function() {
-  return GetUndefinedMirror();
-};
-
-
-UnresolvedFunctionMirror.prototype.name = function() {
-  return this.value_;
-};
-
-
-UnresolvedFunctionMirror.prototype.inferredName = function() {
-  return undefined;
-};
-
-
-UnresolvedFunctionMirror.prototype.propertyNames = function(kind, limit) {
-  return [];
-};
-
-
-/**
- * Mirror object for arrays.
- * @param {Array} value The Array object reflected by this mirror
- * @constructor
- * @extends ObjectMirror
- */
-function ArrayMirror(value) {
-  %_CallFunction(this, value, ObjectMirror);
-}
-inherits(ArrayMirror, ObjectMirror);
-
-
-ArrayMirror.prototype.length = function() {
-  return this.value_.length;
-};
-
-
-ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index,
-                                                            opt_to_index) {
-  var from_index = opt_from_index || 0;
-  var to_index = opt_to_index || this.length() - 1;
-  if (from_index > to_index) return new Array();
-  var values = new Array(to_index - from_index + 1);
-  for (var i = from_index; i <= to_index; i++) {
-    var details = %DebugGetPropertyDetails(this.value_, builtins.$toString(i));
-    var value;
-    if (details) {
-      value = new PropertyMirror(this, i, details);
-    } else {
-      value = GetUndefinedMirror();
-    }
-    values[i - from_index] = value;
-  }
-  return values;
-};
-
-
-/**
- * Mirror object for dates.
- * @param {Date} value The Date object reflected by this mirror
- * @constructor
- * @extends ObjectMirror
- */
-function DateMirror(value) {
-  %_CallFunction(this, value, ObjectMirror);
-}
-inherits(DateMirror, ObjectMirror);
-
-
-DateMirror.prototype.toText = function() {
-  var s = JSON.stringify(this.value_);
-  return s.substring(1, s.length - 1);  // cut quotes
-};
-
-
-/**
- * Mirror object for regular expressions.
- * @param {RegExp} value The RegExp object reflected by this mirror
- * @constructor
- * @extends ObjectMirror
- */
-function RegExpMirror(value) {
-  %_CallFunction(this, value, REGEXP_TYPE, ObjectMirror);
-}
-inherits(RegExpMirror, ObjectMirror);
-
-
-/**
- * Returns the source to the regular expression.
- * @return {string or undefined} The source to the regular expression
- */
-RegExpMirror.prototype.source = function() {
-  return this.value_.source;
-};
-
-
-/**
- * Returns whether this regular expression has the global (g) flag set.
- * @return {boolean} Value of the global flag
- */
-RegExpMirror.prototype.global = function() {
-  return this.value_.global;
-};
-
-
-/**
- * Returns whether this regular expression has the ignore case (i) flag set.
- * @return {boolean} Value of the ignore case flag
- */
-RegExpMirror.prototype.ignoreCase = function() {
-  return this.value_.ignoreCase;
-};
-
-
-/**
- * Returns whether this regular expression has the multiline (m) flag set.
- * @return {boolean} Value of the multiline flag
- */
-RegExpMirror.prototype.multiline = function() {
-  return this.value_.multiline;
-};
-
-
-/**
- * Returns whether this regular expression has the sticky (y) flag set.
- * @return {boolean} Value of the sticky flag
- */
-RegExpMirror.prototype.sticky = function() {
-  return this.value_.sticky;
-};
-
-
-/**
- * Returns whether this regular expression has the unicode (u) flag set.
- * @return {boolean} Value of the unicode flag
- */
-RegExpMirror.prototype.unicode = function() {
-  return this.value_.unicode;
-};
-
-
-RegExpMirror.prototype.toText = function() {
-  // Simpel to text which is used when on specialization in subclass.
-  return "/" + this.source() + "/";
-};
-
-
-/**
- * Mirror object for error objects.
- * @param {Error} value The error object reflected by this mirror
- * @constructor
- * @extends ObjectMirror
- */
-function ErrorMirror(value) {
-  %_CallFunction(this, value, ERROR_TYPE, ObjectMirror);
-}
-inherits(ErrorMirror, ObjectMirror);
-
-
-/**
- * Returns the message for this eror object.
- * @return {string or undefined} The message for this eror object
- */
-ErrorMirror.prototype.message = function() {
-  return this.value_.message;
-};
-
-
-ErrorMirror.prototype.toText = function() {
-  // Use the same text representation as in messages.js.
-  var text;
-  try {
-    text = %_CallFunction(this.value_, builtins.$errorToString);
-  } catch (e) {
-    text = '#<Error>';
-  }
-  return text;
-};
-
-
-/**
- * Mirror object for a Promise object.
- * @param {Object} value The Promise object
- * @constructor
- * @extends ObjectMirror
- */
-function PromiseMirror(value) {
-  %_CallFunction(this, value, PROMISE_TYPE, ObjectMirror);
-}
-inherits(PromiseMirror, ObjectMirror);
-
-
-function PromiseGetStatus_(value) {
-  var status = %DebugGetProperty(value, builtins.$promiseStatus);
-  if (status == 0) return "pending";
-  if (status == 1) return "resolved";
-  return "rejected";
-}
-
-
-function PromiseGetValue_(value) {
-  return %DebugGetProperty(value, builtins.$promiseValue);
-}
-
-
-PromiseMirror.prototype.status = function() {
-  return PromiseGetStatus_(this.value_);
-};
-
-
-PromiseMirror.prototype.promiseValue = function() {
-  return MakeMirror(PromiseGetValue_(this.value_));
-};
-
-
-function MapMirror(value) {
-  %_CallFunction(this, value, MAP_TYPE, ObjectMirror);
-}
-inherits(MapMirror, ObjectMirror);
-
-
-/**
- * Returns an array of key/value pairs of a map.
- * This will keep keys alive for WeakMaps.
- *
- * @param {number=} opt_limit Max elements to return.
- * @returns {Array.<Object>} Array of key/value pairs of a map.
- */
-MapMirror.prototype.entries = function(opt_limit) {
-  var result = [];
-
-  if (IS_WEAKMAP(this.value_)) {
-    var entries = %GetWeakMapEntries(this.value_, opt_limit || 0);
-    for (var i = 0; i < entries.length; i += 2) {
-      result.push({
-        key: entries[i],
-        value: entries[i + 1]
-      });
-    }
-    return result;
-  }
-
-  var iter = %_CallFunction(this.value_, builtins.$mapEntries);
-  var next;
-  while ((!opt_limit || result.length < opt_limit) &&
-         !(next = iter.next()).done) {
-    result.push({
-      key: next.value[0],
-      value: next.value[1]
-    });
-  }
-  return result;
-};
-
-
-function SetMirror(value) {
-  %_CallFunction(this, value, SET_TYPE, ObjectMirror);
-}
-inherits(SetMirror, ObjectMirror);
-
-
-function IteratorGetValues_(iter, next_function, opt_limit) {
-  var result = [];
-  var next;
-  while ((!opt_limit || result.length < opt_limit) &&
-         !(next = %_CallFunction(iter, next_function)).done) {
-    result.push(next.value);
-  }
-  return result;
-}
-
-
-/**
- * Returns an array of elements of a set.
- * This will keep elements alive for WeakSets.
- *
- * @param {number=} opt_limit Max elements to return.
- * @returns {Array.<Object>} Array of elements of a set.
- */
-SetMirror.prototype.values = function(opt_limit) {
-  if (IS_WEAKSET(this.value_)) {
-    return %GetWeakSetValues(this.value_, opt_limit || 0);
-  }
-
-  var iter = %_CallFunction(this.value_, builtins.$setValues);
-  return IteratorGetValues_(iter, builtins.$setIteratorNext, opt_limit);
-};
-
-
-function IteratorMirror(value) {
-  %_CallFunction(this, value, ITERATOR_TYPE, ObjectMirror);
-}
-inherits(IteratorMirror, ObjectMirror);
-
-
-/**
- * Returns a preview of elements of an iterator.
- * Does not change the backing iterator state.
- *
- * @param {number=} opt_limit Max elements to return.
- * @returns {Array.<Object>} Array of elements of an iterator.
- */
-IteratorMirror.prototype.preview = function(opt_limit) {
-  if (IS_MAP_ITERATOR(this.value_)) {
-    return IteratorGetValues_(%MapIteratorClone(this.value_),
-                              builtins.$mapIteratorNext,
-                              opt_limit);
-  } else if (IS_SET_ITERATOR(this.value_)) {
-    return IteratorGetValues_(%SetIteratorClone(this.value_),
-                              builtins.$setIteratorNext,
-                              opt_limit);
-  }
-};
-
-
-/**
- * Mirror object for a Generator object.
- * @param {Object} data The Generator object
- * @constructor
- * @extends Mirror
- */
-function GeneratorMirror(value) {
-  %_CallFunction(this, value, GENERATOR_TYPE, ObjectMirror);
-}
-inherits(GeneratorMirror, ObjectMirror);
-
-
-function GeneratorGetStatus_(value) {
-  var continuation = %GeneratorGetContinuation(value);
-  if (continuation < 0) return "running";
-  if (continuation == 0) return "closed";
-  return "suspended";
-}
-
-
-GeneratorMirror.prototype.status = function() {
-  return GeneratorGetStatus_(this.value_);
-};
-
-
-GeneratorMirror.prototype.sourcePosition_ = function() {
-  return %GeneratorGetSourcePosition(this.value_);
-};
-
-
-GeneratorMirror.prototype.sourceLocation = function() {
-  var pos = this.sourcePosition_();
-  if (!IS_UNDEFINED(pos)) {
-    var script = this.func().script();
-    if (script) {
-      return script.locationFromPosition(pos, true);
-    }
-  }
-};
-
-
-GeneratorMirror.prototype.func = function() {
-  if (!this.func_) {
-    this.func_ = MakeMirror(%GeneratorGetFunction(this.value_));
-  }
-  return this.func_;
-};
-
-
-GeneratorMirror.prototype.context = function() {
-  if (!this.context_) {
-    this.context_ = new ContextMirror(%GeneratorGetContext(this.value_));
-  }
-  return this.context_;
-};
-
-
-GeneratorMirror.prototype.receiver = function() {
-  if (!this.receiver_) {
-    this.receiver_ = MakeMirror(%GeneratorGetReceiver(this.value_));
-  }
-  return this.receiver_;
-};
-
-
-/**
- * Base mirror object for properties.
- * @param {ObjectMirror} mirror The mirror object having this property
- * @param {string} name The name of the property
- * @param {Array} details Details about the property
- * @constructor
- * @extends Mirror
- */
-function PropertyMirror(mirror, name, details) {
-  %_CallFunction(this, PROPERTY_TYPE, Mirror);
-  this.mirror_ = mirror;
-  this.name_ = name;
-  this.value_ = details[0];
-  this.details_ = details[1];
-  this.is_interceptor_ = details[2];
-  if (details.length > 3) {
-    this.exception_ = details[3];
-    this.getter_ = details[4];
-    this.setter_ = details[5];
-  }
-}
-inherits(PropertyMirror, Mirror);
-
-
-PropertyMirror.prototype.isReadOnly = function() {
-  return (this.attributes() & PropertyAttribute.ReadOnly) != 0;
-};
-
-
-PropertyMirror.prototype.isEnum = function() {
-  return (this.attributes() & PropertyAttribute.DontEnum) == 0;
-};
-
-
-PropertyMirror.prototype.canDelete = function() {
-  return (this.attributes() & PropertyAttribute.DontDelete) == 0;
-};
-
-
-PropertyMirror.prototype.name = function() {
-  return this.name_;
-};
-
-
-PropertyMirror.prototype.isIndexed = function() {
-  for (var i = 0; i < this.name_.length; i++) {
-    if (this.name_[i] < '0' || '9' < this.name_[i]) {
-      return false;
-    }
-  }
-  return true;
-};
-
-
-PropertyMirror.prototype.value = function() {
-  return MakeMirror(this.value_, false);
-};
-
-
-/**
- * Returns whether this property value is an exception.
- * @return {booolean} True if this property value is an exception
- */
-PropertyMirror.prototype.isException = function() {
-  return this.exception_ ? true : false;
-};
-
-
-PropertyMirror.prototype.attributes = function() {
-  return %DebugPropertyAttributesFromDetails(this.details_);
-};
-
-
-PropertyMirror.prototype.propertyType = function() {
-  return %DebugPropertyTypeFromDetails(this.details_);
-};
-
-
-PropertyMirror.prototype.insertionIndex = function() {
-  return %DebugPropertyIndexFromDetails(this.details_);
-};
-
-
-/**
- * Returns whether this property has a getter defined through __defineGetter__.
- * @return {booolean} True if this property has a getter
- */
-PropertyMirror.prototype.hasGetter = function() {
-  return this.getter_ ? true : false;
-};
-
-
-/**
- * Returns whether this property has a setter defined through __defineSetter__.
- * @return {booolean} True if this property has a setter
- */
-PropertyMirror.prototype.hasSetter = function() {
-  return this.setter_ ? true : false;
-};
-
-
-/**
- * Returns the getter for this property defined through __defineGetter__.
- * @return {Mirror} FunctionMirror reflecting the getter function or
- *     UndefinedMirror if there is no getter for this property
- */
-PropertyMirror.prototype.getter = function() {
-  if (this.hasGetter()) {
-    return MakeMirror(this.getter_);
-  } else {
-    return GetUndefinedMirror();
-  }
-};
-
-
-/**
- * Returns the setter for this property defined through __defineSetter__.
- * @return {Mirror} FunctionMirror reflecting the setter function or
- *     UndefinedMirror if there is no setter for this property
- */
-PropertyMirror.prototype.setter = function() {
-  if (this.hasSetter()) {
-    return MakeMirror(this.setter_);
-  } else {
-    return GetUndefinedMirror();
-  }
-};
-
-
-/**
- * Returns whether this property is natively implemented by the host or a set
- * through JavaScript code.
- * @return {boolean} True if the property is
- *     UndefinedMirror if there is no setter for this property
- */
-PropertyMirror.prototype.isNative = function() {
-  return this.is_interceptor_ ||
-         ((this.propertyType() == PropertyType.AccessorConstant) &&
-          !this.hasGetter() && !this.hasSetter());
-};
-
-
-/**
- * Mirror object for internal properties. Internal property reflects properties
- * not accessible from user code such as [[BoundThis]] in bound function.
- * Their names are merely symbolic.
- * @param {string} name The name of the property
- * @param {value} property value
- * @constructor
- * @extends Mirror
- */
-function InternalPropertyMirror(name, value) {
-  %_CallFunction(this, INTERNAL_PROPERTY_TYPE, Mirror);
-  this.name_ = name;
-  this.value_ = value;
-}
-inherits(InternalPropertyMirror, Mirror);
-
-
-InternalPropertyMirror.prototype.name = function() {
-  return this.name_;
-};
-
-
-InternalPropertyMirror.prototype.value = function() {
-  return MakeMirror(this.value_, false);
-};
-
-
-var kFrameDetailsFrameIdIndex = 0;
-var kFrameDetailsReceiverIndex = 1;
-var kFrameDetailsFunctionIndex = 2;
-var kFrameDetailsArgumentCountIndex = 3;
-var kFrameDetailsLocalCountIndex = 4;
-var kFrameDetailsSourcePositionIndex = 5;
-var kFrameDetailsConstructCallIndex = 6;
-var kFrameDetailsAtReturnIndex = 7;
-var kFrameDetailsFlagsIndex = 8;
-var kFrameDetailsFirstDynamicIndex = 9;
-
-var kFrameDetailsNameIndex = 0;
-var kFrameDetailsValueIndex = 1;
-var kFrameDetailsNameValueSize = 2;
-
-var kFrameDetailsFlagDebuggerFrameMask = 1 << 0;
-var kFrameDetailsFlagOptimizedFrameMask = 1 << 1;
-var kFrameDetailsFlagInlinedFrameIndexMask = 7 << 2;
-
-/**
- * Wrapper for the frame details information retreived from the VM. The frame
- * details from the VM is an array with the following content. See runtime.cc
- * Runtime_GetFrameDetails.
- *     0: Id
- *     1: Receiver
- *     2: Function
- *     3: Argument count
- *     4: Local count
- *     5: Source position
- *     6: Construct call
- *     7: Is at return
- *     8: Flags (debugger frame, optimized frame, inlined frame index)
- *     Arguments name, value
- *     Locals name, value
- *     Return value if any
- * @param {number} break_id Current break id
- * @param {number} index Frame number
- * @constructor
- */
-function FrameDetails(break_id, index) {
-  this.break_id_ = break_id;
-  this.details_ = %GetFrameDetails(break_id, index);
-}
-
-
-FrameDetails.prototype.frameId = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsFrameIdIndex];
-};
-
-
-FrameDetails.prototype.receiver = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsReceiverIndex];
-};
-
-
-FrameDetails.prototype.func = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsFunctionIndex];
-};
-
-
-FrameDetails.prototype.isConstructCall = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsConstructCallIndex];
-};
-
-
-FrameDetails.prototype.isAtReturn = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsAtReturnIndex];
-};
-
-
-FrameDetails.prototype.isDebuggerFrame = function() {
-  %CheckExecutionState(this.break_id_);
-  var f = kFrameDetailsFlagDebuggerFrameMask;
-  return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
-};
-
-
-FrameDetails.prototype.isOptimizedFrame = function() {
-  %CheckExecutionState(this.break_id_);
-  var f = kFrameDetailsFlagOptimizedFrameMask;
-  return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
-};
-
-
-FrameDetails.prototype.isInlinedFrame = function() {
-  return this.inlinedFrameIndex() > 0;
-};
-
-
-FrameDetails.prototype.inlinedFrameIndex = function() {
-  %CheckExecutionState(this.break_id_);
-  var f = kFrameDetailsFlagInlinedFrameIndexMask;
-  return (this.details_[kFrameDetailsFlagsIndex] & f) >> 2;
-};
-
-
-FrameDetails.prototype.argumentCount = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsArgumentCountIndex];
-};
-
-
-FrameDetails.prototype.argumentName = function(index) {
-  %CheckExecutionState(this.break_id_);
-  if (index >= 0 && index < this.argumentCount()) {
-    return this.details_[kFrameDetailsFirstDynamicIndex +
-                         index * kFrameDetailsNameValueSize +
-                         kFrameDetailsNameIndex];
-  }
-};
-
-
-FrameDetails.prototype.argumentValue = function(index) {
-  %CheckExecutionState(this.break_id_);
-  if (index >= 0 && index < this.argumentCount()) {
-    return this.details_[kFrameDetailsFirstDynamicIndex +
-                         index * kFrameDetailsNameValueSize +
-                         kFrameDetailsValueIndex];
-  }
-};
-
-
-FrameDetails.prototype.localCount = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsLocalCountIndex];
-};
-
-
-FrameDetails.prototype.sourcePosition = function() {
-  %CheckExecutionState(this.break_id_);
-  return this.details_[kFrameDetailsSourcePositionIndex];
-};
-
-
-FrameDetails.prototype.localName = function(index) {
-  %CheckExecutionState(this.break_id_);
-  if (index >= 0 && index < this.localCount()) {
-    var locals_offset = kFrameDetailsFirstDynamicIndex +
-                        this.argumentCount() * kFrameDetailsNameValueSize;
-    return this.details_[locals_offset +
-                         index * kFrameDetailsNameValueSize +
-                         kFrameDetailsNameIndex];
-  }
-};
-
-
-FrameDetails.prototype.localValue = function(index) {
-  %CheckExecutionState(this.break_id_);
-  if (index >= 0 && index < this.localCount()) {
-    var locals_offset = kFrameDetailsFirstDynamicIndex +
-                        this.argumentCount() * kFrameDetailsNameValueSize;
-    return this.details_[locals_offset +
-                         index * kFrameDetailsNameValueSize +
-                         kFrameDetailsValueIndex];
-  }
-};
-
-
-FrameDetails.prototype.returnValue = function() {
-  %CheckExecutionState(this.break_id_);
-  var return_value_offset =
-      kFrameDetailsFirstDynamicIndex +
-      (this.argumentCount() + this.localCount()) * kFrameDetailsNameValueSize;
-  if (this.details_[kFrameDetailsAtReturnIndex]) {
-    return this.details_[return_value_offset];
-  }
-};
-
-
-FrameDetails.prototype.scopeCount = function() {
-  if (IS_UNDEFINED(this.scopeCount_)) {
-    this.scopeCount_ = %GetScopeCount(this.break_id_, this.frameId());
-  }
-  return this.scopeCount_;
-};
-
-
-FrameDetails.prototype.stepInPositionsImpl = function() {
-  return %GetStepInPositions(this.break_id_, this.frameId());
-};
-
-
-/**
- * Mirror object for stack frames.
- * @param {number} break_id The break id in the VM for which this frame is
-       valid
- * @param {number} index The frame index (top frame is index 0)
- * @constructor
- * @extends Mirror
- */
-function FrameMirror(break_id, index) {
-  %_CallFunction(this, FRAME_TYPE, Mirror);
-  this.break_id_ = break_id;
-  this.index_ = index;
-  this.details_ = new FrameDetails(break_id, index);
-}
-inherits(FrameMirror, Mirror);
-
-
-FrameMirror.prototype.details = function() {
-  return this.details_;
-};
-
-
-FrameMirror.prototype.index = function() {
-  return this.index_;
-};
-
-
-FrameMirror.prototype.func = function() {
-  if (this.func_) {
-    return this.func_;
-  }
-
-  // Get the function for this frame from the VM.
-  var f = this.details_.func();
-
-  // Create a function mirror. NOTE: MakeMirror cannot be used here as the
-  // value returned from the VM might be a string if the function for the
-  // frame is unresolved.
-  if (IS_FUNCTION(f)) {
-    return this.func_ = MakeMirror(f);
-  } else {
-    return new UnresolvedFunctionMirror(f);
-  }
-};
-
-
-FrameMirror.prototype.receiver = function() {
-  return MakeMirror(this.details_.receiver());
-};
-
-
-FrameMirror.prototype.isConstructCall = function() {
-  return this.details_.isConstructCall();
-};
-
-
-FrameMirror.prototype.isAtReturn = function() {
-  return this.details_.isAtReturn();
-};
-
-
-FrameMirror.prototype.isDebuggerFrame = function() {
-  return this.details_.isDebuggerFrame();
-};
-
-
-FrameMirror.prototype.isOptimizedFrame = function() {
-  return this.details_.isOptimizedFrame();
-};
-
-
-FrameMirror.prototype.isInlinedFrame = function() {
-  return this.details_.isInlinedFrame();
-};
-
-
-FrameMirror.prototype.inlinedFrameIndex = function() {
-  return this.details_.inlinedFrameIndex();
-};
-
-
-FrameMirror.prototype.argumentCount = function() {
-  return this.details_.argumentCount();
-};
-
-
-FrameMirror.prototype.argumentName = function(index) {
-  return this.details_.argumentName(index);
-};
-
-
-FrameMirror.prototype.argumentValue = function(index) {
-  return MakeMirror(this.details_.argumentValue(index));
-};
-
-
-FrameMirror.prototype.localCount = function() {
-  return this.details_.localCount();
-};
-
-
-FrameMirror.prototype.localName = function(index) {
-  return this.details_.localName(index);
-};
-
-
-FrameMirror.prototype.localValue = function(index) {
-  return MakeMirror(this.details_.localValue(index));
-};
-
-
-FrameMirror.prototype.returnValue = function() {
-  return MakeMirror(this.details_.returnValue());
-};
-
-
-FrameMirror.prototype.sourcePosition = function() {
-  return this.details_.sourcePosition();
-};
-
-
-FrameMirror.prototype.sourceLocation = function() {
-  var func = this.func();
-  if (func.resolved()) {
-    var script = func.script();
-    if (script) {
-      return script.locationFromPosition(this.sourcePosition(), true);
-    }
-  }
-};
-
-
-FrameMirror.prototype.sourceLine = function() {
-  var location = this.sourceLocation();
-  if (location) {
-    return location.line;
-  }
-};
-
-
-FrameMirror.prototype.sourceColumn = function() {
-  var location = this.sourceLocation();
-  if (location) {
-    return location.column;
-  }
-};
-
-
-FrameMirror.prototype.sourceLineText = function() {
-  var location = this.sourceLocation();
-  if (location) {
-    return location.sourceText();
-  }
-};
-
-
-FrameMirror.prototype.scopeCount = function() {
-  return this.details_.scopeCount();
-};
-
-
-FrameMirror.prototype.scope = function(index) {
-  return new ScopeMirror(this, UNDEFINED, index);
-};
-
-
-FrameMirror.prototype.allScopes = function(opt_ignore_nested_scopes) {
-  var scopeDetails = %GetAllScopesDetails(this.break_id_,
-                                          this.details_.frameId(),
-                                          this.details_.inlinedFrameIndex(),
-                                          !!opt_ignore_nested_scopes);
-  var result = [];
-  for (var i = 0; i < scopeDetails.length; ++i) {
-    result.push(new ScopeMirror(this, UNDEFINED, i, scopeDetails[i]));
-  }
-  return result;
-};
-
-
-FrameMirror.prototype.stepInPositions = function() {
-  var script = this.func().script();
-  var funcOffset = this.func().sourcePosition_();
-
-  var stepInRaw = this.details_.stepInPositionsImpl();
-  var result = [];
-  if (stepInRaw) {
-    for (var i = 0; i < stepInRaw.length; i++) {
-      var posStruct = {};
-      var offset = script.locationFromPosition(funcOffset + stepInRaw[i],
-                                               true);
-      serializeLocationFields(offset, posStruct);
-      var item = {
-        position: posStruct
-      };
-      result.push(item);
-    }
-  }
-
-  return result;
-};
-
-
-FrameMirror.prototype.evaluate = function(source, disable_break,
-                                          opt_context_object) {
-  return MakeMirror(%DebugEvaluate(this.break_id_,
-                                   this.details_.frameId(),
-                                   this.details_.inlinedFrameIndex(),
-                                   source,
-                                   Boolean(disable_break),
-                                   opt_context_object));
-};
-
-
-FrameMirror.prototype.invocationText = function() {
-  // Format frame invoaction (receiver, function and arguments).
-  var result = '';
-  var func = this.func();
-  var receiver = this.receiver();
-  if (this.isConstructCall()) {
-    // For constructor frames display new followed by the function name.
-    result += 'new ';
-    result += func.name() ? func.name() : '[anonymous]';
-  } else if (this.isDebuggerFrame()) {
-    result += '[debugger]';
-  } else {
-    // If the receiver has a className which is 'global' don't display it.
-    var display_receiver =
-      !receiver.className || (receiver.className() != 'global');
-    if (display_receiver) {
-      result += receiver.toText();
-    }
-    // Try to find the function as a property in the receiver. Include the
-    // prototype chain in the lookup.
-    var property = GetUndefinedMirror();
-    if (receiver.isObject()) {
-      for (var r = receiver;
-           !r.isNull() && property.isUndefined();
-           r = r.protoObject()) {
-        property = r.lookupProperty(func);
-      }
-    }
-    if (!property.isUndefined()) {
-      // The function invoked was found on the receiver. Use the property name
-      // for the backtrace.
-      if (!property.isIndexed()) {
-        if (display_receiver) {
-          result += '.';
-        }
-        result += property.name();
-      } else {
-        result += '[';
-        result += property.name();
-        result += ']';
-      }
-      // Also known as - if the name in the function doesn't match the name
-      // under which it was looked up.
-      if (func.name() && func.name() != property.name()) {
-        result += '(aka ' + func.name() + ')';
-      }
-    } else {
-      // The function invoked was not found on the receiver. Use the function
-      // name if available for the backtrace.
-      if (display_receiver) {
-        result += '.';
-      }
-      result += func.name() ? func.name() : '[anonymous]';
-    }
-  }
-
-  // Render arguments for normal frames.
-  if (!this.isDebuggerFrame()) {
-    result += '(';
-    for (var i = 0; i < this.argumentCount(); i++) {
-      if (i != 0) result += ', ';
-      if (this.argumentName(i)) {
-        result += this.argumentName(i);
-        result += '=';
-      }
-      result += this.argumentValue(i).toText();
-    }
-    result += ')';
-  }
-
-  if (this.isAtReturn()) {
-    result += ' returning ';
-    result += this.returnValue().toText();
-  }
-
-  return result;
-};
-
-
-FrameMirror.prototype.sourceAndPositionText = function() {
-  // Format source and position.
-  var result = '';
-  var func = this.func();
-  if (func.resolved()) {
-    var script = func.script();
-    if (script) {
-      if (script.name()) {
-        result += script.name();
-      } else {
-        result += '[unnamed]';
-      }
-      if (!this.isDebuggerFrame()) {
-        var location = this.sourceLocation();
-        result += ' line ';
-        result += !IS_UNDEFINED(location) ? (location.line + 1) : '?';
-        result += ' column ';
-        result += !IS_UNDEFINED(location) ? (location.column + 1) : '?';
-        if (!IS_UNDEFINED(this.sourcePosition())) {
-          result += ' (position ' + (this.sourcePosition() + 1) + ')';
-        }
-      }
-    } else {
-      result += '[no source]';
-    }
-  } else {
-    result += '[unresolved]';
-  }
-
-  return result;
-};
-
-
-FrameMirror.prototype.localsText = function() {
-  // Format local variables.
-  var result = '';
-  var locals_count = this.localCount();
-  if (locals_count > 0) {
-    for (var i = 0; i < locals_count; ++i) {
-      result += '      var ';
-      result += this.localName(i);
-      result += ' = ';
-      result += this.localValue(i).toText();
-      if (i < locals_count - 1) result += '\n';
-    }
-  }
-
-  return result;
-};
-
-
-FrameMirror.prototype.restart = function() {
-  var result = %LiveEditRestartFrame(this.break_id_, this.index_);
-  if (IS_UNDEFINED(result)) {
-    result = "Failed to find requested frame";
-  }
-  return result;
-};
-
-
-FrameMirror.prototype.toText = function(opt_locals) {
-  var result = '';
-  result += '#' + (this.index() <= 9 ? '0' : '') + this.index();
-  result += ' ';
-  result += this.invocationText();
-  result += ' ';
-  result += this.sourceAndPositionText();
-  if (opt_locals) {
-    result += '\n';
-    result += this.localsText();
-  }
-  return result;
-};
-
-
-var kScopeDetailsTypeIndex = 0;
-var kScopeDetailsObjectIndex = 1;
-
-function ScopeDetails(frame, fun, index, opt_details) {
-  if (frame) {
-    this.break_id_ = frame.break_id_;
-    this.details_ = opt_details ||
-                    %GetScopeDetails(frame.break_id_,
-                                     frame.details_.frameId(),
-                                     frame.details_.inlinedFrameIndex(),
-                                     index);
-    this.frame_id_ = frame.details_.frameId();
-    this.inlined_frame_id_ = frame.details_.inlinedFrameIndex();
-  } else {
-    this.details_ = opt_details || %GetFunctionScopeDetails(fun.value(), index);
-    this.fun_value_ = fun.value();
-    this.break_id_ = undefined;
-  }
-  this.index_ = index;
-}
-
-
-ScopeDetails.prototype.type = function() {
-  if (!IS_UNDEFINED(this.break_id_)) {
-    %CheckExecutionState(this.break_id_);
-  }
-  return this.details_[kScopeDetailsTypeIndex];
-};
-
-
-ScopeDetails.prototype.object = function() {
-  if (!IS_UNDEFINED(this.break_id_)) {
-    %CheckExecutionState(this.break_id_);
-  }
-  return this.details_[kScopeDetailsObjectIndex];
-};
-
-
-ScopeDetails.prototype.setVariableValueImpl = function(name, new_value) {
-  var raw_res;
-  if (!IS_UNDEFINED(this.break_id_)) {
-    %CheckExecutionState(this.break_id_);
-    raw_res = %SetScopeVariableValue(this.break_id_, this.frame_id_,
-        this.inlined_frame_id_, this.index_, name, new_value);
-  } else {
-    raw_res = %SetScopeVariableValue(this.fun_value_, null, null, this.index_,
-        name, new_value);
-  }
-  if (!raw_res) {
-    throw new Error("Failed to set variable value");
-  }
-};
-
-
-/**
- * Mirror object for scope of frame or function. Either frame or function must
- * be specified.
- * @param {FrameMirror} frame The frame this scope is a part of
- * @param {FunctionMirror} function The function this scope is a part of
- * @param {number} index The scope index in the frame
- * @param {Array=} opt_details Raw scope details data
- * @constructor
- * @extends Mirror
- */
-function ScopeMirror(frame, function, index, opt_details) {
-  %_CallFunction(this, SCOPE_TYPE, Mirror);
-  if (frame) {
-    this.frame_index_ = frame.index_;
-  } else {
-    this.frame_index_ = undefined;
-  }
-  this.scope_index_ = index;
-  this.details_ = new ScopeDetails(frame, function, index, opt_details);
-}
-inherits(ScopeMirror, Mirror);
-
-
-ScopeMirror.prototype.details = function() {
-  return this.details_;
-};
-
-
-ScopeMirror.prototype.frameIndex = function() {
-  return this.frame_index_;
-};
-
-
-ScopeMirror.prototype.scopeIndex = function() {
-  return this.scope_index_;
-};
-
-
-ScopeMirror.prototype.scopeType = function() {
-  return this.details_.type();
-};
-
-
-ScopeMirror.prototype.scopeObject = function() {
-  // For local, closure and script scopes create a transient mirror
-  // as these objects are created on the fly materializing the local
-  // or closure scopes and therefore will not preserve identity.
-  var transient = this.scopeType() == ScopeType.Local ||
-                  this.scopeType() == ScopeType.Closure ||
-                  this.scopeType() == ScopeType.Script;
-  return MakeMirror(this.details_.object(), transient);
-};
-
-
-ScopeMirror.prototype.setVariableValue = function(name, new_value) {
-  this.details_.setVariableValueImpl(name, new_value);
-};
-
-
-/**
- * Mirror object for script source.
- * @param {Script} script The script object
- * @constructor
- * @extends Mirror
- */
-function ScriptMirror(script) {
-  %_CallFunction(this, SCRIPT_TYPE, Mirror);
-  this.script_ = script;
-  this.context_ = new ContextMirror(script.context_data);
-  this.allocateHandle_();
-}
-inherits(ScriptMirror, Mirror);
-
-
-ScriptMirror.prototype.value = function() {
-  return this.script_;
-};
-
-
-ScriptMirror.prototype.name = function() {
-  return this.script_.name || this.script_.nameOrSourceURL();
-};
-
-
-ScriptMirror.prototype.id = function() {
-  return this.script_.id;
-};
-
-
-ScriptMirror.prototype.source = function() {
-  return this.script_.source;
-};
-
-
-ScriptMirror.prototype.setSource = function(source) {
-  %DebugSetScriptSource(this.script_, source);
-};
-
-
-ScriptMirror.prototype.lineOffset = function() {
-  return this.script_.line_offset;
-};
-
-
-ScriptMirror.prototype.columnOffset = function() {
-  return this.script_.column_offset;
-};
-
-
-ScriptMirror.prototype.data = function() {
-  return this.script_.data;
-};
-
-
-ScriptMirror.prototype.scriptType = function() {
-  return this.script_.type;
-};
-
-
-ScriptMirror.prototype.compilationType = function() {
-  return this.script_.compilation_type;
-};
-
-
-ScriptMirror.prototype.lineCount = function() {
-  return this.script_.lineCount();
-};
-
-
-ScriptMirror.prototype.locationFromPosition = function(
-    position, include_resource_offset) {
-  return this.script_.locationFromPosition(position, include_resource_offset);
-};
-
-
-ScriptMirror.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
-  return this.script_.sourceSlice(opt_from_line, opt_to_line);
-};
-
-
-ScriptMirror.prototype.context = function() {
-  return this.context_;
-};
-
-
-ScriptMirror.prototype.evalFromScript = function() {
-  return MakeMirror(this.script_.eval_from_script);
-};
-
-
-ScriptMirror.prototype.evalFromFunctionName = function() {
-  return MakeMirror(this.script_.eval_from_function_name);
-};
-
-
-ScriptMirror.prototype.evalFromLocation = function() {
-  var eval_from_script = this.evalFromScript();
-  if (!eval_from_script.isUndefined()) {
-    var position = this.script_.eval_from_script_position;
-    return eval_from_script.locationFromPosition(position, true);
-  }
-};
-
-
-ScriptMirror.prototype.toText = function() {
-  var result = '';
-  result += this.name();
-  result += ' (lines: ';
-  if (this.lineOffset() > 0) {
-    result += this.lineOffset();
-    result += '-';
-    result += this.lineOffset() + this.lineCount() - 1;
-  } else {
-    result += this.lineCount();
-  }
-  result += ')';
-  return result;
-};
-
-
-/**
- * Mirror object for context.
- * @param {Object} data The context data
- * @constructor
- * @extends Mirror
- */
-function ContextMirror(data) {
-  %_CallFunction(this, CONTEXT_TYPE, Mirror);
-  this.data_ = data;
-  this.allocateHandle_();
-}
-inherits(ContextMirror, Mirror);
-
-
-ContextMirror.prototype.data = function() {
-  return this.data_;
-};
-
-
-/**
- * Returns a mirror serializer
- *
- * @param {boolean} details Set to true to include details
- * @param {Object} options Options comtrolling the serialization
- *     The following options can be set:
- *       includeSource: include ths full source of scripts
- * @returns {MirrorSerializer} mirror serializer
- */
-function MakeMirrorSerializer(details, options) {
-  return new JSONProtocolSerializer(details, options);
-}
-
-
-/**
- * Object for serializing a mirror objects and its direct references.
- * @param {boolean} details Indicates whether to include details for the mirror
- *     serialized
- * @constructor
- */
-function JSONProtocolSerializer(details, options) {
-  this.details_ = details;
-  this.options_ = options;
-  this.mirrors_ = [ ];
-}
-
-
-/**
- * Returns a serialization of an object reference. The referenced object are
- * added to the serialization state.
- *
- * @param {Mirror} mirror The mirror to serialize
- * @returns {String} JSON serialization
- */
-JSONProtocolSerializer.prototype.serializeReference = function(mirror) {
-  return this.serialize_(mirror, true, true);
-};
-
-
-/**
- * Returns a serialization of an object value. The referenced objects are
- * added to the serialization state.
- *
- * @param {Mirror} mirror The mirror to serialize
- * @returns {String} JSON serialization
- */
-JSONProtocolSerializer.prototype.serializeValue = function(mirror) {
-  var json = this.serialize_(mirror, false, true);
-  return json;
-};
-
-
-/**
- * Returns a serialization of all the objects referenced.
- *
- * @param {Mirror} mirror The mirror to serialize.
- * @returns {Array.<Object>} Array of the referenced objects converted to
- *     protcol objects.
- */
-JSONProtocolSerializer.prototype.serializeReferencedObjects = function() {
-  // Collect the protocol representation of the referenced objects in an array.
-  var content = [];
-
-  // Get the number of referenced objects.
-  var count = this.mirrors_.length;
-
-  for (var i = 0; i < count; i++) {
-    content.push(this.serialize_(this.mirrors_[i], false, false));
-  }
-
-  return content;
-};
-
-
-JSONProtocolSerializer.prototype.includeSource_ = function() {
-  return this.options_ && this.options_.includeSource;
-};
-
-
-JSONProtocolSerializer.prototype.inlineRefs_ = function() {
-  return this.options_ && this.options_.inlineRefs;
-};
-
-
-JSONProtocolSerializer.prototype.maxStringLength_ = function() {
-  if (IS_UNDEFINED(this.options_) ||
-      IS_UNDEFINED(this.options_.maxStringLength)) {
-    return kMaxProtocolStringLength;
-  }
-  return this.options_.maxStringLength;
-};
-
-
-JSONProtocolSerializer.prototype.add_ = function(mirror) {
-  // If this mirror is already in the list just return.
-  for (var i = 0; i < this.mirrors_.length; i++) {
-    if (this.mirrors_[i] === mirror) {
-      return;
-    }
-  }
-
-  // Add the mirror to the list of mirrors to be serialized.
-  this.mirrors_.push(mirror);
-};
-
-
-/**
- * Formats mirror object to protocol reference object with some data that can
- * be used to display the value in debugger.
- * @param {Mirror} mirror Mirror to serialize.
- * @return {Object} Protocol reference object.
- */
-JSONProtocolSerializer.prototype.serializeReferenceWithDisplayData_ =
-    function(mirror) {
-  var o = {};
-  o.ref = mirror.handle();
-  o.type = mirror.type();
-  switch (mirror.type()) {
-    case UNDEFINED_TYPE:
-    case NULL_TYPE:
-    case BOOLEAN_TYPE:
-    case NUMBER_TYPE:
-      o.value = mirror.value();
-      break;
-    case STRING_TYPE:
-      o.value = mirror.getTruncatedValue(this.maxStringLength_());
-      break;
-    case SYMBOL_TYPE:
-      o.description = mirror.description();
-      break;
-    case FUNCTION_TYPE:
-      o.name = mirror.name();
-      o.inferredName = mirror.inferredName();
-      if (mirror.script()) {
-        o.scriptId = mirror.script().id();
-      }
-      break;
-    case ERROR_TYPE:
-    case REGEXP_TYPE:
-      o.value = mirror.toText();
-      break;
-    case OBJECT_TYPE:
-      o.className = mirror.className();
-      break;
-  }
-  return o;
-};
-
-
-JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
-                                                       details) {
-  // If serializing a reference to a mirror just return the reference and add
-  // the mirror to the referenced mirrors.
-  if (reference &&
-      (mirror.isValue() || mirror.isScript() || mirror.isContext())) {
-    if (this.inlineRefs_() && mirror.isValue()) {
-      return this.serializeReferenceWithDisplayData_(mirror);
-    } else {
-      this.add_(mirror);
-      return {'ref' : mirror.handle()};
-    }
-  }
-
-  // Collect the JSON property/value pairs.
-  var content = {};
-
-  // Add the mirror handle.
-  if (mirror.isValue() || mirror.isScript() || mirror.isContext()) {
-    content.handle = mirror.handle();
-  }
-
-  // Always add the type.
-  content.type = mirror.type();
-
-  switch (mirror.type()) {
-    case UNDEFINED_TYPE:
-    case NULL_TYPE:
-      // Undefined and null are represented just by their type.
-      break;
-
-    case BOOLEAN_TYPE:
-      // Boolean values are simply represented by their value.
-      content.value = mirror.value();
-      break;
-
-    case NUMBER_TYPE:
-      // Number values are simply represented by their value.
-      content.value = NumberToJSON_(mirror.value());
-      break;
-
-    case STRING_TYPE:
-      // String values might have their value cropped to keep down size.
-      if (this.maxStringLength_() != -1 &&
-          mirror.length() > this.maxStringLength_()) {
-        var str = mirror.getTruncatedValue(this.maxStringLength_());
-        content.value = str;
-        content.fromIndex = 0;
-        content.toIndex = this.maxStringLength_();
-      } else {
-        content.value = mirror.value();
-      }
-      content.length = mirror.length();
-      break;
-
-    case SYMBOL_TYPE:
-      content.description = mirror.description();
-      break;
-
-    case OBJECT_TYPE:
-    case FUNCTION_TYPE:
-    case ERROR_TYPE:
-    case REGEXP_TYPE:
-    case PROMISE_TYPE:
-    case GENERATOR_TYPE:
-      // Add object representation.
-      this.serializeObject_(mirror, content, details);
-      break;
-
-    case PROPERTY_TYPE:
-    case INTERNAL_PROPERTY_TYPE:
-      throw new Error('PropertyMirror cannot be serialized independently');
-      break;
-
-    case FRAME_TYPE:
-      // Add object representation.
-      this.serializeFrame_(mirror, content);
-      break;
-
-    case SCOPE_TYPE:
-      // Add object representation.
-      this.serializeScope_(mirror, content);
-      break;
-
-    case SCRIPT_TYPE:
-      // Script is represented by id, name and source attributes.
-      if (mirror.name()) {
-        content.name = mirror.name();
-      }
-      content.id = mirror.id();
-      content.lineOffset = mirror.lineOffset();
-      content.columnOffset = mirror.columnOffset();
-      content.lineCount = mirror.lineCount();
-      if (mirror.data()) {
-        content.data = mirror.data();
-      }
-      if (this.includeSource_()) {
-        content.source = mirror.source();
-      } else {
-        var sourceStart = mirror.source().substring(0, 80);
-        content.sourceStart = sourceStart;
-      }
-      content.sourceLength = mirror.source().length;
-      content.scriptType = mirror.scriptType();
-      content.compilationType = mirror.compilationType();
-      // For compilation type eval emit information on the script from which
-      // eval was called if a script is present.
-      if (mirror.compilationType() == 1 &&
-          mirror.evalFromScript()) {
-        content.evalFromScript =
-            this.serializeReference(mirror.evalFromScript());
-        var evalFromLocation = mirror.evalFromLocation();
-        if (evalFromLocation) {
-          content.evalFromLocation = { line: evalFromLocation.line,
-                                       column: evalFromLocation.column };
-        }
-        if (mirror.evalFromFunctionName()) {
-          content.evalFromFunctionName = mirror.evalFromFunctionName();
-        }
-      }
-      if (mirror.context()) {
-        content.context = this.serializeReference(mirror.context());
-      }
-      break;
-
-    case CONTEXT_TYPE:
-      content.data = mirror.data();
-      break;
-  }
-
-  // Always add the text representation.
-  content.text = mirror.toText();
-
-  // Create and return the JSON string.
-  return content;
-};
-
-
-/**
- * Serialize object information to the following JSON format.
- *
- *   {"className":"<class name>",
- *    "constructorFunction":{"ref":<number>},
- *    "protoObject":{"ref":<number>},
- *    "prototypeObject":{"ref":<number>},
- *    "namedInterceptor":<boolean>,
- *    "indexedInterceptor":<boolean>,
- *    "properties":[<properties>],
- *    "internalProperties":[<internal properties>]}
- */
-JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
-                                                             details) {
-  // Add general object properties.
-  content.className = mirror.className();
-  content.constructorFunction =
-      this.serializeReference(mirror.constructorFunction());
-  content.protoObject = this.serializeReference(mirror.protoObject());
-  content.prototypeObject = this.serializeReference(mirror.prototypeObject());
-
-  // Add flags to indicate whether there are interceptors.
-  if (mirror.hasNamedInterceptor()) {
-    content.namedInterceptor = true;
-  }
-  if (mirror.hasIndexedInterceptor()) {
-    content.indexedInterceptor = true;
-  }
-
-  if (mirror.isFunction()) {
-    // Add function specific properties.
-    content.name = mirror.name();
-    if (!IS_UNDEFINED(mirror.inferredName())) {
-      content.inferredName = mirror.inferredName();
-    }
-    content.resolved = mirror.resolved();
-    if (mirror.resolved()) {
-      content.source = mirror.source();
-    }
-    if (mirror.script()) {
-      content.script = this.serializeReference(mirror.script());
-      content.scriptId = mirror.script().id();
-
-      serializeLocationFields(mirror.sourceLocation(), content);
-    }
-
-    content.scopes = [];
-    for (var i = 0; i < mirror.scopeCount(); i++) {
-      var scope = mirror.scope(i);
-      content.scopes.push({
-        type: scope.scopeType(),
-        index: i
-      });
-    }
-  }
-
-  if (mirror.isGenerator()) {
-    // Add generator specific properties.
-
-    // Either 'running', 'closed', or 'suspended'.
-    content.status = mirror.status();
-
-    content.func = this.serializeReference(mirror.func())
-    content.receiver = this.serializeReference(mirror.receiver())
-
-    // If the generator is suspended, the content add line/column properties.
-    serializeLocationFields(mirror.sourceLocation(), content);
-
-    // TODO(wingo): Also serialize a reference to the context (scope chain).
-  }
-
-  if (mirror.isDate()) {
-    // Add date specific properties.
-    content.value = mirror.value();
-  }
-
-  if (mirror.isPromise()) {
-    // Add promise specific properties.
-    content.status = mirror.status();
-    content.promiseValue = this.serializeReference(mirror.promiseValue());
-  }
-
-  // Add actual properties - named properties followed by indexed properties.
-  var propertyNames = mirror.propertyNames(PropertyKind.Named);
-  var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed);
-  var p = new Array(propertyNames.length + propertyIndexes.length);
-  for (var i = 0; i < propertyNames.length; i++) {
-    var propertyMirror = mirror.property(propertyNames[i]);
-    p[i] = this.serializeProperty_(propertyMirror);
-    if (details) {
-      this.add_(propertyMirror.value());
-    }
-  }
-  for (var i = 0; i < propertyIndexes.length; i++) {
-    var propertyMirror = mirror.property(propertyIndexes[i]);
-    p[propertyNames.length + i] = this.serializeProperty_(propertyMirror);
-    if (details) {
-      this.add_(propertyMirror.value());
-    }
-  }
-  content.properties = p;
-
-  var internalProperties = mirror.internalProperties();
-  if (internalProperties.length > 0) {
-    var ip = [];
-    for (var i = 0; i < internalProperties.length; i++) {
-      ip.push(this.serializeInternalProperty_(internalProperties[i]));
-    }
-    content.internalProperties = ip;
-  }
-};
-
-
-/**
- * Serialize location information to the following JSON format:
- *
- *   "position":"<position>",
- *   "line":"<line>",
- *   "column":"<column>",
- *
- * @param {SourceLocation} location The location to serialize, may be undefined.
- */
-function serializeLocationFields (location, content) {
-  if (!location) {
-    return;
-  }
-  content.position = location.position;
-  var line = location.line;
-  if (!IS_UNDEFINED(line)) {
-    content.line = line;
-  }
-  var column = location.column;
-  if (!IS_UNDEFINED(column)) {
-    content.column = column;
-  }
-}
-
-
-/**
- * Serialize property information to the following JSON format for building the
- * array of properties.
- *
- *   {"name":"<property name>",
- *    "attributes":<number>,
- *    "propertyType":<number>,
- *    "ref":<number>}
- *
- * If the attribute for the property is PropertyAttribute.None it is not added.
- * Here are a couple of examples.
- *
- *   {"name":"hello","propertyType":0,"ref":1}
- *   {"name":"length","attributes":7,"propertyType":3,"ref":2}
- *
- * @param {PropertyMirror} propertyMirror The property to serialize.
- * @returns {Object} Protocol object representing the property.
- */
-JSONProtocolSerializer.prototype.serializeProperty_ = function(propertyMirror) {
-  var result = {};
-
-  result.name = propertyMirror.name();
-  var propertyValue = propertyMirror.value();
-  if (this.inlineRefs_() && propertyValue.isValue()) {
-    result.value = this.serializeReferenceWithDisplayData_(propertyValue);
-  } else {
-    if (propertyMirror.attributes() != PropertyAttribute.None) {
-      result.attributes = propertyMirror.attributes();
-    }
-    result.propertyType = propertyMirror.propertyType();
-    result.ref = propertyValue.handle();
-  }
-  return result;
-};
-
-
-/**
- * Serialize internal property information to the following JSON format for
- * building the array of properties.
- *
- *   {"name":"<property name>",
- *    "ref":<number>}
- *
- *   {"name":"[[BoundThis]]","ref":117}
- *
- * @param {InternalPropertyMirror} propertyMirror The property to serialize.
- * @returns {Object} Protocol object representing the property.
- */
-JSONProtocolSerializer.prototype.serializeInternalProperty_ =
-    function(propertyMirror) {
-  var result = {};
-
-  result.name = propertyMirror.name();
-  var propertyValue = propertyMirror.value();
-  if (this.inlineRefs_() && propertyValue.isValue()) {
-    result.value = this.serializeReferenceWithDisplayData_(propertyValue);
-  } else {
-    result.ref = propertyValue.handle();
-  }
-  return result;
-};
-
-
-JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) {
-  content.index = mirror.index();
-  content.receiver = this.serializeReference(mirror.receiver());
-  var func = mirror.func();
-  content.func = this.serializeReference(func);
-  var script = func.script();
-  if (script) {
-    content.script = this.serializeReference(script);
-  }
-  content.constructCall = mirror.isConstructCall();
-  content.atReturn = mirror.isAtReturn();
-  if (mirror.isAtReturn()) {
-    content.returnValue = this.serializeReference(mirror.returnValue());
-  }
-  content.debuggerFrame = mirror.isDebuggerFrame();
-  var x = new Array(mirror.argumentCount());
-  for (var i = 0; i < mirror.argumentCount(); i++) {
-    var arg = {};
-    var argument_name = mirror.argumentName(i);
-    if (argument_name) {
-      arg.name = argument_name;
-    }
-    arg.value = this.serializeReference(mirror.argumentValue(i));
-    x[i] = arg;
-  }
-  content.arguments = x;
-  var x = new Array(mirror.localCount());
-  for (var i = 0; i < mirror.localCount(); i++) {
-    var local = {};
-    local.name = mirror.localName(i);
-    local.value = this.serializeReference(mirror.localValue(i));
-    x[i] = local;
-  }
-  content.locals = x;
-  serializeLocationFields(mirror.sourceLocation(), content);
-  var source_line_text = mirror.sourceLineText();
-  if (!IS_UNDEFINED(source_line_text)) {
-    content.sourceLineText = source_line_text;
-  }
-
-  content.scopes = [];
-  for (var i = 0; i < mirror.scopeCount(); i++) {
-    var scope = mirror.scope(i);
-    content.scopes.push({
-      type: scope.scopeType(),
-      index: i
-    });
-  }
-};
-
-
-JSONProtocolSerializer.prototype.serializeScope_ = function(mirror, content) {
-  content.index = mirror.scopeIndex();
-  content.frameIndex = mirror.frameIndex();
-  content.type = mirror.scopeType();
-  content.object = this.inlineRefs_() ?
-                   this.serializeValue(mirror.scopeObject()) :
-                   this.serializeReference(mirror.scopeObject());
-};
-
-
-/**
- * Convert a number to a protocol value. For all finite numbers the number
- * itself is returned. For non finite numbers NaN, Infinite and
- * -Infinite the string representation "NaN", "Infinite" or "-Infinite"
- * (not including the quotes) is returned.
- *
- * @param {number} value The number value to convert to a protocol value.
- * @returns {number|string} Protocol value.
- */
-function NumberToJSON_(value) {
-  if (isNaN(value)) {
-    return 'NaN';
-  }
-  if (!NUMBER_IS_FINITE(value)) {
-    if (value > 0) {
-      return 'Infinity';
-    } else {
-      return '-Infinity';
-    }
-  }
-  return value;
-}
index 3df88e300c3ad8f53028e452dc8f0a5a24976b73..8bb95c518c79327fe1548fcdf8cf017a9004cd16 100644 (file)
@@ -20,7 +20,7 @@
 #include "src/compiler.h"
 #include "src/cpu-profiler.h"
 #include "src/date.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/elements.h"
 #include "src/execution.h"
index 10a10320a6e788fac41b920c939149aec651f65b..afb347e419d488f5d446d653c16be0dd24217c2a 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "src/pending-compilation-error-handler.h"
 
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/handles.h"
 #include "src/isolate.h"
 #include "src/messages.h"
index 3f0ae733cf04ac15b7d2f76bcbac60d023ce6c75..35968fc682a06ec9814a67fc67336572f34b63d1 100644 (file)
@@ -40,7 +40,7 @@
 #include "src/ppc/assembler-ppc.h"
 
 #include "src/assembler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 
 
 namespace v8 {
index a8c24f15b8e909e653c3badc51c9cda8741e5d06..bdcf4061433ae13bf3d10fcaeb2b4e44d215101d 100644 (file)
@@ -7,7 +7,7 @@
 #if V8_TARGET_ARCH_PPC
 
 #include "src/codegen.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/interpreter/bytecodes.h"
diff --git a/src/ppc/debug-ppc.cc b/src/ppc/debug-ppc.cc
deleted file mode 100644 (file)
index fbc1629..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#if V8_TARGET_ARCH_PPC
-
-#include "src/codegen.h"
-#include "src/debug.h"
-
-namespace v8 {
-namespace internal {
-
-#define __ ACCESS_MASM(masm)
-
-
-void EmitDebugBreakSlot(MacroAssembler* masm) {
-  Label check_size;
-  __ bind(&check_size);
-  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
-    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
-  }
-  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
-            masm->InstructionsGeneratedSince(&check_size));
-}
-
-
-void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                                int call_argc) {
-  // Generate enough nop's to make space for a call instruction. Avoid emitting
-  // the trampoline pool in the debug break slot code.
-  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
-  masm->RecordDebugBreakSlot(mode, call_argc);
-  EmitDebugBreakSlot(masm);
-}
-
-
-void DebugCodegen::ClearDebugBreakSlot(Address pc) {
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
-  EmitDebugBreakSlot(patcher.masm());
-}
-
-
-void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
-  DCHECK_EQ(Code::BUILTIN, code->kind());
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
-  // Patch the code changing the debug break slot code from
-  //
-  //   ori r3, r3, 0
-  //   ori r3, r3, 0
-  //   ori r3, r3, 0
-  //   ori r3, r3, 0
-  //   ori r3, r3, 0
-  //
-  // to a call to the debug break code, using a FIXED_SEQUENCE.
-  //
-  //   mov r0, <address>
-  //   mtlr r0
-  //   blrl
-  //
-  Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm());
-  patcher.masm()->mov(v8::internal::r0,
-                      Operand(reinterpret_cast<intptr_t>(code->entry())));
-  patcher.masm()->mtctr(v8::internal::r0);
-  patcher.masm()->bctrl();
-}
-
-
-void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
-                                          DebugBreakCallHelperMode mode) {
-  __ RecordComment("Debug break");
-  {
-    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
-
-    // Load padding words on stack.
-    __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingValue));
-    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
-      __ push(ip);
-    }
-    __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
-    __ push(ip);
-
-    if (mode == SAVE_RESULT_REGISTER) __ push(r3);
-
-    __ mov(r3, Operand::Zero());  // no arguments
-    __ mov(r4,
-           Operand(ExternalReference(
-               Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
-
-    CEntryStub ceb(masm->isolate(), 1);
-    __ CallStub(&ceb);
-
-    if (FLAG_debug_code) {
-      for (int i = 0; i < kNumJSCallerSaved; i++) {
-        Register reg = {JSCallerSavedCode(i)};
-        __ mov(reg, Operand(kDebugZapValue));
-      }
-    }
-
-    if (mode == SAVE_RESULT_REGISTER) __ pop(r3);
-
-    // Don't bother removing padding bytes pushed on the stack
-    // as the frame is going to be restored right away.
-
-    // Leave the internal frame.
-  }
-
-  // Now that the break point has been handled, resume normal execution by
-  // jumping to the target address intended by the caller and that was
-  // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target =
-      ExternalReference::debug_after_break_target_address(masm->isolate());
-  __ mov(ip, Operand(after_break_target));
-  __ LoadP(ip, MemOperand(ip));
-  __ JumpToJSEntry(ip);
-}
-
-
-void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
-  __ Ret();
-}
-
-
-void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
-  ExternalReference restarter_frame_function_slot =
-      ExternalReference::debug_restarter_frame_function_pointer_address(
-          masm->isolate());
-  __ mov(ip, Operand(restarter_frame_function_slot));
-  __ li(r4, Operand::Zero());
-  __ StoreP(r4, MemOperand(ip, 0));
-
-  // Load the function pointer off of our current stack frame.
-  __ LoadP(r4, MemOperand(fp, StandardFrameConstants::kConstantPoolOffset -
-                                  kPointerSize));
-
-  // Pop return address and frame
-  __ LeaveFrame(StackFrame::INTERNAL);
-
-  // Load context from the function.
-  __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
-
-  // Get function code.
-  __ LoadP(ip, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
-  __ LoadP(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset));
-  __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-  // Re-run JSFunction, r4 is function, cp is context.
-  __ Jump(ip);
-}
-
-
-const bool LiveEdit::kFrameDropperSupported = true;
-
-#undef __
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TARGET_ARCH_PPC
index 976290baa2b5191bf350213b5d021addd91e942c..1598f8fee763d28659dc734deb0571360607754d 100644 (file)
@@ -14,7 +14,7 @@
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
index 070a9eee2bd39d71fb53b3c862fd24c7c89f2cdf..006ca7f4bede98b5f7319ec878217cbe24acf931 100644 (file)
@@ -7,7 +7,7 @@
 #include "src/profile-generator-inl.h"
 
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/global-handles.h"
 #include "src/sampler.h"
index 5d95f05e8ac28741c148fa92ab812e3afad6acfc..33d3b8d7efd6ef20b235efb070202cfaeb6cce2b 100644 (file)
@@ -53,7 +53,7 @@ enum PropertyLocation { kField = 0, kDescriptor = 1 };
 
 // Order of properties is significant.
 // Must fit in the BitField PropertyDetails::TypeField.
-// A copy of this is in mirror-debugger.js.
+// A copy of this is in debug/mirrors.js.
 enum PropertyType {
   DATA = (kField << 1) | kData,
   DATA_CONSTANT = (kDescriptor << 1) | kData,
index 317d34b8f5b0b4828a49b0034eb226255e1c68ad..76c5c0068da4764a4bae6e81286184187a7ca2bc 100644 (file)
@@ -8,7 +8,7 @@
 #include "src/v8.h"
 
 #include "src/arguments.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/messages.h"
 #include "src/runtime/runtime.h"
 #include "src/runtime/runtime-utils.h"
index f167fa6199f809e36cee69efc33ce255bbf35402..c3862f08d927e8dbf6d51bb5b0141b60b09bd8fa 100644 (file)
@@ -7,7 +7,7 @@
 #include "src/accessors.h"
 #include "src/arguments.h"
 #include "src/compiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/parser.h"
 #include "src/runtime/runtime.h"
index c58266ab6f34e4db260cd3aca2d4beb88b434c48..724d679bbc1aab088a46db8cbe55aa9ae5e97aed 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "src/arguments.h"
 #include "src/bootstrapper.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/messages.h"
 #include "src/parser.h"
 #include "src/prettyprinter.h"
index 555fb6a74b6aabce0be1d2d9f454bde6958d4fe7..e2b895f9a5259fc57e3d8552ca715d40594443c2 100644 (file)
@@ -5,8 +5,8 @@
 #include "src/v8.h"
 
 #include "src/arguments.h"
-#include "src/debug.h"
-#include "src/liveedit.h"
+#include "src/debug/debug.h"
+#include "src/debug/liveedit.h"
 #include "src/runtime/runtime.h"
 #include "src/runtime/runtime-utils.h"
 
index 07ba01f957ad108153a546656c61ce1d9a418a2f..255dbf073debf4b5b4444473150d2815210e3250 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "src/arguments.h"
 #include "src/bootstrapper.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/messages.h"
 #include "src/runtime/runtime.h"
 #include "src/runtime/runtime-utils.h"
index 8fc201da0e66626169d5926aec80a6afb27efed3..d1fe0b453c331fcc65d867e2995082a25e1f6358 100644 (file)
@@ -5,7 +5,7 @@
 #include "src/v8.h"
 
 #include "src/arguments.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/runtime/runtime-utils.h"
 
 namespace v8 {
index 7e346837dee374bb473ee6184384eedc538b5e37..d16dbee255397455a2f8a78cc01f65a1ee50658b 100644 (file)
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -8,7 +8,7 @@
 #include "src/base/once.h"
 #include "src/base/platform/platform.h"
 #include "src/bootstrapper.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/elements.h"
 #include "src/frames.h"
index e2d9d49fe105bdc05f4568ab20a8ca76340d08c6..76ec9d0d3d997cd9494b3dc9f0b51d626a8b2060 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "src/api.h"
 #include "src/bootstrapper.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/execution.h"
 #include "src/regexp-stack.h"
 #include "src/v8threads.h"
index 96e70673837b00fe7b051f25c0f0b56dabca1468..74d5d2436afcffd94cbb11f6f03822c2ddd0be71 100644 (file)
@@ -8,7 +8,7 @@
 #include "src/x64/assembler-x64.h"
 
 #include "src/base/cpu.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/v8memory.h"
 
 namespace v8 {
diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc
deleted file mode 100644 (file)
index 916eb76..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#if V8_TARGET_ARCH_X64
-
-#include "src/assembler.h"
-#include "src/codegen.h"
-#include "src/debug.h"
-
-
-namespace v8 {
-namespace internal {
-
-#define __ ACCESS_MASM(masm)
-
-
-void EmitDebugBreakSlot(MacroAssembler* masm) {
-  Label check_codesize;
-  __ bind(&check_codesize);
-  __ Nop(Assembler::kDebugBreakSlotLength);
-  DCHECK_EQ(Assembler::kDebugBreakSlotLength,
-            masm->SizeOfCodeGeneratedSince(&check_codesize));
-}
-
-
-void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                                int call_argc) {
-  // Generate enough nop's to make space for a call instruction.
-  masm->RecordDebugBreakSlot(mode, call_argc);
-  EmitDebugBreakSlot(masm);
-}
-
-
-void DebugCodegen::ClearDebugBreakSlot(Address pc) {
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotLength);
-  EmitDebugBreakSlot(patcher.masm());
-}
-
-
-void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
-  DCHECK_EQ(Code::BUILTIN, code->kind());
-  static const int kSize = Assembler::kDebugBreakSlotLength;
-  CodePatcher patcher(pc, kSize);
-  Label check_codesize;
-  patcher.masm()->bind(&check_codesize);
-  patcher.masm()->movp(kScratchRegister, reinterpret_cast<void*>(code->entry()),
-                       Assembler::RelocInfoNone());
-  patcher.masm()->call(kScratchRegister);
-  // Check that the size of the code generated is as expected.
-  DCHECK_EQ(kSize, patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
-}
-
-
-void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
-                                          DebugBreakCallHelperMode mode) {
-  __ RecordComment("Debug break");
-
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Load padding words on stack.
-    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
-      __ Push(Smi::FromInt(LiveEdit::kFramePaddingValue));
-    }
-    __ Push(Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
-
-    if (mode == SAVE_RESULT_REGISTER) __ Push(rax);
-
-    __ Set(rax, 0);  // No arguments (argc == 0).
-    __ Move(rbx, ExternalReference(Runtime::FunctionForId(Runtime::kDebugBreak),
-                                   masm->isolate()));
-
-    CEntryStub ceb(masm->isolate(), 1);
-    __ CallStub(&ceb);
-
-    if (FLAG_debug_code) {
-      for (int i = 0; i < kNumJSCallerSaved; ++i) {
-        Register reg = {JSCallerSavedCode(i)};
-        __ Set(reg, kDebugZapValue);
-      }
-    }
-
-    if (mode == SAVE_RESULT_REGISTER) __ Pop(rax);
-
-    // Read current padding counter and skip corresponding number of words.
-    __ Pop(kScratchRegister);
-    __ SmiToInteger32(kScratchRegister, kScratchRegister);
-    __ leap(rsp, Operand(rsp, kScratchRegister, times_pointer_size, 0));
-
-    // Get rid of the internal frame.
-  }
-
-  // This call did not replace a call , so there will be an unwanted
-  // return address left on the stack. Here we get rid of that.
-  __ addp(rsp, Immediate(kPCOnStackSize));
-
-  // Now that the break point has been handled, resume normal execution by
-  // jumping to the target address intended by the caller and that was
-  // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target =
-      ExternalReference::debug_after_break_target_address(masm->isolate());
-  __ Move(kScratchRegister, after_break_target);
-  __ Jump(Operand(kScratchRegister, 0));
-}
-
-
-void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
-  masm->ret(0);
-}
-
-
-void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
-  ExternalReference restarter_frame_function_slot =
-      ExternalReference::debug_restarter_frame_function_pointer_address(
-          masm->isolate());
-  __ Move(rax, restarter_frame_function_slot);
-  __ movp(Operand(rax, 0), Immediate(0));
-
-  // We do not know our frame height, but set rsp based on rbp.
-  __ leap(rsp, Operand(rbp, -1 * kPointerSize));
-
-  __ Pop(rdi);  // Function.
-  __ popq(rbp);
-
-  // Load context from the function.
-  __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
-
-  // Get function code.
-  __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
-  __ movp(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
-  __ leap(rdx, FieldOperand(rdx, Code::kHeaderSize));
-
-  // Re-run JSFunction, rdi is function, rsi is context.
-  __ jmp(rdx);
-}
-
-const bool LiveEdit::kFrameDropperSupported = true;
-
-#undef __
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TARGET_ARCH_X64
index b1b02aa77bad1da99d9095de4dc64f06699d0502..8ddcc8529331aba8dea17cc56151844f9934558e 100644 (file)
@@ -11,7 +11,7 @@
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/heap/heap.h"
 #include "src/x64/assembler-x64.h"
 #include "src/x64/macro-assembler-x64.h"
index a21c6140301a663c58381d05c73c4c713e5e73ec..0e3de87e9604a27ed0627ba58ca49f736bcd34b0 100644 (file)
@@ -40,7 +40,7 @@
 #include "src/x87/assembler-x87.h"
 
 #include "src/assembler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/x87/debug-x87.cc b/src/x87/debug-x87.cc
deleted file mode 100644 (file)
index aa9ed3e..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-
-#if V8_TARGET_ARCH_X87
-
-#include "src/codegen.h"
-#include "src/debug.h"
-
-
-namespace v8 {
-namespace internal {
-
-#define __ ACCESS_MASM(masm)
-
-
-void EmitDebugBreakSlot(MacroAssembler* masm) {
-  Label check_codesize;
-  __ bind(&check_codesize);
-  __ Nop(Assembler::kDebugBreakSlotLength);
-  DCHECK_EQ(Assembler::kDebugBreakSlotLength,
-            masm->SizeOfCodeGeneratedSince(&check_codesize));
-}
-
-
-void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
-                                int call_argc) {
-  // Generate enough nop's to make space for a call instruction.
-  masm->RecordDebugBreakSlot(mode, call_argc);
-  EmitDebugBreakSlot(masm);
-}
-
-
-void DebugCodegen::ClearDebugBreakSlot(Address pc) {
-  CodePatcher patcher(pc, Assembler::kDebugBreakSlotLength);
-  EmitDebugBreakSlot(patcher.masm());
-}
-
-
-void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
-  DCHECK_EQ(Code::BUILTIN, code->kind());
-  static const int kSize = Assembler::kDebugBreakSlotLength;
-  CodePatcher patcher(pc, kSize);
-
-  // Add a label for checking the size of the code used for returning.
-  Label check_codesize;
-  patcher.masm()->bind(&check_codesize);
-  patcher.masm()->call(code->entry(), RelocInfo::NONE32);
-  // Check that the size of the code generated is as expected.
-  DCHECK_EQ(kSize, patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
-}
-
-
-void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
-                                          DebugBreakCallHelperMode mode) {
-  __ RecordComment("Debug break");
-
-  // Enter an internal frame.
-  {
-    FrameScope scope(masm, StackFrame::INTERNAL);
-
-    // Load padding words on stack.
-    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
-      __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue)));
-    }
-    __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
-
-    if (mode == SAVE_RESULT_REGISTER) __ push(eax);
-
-    __ Move(eax, Immediate(0));  // No arguments.
-    __ mov(ebx,
-           Immediate(ExternalReference(
-               Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
-
-    CEntryStub ceb(masm->isolate(), 1);
-    __ CallStub(&ceb);
-
-    if (FLAG_debug_code) {
-      for (int i = 0; i < kNumJSCallerSaved; ++i) {
-        Register reg = {JSCallerSavedCode(i)};
-        __ Move(reg, Immediate(kDebugZapValue));
-      }
-    }
-
-    if (mode == SAVE_RESULT_REGISTER) __ pop(eax);
-
-    __ pop(ebx);
-    // We divide stored value by 2 (untagging) and multiply it by word's size.
-    STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0);
-    __ lea(esp, Operand(esp, ebx, times_half_pointer_size, 0));
-
-    // Get rid of the internal frame.
-  }
-
-  // This call did not replace a call , so there will be an unwanted
-  // return address left on the stack. Here we get rid of that.
-  __ add(esp, Immediate(kPointerSize));
-
-  // Now that the break point has been handled, resume normal execution by
-  // jumping to the target address intended by the caller and that was
-  // overwritten by the address of DebugBreakXXX.
-  ExternalReference after_break_target =
-      ExternalReference::debug_after_break_target_address(masm->isolate());
-  __ jmp(Operand::StaticVariable(after_break_target));
-}
-
-
-void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
-  masm->ret(0);
-}
-
-
-void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
-  ExternalReference restarter_frame_function_slot =
-      ExternalReference::debug_restarter_frame_function_pointer_address(
-          masm->isolate());
-  __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
-
-  // We do not know our frame height, but set esp based on ebp.
-  __ lea(esp, Operand(ebp, -1 * kPointerSize));
-
-  __ pop(edi);  // Function.
-  __ pop(ebp);
-
-  // Load context from the function.
-  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-
-  // Get function code.
-  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
-  __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
-  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
-
-  // Re-run JSFunction, edi is function, esi is context.
-  __ jmp(edx);
-}
-
-
-const bool LiveEdit::kFrameDropperSupported = true;
-
-#undef __
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TARGET_ARCH_X87
index 03ec76a799709b31cf1bf833e939e0b21d9eb1a4..337feac88eddfc29e12b7c38e4b293feea00b081 100644 (file)
@@ -11,7 +11,7 @@
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
index f18ed55a7c8752a7e45454dafe183aef4456b914..69a040ae6ac4edf22a6d8618fbadbfffb7650164 100644 (file)
@@ -29,7 +29,7 @@
 #include "test/cctest/cctest.h"
 
 #include "include/libplatform/libplatform.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "test/cctest/print-extension.h"
 #include "test/cctest/profiler-extension.h"
 #include "test/cctest/trace-extension.h"
index 376d0d89a5c54ce463bdec570655e02368223855..e5a6d2f6ff43f0cf9719094c8d319c7fa88e852c 100644 (file)
@@ -42,7 +42,7 @@
 #include "src/base/platform/platform.h"
 #include "src/base/smart-pointers.h"
 #include "src/compilation-cache.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/execution.h"
 #include "src/futex-emulation.h"
 #include "src/objects.h"
index 7bf35f530070ab55995bf65ecdb71399cebe94ba..5461f300fbf0aec04aa63193d5c1304d6d6064b4 100644 (file)
@@ -33,7 +33,7 @@
 #include "src/base/platform/condition-variable.h"
 #include "src/base/platform/platform.h"
 #include "src/compilation-cache.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/frames.h"
 #include "src/utils.h"
index 1d512e0a75db41a71493011bee7725ae2d6da2d4..20c19139236644604d89cac6ff58c0506ce4ed88 100644 (file)
@@ -32,7 +32,7 @@
 #include "src/api.h"
 #include "src/base/platform/platform.h"
 #include "src/compilation-cache.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/deoptimizer.h"
 #include "src/isolate.h"
 #include "test/cctest/cctest.h"
index 03f3c27d51dce2611ef04f16d5089e4d5c1b1367..dc8a8b5bedcc208ab15b47856ecd4cbc85bd6e94 100644 (file)
@@ -29,7 +29,7 @@
 #include "test/cctest/cctest.h"
 
 #include "src/api.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/execution.h"
 #include "src/factory.h"
 #include "src/global-handles.h"
index cc5e89f1fdb81200fd5b3e437eb5e66e1df63363..b3b8a0358e467d7a53cd9b7feb6f0e2d6f9e2ab2 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "src/v8.h"
 
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
 #include "src/macro-assembler.h"
index e71deb866bc9c7c8aec4c8d50a4dc9899d17d8b1..97dc2a3f6439d8004b292111e35fbc3498c58174 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "src/v8.h"
 
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
 #include "src/ic/ic.h"
index df728dc3a4ae3e694b97103ddb9f93eca036d14a..6895ebf5d489edc88f79c88fa09d6a644beeeafc 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "src/v8.h"
 
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
 #include "src/macro-assembler.h"
index 43f24c1976403e1f42b1ac22c04f3a4ff48ceb9f..7cf6397886ea85f168df5c8fac28def3b422c416 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "src/v8.h"
 
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
 #include "src/macro-assembler.h"
index 4933f5900a00b993bacbb2b4b43f6ab1c78e84c9..e4b434ffb155381e32b39c73b971e545f1444627 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "src/v8.h"
 
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
 #include "src/macro-assembler.h"
index 0c9677f474ffe7ea2050daa1cfccf89799c1caef..980f5d5b0f8fe39697f379962c925de3edb266f0 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "src/v8.h"
 
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
 #include "src/ic/ic.h"
index baa38324e790262645af0c1e8a6fb2869c9605f5..a3fdc3f40f5f9cd3e3712e03016db8f5525de747 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "src/v8.h"
 
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/disasm.h"
 #include "src/disassembler.h"
 #include "src/ic/ic.h"
index 2995fb9730eeec0172f2772344dc688abc66852e..9fc2a73ef571fcf672e1351218e1f6635972db56 100644 (file)
@@ -6,7 +6,7 @@
 #include "test/cctest/cctest.h"
 
 #include "src/api.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/execution.h"
 #include "src/factory.h"
 #include "src/global-handles.h"
index d01a938590fddc4a6e50610bb49aaeac0628881c..6c7aa030bc310f9458e57bc9a0879c18be411e34 100644 (file)
@@ -29,7 +29,7 @@
 #include "src/v8.h"
 
 #include "src/api.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/string-search.h"
 #include "test/cctest/cctest.h"
 
index 0c367479d2ef8446c344964ec6cf029f9d13febd..4f6813778561f0fc0905749d87fc861fb55c4199 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "include/v8-profiler.h"
 #include "src/allocation-tracker.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/hashmap.h"
 #include "src/heap-profiler.h"
 #include "test/cctest/cctest.h"
index 8419dc5a4393351022a434db2326c7605a38514c..fdda3f53c6984a1a701158390db9499ebc599f32 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "src/v8.h"
 
-#include "src/liveedit.h"
+#include "src/debug/liveedit.h"
 #include "test/cctest/cctest.h"
 
 
index ebfd8d54786f1cf1f9762047850513342b35c6f3..bf36081201f57e4a9938ab9d10e7a49812d02299 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "src/bootstrapper.h"
 #include "src/compilation-cache.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/heap/spaces.h"
 #include "src/objects.h"
 #include "src/parser.h"
index 8992fe79c573e2a64bb97e9c9a5c5446db780fb9..fac3b16b8d0757b85f72aa81cd6c4cb0106802f6 100644 (file)
@@ -42,7 +42,7 @@ function CheckScope(scope_mirror, scope_expectations, expected_scope_type) {
   }
 }
 
-// A copy of the scope types from mirror-debugger.js.
+// A copy of the scope types from debug/mirrors.js.
 var ScopeType = { Global: 0,
                   Local: 1,
                   With: 2,
index e7049ee3c0a77a5aa7ec9f0ad2dbe332ae02ae7a..c1a20e7b9e3b36269b340da9391656e593a0b256 100644 (file)
@@ -45,7 +45,7 @@ function CheckScope(scope_mirror, scope_expectations, expected_scope_type) {
   }
 }
 
-// A copy of the scope types from mirror-debugger.js.
+// A copy of the scope types from debug/mirrors.js.
 var ScopeType = { Global: 0,
                   Local: 1,
                   With: 2,
index 93a46ed15d50c70221746293251953f2979066b1..7d042151435234c3ee501bb079b401daa41fce39 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "include/libplatform/libplatform.h"
 #include "src/base/platform/time.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
 #include "src/flags.h"
 #include "src/isolate.h"
 #include "src/v8.h"
index 487910754bc7fff6f4df6a02a6eb45bbbc00265a..8141265609aeb62854896962e6c379a8772dc447 100644 (file)
         '../../src/dateparser-inl.h',
         '../../src/dateparser.cc',
         '../../src/dateparser.h',
-        '../../src/debug.cc',
-        '../../src/debug.h',
+        '../../src/debug/debug.cc',
+        '../../src/debug/debug.h',
+        '../../src/debug/liveedit.cc',
+        '../../src/debug/liveedit.h',
         '../../src/deoptimizer.cc',
         '../../src/deoptimizer.h',
         '../../src/disasm.h',
         '../../src/lithium.cc',
         '../../src/lithium.h',
         '../../src/lithium-inl.h',
-        '../../src/liveedit.cc',
-        '../../src/liveedit.h',
         '../../src/log-inl.h',
         '../../src/log-utils.cc',
         '../../src/log-utils.h',
             '../../src/arm/constants-arm.h',
             '../../src/arm/constants-arm.cc',
             '../../src/arm/cpu-arm.cc',
-            '../../src/arm/debug-arm.cc',
             '../../src/arm/deoptimizer-arm.cc',
             '../../src/arm/disasm-arm.cc',
             '../../src/arm/frames-arm.cc',
             '../../src/compiler/arm/instruction-codes-arm.h',
             '../../src/compiler/arm/instruction-selector-arm.cc',
             '../../src/compiler/arm/linkage-arm.cc',
+            '../../src/debug/arm/debug-arm.cc',
             '../../src/full-codegen/arm/full-codegen-arm.cc',
             '../../src/ic/arm/access-compiler-arm.cc',
             '../../src/ic/arm/handler-compiler-arm.cc',
             '../../src/arm64/code-stubs-arm64.h',
             '../../src/arm64/constants-arm64.h',
             '../../src/arm64/cpu-arm64.cc',
-            '../../src/arm64/debug-arm64.cc',
             '../../src/arm64/decoder-arm64.cc',
             '../../src/arm64/decoder-arm64.h',
             '../../src/arm64/decoder-arm64-inl.h',
             '../../src/compiler/arm64/instruction-codes-arm64.h',
             '../../src/compiler/arm64/instruction-selector-arm64.cc',
             '../../src/compiler/arm64/linkage-arm64.cc',
+            '../../src/debug/arm64/debug-arm64.cc',
             '../../src/full-codegen/arm64/full-codegen-arm64.cc',
             '../../src/ic/arm64/access-compiler-arm64.cc',
             '../../src/ic/arm64/handler-compiler-arm64.cc',
             '../../src/ia32/codegen-ia32.cc',
             '../../src/ia32/codegen-ia32.h',
             '../../src/ia32/cpu-ia32.cc',
-            '../../src/ia32/debug-ia32.cc',
             '../../src/ia32/deoptimizer-ia32.cc',
             '../../src/ia32/disasm-ia32.cc',
             '../../src/ia32/frames-ia32.cc',
             '../../src/compiler/ia32/instruction-codes-ia32.h',
             '../../src/compiler/ia32/instruction-selector-ia32.cc',
             '../../src/compiler/ia32/linkage-ia32.cc',
+            '../../src/debug/ia32/debug-ia32.cc',
             '../../src/full-codegen/ia32/full-codegen-ia32.cc',
             '../../src/ic/ia32/access-compiler-ia32.cc',
             '../../src/ic/ia32/handler-compiler-ia32.cc',
             '../../src/x87/codegen-x87.cc',
             '../../src/x87/codegen-x87.h',
             '../../src/x87/cpu-x87.cc',
-            '../../src/x87/debug-x87.cc',
             '../../src/x87/deoptimizer-x87.cc',
             '../../src/x87/disasm-x87.cc',
             '../../src/x87/frames-x87.cc',
             '../../src/compiler/x87/instruction-codes-x87.h',
             '../../src/compiler/x87/instruction-selector-x87.cc',
             '../../src/compiler/x87/linkage-x87.cc',
+            '../../src/debug/x87/debug-x87.cc',
             '../../src/full-codegen/x87/full-codegen-x87.cc',
             '../../src/ic/x87/access-compiler-x87.cc',
             '../../src/ic/x87/handler-compiler-x87.cc',
             '../../src/mips/constants-mips.cc',
             '../../src/mips/constants-mips.h',
             '../../src/mips/cpu-mips.cc',
-            '../../src/mips/debug-mips.cc',
             '../../src/mips/deoptimizer-mips.cc',
             '../../src/mips/disasm-mips.cc',
             '../../src/mips/frames-mips.cc',
             '../../src/compiler/mips/instruction-selector-mips.cc',
             '../../src/compiler/mips/linkage-mips.cc',
             '../../src/full-codegen/mips/full-codegen-mips.cc',
+            '../../src/debug/mips/debug-mips.cc',
             '../../src/ic/mips/access-compiler-mips.cc',
             '../../src/ic/mips/handler-compiler-mips.cc',
             '../../src/ic/mips/ic-mips.cc',
             '../../src/mips64/constants-mips64.cc',
             '../../src/mips64/constants-mips64.h',
             '../../src/mips64/cpu-mips64.cc',
-            '../../src/mips64/debug-mips64.cc',
             '../../src/mips64/deoptimizer-mips64.cc',
             '../../src/mips64/disasm-mips64.cc',
             '../../src/mips64/frames-mips64.cc',
             '../../src/compiler/mips64/instruction-codes-mips64.h',
             '../../src/compiler/mips64/instruction-selector-mips64.cc',
             '../../src/compiler/mips64/linkage-mips64.cc',
+            '../../src/debug/mips64/debug-mips64.cc',
             '../../src/full-codegen/mips64/full-codegen-mips64.cc',
             '../../src/ic/mips64/access-compiler-mips64.cc',
             '../../src/ic/mips64/handler-compiler-mips64.cc',
             '../../src/x64/codegen-x64.cc',
             '../../src/x64/codegen-x64.h',
             '../../src/x64/cpu-x64.cc',
-            '../../src/x64/debug-x64.cc',
             '../../src/x64/deoptimizer-x64.cc',
             '../../src/x64/disasm-x64.cc',
             '../../src/x64/frames-x64.cc',
             '../../src/x64/macro-assembler-x64.h',
             '../../src/x64/regexp-macro-assembler-x64.cc',
             '../../src/x64/regexp-macro-assembler-x64.h',
+            '../../src/debug/x64/debug-x64.cc',
             '../../src/full-codegen/x64/full-codegen-x64.cc',
             '../../src/ic/x64/access-compiler-x64.cc',
             '../../src/ic/x64/handler-compiler-x64.cc',
             '../../src/ppc/constants-ppc.h',
             '../../src/ppc/constants-ppc.cc',
             '../../src/ppc/cpu-ppc.cc',
-            '../../src/ppc/debug-ppc.cc',
             '../../src/ppc/deoptimizer-ppc.cc',
             '../../src/ppc/disasm-ppc.cc',
             '../../src/ppc/frames-ppc.cc',
             '../../src/compiler/ppc/instruction-codes-ppc.h',
             '../../src/compiler/ppc/instruction-selector-ppc.cc',
             '../../src/compiler/ppc/linkage-ppc.cc',
+            '../../src/debug/ppc/debug-ppc.cc',
             '../../src/full-codegen/ppc/full-codegen-ppc.cc',
             '../../src/ic/ppc/access-compiler-ppc.cc',
             '../../src/ic/ppc/handler-compiler-ppc.cc',
           '../../src/json.js',
           '../../src/array-iterator.js',
           '../../src/string-iterator.js',
-          '../../src/debug-debugger.js',
-          '../../src/mirror-debugger.js',
-          '../../src/liveedit-debugger.js',
           '../../src/templates.js',
           '../../src/harmony-array.js',
           '../../src/harmony-typedarray.js',
+          '../../src/debug/debug.js',
+          '../../src/debug/mirrors.js',
+          '../../src/debug/liveedit.js',
         ],
         'experimental_library_files': [
           '../../src/macros.py',
index ff8e2dc4c71f4e9746eea3548791c9eca262542d..c2805373796f0c58f88cd2c63a2e25a6ab97637f 100755 (executable)
@@ -377,7 +377,7 @@ class Sources:
 
 
 def IsDebuggerFile(filename):
-  return filename.endswith("-debugger.js")
+  return "debug" in filename
 
 def IsMacroFile(filename):
   return filename.endswith("macros.py")
@@ -447,7 +447,7 @@ def PrepareSources(source_files, native_type, emit_js):
     result.is_debugger_id.append(is_debugger)
 
     name = os.path.basename(source)[:-3]
-    result.names.append(name if not is_debugger else name[:-9])
+    result.names.append(name)
 
   return result