mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 711491. Refactor MapInfo. r=bgirard
Moves MapInfo out of platform and renames it to SharedLibrary. There will eventually be an implementation for all major platforms. --HG-- extra : rebase_source : c7eae4bc0f0e27f2801c4e639d7dc82b47465f0b
This commit is contained in:
parent
c7a02e442c
commit
b48d6841f9
@ -83,6 +83,7 @@ ifneq (,$(filter Android Linux,$(OS_TARGET)))
|
||||
DEFINES += -DMOZ_ENABLE_PROFILER_SPS
|
||||
|
||||
CPPSRCS += \
|
||||
shared-libraries-linux.cc \
|
||||
platform-linux.cc \
|
||||
TableTicker.cpp \
|
||||
$(NULL)
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "prenv.h"
|
||||
#include "shared-libraries.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
@ -156,9 +157,9 @@ public:
|
||||
void ToString(string* profile)
|
||||
{
|
||||
// Can't be called from signal because
|
||||
// get_maps calls non reentrant functions.
|
||||
// getting the shared library information can call non-reentrant functions.
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
mMaps = getmaps(getpid());
|
||||
mSharedLibraryInfo = SharedLibraryInfo::GetInfoForSelf();
|
||||
#endif
|
||||
|
||||
*profile = "";
|
||||
@ -173,9 +174,9 @@ public:
|
||||
void WriteProfile(FILE* stream)
|
||||
{
|
||||
// Can't be called from signal because
|
||||
// get_maps calls non reentrant functions.
|
||||
// getting the shared library information can call non-reentrant functions.
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
mMaps = getmaps(getpid());
|
||||
mSharedLibraryInfo = SharedLibraryInfo::GetInfoForSelf();
|
||||
#endif
|
||||
|
||||
int oldReadPos = mReadPos;
|
||||
@ -187,9 +188,9 @@ public:
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
MapInfo& getMap()
|
||||
SharedLibraryInfo& getSharedLibraryInfo()
|
||||
{
|
||||
return mMaps;
|
||||
return mSharedLibraryInfo;
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
@ -200,7 +201,7 @@ private:
|
||||
int mReadPos; // points to the next entry we will read to
|
||||
int mEntrySize;
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
MapInfo mMaps;
|
||||
SharedLibraryInfo mSharedLibraryInfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -351,11 +352,11 @@ string ProfileEntry::TagToString(Profile *profile)
|
||||
if (mLeafAddress) {
|
||||
bool found = false;
|
||||
char tagBuff[1024];
|
||||
MapInfo& maps = profile->getMap();
|
||||
SharedLibraryInfo& shlibInfo = profile->getSharedLibraryInfo();
|
||||
unsigned long pc = (unsigned long)mLeafAddress;
|
||||
// TODO Use binary sort (STL)
|
||||
for (size_t i = 0; i < maps.GetSize(); i++) {
|
||||
MapEntry &e = maps.GetEntry(i);
|
||||
for (size_t i = 0; i < shlibInfo.GetSize(); i++) {
|
||||
SharedLibrary &e = shlibInfo.GetEntry(i);
|
||||
if (pc > e.GetStart() && pc < e.GetEnd()) {
|
||||
if (e.GetName()) {
|
||||
found = true;
|
||||
@ -381,11 +382,11 @@ void ProfileEntry::WriteTag(Profile *profile, FILE *stream)
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
if (mLeafAddress) {
|
||||
bool found = false;
|
||||
MapInfo& maps = profile->getMap();
|
||||
SharedLibraryInfo& shlibInfo = profile->getSharedLibraryInfo();
|
||||
unsigned long pc = (unsigned long)mLeafAddress;
|
||||
// TODO Use binary sort (STL)
|
||||
for (size_t i = 0; i < maps.GetSize(); i++) {
|
||||
MapEntry &e = maps.GetEntry(i);
|
||||
for (size_t i = 0; i < shlibInfo.GetSize(); i++) {
|
||||
SharedLibrary &e = shlibInfo.GetEntry(i);
|
||||
if (pc > e.GetStart() && pc < e.GetEnd()) {
|
||||
if (e.GetName()) {
|
||||
found = true;
|
||||
|
@ -41,9 +41,6 @@
|
||||
|
||||
#define SIGNAL_SAVE_PROFILE SIGUSR2
|
||||
|
||||
#define PATH_MAX_TOSTRING(x) #x
|
||||
#define PATH_MAX_STRING(x) PATH_MAX_TOSTRING(x)
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
// glibc doesn't implement gettid(2).
|
||||
#include <sys/syscall.h>
|
||||
@ -53,61 +50,6 @@ pid_t gettid()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
/* a crapy version of getline, because it's not included in bionic */
|
||||
static ssize_t getline(char **lineptr, size_t *n, FILE *stream)
|
||||
{
|
||||
char *ret;
|
||||
if (!*lineptr) {
|
||||
*lineptr = (char*)malloc(4096);
|
||||
}
|
||||
ret = fgets(*lineptr, 4096, stream);
|
||||
if (!ret)
|
||||
return 0;
|
||||
return strlen(*lineptr);
|
||||
}
|
||||
|
||||
MapInfo getmaps(pid_t pid)
|
||||
{
|
||||
MapInfo info;
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, PATH_MAX, "/proc/%d/maps", pid);
|
||||
FILE *maps = fopen(path, "r");
|
||||
char *line = NULL;
|
||||
int count = 0;
|
||||
size_t line_size = 0;
|
||||
while (maps && getline (&line, &line_size, maps) > 0) {
|
||||
int ret;
|
||||
//XXX: needs input sanitizing
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
char perm[6] = "";
|
||||
unsigned long offset;
|
||||
char name[PATH_MAX] = "";
|
||||
ret = sscanf(line,
|
||||
"%lx-%lx %6s %lx %*s %*x %" PATH_MAX_STRING(PATH_MAX) "s\n",
|
||||
&start, &end, perm, &offset, name);
|
||||
if (!strchr(perm, 'x')) {
|
||||
// Ignore non executable entries
|
||||
continue;
|
||||
}
|
||||
if (ret != 5 && ret != 4) {
|
||||
LOG("Get maps line failed");
|
||||
continue;
|
||||
}
|
||||
MapEntry entry(start, end, offset, name);
|
||||
info.AddMapEntry(entry);
|
||||
if (count > 10000) {
|
||||
LOG("Get maps failed");
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
free(line);
|
||||
return info;
|
||||
}
|
||||
#endif
|
||||
|
||||
static Sampler* sActiveSampler = NULL;
|
||||
|
||||
|
||||
|
@ -24,74 +24,6 @@
|
||||
|
||||
typedef uint8_t* Address;
|
||||
|
||||
class MapEntry {
|
||||
public:
|
||||
MapEntry(unsigned long aStart, unsigned long aEnd, unsigned long aOffset, char *aName)
|
||||
: mStart(aStart)
|
||||
, mEnd(aEnd)
|
||||
, mOffset(aOffset)
|
||||
, mName(strdup(aName))
|
||||
{}
|
||||
|
||||
MapEntry(const MapEntry& aEntry)
|
||||
: mStart(aEntry.mStart)
|
||||
, mEnd(aEntry.mEnd)
|
||||
, mOffset(aEntry.mOffset)
|
||||
, mName(strdup(aEntry.mName))
|
||||
{}
|
||||
|
||||
MapEntry& operator=(const MapEntry& aEntry)
|
||||
{
|
||||
mStart = aEntry.mStart;
|
||||
mEnd = aEntry.mEnd;
|
||||
mOffset = aEntry.mOffset;
|
||||
mName = strdup(aEntry.mName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~MapEntry()
|
||||
{
|
||||
free(mName);
|
||||
}
|
||||
|
||||
unsigned long GetStart() { return mStart; }
|
||||
unsigned long GetEnd() { return mEnd; }
|
||||
char* GetName() { return mName; }
|
||||
|
||||
private:
|
||||
explicit MapEntry() {}
|
||||
|
||||
unsigned long mStart;
|
||||
unsigned long mEnd;
|
||||
unsigned long mOffset;
|
||||
char *mName;
|
||||
};
|
||||
|
||||
class MapInfo {
|
||||
public:
|
||||
MapInfo() {}
|
||||
|
||||
void AddMapEntry(MapEntry entry)
|
||||
{
|
||||
mEntries.push_back(entry);
|
||||
}
|
||||
|
||||
MapEntry& GetEntry(size_t i)
|
||||
{
|
||||
return mEntries[i];
|
||||
}
|
||||
|
||||
size_t GetSize()
|
||||
{
|
||||
return mEntries.size();
|
||||
}
|
||||
private:
|
||||
std::vector<MapEntry> mEntries;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
struct MapInfo getmaps(pid_t pid);
|
||||
#endif
|
||||
// ----------------------------------------------------------------------------
|
||||
// Mutex
|
||||
//
|
||||
|
67
tools/profiler/sps/shared-libraries-linux.cc
Normal file
67
tools/profiler/sps/shared-libraries-linux.cc
Normal file
@ -0,0 +1,67 @@
|
||||
#define PATH_MAX_TOSTRING(x) #x
|
||||
#define PATH_MAX_STRING(x) PATH_MAX_TOSTRING(x)
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include "platform.h"
|
||||
#include "shared-libraries.h"
|
||||
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
#ifndef __GLIBC__
|
||||
/* a crapy version of getline, because it's not included in bionic */
|
||||
static ssize_t getline(char **lineptr, size_t *n, FILE *stream)
|
||||
{
|
||||
char *ret;
|
||||
if (!*lineptr) {
|
||||
*lineptr = (char*)malloc(4096);
|
||||
}
|
||||
ret = fgets(*lineptr, 4096, stream);
|
||||
if (!ret)
|
||||
return 0;
|
||||
return strlen(*lineptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
|
||||
{
|
||||
pid_t pid = getpid();
|
||||
SharedLibraryInfo info;
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, PATH_MAX, "/proc/%d/maps", pid);
|
||||
FILE *maps = fopen(path, "r");
|
||||
char *line = NULL;
|
||||
int count = 0;
|
||||
size_t line_size = 0;
|
||||
while (maps && getline (&line, &line_size, maps) > 0) {
|
||||
int ret;
|
||||
//XXX: needs input sanitizing
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
char perm[6] = "";
|
||||
unsigned long offset;
|
||||
char name[PATH_MAX] = "";
|
||||
ret = sscanf(line,
|
||||
"%lx-%lx %6s %lx %*s %*x %" PATH_MAX_STRING(PATH_MAX) "s\n",
|
||||
&start, &end, perm, &offset, name);
|
||||
if (!strchr(perm, 'x')) {
|
||||
// Ignore non executable entries
|
||||
continue;
|
||||
}
|
||||
if (ret != 5 && ret != 4) {
|
||||
LOG("Get maps line failed");
|
||||
continue;
|
||||
}
|
||||
SharedLibrary shlib(start, end, offset, name);
|
||||
info.AddSharedLibrary(shlib);
|
||||
if (count > 10000) {
|
||||
LOG("Get maps failed");
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
free(line);
|
||||
return info;
|
||||
}
|
||||
#endif
|
108
tools/profiler/sps/shared-libraries.h
Normal file
108
tools/profiler/sps/shared-libraries.h
Normal file
@ -0,0 +1,108 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:set ts=4 sw=4 sts=4 et cindent: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <mozilla/StdInt.h>
|
||||
|
||||
class SharedLibrary {
|
||||
public:
|
||||
SharedLibrary(unsigned long aStart, unsigned long aEnd, unsigned long aOffset, char *aName)
|
||||
: mStart(aStart)
|
||||
, mEnd(aEnd)
|
||||
, mOffset(aOffset)
|
||||
, mName(strdup(aName))
|
||||
{}
|
||||
|
||||
SharedLibrary(const SharedLibrary& aEntry)
|
||||
: mStart(aEntry.mStart)
|
||||
, mEnd(aEntry.mEnd)
|
||||
, mOffset(aEntry.mOffset)
|
||||
, mName(strdup(aEntry.mName))
|
||||
{}
|
||||
|
||||
SharedLibrary& operator=(const SharedLibrary& aEntry)
|
||||
{
|
||||
mStart = aEntry.mStart;
|
||||
mEnd = aEntry.mEnd;
|
||||
mOffset = aEntry.mOffset;
|
||||
mName = strdup(aEntry.mName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SharedLibrary()
|
||||
{
|
||||
free(mName);
|
||||
}
|
||||
|
||||
uintptr_t GetStart() { return mStart; }
|
||||
uintptr_t GetEnd() { return mEnd; }
|
||||
char* GetName() { return mName; }
|
||||
|
||||
private:
|
||||
explicit SharedLibrary() {}
|
||||
|
||||
uintptr_t mStart;
|
||||
uintptr_t mEnd;
|
||||
uintptr_t mOffset;
|
||||
char *mName;
|
||||
};
|
||||
|
||||
class SharedLibraryInfo {
|
||||
public:
|
||||
static SharedLibraryInfo GetInfoForSelf();
|
||||
SharedLibraryInfo() {}
|
||||
|
||||
void AddSharedLibrary(SharedLibrary entry)
|
||||
{
|
||||
mEntries.push_back(entry);
|
||||
}
|
||||
|
||||
SharedLibrary& GetEntry(size_t i)
|
||||
{
|
||||
return mEntries[i];
|
||||
}
|
||||
|
||||
size_t GetSize()
|
||||
{
|
||||
return mEntries.size();
|
||||
}
|
||||
private:
|
||||
std::vector<SharedLibrary> mEntries;
|
||||
};
|
Loading…
Reference in New Issue
Block a user