From: mstarzinger@chromium.org Date: Fri, 27 Jan 2012 16:09:20 +0000 (+0000) Subject: Fix and adapt debugger for new call target caches. X-Git-Tag: upstream/4.7.83~17503 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=74feaa6c3dbd25ece76c6c7924c2721faca2acfb;p=platform%2Fupstream%2Fv8.git Fix and adapt debugger for new call target caches. 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 --- diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc index 92f23f4..96139a2 100644 --- a/src/arm/debug-arm.cc +++ b/src/arm/debug-arm.cc @@ -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. diff --git a/src/builtins.cc b/src/builtins.cc index 12c4c74..bcb1198 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -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); } diff --git a/src/builtins.h b/src/builtins.h index 10eaa5a..f079139 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -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 diff --git a/src/code-stubs.h b/src/code-stubs.h index 1141cb5..78ff554 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -739,6 +739,10 @@ class CallFunctionStub: public CodeStub { void Generate(MacroAssembler* masm); + virtual void FinishCode(Handle 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->set_has_function_cache(RecordCallTarget()); + } + private: CallFunctionFlags flags_; diff --git a/src/debug.cc b/src/debug.cc index 01c4dba..f6c4d6c 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -85,12 +85,6 @@ static void PrintLn(v8::Local value) { } -static Handle ComputeCallDebugBreak(int argc, Code::Kind kind) { - Isolate* isolate = Isolate::Current(); - return isolate->stub_cache()->ComputeCallDebugBreak(argc, kind); -} - - static Handle 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 Debug::FindDebugBreak(Handle 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 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 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(); diff --git a/src/debug.h b/src/debug.h index 582aada..b9384e5 100644 --- a/src/debug.h +++ b/src/debug.h @@ -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); diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc index 1f2faf9..d13fa75 100644 --- a/src/ia32/debug-ia32.cc +++ b/src/ia32/debug-ia32.cc @@ -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; diff --git a/src/objects-inl.h b/src/objects-inl.h index b27b0bb..7901f08 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -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; diff --git a/src/objects.h b/src/objects.h index ca3dd57..6871176 100644 --- a/src/objects.h +++ b/src/objects.h @@ -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: diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc index 59b5e25..eec83d9 100644 --- a/src/x64/debug-x64.cc +++ b/src/x64/debug-x64.cc @@ -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;