Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/tcmalloc/chromium/src/getpc.h

Issue 14321006: Adds TCMalloc support for Android. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Just my patch Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2005, Google Inc. 1 // Copyright (c) 2005, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 //#define _XOPEN_SOURCE 500 55 //#define _XOPEN_SOURCE 500
56 56
57 #include <string.h> // for memcmp 57 #include <string.h> // for memcmp
58 #if defined(HAVE_SYS_UCONTEXT_H) 58 #if defined(HAVE_SYS_UCONTEXT_H)
59 #include <sys/ucontext.h> 59 #include <sys/ucontext.h>
60 #elif defined(HAVE_UCONTEXT_H) 60 #elif defined(HAVE_UCONTEXT_H)
61 #include <ucontext.h> // for ucontext_t (and also mcontext_t) 61 #include <ucontext.h> // for ucontext_t (and also mcontext_t)
62 #elif defined(HAVE_CYGWIN_SIGNAL_H) 62 #elif defined(HAVE_CYGWIN_SIGNAL_H)
63 #include <cygwin/signal.h> 63 #include <cygwin/signal.h>
64 typedef ucontext ucontext_t; 64 typedef ucontext ucontext_t;
65 #elif defined(__ANDROID__)
66 #include <unwind.h>
65 #endif 67 #endif
66 68
67 69
68 // Take the example where function Foo() calls function Bar(). For 70 // Take the example where function Foo() calls function Bar(). For
69 // many architectures, Bar() is responsible for setting up and tearing 71 // many architectures, Bar() is responsible for setting up and tearing
70 // down its own stack frame. In that case, it's possible for the 72 // down its own stack frame. In that case, it's possible for the
71 // interrupt to happen when execution is in Bar(), but the stack frame 73 // interrupt to happen when execution is in Bar(), but the stack frame
72 // is not properly set up (either before it's done being set up, or 74 // is not properly set up (either before it's done being set up, or
73 // after it's been torn down but before Bar() returns). In those 75 // after it's been torn down but before Bar() returns). In those
74 // cases, the stack trace cannot see the caller function anymore. 76 // cases, the stack trace cannot see the caller function anymore.
(...skipping 27 matching lines...) Expand all
102 int return_sp_offset; 104 int return_sp_offset;
103 }; 105 };
104 106
105 107
106 // The dereferences needed to get the PC from a struct ucontext were 108 // The dereferences needed to get the PC from a struct ucontext were
107 // determined at configure time, and stored in the macro 109 // determined at configure time, and stored in the macro
108 // PC_FROM_UCONTEXT in config.h. The only thing we need to do here, 110 // PC_FROM_UCONTEXT in config.h. The only thing we need to do here,
109 // then, is to do the magic call-unrolling for systems that support it. 111 // then, is to do the magic call-unrolling for systems that support it.
110 112
111 // -- Special case 1: linux x86, for which we have CallUnrollInfo 113 // -- Special case 1: linux x86, for which we have CallUnrollInfo
112 #if defined(__linux) && defined(__i386) && defined(__GNUC__) 114 #if defined(__linux) && defined(__i386) && defined(__GNUC__)
Dai Mikurube (NOT FULLTIME) 2013/05/03 08:53:00 I'm not sure if we have x86 Android, but we may wa
bulach 2013/05/07 14:55:51 we do have x86, added the guard here.
113 static const CallUnrollInfo callunrollinfo[] = { 115 static const CallUnrollInfo callunrollinfo[] = {
114 // Entry to a function: push %ebp; mov %esp,%ebp 116 // Entry to a function: push %ebp; mov %esp,%ebp
115 // Top-of-stack contains the caller IP. 117 // Top-of-stack contains the caller IP.
116 { 0, 118 { 0,
117 {0x55, 0x89, 0xe5}, 3, 119 {0x55, 0x89, 0xe5}, 3,
118 0 120 0
119 }, 121 },
120 // Entry to a function, second instruction: push %ebp; mov %esp,%ebp 122 // Entry to a function, second instruction: push %ebp; mov %esp,%ebp
121 // Top-of-stack contains the old frame, caller IP is +4. 123 // Top-of-stack contains the old frame, caller IP is +4.
122 { -1, 124 { -1,
123 {0x55, 0x89, 0xe5}, 3, 125 {0x55, 0x89, 0xe5}, 3,
124 4 126 4
125 }, 127 },
126 // Return from a function: RET. 128 // Return from a function: RET.
127 // Top-of-stack contains the caller IP. 129 // Top-of-stack contains the caller IP.
128 { 0, 130 { 0,
129 {0xc3}, 1, 131 {0xc3}, 1,
130 0 132 0
131 } 133 }
132 }; 134 };
133 135
134 inline void* GetPC(const ucontext_t& signal_ucontext) { 136 inline void* GetPC(const ucontext_t& signal_ucontext) {
135 // See comment above struct CallUnrollInfo. Only try instruction 137 // See comment above struct CallUnrollInfo. Only try instruction
136 // flow matching if both eip and esp looks reasonable. 138 // flow matching if both eip and esp looks reasonable.
137 const int eip = signal_ucontext.uc_mcontext.gregs[REG_EIP]; 139 const int eip = signal_ucontext.uc_mcontext.gregs[REG_EIP];
138 const int esp = signal_ucontext.uc_mcontext.gregs[REG_ESP]; 140 const int esp = signal_ucontext.uc_mcontext.gregs[REG_ESP];
139 if ((eip & 0xffff0000) != 0 && (~eip & 0xffff0000) != 0 && 141 if ((eip & 0xffff0000) != 0 && (~eip & 0xffff0000) != 0 &&
140 (esp & 0xffff0000) != 0) { 142 (esp & 0xffff0000) != 0) {
141 char* eip_char = reinterpret_cast<char*>(eip); 143 char* eip_char = reinterpret_cast<char*>(eip);
142 for (int i = 0; i < sizeof(callunrollinfo)/sizeof(*callunrollinfo); ++i) { 144 for (int i = 0; i < sizeof(CallUnrollInfo)/sizeof(*callunrollinfo); ++i) {
Dai Mikurube (NOT FULLTIME) 2013/05/03 08:53:00 It's necessary? (Since tcmalloc is a third_party
bulach 2013/05/07 14:55:51 Done.
143 if (!memcmp(eip_char + callunrollinfo[i].pc_offset, 145 if (!memcmp(eip_char + callunrollinfo[i].pc_offset,
144 callunrollinfo[i].ins, callunrollinfo[i].ins_size)) { 146 callunrollinfo[i].ins, callunrollinfo[i].ins_size)) {
145 // We have a match. 147 // We have a match.
146 void **retaddr = (void**)(esp + callunrollinfo[i].return_sp_offset); 148 void **retaddr = (void**)(esp + callunrollinfo[i].return_sp_offset);
147 return *retaddr; 149 return *retaddr;
148 } 150 }
149 } 151 }
150 } 152 }
151 return (void*)eip; 153 return (void*)eip;
152 } 154 }
(...skipping 11 matching lines...) Expand all
164 166
165 #include "base/logging.h" // for RAW_LOG 167 #include "base/logging.h" // for RAW_LOG
166 #ifndef HAVE_CYGWIN_SIGNAL_H 168 #ifndef HAVE_CYGWIN_SIGNAL_H
167 typedef int ucontext_t; 169 typedef int ucontext_t;
168 #endif 170 #endif
169 171
170 inline void* GetPC(const struct ucontext_t& signal_ucontext) { 172 inline void* GetPC(const struct ucontext_t& signal_ucontext) {
171 RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n"); 173 RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n");
172 return NULL; 174 return NULL;
173 } 175 }
176 #elif defined(__ANDROID__)
174 177
178 typedef struct _Unwind_Context ucontext_t;
179
180 inline void* GetPC(const ucontext_t& signal_ucontext) {
181 // Bionic doesn't export ucontext, see
182 // https://code.google.com/p/android/issues/detail?id=34784.
183 return reinterpret_cast<void*>(_Unwind_GetIP(
184 const_cast<ucontext_t*>(&signal_ucontext)));
185 }
186 #else
187 //
175 // Normal cases. If this doesn't compile, it's probably because 188 // Normal cases. If this doesn't compile, it's probably because
176 // PC_FROM_UCONTEXT is the empty string. You need to figure out 189 // PC_FROM_UCONTEXT is the empty string. You need to figure out
177 // the right value for your system, and add it to the list in 190 // the right value for your system, and add it to the list in
178 // configure.ac (or set it manually in your config.h). 191 // configure.ac (or set it manually in your config.h).
179 #else
180 inline void* GetPC(const ucontext_t& signal_ucontext) { 192 inline void* GetPC(const ucontext_t& signal_ucontext) {
181 return (void*)signal_ucontext.PC_FROM_UCONTEXT; // defined in config.h 193 return (void*)signal_ucontext.PC_FROM_UCONTEXT; // defined in config.h
182 } 194 }
183 195
184 #endif 196 #endif
185 197
186 #endif // BASE_GETPC_H_ 198 #endif // BASE_GETPC_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698