Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 # HG changeset patch
2 # User Julian Seward <jseward@acm.org>
3 # Date 1372168568 -7200
4 # Tue Jun 25 15:56:08 2013 +0200
5 # Node ID 6d06a09b3f5624dd833bd6f905bfd88e3fdec00a
6 # Parent 11f7a9321b7d5d85eddc2db16e58e6870a7c4e06
7 Bug 883126 - Improve performance of EXIDX unwinding in Breakpad. r=ted
9 diff --git a/src/common/arm_ex_to_module.cc b/src/common/arm_ex_to_module.cc
10 --- a/src/common/arm_ex_to_module.cc
11 +++ b/src/common/arm_ex_to_module.cc
12 @@ -66,141 +66,126 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE
14 #define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f)
15 #define ARM_EXBUF_COUNT(x) ((x) & 0x0f)
16 #define ARM_EXBUF_END(x) (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x))
18 using google_breakpad::ustr__pc;
19 using google_breakpad::ustr__lr;
20 using google_breakpad::ustr__sp;
21 +using google_breakpad::ustr__ZDra;
22 +using google_breakpad::ustr__ZDcfa;
23 using google_breakpad::Module;
24 using google_breakpad::ToUniqueString;
25 using google_breakpad::UniqueString;
27 namespace arm_ex_to_module {
29 // Translate command from extab_data to command for Module.
30 int ARMExToModule::TranslateCmd(const struct extab_data* edata,
31 - Module::StackFrameEntry* entry, string& vsp) {
32 + Module::StackFrameEntry* entry,
33 + Module::Expr& vsp) {
34 int ret = 0;
35 switch (edata->cmd) {
36 case ARM_EXIDX_CMD_FINISH:
37 /* Copy LR to PC if there isn't currently a rule for PC in force. */
38 if (entry->initial_rules.find(ustr__pc())
39 == entry->initial_rules.end()) {
40 if (entry->initial_rules.find(ustr__lr())
41 == entry->initial_rules.end()) {
42 - entry->initial_rules[ustr__pc()] = Module::Expr("lr");
43 + entry->initial_rules[ustr__pc()] = Module::Expr(ustr__lr(),
44 + 0, false); // "lr"
45 } else {
46 entry->initial_rules[ustr__pc()] = entry->initial_rules[ustr__lr()];
47 }
48 }
49 break;
50 case ARM_EXIDX_CMD_SUB_FROM_VSP:
51 - {
52 - char c[16];
53 - sprintf(c, " %d -", edata->data);
54 - vsp += c;
55 - }
56 + vsp = vsp.add_delta(- static_cast<long>(edata->data));
57 break;
58 case ARM_EXIDX_CMD_ADD_TO_VSP:
59 - {
60 - char c[16];
61 - sprintf(c, " %d +", edata->data);
62 - vsp += c;
63 - }
64 + vsp = vsp.add_delta(static_cast<long>(edata->data));
65 break;
66 case ARM_EXIDX_CMD_REG_POP:
67 for (unsigned int i = 0; i < 16; i++) {
68 if (edata->data & (1 << i)) {
69 - entry->initial_rules[ToUniqueString(regnames[i])]
70 - = Module::Expr(vsp + " ^");
71 - vsp += " 4 +";
72 + entry->initial_rules[ToUniqueString(regnames[i])] = vsp.deref();
73 + vsp = vsp.add_delta(4);
74 }
75 }
76 /* Set cfa in case the SP got popped. */
77 if (edata->data & (1 << 13)) {
78 - Module::Expr& vsp_expr = entry->initial_rules[ustr__sp()];
79 - // It must be a postfix expression (we don't generate anything
80 - // else here), so return -1 to fail out if it isn't.
81 - if (!vsp_expr.isExprPostfix()) {
82 - ret = -1;
83 - break;
84 - };
85 - vsp = vsp_expr.getExprPostfix();
86 + vsp = entry->initial_rules[ustr__sp()];
87 }
88 break;
89 case ARM_EXIDX_CMD_REG_TO_SP: {
90 assert (edata->data < 16);
91 const char* const regname = regnames[edata->data];
92 const UniqueString* regname_us = ToUniqueString(regname);
93 if (entry->initial_rules.find(regname_us) == entry->initial_rules.end()) {
94 - entry->initial_rules[ustr__sp()] = Module::Expr(regname);
95 + entry->initial_rules[ustr__sp()] = Module::Expr(regname_us,
96 + 0, false); // "regname"
97 } else {
98 entry->initial_rules[ustr__sp()] = entry->initial_rules[regname_us];
99 }
100 - Module::Expr& vsp_expr = entry->initial_rules[ustr__sp()];
101 - if (!vsp_expr.isExprPostfix()) {
102 - ret = -1;
103 - break;
104 - };
105 - vsp = vsp_expr.getExprPostfix();
106 + vsp = entry->initial_rules[ustr__sp()];
107 break;
108 }
109 case ARM_EXIDX_CMD_VFP_POP:
110 /* Don't recover VFP registers, but be sure to adjust the stack
111 pointer. */
112 for (unsigned int i = ARM_EXBUF_START(edata->data);
113 i <= ARM_EXBUF_END(edata->data); i++) {
114 - vsp += " 8 +";
115 + vsp = vsp.add_delta(8);
116 }
117 if (!(edata->data & ARM_EXIDX_VFP_FSTMD)) {
118 - vsp += " 4 +";
119 + vsp = vsp.add_delta(4);
120 }
121 break;
122 case ARM_EXIDX_CMD_WREG_POP:
123 for (unsigned int i = ARM_EXBUF_START(edata->data);
124 i <= ARM_EXBUF_END(edata->data); i++) {
125 - vsp += " 8 +";
126 + vsp = vsp.add_delta(8);
127 }
128 break;
129 case ARM_EXIDX_CMD_WCGR_POP:
130 // Pop wCGR registers under mask {wCGR3,2,1,0}, hence "i < 4"
131 for (unsigned int i = 0; i < 4; i++) {
132 if (edata->data & (1 << i)) {
133 - vsp += " 4 +";
134 + vsp = vsp.add_delta(4);
135 }
136 }
137 break;
138 case ARM_EXIDX_CMD_REFUSED:
139 case ARM_EXIDX_CMD_RESERVED:
140 ret = -1;
141 break;
142 }
143 return ret;
144 }
146 void ARMExToModule::AddStackFrame(uintptr_t addr, size_t size) {
147 stack_frame_entry_ = new Module::StackFrameEntry;
148 stack_frame_entry_->address = addr;
149 stack_frame_entry_->size = size;
150 - stack_frame_entry_->initial_rules[ToUniqueString(kCFA)] = Module::Expr("sp");
151 - vsp_ = "sp";
152 + Module::Expr sp_expr = Module::Expr(ustr__sp(), 0, false); // "sp"
153 + stack_frame_entry_->initial_rules[ustr__ZDcfa()] = sp_expr; // ".cfa"
154 + vsp_ = sp_expr;
155 }
157 int ARMExToModule::ImproveStackFrame(const struct extab_data* edata) {
158 return TranslateCmd(edata, stack_frame_entry_, vsp_) ;
159 }
161 void ARMExToModule::DeleteStackFrame() {
162 delete stack_frame_entry_;
163 }
165 void ARMExToModule::SubmitStackFrame() {
166 // return address always winds up in pc
167 - stack_frame_entry_->initial_rules[ToUniqueString(kRA)]
168 + stack_frame_entry_->initial_rules[ustr__ZDra()] // ".ra"
169 = stack_frame_entry_->initial_rules[ustr__pc()];
170 // the final value of vsp is the new value of sp
171 stack_frame_entry_->initial_rules[ustr__sp()] = vsp_;
172 module_->AddStackFrameEntry(stack_frame_entry_);
173 }
175 } // namespace arm_ex_to_module
176 diff --git a/src/common/arm_ex_to_module.h b/src/common/arm_ex_to_module.h
177 --- a/src/common/arm_ex_to_module.h
178 +++ b/src/common/arm_ex_to_module.h
179 @@ -89,19 +89,16 @@ struct extab_data {
180 uint32_t data;
181 };
183 enum extab_cmd_flags {
184 ARM_EXIDX_VFP_SHIFT_16 = 1 << 16,
185 ARM_EXIDX_VFP_FSTMD = 1 << 17, // distinguishes FSTMxxD from FSTMxxX
186 };
188 -const string kRA = ".ra";
189 -const string kCFA = ".cfa";
190 -
191 static const char* const regnames[] = {
192 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
193 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
194 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
195 "fps", "cpsr"
196 };
198 // Receives information from arm_ex_reader::ExceptionTableInfo
199 @@ -113,17 +110,17 @@ class ARMExToModule {
200 ~ARMExToModule() { }
201 void AddStackFrame(uintptr_t addr, size_t size);
202 int ImproveStackFrame(const struct extab_data* edata);
203 void DeleteStackFrame();
204 void SubmitStackFrame();
205 private:
206 Module* module_;
207 Module::StackFrameEntry* stack_frame_entry_;
208 - string vsp_;
209 + Module::Expr vsp_;
210 int TranslateCmd(const struct extab_data* edata,
211 Module::StackFrameEntry* entry,
212 - string& vsp);
213 + Module::Expr& vsp);
214 };
216 } // namespace arm_ex_to_module
218 #endif // COMMON_ARM_EX_TO_MODULE__
219 diff --git a/src/common/module.h b/src/common/module.h
220 --- a/src/common/module.h
221 +++ b/src/common/module.h
222 @@ -39,16 +39,20 @@
223 #define COMMON_LINUX_MODULE_H__
225 #include <iostream>
226 #include <map>
227 #include <set>
228 #include <string>
229 #include <vector>
231 +#include <assert.h>
232 +#include <stdlib.h>
233 +#include <stdio.h>
234 +
235 #include "common/symbol_data.h"
236 #include "common/using_std_string.h"
237 #include "common/unique_string.h"
238 #include "google_breakpad/common/breakpad_types.h"
240 namespace google_breakpad {
242 using std::set;
243 @@ -161,30 +165,98 @@ class Module {
244 // Construct an invalid expression
245 Expr() {
246 postfix_ = "";
247 ident_ = NULL;
248 offset_ = 0;
249 how_ = kExprInvalid;
250 }
251 bool isExprInvalid() const { return how_ == kExprInvalid; }
252 - bool isExprPostfix() const { return how_ == kExprPostfix; }
254 - // Return the postfix expression string. This is only
255 - // meaningful on Exprs for which isExprPostfix returns true.
256 - // In all other cases it returns an empty string.
257 - string getExprPostfix() const { return postfix_; }
258 + // Return the postfix expression string, either directly,
259 + // if this is a postfix expression, or by synthesising it
260 + // for a simple expression.
261 + string getExprPostfix() const {
262 + switch (how_) {
263 + case kExprPostfix:
264 + return postfix_;
265 + case kExprSimple:
266 + case kExprSimpleMem: {
267 + char buf[40];
268 + sprintf(buf, " %ld %c%s", labs(offset_), offset_ < 0 ? '-' : '+',
269 + how_ == kExprSimple ? "" : " ^");
270 + return string(FromUniqueString(ident_)) + string(buf);
271 + }
272 + case kExprInvalid:
273 + default:
274 + assert(0 && "getExprPostfix: invalid Module::Expr type");
275 + return "Expr::genExprPostfix: kExprInvalid";
276 + }
277 + }
279 bool operator==(const Expr& other) const {
280 return how_ == other.how_ &&
281 ident_ == other.ident_ &&
282 offset_ == other.offset_ &&
283 postfix_ == other.postfix_;
284 }
286 + // Returns an Expr which evaluates to |this| + |delta|
287 + Expr add_delta(long delta) {
288 + if (delta == 0) {
289 + return *this;
290 + }
291 + // If it's a simple form expression of the form "identifier + offset",
292 + // simply add |delta| on to |offset|. In the other two possible
293 + // cases:
294 + // *(identifier + offset)
295 + // completely arbitrary postfix expression string
296 + // the only option is to "downgrade" it to a postfix expression and add
297 + // "+/- delta" at the end of the string, since the result can't be
298 + // represented in the simple form.
299 + switch (how_) {
300 + case kExprSimpleMem:
301 + case kExprPostfix: {
302 + char buf[40];
303 + sprintf(buf, " %ld %c", labs(delta), delta < 0 ? '-' : '+');
304 + return Expr(getExprPostfix() + string(buf));
305 + }
306 + case kExprSimple:
307 + return Expr(ident_, offset_ + delta, false);
308 + case kExprInvalid:
309 + default:
310 + assert(0 && "add_delta: invalid Module::Expr type");
311 + // Invalid inputs produce an invalid result
312 + return Expr();
313 + }
314 + }
315 +
316 + // Returns an Expr which evaluates to *|this|
317 + Expr deref() {
318 + // In the simplest case, a kExprSimple can be changed into a
319 + // kExprSimpleMem. In all other cases it has to be dumped as a
320 + // postfix string, and " ^" added at the end.
321 + switch (how_) {
322 + case kExprSimple: {
323 + Expr t = *this;
324 + t.how_ = kExprSimpleMem;
325 + return t;
326 + }
327 + case kExprSimpleMem:
328 + case kExprPostfix: {
329 + return Expr(getExprPostfix() + " ^");
330 + }
331 + case kExprInvalid:
332 + default:
333 + assert(0 && "deref: invalid Module::Expr type");
334 + // Invalid inputs produce an invalid result
335 + return Expr();
336 + }
337 + }
338 +
339 // The identifier that gives the starting value for simple expressions.
340 const UniqueString* ident_;
341 // The offset to add for simple expressions.
342 long offset_;
343 // The Postfix expression string to evaluate for non-simple expressions.
344 string postfix_;
345 // The operation expressed by this expression.
346 ExprHow how_;