Commit 3003b215 authored by vegorov@chromium.org's avatar vegorov@chromium.org

Basic GDB JIT Interface integration.

It has certain overheads even when gdb is not attached so it is guarded by ENABLE_GDBJIT_INTERFACE define and --gdbjit flag.

Review URL: http://codereview.chromium.org/5965011

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6367 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9cee2813
......@@ -229,6 +229,9 @@ LIBRARY_FLAGS = {
},
'prof:oprofile': {
'CPPDEFINES': ['ENABLE_OPROFILE_AGENT']
},
'gdbjit:on': {
'CPPDEFINES': ['ENABLE_GDB_JIT_INTERFACE']
}
},
'msvc': {
......@@ -706,6 +709,11 @@ SIMPLE_OPTIONS = {
'default': 'off',
'help': 'enable profiling of build target'
},
'gdbjit': {
'values': ['on', 'off'],
'default': 'off',
'help': 'enable GDB JIT interface'
},
'library': {
'values': ['static', 'shared'],
'default': 'static',
......@@ -872,6 +880,8 @@ def VerifyOptions(env):
return False
if env['os'] == 'win32' and env['library'] == 'shared' and env['prof'] == 'on':
Abort("Profiling on windows only supported for static library.")
if env['gdbjit'] == 'on' and (env['os'] != 'linux' or (env['arch'] != 'ia32' and env['arch'] != 'x64')):
Abort("GDBJIT interface is supported only for Intel-compatible (ia32 or x64) Linux target.")
if env['prof'] == 'oprofile' and env['os'] != 'linux':
Abort("OProfile is only supported on Linux.")
if env['os'] == 'win32' and env['soname'] == 'on':
......
......@@ -71,6 +71,7 @@ SOURCES = {
frames.cc
full-codegen.cc
func-name-inferrer.cc
gdb-jit.cc
global-handles.cc
fast-dtoa.cc
fixed-dtoa.cc
......
......@@ -917,6 +917,11 @@ void PositionsRecorder::RecordPosition(int pos) {
ASSERT(pos != RelocInfo::kNoPosition);
ASSERT(pos >= 0);
state_.current_position = pos;
#ifdef ENABLE_GDB_JIT_INTERFACE
if (gdbjit_lineinfo_ != NULL) {
gdbjit_lineinfo_->SetPosition(assembler_->pc_offset(), pos, false);
}
#endif
}
......@@ -924,6 +929,11 @@ void PositionsRecorder::RecordStatementPosition(int pos) {
ASSERT(pos != RelocInfo::kNoPosition);
ASSERT(pos >= 0);
state_.current_statement_position = pos;
#ifdef ENABLE_GDB_JIT_INTERFACE
if (gdbjit_lineinfo_ != NULL) {
gdbjit_lineinfo_->SetPosition(assembler_->pc_offset(), pos, true);
}
#endif
}
......
......@@ -35,6 +35,7 @@
#ifndef V8_ASSEMBLER_H_
#define V8_ASSEMBLER_H_
#include "gdb-jit.h"
#include "runtime.h"
#include "top.h"
#include "token.h"
......@@ -637,7 +638,29 @@ struct PositionState {
class PositionsRecorder BASE_EMBEDDED {
public:
explicit PositionsRecorder(Assembler* assembler)
: assembler_(assembler) {}
: assembler_(assembler) {
#ifdef ENABLE_GDB_JIT_INTERFACE
gdbjit_lineinfo_ = NULL;
#endif
}
#ifdef ENABLE_GDB_JIT_INTERFACE
~PositionsRecorder() {
delete gdbjit_lineinfo_;
}
void StartGDBJITLineInfoRecording() {
if (FLAG_gdbjit) {
gdbjit_lineinfo_ = new GDBJITLineInfo();
}
}
GDBJITLineInfo* DetachGDBJITLineInfo() {
GDBJITLineInfo* lineinfo = gdbjit_lineinfo_;
gdbjit_lineinfo_ = NULL; // To prevent deallocation in destructor.
return lineinfo;
}
#endif
// Set current position to pos.
void RecordPosition(int pos);
......@@ -657,6 +680,9 @@ class PositionsRecorder BASE_EMBEDDED {
private:
Assembler* assembler_;
PositionState state_;
#ifdef ENABLE_GDB_JIT_INTERFACE
GDBJITLineInfo* gdbjit_lineinfo_;
#endif
friend class PreservePositionScope;
......
......@@ -31,6 +31,7 @@
#include "arguments.h"
#include "bootstrapper.h"
#include "builtins.h"
#include "gdb-jit.h"
#include "ic-inl.h"
#include "vm-state-inl.h"
......@@ -1550,7 +1551,7 @@ void Builtins::Setup(bool create_heap_objects) {
CodeDesc desc;
masm.GetCode(&desc);
Code::Flags flags = functions[i].flags;
Object* code = 0;
Object* code = NULL;
{
// During startup it's OK to always allocate and defer GC to later.
// This simplifies things because we don't need to retry.
......@@ -1564,7 +1565,11 @@ void Builtins::Setup(bool create_heap_objects) {
}
// Log the event and add the code to the builtins array.
PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG,
Code::cast(code), functions[i].s_name));
Code::cast(code),
functions[i].s_name));
GDBJIT(AddCode(GDBJITInterface::BUILTIN,
functions[i].s_name,
Code::cast(code)));
builtins_[i] = code;
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_builtin_code) {
......
......@@ -30,6 +30,7 @@
#include "bootstrapper.h"
#include "code-stubs.h"
#include "factory.h"
#include "gdb-jit.h"
#include "macro-assembler.h"
#include "oprofile-agent.h"
......@@ -66,6 +67,7 @@ void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
code->instruction_start(),
code->instruction_size()));
PROFILE(CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
GDBJIT(AddCode(GDBJITInterface::STUB, GetName(), code));
Counters::total_stubs_code_size.Increment(code->instruction_size());
#ifdef ENABLE_DISASSEMBLER
......
......@@ -248,6 +248,9 @@ bool CodeGenerator::MakeCode(CompilationInfo* info) {
// Generate code.
const int kInitialBufferSize = 4 * KB;
MacroAssembler masm(NULL, kInitialBufferSize);
#ifdef ENABLE_GDB_JIT_INTERFACE
masm.positions_recorder()->StartGDBJITLineInfoRecording();
#endif
CodeGenerator cgen(&masm);
CodeGeneratorScope scope(&cgen);
cgen.Generate(info);
......@@ -263,6 +266,14 @@ bool CodeGenerator::MakeCode(CompilationInfo* info) {
code->SetNoStackCheckTable();
CodeGenerator::PrintCode(code, info);
info->SetCode(code); // May be an empty handle.
#ifdef ENABLE_GDB_JIT_INTERFACE
if (!code.is_null()) {
GDBJITLineInfo* lineinfo =
masm.positions_recorder()->DetachGDBJITLineInfo();
GDBJIT(RegisterDetailedLineInfo(*code, lineinfo));
}
#endif
return !code.is_null();
}
......
......@@ -35,6 +35,7 @@
#include "data-flow.h"
#include "debug.h"
#include "full-codegen.h"
#include "gdb-jit.h"
#include "hydrogen.h"
#include "lithium-allocator.h"
#include "liveedit.h"
......@@ -421,6 +422,9 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
OPROFILE(CreateNativeCodeRegion(String::cast(script->name()),
info->code()->instruction_start(),
info->code()->instruction_size()));
GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
script,
info->code()));
} else {
PROFILE(CodeCreateEvent(
info->is_eval()
......@@ -431,6 +435,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
OPROFILE(CreateNativeCodeRegion(info->is_eval() ? "Eval" : "Script",
info->code()->instruction_start(),
info->code()->instruction_size()));
GDBJIT(AddCode(Handle<String>(), script, info->code()));
}
// Allocate function.
......@@ -794,6 +799,10 @@ void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
code->instruction_size()));
}
}
GDBJIT(AddCode(name,
Handle<Script>(info->script()),
Handle<Code>(info->code())));
}
} } // namespace v8::internal
......@@ -366,6 +366,14 @@ DEFINE_bool(debug_script_collected_events, true,
"Enable debugger script collected events")
#endif
//
// GDB JIT integration flags.
//
DEFINE_bool(gdbjit, false, "enable GDBJIT interface (disables compacting GC)")
DEFINE_bool(gdbjit_full, false, "enable GDBJIT interface for all code objects")
//
// Debug only flags
//
......
......@@ -286,6 +286,9 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
CodeGenerator::MakeCodePrologue(info);
const int kInitialBufferSize = 4 * KB;
MacroAssembler masm(NULL, kInitialBufferSize);
#ifdef ENABLE_GDB_JIT_INTERFACE
masm.positions_recorder()->StartGDBJITLineInfoRecording();
#endif
FullCodeGenerator cgen(&masm);
cgen.Generate(info);
......@@ -304,6 +307,14 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
code->set_stack_check_table_start(table_offset);
CodeGenerator::PrintCode(code, info);
info->SetCode(code); // may be an empty handle.
#ifdef ENABLE_GDB_JIT_INTERFACE
if (!code.is_null()) {
GDBJITLineInfo* lineinfo =
masm.positions_recorder()->DetachGDBJITLineInfo();
GDBJIT(RegisterDetailedLineInfo(*code, lineinfo));
}
#endif
return !code.is_null();
}
......
This diff is collapsed.
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_GDB_JIT_H_
#define V8_GDB_JIT_H_
//
// Basic implementation of GDB JIT Interface client.
// GBD JIT Interface is supported in GDB 7.0 and above.
// Currently on x64 and ia32 architectures and Linux OS are supported.
//
#ifdef ENABLE_GDB_JIT_INTERFACE
#include "v8.h"
#include "factory.h"
namespace v8 {
namespace internal {
#define CODE_TAGS_LIST(V) \
V(LOAD_IC) \
V(KEYED_LOAD_IC) \
V(STORE_IC) \
V(KEYED_STORE_IC) \
V(CALL_IC) \
V(CALL_INITIALIZE) \
V(CALL_PRE_MONOMORPHIC) \
V(CALL_NORMAL) \
V(CALL_MEGAMORPHIC) \
V(CALL_MISS) \
V(STUB) \
V(BUILTIN) \
V(SCRIPT) \
V(EVAL)
class GDBJITLineInfo : public Malloced {
public:
GDBJITLineInfo()
: pc_info_(10) { }
void SetPosition(intptr_t pc, int pos, bool is_statement) {
AddPCInfo(PCInfo(pc, pos, is_statement));
}
struct PCInfo {
PCInfo(intptr_t pc, int pos, bool is_statement)
: pc_(pc), pos_(pos), is_statement_(is_statement) { }
intptr_t pc_;
int pos_;
bool is_statement_;
};
List<PCInfo>* pc_info() {
return &pc_info_;
}
private:
void AddPCInfo(const PCInfo& pc_info) {
pc_info_.Add(pc_info);
}
List<PCInfo> pc_info_;
};
class GDBJITInterface: public AllStatic {
public:
enum CodeTag {
#define V(x) x,
CODE_TAGS_LIST(V)
#undef V
TAG_COUNT
};
static const char* Tag2String(CodeTag tag) {
switch (tag) {
#define V(x) case x: return #x;
CODE_TAGS_LIST(V)
#undef V
default:
return NULL;
}
}
static void AddCode(const char* name,
Code* code,
Script* script = NULL);
static void AddCode(Handle<String> name,
Handle<Script> script,
Handle<Code> code);
static void AddCode(CodeTag tag, String* name, Code* code);
static void AddCode(CodeTag tag, const char* name, Code* code);
static void AddCode(CodeTag tag, Code* code);
static void RemoveCode(Code* code);
static void RegisterDetailedLineInfo(Code* code, GDBJITLineInfo* line_info);
};
#define GDBJIT(action) GDBJITInterface::action
} } // namespace v8::internal
#else
#define GDBJIT(action) ((void) 0)
#endif
#endif
......@@ -30,6 +30,7 @@
#include "compilation-cache.h"
#include "execution.h"
#include "heap-profiler.h"
#include "gdb-jit.h"
#include "global-handles.h"
#include "ic-inl.h"
#include "mark-compact.h"
......@@ -125,6 +126,12 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
if (!Heap::map_space()->MapPointersEncodable())
compacting_collection_ = false;
if (FLAG_collect_maps) CreateBackPointers();
#ifdef ENABLE_GDB_JIT_INTERFACE
if (FLAG_gdbjit) {
// If GDBJIT interface is active disable compaction.
compacting_collection_ = false;
}
#endif
PagedSpaces spaces;
for (PagedSpace* space = spaces.next();
......@@ -2906,6 +2913,11 @@ int MarkCompactCollector::RelocateNewObject(HeapObject* obj) {
void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) {
#ifdef ENABLE_GDB_JIT_INTERFACE
if (obj->IsCode()) {
GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj));
}
#endif
#ifdef ENABLE_LOGGING_AND_PROFILING
if (obj->IsCode()) {
PROFILE(CodeDeleteEvent(obj->address()));
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment