Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Add a new API V8::SetJitCodeEventHandler to push code name and locati…
Browse files Browse the repository at this point in the history
…on to users such as profilers.

BUG=None
TEST=Included in CL.

Review URL: https://chromiumcodereview.appspot.com/10795074
Patch from Sigurður Ásgeirsson <siggi@chromium.org>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@12389 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
  • Loading branch information
jakobkummerow authored and piscisaureus committed Aug 28, 2012
1 parent ee484a5 commit 65d4dab
Show file tree
Hide file tree
Showing 11 changed files with 411 additions and 18 deletions.
74 changes: 74 additions & 0 deletions deps/v8/include/v8.h
Expand Up @@ -2944,6 +2944,57 @@ typedef void (*FunctionEntryHook)(uintptr_t function,
uintptr_t return_addr_location);


/**
* A JIT code event is issued each time code is added, moved or removed.
*
* \note removal events are not currently issued.
*/
struct JitCodeEvent {
enum EventType {
CODE_ADDED,
CODE_MOVED,
CODE_REMOVED
};

// Type of event.
EventType type;
// Start of the instructions.
void* code_start;
// Size of the instructions.
size_t code_len;

union {
// Only valid for CODE_ADDED.
struct {
// Name of the object associated with the code, note that the string is
// not zero-terminated.
const char* str;
// Number of chars in str.
size_t len;
} name;
// New location of instructions. Only valid for CODE_MOVED.
void* new_code_start;
};
};

/**
* Option flags passed to the SetJitCodeEventHandler function.
*/
enum JitCodeEventOptions {
kJitCodeEventDefault = 0,
// Generate callbacks for already existent code.
kJitCodeEventEnumExisting = 1
};


/**
* Callback function passed to SetJitCodeEventHandler.
*
* \param event code add, move or removal event.
*/
typedef void (*JitCodeEventHandler)(const JitCodeEvent* event);


/**
* Interface for iterating though all external resources in the heap.
*/
Expand Down Expand Up @@ -3218,6 +3269,29 @@ class V8EXPORT V8 {
*/
static bool SetFunctionEntryHook(FunctionEntryHook entry_hook);

/**
* Allows the host application to provide the address of a function that is
* notified each time code is added, moved or removed.
*
* \param options options for the JIT code event handler.
* \param event_handler the JIT code event handler, which will be invoked
* each time code is added, moved or removed.
* \note \p event_handler won't get notified of existent code.
* \note since code removal notifications are not currently issued, the
* \p event_handler may get notifications of code that overlaps earlier
* code notifications. This happens when code areas are reused, and the
* earlier overlapping code areas should therefore be discarded.
* \note the events passed to \p event_handler and the strings they point to
* are not guaranteed to live past each call. The \p event_handler must
* copy strings and other parameters it needs to keep around.
* \note the set of events declared in JitCodeEvent::EventType is expected to
* grow over time, and the JitCodeEvent structure is expected to accrue
* new members. The \p event_handler function must ignore event codes
* it does not recognize to maintain future compatibility.
*/
static void SetJitCodeEventHandler(JitCodeEventOptions options,
JitCodeEventHandler event_handler);

/**
* Adjusts the amount of registered external memory. Used to give
* V8 an indication of the amount of externally allocated memory
Expand Down
9 changes: 9 additions & 0 deletions deps/v8/src/api.cc
Expand Up @@ -4261,6 +4261,15 @@ bool v8::V8::SetFunctionEntryHook(FunctionEntryHook entry_hook) {
}


void v8::V8::SetJitCodeEventHandler(
JitCodeEventOptions options, JitCodeEventHandler event_handler) {
i::Isolate* isolate = i::Isolate::Current();
// Ensure that logging is initialized for our isolate.
isolate->InitializeLoggingAndCounters();
isolate->logger()->SetCodeEventHandler(options, event_handler);
}


bool v8::V8::Dispose() {
i::Isolate* isolate = i::Isolate::Current();
if (!ApiCheck(isolate != NULL && isolate->IsDefaultIsolate(),
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/compiler.cc
Expand Up @@ -1003,7 +1003,7 @@ void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
// Log the code generation. If source information is available include
// script name and line number. Check explicitly whether logging is
// enabled as finding the line number is not free.
if (info->isolate()->logger()->is_logging() ||
if (info->isolate()->logger()->is_logging_code_events() ||
CpuProfiler::is_profiling(info->isolate())) {
Handle<Script> script = info->script();
Handle<Code> code = info->code();
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/cpu-profiler.h
Expand Up @@ -188,7 +188,7 @@ class ProfilerEventsProcessor : public Thread {


#define PROFILE(isolate, Call) \
LOG(isolate, Call); \
LOG_CODE_EVENT(isolate, Call); \
do { \
if (v8::internal::CpuProfiler::is_profiling(isolate)) { \
v8::internal::CpuProfiler::Call; \
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/heap.cc
Expand Up @@ -1741,7 +1741,7 @@ class ScavengingVisitor : public StaticVisitorBase {
RecordCopiedObject(heap, target);
HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
Isolate* isolate = heap->isolate();
if (isolate->logger()->is_logging() ||
if (isolate->logger()->is_logging_code_events() ||
CpuProfiler::is_profiling(isolate)) {
if (target->IsSharedFunctionInfo()) {
PROFILE(isolate, SharedFunctionInfoMoveEvent(
Expand Down
3 changes: 2 additions & 1 deletion deps/v8/src/isolate.cc
Expand Up @@ -1901,7 +1901,8 @@ bool Isolate::Init(Deserializer* des) {

// If we are deserializing, log non-function code objects and compiled
// functions found in the snapshot.
if (create_heap_objects && (FLAG_log_code || FLAG_ll_prof)) {
if (create_heap_objects &&
(FLAG_log_code || FLAG_ll_prof || logger_->is_logging_code_events())) {
HandleScope scope;
LOG(this, LogCodeObjects());
LOG(this, LogCompiledFunctions());
Expand Down
109 changes: 96 additions & 13 deletions deps/v8/src/log.cc
Expand Up @@ -526,6 +526,7 @@ Logger::Logger()
name_buffer_(new NameBuffer),
address_to_name_map_(NULL),
is_initialized_(false),
code_event_handler_(NULL),
last_address_(NULL),
prev_sp_(NULL),
prev_function_(NULL),
Expand All @@ -541,6 +542,50 @@ Logger::~Logger() {
}


void Logger::IssueCodeAddedEvent(Code* code,
const char* name,
size_t name_len) {
JitCodeEvent event;
event.type = JitCodeEvent::CODE_ADDED;
event.code_start = code->instruction_start();
event.code_len = code->instruction_size();
event.name.str = name;
event.name.len = name_len;

code_event_handler_(&event);
}


void Logger::IssueCodeMovedEvent(Address from, Address to) {
Code* from_code = Code::cast(HeapObject::FromAddress(from));

JitCodeEvent event;
event.type = JitCodeEvent::CODE_MOVED;
event.code_start = from_code->instruction_start();
event.code_len = from_code->instruction_size();

// Calculate the header size.
const size_t header_size =
from_code->instruction_start() - reinterpret_cast<byte*>(from_code);

event.new_code_start = to + header_size;

code_event_handler_(&event);
}


void Logger::IssueCodeRemovedEvent(Address from) {
Code* from_code = Code::cast(HeapObject::FromAddress(from));

JitCodeEvent event;
event.type = JitCodeEvent::CODE_REMOVED;
event.code_start = from_code->instruction_start();
event.code_len = from_code->instruction_size();

code_event_handler_(&event);
}


#define DECLARE_EVENT(ignore1, name) name,
static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
Expand Down Expand Up @@ -864,13 +909,17 @@ void Logger::SetterCallbackEvent(String* name, Address entry_point) {
void Logger::CodeCreateEvent(LogEventsAndTags tag,
Code* code,
const char* comment) {
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof || Serializer::enabled()) {
if (!is_logging_code_events()) return;
if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
name_buffer_->AppendBytes(comment);
}
if (code_event_handler_ != NULL) {
IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
}
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
Expand Down Expand Up @@ -899,13 +948,17 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
void Logger::CodeCreateEvent(LogEventsAndTags tag,
Code* code,
String* name) {
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof || Serializer::enabled()) {
if (!is_logging_code_events()) return;
if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
name_buffer_->AppendString(name);
}
if (code_event_handler_ != NULL) {
IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
}
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
Expand Down Expand Up @@ -940,14 +993,18 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
String* name) {
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof || Serializer::enabled()) {
if (!is_logging_code_events()) return;
if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
name_buffer_->AppendBytes(ComputeMarker(code));
name_buffer_->AppendString(name);
}
if (code_event_handler_ != NULL) {
IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
}
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
Expand Down Expand Up @@ -981,8 +1038,8 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
Code* code,
SharedFunctionInfo* shared,
String* source, int line) {
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof || Serializer::enabled()) {
if (!is_logging_code_events()) return;
if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
Expand All @@ -993,6 +1050,10 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
name_buffer_->AppendByte(':');
name_buffer_->AppendInt(line);
}
if (code_event_handler_ != NULL) {
IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
}
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
Expand Down Expand Up @@ -1022,13 +1083,17 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,


void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof || Serializer::enabled()) {
if (!is_logging_code_events()) return;
if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[tag]);
name_buffer_->AppendByte(':');
name_buffer_->AppendInt(args_count);
}
if (code_event_handler_ != NULL) {
IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
}
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
Expand All @@ -1055,13 +1120,17 @@ void Logger::CodeMovingGCEvent() {


void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof || Serializer::enabled()) {
if (!is_logging_code_events()) return;
if (FLAG_ll_prof || Serializer::enabled() || code_event_handler_ != NULL) {
name_buffer_->Reset();
name_buffer_->AppendBytes(kLogEventsNames[REG_EXP_TAG]);
name_buffer_->AppendByte(':');
name_buffer_->AppendString(source);
}
if (code_event_handler_ != NULL) {
IssueCodeAddedEvent(code, name_buffer_->get(), name_buffer_->size());
}
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) {
LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
}
Expand All @@ -1083,6 +1152,7 @@ void Logger::RegExpCodeCreateEvent(Code* code, String* source) {


void Logger::CodeMoveEvent(Address from, Address to) {
if (code_event_handler_ != NULL) IssueCodeMovedEvent(from, to);
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to);
if (Serializer::enabled() && address_to_name_map_ != NULL) {
Expand All @@ -1093,6 +1163,7 @@ void Logger::CodeMoveEvent(Address from, Address to) {


void Logger::CodeDeleteEvent(Address from) {
if (code_event_handler_ != NULL) IssueCodeRemovedEvent(from);
if (!log_->IsEnabled()) return;
if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from);
if (Serializer::enabled() && address_to_name_map_ != NULL) {
Expand Down Expand Up @@ -1392,7 +1463,7 @@ static int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis,


void Logger::LogCodeObject(Object* object) {
if (FLAG_log_code || FLAG_ll_prof) {
if (FLAG_log_code || FLAG_ll_prof || is_logging_code_events()) {
Code* code_object = Code::cast(object);
LogEventsAndTags tag = Logger::STUB_TAG;
const char* description = "Unknown code from the snapshot";
Expand Down Expand Up @@ -1676,6 +1747,18 @@ bool Logger::SetUp() {
}


void Logger::SetCodeEventHandler(uint32_t options,
JitCodeEventHandler event_handler) {
code_event_handler_ = event_handler;

if (code_event_handler_ != NULL && (options & kJitCodeEventEnumExisting)) {
HandleScope scope;
LogCodeObjects();
LogCompiledFunctions();
}
}


Sampler* Logger::sampler() {
return ticker_;
}
Expand Down

0 comments on commit 65d4dab

Please sign in to comment.