if (engaged_) return;
engaged_ = true;
- OS::LogSharedLibraryAddresses(isolate_);
+ std::vector<OS::SharedLibraryAddress> addresses =
+ OS::GetSharedLibraryAddresses();
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ LOG(isolate_, SharedLibraryEvent(
+ addresses[i].library_path, addresses[i].start, addresses[i].end));
+ }
// Start thread processing the profiler buffer.
running_ = true;
}
-void Logger::SharedLibraryEvent(const char* library_path,
+void Logger::SharedLibraryEvent(const std::string& library_path,
uintptr_t start,
uintptr_t end) {
if (!log_->IsEnabled() || !FLAG_prof) return;
Log::MessageBuilder msg(log_);
msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
- library_path,
- start,
- end);
- msg.WriteToLogFile();
-}
-
-
-void Logger::SharedLibraryEvent(const wchar_t* library_path,
- uintptr_t start,
- uintptr_t end) {
- if (!log_->IsEnabled() || !FLAG_prof) return;
- Log::MessageBuilder msg(log_);
- msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
- library_path,
+ library_path.c_str(),
start,
end);
msg.WriteToLogFile();
#ifndef V8_LOG_H_
#define V8_LOG_H_
+#include <string>
+
#include "src/allocation.h"
#include "src/objects.h"
#include "src/platform.h"
void HeapSampleStats(const char* space, const char* kind,
intptr_t capacity, intptr_t used);
- void SharedLibraryEvent(const char* library_path,
- uintptr_t start,
- uintptr_t end);
- void SharedLibraryEvent(const wchar_t* library_path,
+ void SharedLibraryEvent(const std::string& library_path,
uintptr_t start,
uintptr_t end);
}
-void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ std::vector<SharedLibraryAddresses> result;
// This function assumes that the layout of the file is as follows:
// hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
// If we encounter an unexpected situation we abort scanning further entries.
FILE* fp = fopen("/proc/self/maps", "r");
- if (fp == NULL) return;
+ if (fp == NULL) return result;
// Allocate enough room to be able to store a full file name.
const int kLibNameLen = FILENAME_MAX + 1;
snprintf(lib_name, kLibNameLen,
"%08" V8PRIxPTR "-%08" V8PRIxPTR, start, end);
}
- LOG(isolate, SharedLibraryEvent(lib_name, start, end));
+ result.push_back(SharedLibraryAddress(lib_name, start, end));
} else {
// Entry not describing executable data. Skip to end of line to set up
// reading the next entry.
}
free(lib_name);
fclose(fp);
+ return result;
}
}
-void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ std::vector<SharedLibraryAddress> result;
static const int MAP_LENGTH = 1024;
int fd = open("/proc/self/maps", O_RDONLY);
- if (fd < 0) return;
+ if (fd < 0) return result;
while (true) {
char addr_buffer[11];
addr_buffer[0] = '0';
// There may be no filename in this line. Skip to next.
if (start_of_path == NULL) continue;
buffer[bytes_read] = 0;
- LOG(isolate, SharedLibraryEvent(start_of_path, start, end));
+ result.push_back(SharedLibraryAddress(start_of_path, start, end));
}
close(fd);
+ return result;
}
}
-void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ std::vector<SharedLibraryAddress> result;
// This function assumes that the layout of the file is as follows:
// hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
// If we encounter an unexpected situation we abort scanning further entries.
FILE* fp = fopen("/proc/self/maps", "r");
- if (fp == NULL) return;
+ if (fp == NULL) return result;
// Allocate enough room to be able to store a full file name.
const int kLibNameLen = FILENAME_MAX + 1;
snprintf(lib_name, kLibNameLen,
"%08" V8PRIxPTR "-%08" V8PRIxPTR, start, end);
}
- LOG(isolate, SharedLibraryEvent(lib_name, start, end));
+ result.push_back(SharedLibraryAddress(lib_name, start, end));
} else {
// Entry not describing executable data. Skip to end of line to set up
// reading the next entry.
}
free(lib_name);
fclose(fp);
+ return result;
}
}
-void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ std::vector<SharedLibraryAddress> result;
unsigned int images_count = _dyld_image_count();
for (unsigned int i = 0; i < images_count; ++i) {
const mach_header* header = _dyld_get_image_header(i);
if (code_ptr == NULL) continue;
const uintptr_t slide = _dyld_get_image_vmaddr_slide(i);
const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr) + slide;
- LOG(isolate,
- SharedLibraryEvent(_dyld_get_image_name(i), start, start + size));
+ result.push_back(
+ SharedLibraryAddress(_dyld_get_image_name(i), start, start + size));
}
+ return result;
}
}
-void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ std::vector<SharedLibraryAddress> result;
// This function assumes that the layout of the file is as follows:
// hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
// If we encounter an unexpected situation we abort scanning further entries.
FILE* fp = fopen("/proc/self/maps", "r");
- if (fp == NULL) return;
+ if (fp == NULL) return result;
// Allocate enough room to be able to store a full file name.
const int kLibNameLen = FILENAME_MAX + 1;
snprintf(lib_name, kLibNameLen,
"%08" V8PRIxPTR "-%08" V8PRIxPTR, start, end);
}
- LOG(isolate, SharedLibraryEvent(lib_name, start, end));
+ result.push_back(SharedLibraryAddress(lib_name, start, end));
} else {
// Entry not describing executable data. Skip to end of line to set up
// reading the next entry.
}
free(lib_name);
fclose(fp);
+ return result;
}
}
-void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ std::vector<SharedLibraryAddress> result;
procfs_mapinfo *mapinfos = NULL, *mapinfo;
int proc_fd, num, i;
if ((proc_fd = open(buf, O_RDONLY)) == -1) {
close(proc_fd);
- return;
+ return result;
}
/* Get the number of map entries. */
if (devctl(proc_fd, DCMD_PROC_MAPINFO, NULL, 0, &num) != EOK) {
close(proc_fd);
- return;
+ return result;
}
mapinfos = reinterpret_cast<procfs_mapinfo *>(
malloc(num * sizeof(procfs_mapinfo)));
if (mapinfos == NULL) {
close(proc_fd);
- return;
+ return result;
}
/* Fill the map entries. */
mapinfos, num * sizeof(procfs_mapinfo), &num) != EOK) {
free(mapinfos);
close(proc_fd);
- return;
+ return result;
}
for (i = 0; i < num; i++) {
if (devctl(proc_fd, DCMD_PROC_MAPDEBUG, &map, sizeof(map), 0) != EOK) {
continue;
}
- LOG(isolate, SharedLibraryEvent(map.info.path,
- mapinfo->vaddr,
- mapinfo->vaddr + mapinfo->size));
+ result.push_back(SharedLibraryAddress(
+ map.info.path, mapinfo->vaddr, mapinfo->vaddr + mapinfo->size));
}
}
free(mapinfos);
close(proc_fd);
+ return result;
}
}
-void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ return std::vector<SharedLibraryAddress>();
}
// Load the symbols for generating stack traces.
-static bool LoadSymbols(Isolate* isolate, HANDLE process_handle) {
+static std::vector<OS::SharedLibraryAddress> LoadSymbols(
+ HANDLE process_handle) {
+ static std::vector<OS::SharedLibraryAddress> result;
+
static bool symbols_loaded = false;
- if (symbols_loaded) return true;
+ if (symbols_loaded) return result;
BOOL ok;
ok = _SymInitialize(process_handle, // hProcess
NULL, // UserSearchPath
false); // fInvadeProcess
- if (!ok) return false;
+ if (!ok) return result;
DWORD options = _SymGetOptions();
options |= SYMOPT_LOAD_LINES;
if (!ok) {
int err = GetLastError();
PrintF("%d\n", err);
- return false;
+ return result;
}
HANDLE snapshot = _CreateToolhelp32Snapshot(
TH32CS_SNAPMODULE, // dwFlags
GetCurrentProcessId()); // th32ProcessId
- if (snapshot == INVALID_HANDLE_VALUE) return false;
+ if (snapshot == INVALID_HANDLE_VALUE) return result;
MODULEENTRY32W module_entry;
module_entry.dwSize = sizeof(module_entry); // Set the size of the structure.
BOOL cont = _Module32FirstW(snapshot, &module_entry);
if (base == 0) {
int err = GetLastError();
if (err != ERROR_MOD_NOT_FOUND &&
- err != ERROR_INVALID_HANDLE) return false;
+ err != ERROR_INVALID_HANDLE) {
+ result.clear();
+ return result;
+ }
}
- LOG(isolate,
- SharedLibraryEvent(
- module_entry.szExePath,
- reinterpret_cast<unsigned int>(module_entry.modBaseAddr),
- reinterpret_cast<unsigned int>(module_entry.modBaseAddr +
- module_entry.modBaseSize)));
+ int lib_name_length = WideCharToMultiByte(
+ CP_UTF8, 0, module_entry.szExePath, -1, NULL, 0, NULL, NULL);
+ std::string lib_name(lib_name_length, 0);
+ WideCharToMultiByte(CP_UTF8, 0, module_entry.szExePath, -1, &lib_name[0],
+ lib_name_length, NULL, NULL);
+ result.push_back(OS::SharedLibraryAddress(
+ lib_name, reinterpret_cast<unsigned int>(module_entry.modBaseAddr),
+ reinterpret_cast<unsigned int>(module_entry.modBaseAddr +
+ module_entry.modBaseSize)));
cont = _Module32NextW(snapshot, &module_entry);
}
CloseHandle(snapshot);
symbols_loaded = true;
- return true;
+ return result;
}
-void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
// SharedLibraryEvents are logged when loading symbol information.
// Only the shared libraries loaded at the time of the call to
- // LogSharedLibraryAddresses are logged. DLLs loaded after
+ // GetSharedLibraryAddresses are logged. DLLs loaded after
// initialization are not accounted for.
- if (!LoadDbgHelpAndTlHelp32()) return;
+ if (!LoadDbgHelpAndTlHelp32()) return std::vector<OS::SharedLibraryAddress>();
HANDLE process_handle = GetCurrentProcess();
- LoadSymbols(isolate, process_handle);
+ return LoadSymbols(process_handle);
}
#else // __MINGW32__
-void OS::LogSharedLibraryAddresses(Isolate* isolate) { }
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ return std::vector<OS::SharedLibraryAddress>();
+}
+
+
void OS::SignalCodeMovingGC() { }
#endif // __MINGW32__
#define V8_PLATFORM_H_
#include <stdarg.h>
+#include <string>
+#include <vector>
#include "src/base/build_config.h"
#include "src/platform/mutex.h"
// Support for the profiler. Can do nothing, in which case ticks
// occuring in shared libraries will not be properly accounted for.
- static void LogSharedLibraryAddresses(Isolate* isolate);
+ struct SharedLibraryAddress {
+ SharedLibraryAddress(
+ const std::string& library_path, uintptr_t start, uintptr_t end)
+ : library_path(library_path), start(start), end(end) {}
+
+ std::string library_path;
+ uintptr_t start;
+ uintptr_t end;
+ };
+
+ static std::vector<SharedLibraryAddress> GetSharedLibraryAddresses();
// Support for the profiler. Notifies the external profiling
// process that a code moving garbage collection starts. Can do