Fix and adapt debugger for new call target caches.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 27 Jan 2012 16:09:20 +0000 (16:09 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 27 Jan 2012 16:09:20 +0000 (16:09 +0000)
R=yangguo@chromium.org
TEST=mjsunit/debug-stepout-scope

Review URL: https://chromiumcodereview.appspot.com/9297019

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10540 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/debug-arm.cc
src/builtins.cc
src/builtins.h
src/code-stubs.h
src/debug.cc
src/debug.h
src/ia32/debug-ia32.cc
src/objects-inl.h
src/objects.h
src/x64/debug-x64.cc

index 92f23f4..96139a2 100644 (file)
@@ -251,15 +251,6 @@ void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
 }
 
 
-void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
-  // Calling convention for construct call (from builtins-arm.cc)
-  //  -- r0     : number of arguments (not smi)
-  //  -- r1     : constructor function
-  //  -- r2     : cache cell for call target
-  Generate_DebugBreakCallHelper(masm, r1.bit() | r2.bit(), r0.bit());
-}
-
-
 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
   // In places other than IC call sites it is expected that r0 is TOS which
   // is an object - this is not generally the case so this should be used with
@@ -277,6 +268,37 @@ void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
 }
 
 
+void Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
+  // Register state for CallFunctionStub (from code-stubs-arm.cc).
+  // ----------- S t a t e -------------
+  //  -- r1 : function
+  //  -- r2 : cache cell for call target
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, r1.bit() | r2.bit(), 0);
+}
+
+
+void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
+  // Calling convention for CallConstructStub (from code-stubs-arm.cc)
+  // ----------- S t a t e -------------
+  //  -- r0     : number of arguments (not smi)
+  //  -- r1     : constructor function
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, r1.bit(), r0.bit());
+}
+
+
+void Debug::GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm) {
+  // Calling convention for CallConstructStub (from code-stubs-arm.cc)
+  // ----------- S t a t e -------------
+  //  -- r0     : number of arguments (not smi)
+  //  -- r1     : constructor function
+  //  -- r2     : cache cell for call target
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, r1.bit() | r2.bit(), r0.bit());
+}
+
+
 void Debug::GenerateSlot(MacroAssembler* masm) {
   // Generate enough nop's to make space for a call instruction. Avoid emitting
   // the constant pool in the debug break slot code.
index 12c4c74..bcb1198 100644 (file)
@@ -1508,11 +1508,6 @@ static void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {
 }
 
 
-static void Generate_ConstructCall_DebugBreak(MacroAssembler* masm) {
-  Debug::GenerateConstructCallDebugBreak(masm);
-}
-
-
 static void Generate_Return_DebugBreak(MacroAssembler* masm) {
   Debug::GenerateReturnDebugBreak(masm);
 }
@@ -1523,6 +1518,23 @@ static void Generate_CallFunctionStub_DebugBreak(MacroAssembler* masm) {
 }
 
 
+static void Generate_CallFunctionStub_Recording_DebugBreak(
+    MacroAssembler* masm) {
+  Debug::GenerateCallFunctionStubRecordDebugBreak(masm);
+}
+
+
+static void Generate_CallConstructStub_DebugBreak(MacroAssembler* masm) {
+  Debug::GenerateCallConstructStubDebugBreak(masm);
+}
+
+
+static void Generate_CallConstructStub_Recording_DebugBreak(
+    MacroAssembler* masm) {
+  Debug::GenerateCallConstructStubRecordDebugBreak(masm);
+}
+
+
 static void Generate_Slot_DebugBreak(MacroAssembler* masm) {
   Debug::GenerateSlotDebugBreak(masm);
 }
index 10eaa5a..f079139 100644 (file)
@@ -194,26 +194,30 @@ enum BuiltinExtraArguments {
 #ifdef ENABLE_DEBUGGER_SUPPORT
 // Define list of builtins used by the debugger implemented in assembly.
 #define BUILTIN_LIST_DEBUG_A(V)                                 \
-  V(Return_DebugBreak,           BUILTIN, DEBUG_BREAK,          \
-                                 Code::kNoExtraICState)         \
-  V(ConstructCall_DebugBreak,    BUILTIN, DEBUG_BREAK,          \
-                                 Code::kNoExtraICState)         \
-  V(CallFunctionStub_DebugBreak, BUILTIN, DEBUG_BREAK,          \
-                                 Code::kNoExtraICState)         \
-  V(LoadIC_DebugBreak,           LOAD_IC, DEBUG_BREAK,          \
-                                 Code::kNoExtraICState)         \
-  V(KeyedLoadIC_DebugBreak,      KEYED_LOAD_IC, DEBUG_BREAK,    \
-                                 Code::kNoExtraICState)         \
-  V(StoreIC_DebugBreak,          STORE_IC, DEBUG_BREAK,         \
-                                 Code::kNoExtraICState)         \
-  V(KeyedStoreIC_DebugBreak,     KEYED_STORE_IC, DEBUG_BREAK,   \
-                                 Code::kNoExtraICState)         \
-  V(Slot_DebugBreak,             BUILTIN, DEBUG_BREAK,          \
-                                 Code::kNoExtraICState)         \
-  V(PlainReturn_LiveEdit,        BUILTIN, DEBUG_BREAK,          \
-                                 Code::kNoExtraICState)         \
-  V(FrameDropper_LiveEdit,       BUILTIN, DEBUG_BREAK,          \
-                                 Code::kNoExtraICState)
+  V(Return_DebugBreak,                         BUILTIN, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)         \
+  V(CallFunctionStub_DebugBreak,               BUILTIN, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)         \
+  V(CallFunctionStub_Recording_DebugBreak,     BUILTIN, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)         \
+  V(CallConstructStub_DebugBreak,              BUILTIN, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)         \
+  V(CallConstructStub_Recording_DebugBreak,    BUILTIN, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)         \
+  V(LoadIC_DebugBreak,                         LOAD_IC, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)         \
+  V(KeyedLoadIC_DebugBreak,                    KEYED_LOAD_IC, DEBUG_BREAK,    \
+                                               Code::kNoExtraICState)         \
+  V(StoreIC_DebugBreak,                        STORE_IC, DEBUG_BREAK,         \
+                                               Code::kNoExtraICState)         \
+  V(KeyedStoreIC_DebugBreak,                   KEYED_STORE_IC, DEBUG_BREAK,   \
+                                               Code::kNoExtraICState)         \
+  V(Slot_DebugBreak,                           BUILTIN, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)         \
+  V(PlainReturn_LiveEdit,                      BUILTIN, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)         \
+  V(FrameDropper_LiveEdit,                     BUILTIN, DEBUG_BREAK,          \
+                                               Code::kNoExtraICState)
 #else
 #define BUILTIN_LIST_DEBUG_A(V)
 #endif
index 1141cb5..78ff554 100644 (file)
@@ -739,6 +739,10 @@ class CallFunctionStub: public CodeStub {
 
   void Generate(MacroAssembler* masm);
 
+  virtual void FinishCode(Handle<Code> code) {
+    code->set_has_function_cache(RecordCallTarget());
+  }
+
   static int ExtractArgcFromMinorKey(int minor_key) {
     return ArgcBits::decode(minor_key);
   }
@@ -775,6 +779,10 @@ class CallConstructStub: public CodeStub {
 
   void Generate(MacroAssembler* masm);
 
+  virtual void FinishCode(Handle<Code> code) {
+    code->set_has_function_cache(RecordCallTarget());
+  }
+
  private:
   CallFunctionFlags flags_;
 
index 01c4dba..f6c4d6c 100644 (file)
@@ -85,12 +85,6 @@ static void PrintLn(v8::Local<v8::Value> value) {
 }
 
 
-static Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind) {
-  Isolate* isolate = Isolate::Current();
-  return isolate->stub_cache()->ComputeCallDebugBreak(argc, kind);
-}
-
-
 static Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind) {
   Isolate* isolate = Isolate::Current();
   return isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind);
@@ -1538,40 +1532,47 @@ bool Debug::IsBreakStub(Code* code) {
 
 // Find the builtin to use for invoking the debug break
 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
+  Isolate* isolate = Isolate::Current();
+
   // Find the builtin debug break function matching the calling convention
   // used by the call site.
   if (code->is_inline_cache_stub()) {
     switch (code->kind()) {
       case Code::CALL_IC:
       case Code::KEYED_CALL_IC:
-        return ComputeCallDebugBreak(code->arguments_count(), code->kind());
+        return isolate->stub_cache()->ComputeCallDebugBreak(
+            code->arguments_count(), code->kind());
 
       case Code::LOAD_IC:
-        return Isolate::Current()->builtins()->LoadIC_DebugBreak();
+        return isolate->builtins()->LoadIC_DebugBreak();
 
       case Code::STORE_IC:
-        return Isolate::Current()->builtins()->StoreIC_DebugBreak();
+        return isolate->builtins()->StoreIC_DebugBreak();
 
       case Code::KEYED_LOAD_IC:
-        return Isolate::Current()->builtins()->KeyedLoadIC_DebugBreak();
+        return isolate->builtins()->KeyedLoadIC_DebugBreak();
 
       case Code::KEYED_STORE_IC:
-        return Isolate::Current()->builtins()->KeyedStoreIC_DebugBreak();
+        return isolate->builtins()->KeyedStoreIC_DebugBreak();
 
       default:
         UNREACHABLE();
     }
   }
   if (RelocInfo::IsConstructCall(mode)) {
-    Handle<Code> result =
-        Isolate::Current()->builtins()->ConstructCall_DebugBreak();
-    return result;
+    if (code->has_function_cache()) {
+      return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
+    } else {
+      return isolate->builtins()->CallConstructStub_DebugBreak();
+    }
   }
   if (code->kind() == Code::STUB) {
     ASSERT(code->major_key() == CodeStub::CallFunction);
-    Handle<Code> result =
-        Isolate::Current()->builtins()->CallFunctionStub_DebugBreak();
-    return result;
+    if (code->has_function_cache()) {
+      return isolate->builtins()->CallFunctionStub_Recording_DebugBreak();
+    } else {
+      return isolate->builtins()->CallFunctionStub_DebugBreak();
+    }
   }
 
   UNREACHABLE();
index 582aada..b9384e5 100644 (file)
@@ -402,9 +402,11 @@ class Debug {
   static void GenerateStoreICDebugBreak(MacroAssembler* masm);
   static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm);
   static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm);
-  static void GenerateConstructCallDebugBreak(MacroAssembler* masm);
   static void GenerateReturnDebugBreak(MacroAssembler* masm);
   static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm);
+  static void GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm);
+  static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm);
+  static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm);
   static void GenerateSlotDebugBreak(MacroAssembler* masm);
   static void GeneratePlainReturnLiveEdit(MacroAssembler* masm);
 
index 1f2faf9..d13fa75 100644 (file)
@@ -222,30 +222,25 @@ void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
 }
 
 
-void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
+void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
   // Register state just before return from JS function (from codegen-ia32.cc).
-  // eax is the actual number of arguments not encoded as a smi see comment
-  // above IC call.
   // ----------- S t a t e -------------
-  //  -- eax: number of arguments (not smi)
-  //  -- ebx: cache cell for call target
-  //  -- edi: constructor function
+  //  -- eax: return value
   // -----------------------------------
-  // The number of arguments in eax is not smi encoded.
-  Generate_DebugBreakCallHelper(masm, ebx.bit() | edi.bit(), eax.bit(), false);
+  Generate_DebugBreakCallHelper(masm, eax.bit(), 0, true);
 }
 
 
-void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
-  // Register state just before return from JS function (from codegen-ia32.cc).
+void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
+  // Register state for CallFunctionStub (from code-stubs-ia32.cc).
   // ----------- S t a t e -------------
-  //  -- eax: return value
+  //  -- edi: function
   // -----------------------------------
-  Generate_DebugBreakCallHelper(masm, eax.bit(), 0, true);
+  Generate_DebugBreakCallHelper(masm, edi.bit(), 0, false);
 }
 
 
-void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
+void Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
   // Register state for CallFunctionStub (from code-stubs-ia32.cc).
   // ----------- S t a t e -------------
   //  -- ebx: cache cell for call target
@@ -255,6 +250,33 @@ void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
 }
 
 
+void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
+  // Register state for CallConstructStub (from code-stubs-ia32.cc).
+  // eax is the actual number of arguments not encoded as a smi see comment
+  // above IC call.
+  // ----------- S t a t e -------------
+  //  -- eax: number of arguments (not smi)
+  //  -- edi: constructor function
+  // -----------------------------------
+  // The number of arguments in eax is not smi encoded.
+  Generate_DebugBreakCallHelper(masm, edi.bit(), eax.bit(), false);
+}
+
+
+void Debug::GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm) {
+  // Register state for CallConstructStub (from code-stubs-ia32.cc).
+  // eax is the actual number of arguments not encoded as a smi see comment
+  // above IC call.
+  // ----------- S t a t e -------------
+  //  -- eax: number of arguments (not smi)
+  //  -- ebx: cache cell for call target
+  //  -- edi: constructor function
+  // -----------------------------------
+  // The number of arguments in eax is not smi encoded.
+  Generate_DebugBreakCallHelper(masm, ebx.bit() | edi.bit(), eax.bit(), false);
+}
+
+
 void Debug::GenerateSlot(MacroAssembler* masm) {
   // Generate enough nop's to make space for a call instruction.
   Label check_codesize;
index b27b0bb..7901f08 100644 (file)
@@ -3202,6 +3202,18 @@ void Code::set_to_boolean_state(byte value) {
 }
 
 
+bool Code::has_function_cache() {
+  ASSERT(kind() == STUB);
+  return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
+}
+
+
+void Code::set_has_function_cache(bool flag) {
+  ASSERT(kind() == STUB);
+  WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
+}
+
+
 bool Code::is_inline_cache_stub() {
   Kind kind = this->kind();
   return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
index ca3dd57..6871176 100644 (file)
@@ -4201,6 +4201,11 @@ class Code: public HeapObject {
   inline byte to_boolean_state();
   inline void set_to_boolean_state(byte value);
 
+  // [has_function_cache]: For kind STUB tells whether there is a function
+  // cache is passed to the stub.
+  inline bool has_function_cache();
+  inline void set_has_function_cache(bool flag);
+
   // Get the safepoint entry for the given pc.
   SafepointEntry GetSafepointEntry(Address pc);
 
@@ -4341,6 +4346,7 @@ class Code: public HeapObject {
   static const int kBinaryOpTypeOffset = kStubMajorKeyOffset + 1;
   static const int kCompareStateOffset = kStubMajorKeyOffset + 1;
   static const int kToBooleanTypeOffset = kStubMajorKeyOffset + 1;
+  static const int kHasFunctionCacheOffset = kStubMajorKeyOffset + 1;
 
   static const int kFullCodeFlags = kOptimizableOffset + 1;
   class FullCodeFlagsHasDeoptimizationSupportField:
index 59b5e25..eec83d9 100644 (file)
@@ -229,19 +229,6 @@ void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
 }
 
 
-void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
-  // Register state just before return from JS function (from codegen-x64.cc).
-  // rax is the actual number of arguments not encoded as a smi, see comment
-  // above IC call.
-  // ----------- S t a t e -------------
-  //  -- rax: number of arguments
-  //  -- rbx: cache cell for call target
-  // -----------------------------------
-  // The number of arguments in rax is not smi encoded.
-  Generate_DebugBreakCallHelper(masm, rbx.bit() | rdi.bit(), rax.bit(), false);
-}
-
-
 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
   // Register state just before return from JS function (from codegen-x64.cc).
   // ----------- S t a t e -------------
@@ -260,6 +247,41 @@ void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
 }
 
 
+void Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
+  // Register state for CallFunctionStub (from code-stubs-x64.cc).
+  // ----------- S t a t e -------------
+  //  -- rdi : function
+  //  -- rbx: cache cell for call target
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, rbx.bit() | rdi.bit(), 0, false);
+}
+
+
+void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
+  // Register state for CallConstructStub (from code-stubs-x64.cc).
+  // rax is the actual number of arguments not encoded as a smi, see comment
+  // above IC call.
+  // ----------- S t a t e -------------
+  //  -- rax: number of arguments
+  // -----------------------------------
+  // The number of arguments in rax is not smi encoded.
+  Generate_DebugBreakCallHelper(masm, rdi.bit(), rax.bit(), false);
+}
+
+
+void Debug::GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm) {
+  // Register state for CallConstructStub (from code-stubs-x64.cc).
+  // rax is the actual number of arguments not encoded as a smi, see comment
+  // above IC call.
+  // ----------- S t a t e -------------
+  //  -- rax: number of arguments
+  //  -- rbx: cache cell for call target
+  // -----------------------------------
+  // The number of arguments in rax is not smi encoded.
+  Generate_DebugBreakCallHelper(masm, rbx.bit() | rdi.bit(), rax.bit(), false);
+}
+
+
 void Debug::GenerateSlot(MacroAssembler* masm) {
   // Generate enough nop's to make space for a call instruction.
   Label check_codesize;