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

Side by Side Diff: test/cctest/test-deoptimization.cc

Issue 9378007: Ensure that we do a non-incremental GC before relying on weak handle callbacks. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 i::FLAG_allow_natives_syntax = allow_natives_syntax_; 90 i::FLAG_allow_natives_syntax = allow_natives_syntax_;
91 i::FLAG_use_inlining = use_inlining_; 91 i::FLAG_use_inlining = use_inlining_;
92 } 92 }
93 93
94 private: 94 private:
95 bool allow_natives_syntax_; 95 bool allow_natives_syntax_;
96 bool use_inlining_; 96 bool use_inlining_;
97 }; 97 };
98 98
99 99
100 // Do a non-incremental GC, making sure that all weak global handle callbacks
Michael Starzinger 2012/02/13 09:50:52 More precise: "Abort any ongoing incremental marki
Sven Panne 2012/02/13 10:09:56 Done.
101 // are processed.
102 static void NonIncrementalGC() {
103 // TODO(1608): This should use kAbortIncrementalMarking.
104 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
105 }
106
107
100 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, 108 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
101 const char* property_name) { 109 const char* property_name) {
102 v8::Local<v8::Function> fun = 110 v8::Local<v8::Function> fun =
103 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); 111 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name)));
104 return v8::Utils::OpenHandle(*fun); 112 return v8::Utils::OpenHandle(*fun);
105 } 113 }
106 114
107 115
108 TEST(DeoptimizeSimple) { 116 TEST(DeoptimizeSimple) {
109 v8::HandleScope scope; 117 v8::HandleScope scope;
110 const char* extension_list[] = { "v8/gc" }; 118 LocalContext env;
111 v8::ExtensionConfiguration extensions(1, extension_list);
112 LocalContext env(&extensions);
113 119
114 // Test lazy deoptimization of a simple function. 120 // Test lazy deoptimization of a simple function.
115 { 121 {
116 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 122 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
117 CompileRun( 123 CompileRun(
118 "var count = 0;" 124 "var count = 0;"
119 "function h() { %DeoptimizeFunction(f); }" 125 "function h() { %DeoptimizeFunction(f); }"
120 "function g() { count++; h(); }" 126 "function g() { count++; h(); }"
121 "function f() { g(); };" 127 "function f() { g(); };"
122 "f();" 128 "f();");
123 "gc(); gc()");
124 } 129 }
130 NonIncrementalGC();
125 131
126 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 132 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
127 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 133 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
128 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 134 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
129 135
130 // Test lazy deoptimization of a simple function. Call the function after the 136 // Test lazy deoptimization of a simple function. Call the function after the
131 // deoptimization while it is still activated further down the stack. 137 // deoptimization while it is still activated further down the stack.
132 { 138 {
133 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 139 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
134 CompileRun( 140 CompileRun(
135 "var count = 0;" 141 "var count = 0;"
136 "function g() { count++; %DeoptimizeFunction(f); f(false); }" 142 "function g() { count++; %DeoptimizeFunction(f); f(false); }"
137 "function f(x) { if (x) { g(); } else { return } };" 143 "function f(x) { if (x) { g(); } else { return } };"
138 "f(true);" 144 "f(true);");
139 "gc(); gc()");
140 } 145 }
146 NonIncrementalGC();
141 147
142 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 148 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
143 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 149 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
144 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 150 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
145 } 151 }
146 152
147 153
148 TEST(DeoptimizeSimpleWithArguments) { 154 TEST(DeoptimizeSimpleWithArguments) {
149 v8::HandleScope scope; 155 v8::HandleScope scope;
150 const char* extension_list[] = { "v8/gc" }; 156 LocalContext env;
151 v8::ExtensionConfiguration extensions(1, extension_list);
152 LocalContext env(&extensions);
153 157
154 // Test lazy deoptimization of a simple function with some arguments. 158 // Test lazy deoptimization of a simple function with some arguments.
155 { 159 {
156 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 160 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
157 CompileRun( 161 CompileRun(
158 "var count = 0;" 162 "var count = 0;"
159 "function h(x) { %DeoptimizeFunction(f); }" 163 "function h(x) { %DeoptimizeFunction(f); }"
160 "function g(x, y) { count++; h(x); }" 164 "function g(x, y) { count++; h(x); }"
161 "function f(x, y, z) { g(1,x); y+z; };" 165 "function f(x, y, z) { g(1,x); y+z; };"
162 "f(1, \"2\", false);" 166 "f(1, \"2\", false);");
163 "gc(); gc()");
164 } 167 }
168 NonIncrementalGC();
165 169
166 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 170 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
167 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 171 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
168 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 172 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
169 173
170 // Test lazy deoptimization of a simple function with some arguments. Call the 174 // Test lazy deoptimization of a simple function with some arguments. Call the
171 // function after the deoptimization while it is still activated further down 175 // function after the deoptimization while it is still activated further down
172 // the stack. 176 // the stack.
173 { 177 {
174 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 178 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
175 CompileRun( 179 CompileRun(
176 "var count = 0;" 180 "var count = 0;"
177 "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }" 181 "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }"
178 "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" 182 "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };"
179 "f(true, 1, \"2\");" 183 "f(true, 1, \"2\");");
180 "gc(); gc()");
181 } 184 }
185 NonIncrementalGC();
182 186
183 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 187 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
184 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 188 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
185 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 189 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
186 } 190 }
187 191
188 192
189 TEST(DeoptimizeSimpleNested) { 193 TEST(DeoptimizeSimpleNested) {
190 v8::HandleScope scope; 194 v8::HandleScope scope;
191 const char* extension_list[] = { "v8/gc" }; 195 LocalContext env;
192 v8::ExtensionConfiguration extensions(1, extension_list);
193 LocalContext env(&extensions);
194 196
195 // Test lazy deoptimization of a simple function. Have a nested function call 197 // Test lazy deoptimization of a simple function. Have a nested function call
196 // do the deoptimization. 198 // do the deoptimization.
197 { 199 {
198 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 200 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
199 CompileRun( 201 CompileRun(
200 "var count = 0;" 202 "var count = 0;"
201 "var result = 0;" 203 "var result = 0;"
202 "function h(x, y, z) { return x + y + z; }" 204 "function h(x, y, z) { return x + y + z; }"
203 "function g(z) { count++; %DeoptimizeFunction(f); return z;}" 205 "function g(z) { count++; %DeoptimizeFunction(f); return z;}"
204 "function f(x,y,z) { return h(x, y, g(z)); };" 206 "function f(x,y,z) { return h(x, y, g(z)); };"
205 "result = f(1, 2, 3);" 207 "result = f(1, 2, 3);");
206 "gc(); gc()"); 208 NonIncrementalGC();
207 209
208 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 210 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
209 CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); 211 CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value());
210 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 212 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
211 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 213 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
212 } 214 }
213 } 215 }
214 216
215 217
216 TEST(DeoptimizeRecursive) { 218 TEST(DeoptimizeRecursive) {
217 v8::HandleScope scope; 219 v8::HandleScope scope;
218 const char* extension_list[] = { "v8/gc" }; 220 LocalContext env;
219 v8::ExtensionConfiguration extensions(1, extension_list);
220 LocalContext env(&extensions);
221 221
222 { 222 {
223 // Test lazy deoptimization of a simple function called recursively. Call 223 // Test lazy deoptimization of a simple function called recursively. Call
224 // the function recursively a number of times before deoptimizing it. 224 // the function recursively a number of times before deoptimizing it.
225 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 225 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
226 CompileRun( 226 CompileRun(
227 "var count = 0;" 227 "var count = 0;"
228 "var calls = 0;" 228 "var calls = 0;"
229 "function g() { count++; %DeoptimizeFunction(f); }" 229 "function g() { count++; %DeoptimizeFunction(f); }"
230 "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" 230 "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };"
231 "f(10); gc(); gc()"); 231 "f(10);");
232 } 232 }
233 NonIncrementalGC();
233 234
234 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 235 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
235 CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); 236 CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value());
236 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 237 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
237 238
238 v8::Local<v8::Function> fun = 239 v8::Local<v8::Function> fun =
239 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 240 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
240 CHECK(!fun.IsEmpty()); 241 CHECK(!fun.IsEmpty());
241 } 242 }
242 243
243 244
244 TEST(DeoptimizeMultiple) { 245 TEST(DeoptimizeMultiple) {
245 v8::HandleScope scope; 246 v8::HandleScope scope;
246 const char* extension_list[] = { "v8/gc" }; 247 LocalContext env;
247 v8::ExtensionConfiguration extensions(1, extension_list);
248 LocalContext env(&extensions);
249 248
250 { 249 {
251 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 250 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
252 CompileRun( 251 CompileRun(
253 "var count = 0;" 252 "var count = 0;"
254 "var result = 0;" 253 "var result = 0;"
255 "function g() { count++;" 254 "function g() { count++;"
256 " %DeoptimizeFunction(f1);" 255 " %DeoptimizeFunction(f1);"
257 " %DeoptimizeFunction(f2);" 256 " %DeoptimizeFunction(f2);"
258 " %DeoptimizeFunction(f3);" 257 " %DeoptimizeFunction(f3);"
259 " %DeoptimizeFunction(f4);}" 258 " %DeoptimizeFunction(f4);}"
260 "function f4(x) { g(); };" 259 "function f4(x) { g(); };"
261 "function f3(x, y, z) { f4(); return x + y + z; };" 260 "function f3(x, y, z) { f4(); return x + y + z; };"
262 "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };" 261 "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };"
263 "function f1(x) { return f2(x + 1, x + 1) + x; };" 262 "function f1(x) { return f2(x + 1, x + 1) + x; };"
264 "result = f1(1);" 263 "result = f1(1);");
265 "gc(); gc()");
266 } 264 }
265 NonIncrementalGC();
267 266
268 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 267 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
269 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); 268 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value());
270 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 269 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
271 } 270 }
272 271
273 272
274 TEST(DeoptimizeConstructor) { 273 TEST(DeoptimizeConstructor) {
275 v8::HandleScope scope; 274 v8::HandleScope scope;
276 const char* extension_list[] = { "v8/gc" }; 275 LocalContext env;
277 v8::ExtensionConfiguration extensions(1, extension_list);
278 LocalContext env(&extensions);
279 276
280 { 277 {
281 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 278 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
282 CompileRun( 279 CompileRun(
283 "var count = 0;" 280 "var count = 0;"
284 "function g() { count++;" 281 "function g() { count++;"
285 " %DeoptimizeFunction(f); }" 282 " %DeoptimizeFunction(f); }"
286 "function f() { g(); };" 283 "function f() { g(); };"
287 "result = new f() instanceof f;" 284 "result = new f() instanceof f;");
288 "gc(); gc()");
289 } 285 }
286 NonIncrementalGC();
290 287
291 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 288 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
292 CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); 289 CHECK(env->Global()->Get(v8_str("result"))->IsTrue());
293 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 290 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
294 291
295 { 292 {
296 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 293 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
297 CompileRun( 294 CompileRun(
298 "var count = 0;" 295 "var count = 0;"
299 "var result = 0;" 296 "var result = 0;"
300 "function g() { count++;" 297 "function g() { count++;"
301 " %DeoptimizeFunction(f); }" 298 " %DeoptimizeFunction(f); }"
302 "function f(x, y) { this.x = x; g(); this.y = y; };" 299 "function f(x, y) { this.x = x; g(); this.y = y; };"
303 "result = new f(1, 2);" 300 "result = new f(1, 2);"
304 "result = result.x + result.y;" 301 "result = result.x + result.y;");
305 "gc(); gc()");
306 } 302 }
303 NonIncrementalGC();
307 304
308 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 305 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
309 CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); 306 CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value());
310 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 307 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
311 } 308 }
312 309
313 310
314 TEST(DeoptimizeConstructorMultiple) { 311 TEST(DeoptimizeConstructorMultiple) {
315 v8::HandleScope scope; 312 v8::HandleScope scope;
316 const char* extension_list[] = { "v8/gc" }; 313 LocalContext env;
317 v8::ExtensionConfiguration extensions(1, extension_list);
318 LocalContext env(&extensions);
319 314
320 { 315 {
321 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 316 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
322 CompileRun( 317 CompileRun(
323 "var count = 0;" 318 "var count = 0;"
324 "var result = 0;" 319 "var result = 0;"
325 "function g() { count++;" 320 "function g() { count++;"
326 " %DeoptimizeFunction(f1);" 321 " %DeoptimizeFunction(f1);"
327 " %DeoptimizeFunction(f2);" 322 " %DeoptimizeFunction(f2);"
328 " %DeoptimizeFunction(f3);" 323 " %DeoptimizeFunction(f3);"
329 " %DeoptimizeFunction(f4);}" 324 " %DeoptimizeFunction(f4);}"
330 "function f4(x) { this.result = x; g(); };" 325 "function f4(x) { this.result = x; g(); };"
331 "function f3(x, y, z) { this.result = new f4(x + y + z).result; };" 326 "function f3(x, y, z) { this.result = new f4(x + y + z).result; };"
332 "function f2(x, y) {" 327 "function f2(x, y) {"
333 " this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };" 328 " this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };"
334 "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" 329 "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };"
335 "result = new f1(1).result;" 330 "result = new f1(1).result;");
336 "gc(); gc()");
337 } 331 }
332 NonIncrementalGC();
338 333
339 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 334 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
340 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); 335 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value());
341 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 336 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
342 } 337 }
343 338
344 339
345 TEST(DeoptimizeBinaryOperationADDString) { 340 TEST(DeoptimizeBinaryOperationADDString) {
346 v8::HandleScope scope; 341 v8::HandleScope scope;
347 const char* extension_list[] = { "v8/gc" }; 342 LocalContext env;
348 v8::ExtensionConfiguration extensions(1, extension_list);
349 LocalContext env(&extensions);
350 343
351 const char* f_source = "function f(x, y) { return x + y; };"; 344 const char* f_source = "function f(x, y) { return x + y; };";
352 345
353 { 346 {
354 AllowNativesSyntaxNoInlining options; 347 AllowNativesSyntaxNoInlining options;
355 // Compile function f and collect to type feedback to insert binary op stub 348 // Compile function f and collect to type feedback to insert binary op stub
356 // call in the optimized code. 349 // call in the optimized code.
357 i::FLAG_prepare_always_opt = true; 350 i::FLAG_prepare_always_opt = true;
358 CompileRun("var count = 0;" 351 CompileRun("var count = 0;"
359 "var result = 0;" 352 "var result = 0;"
360 "var deopt = false;" 353 "var deopt = false;"
361 "function X() { };" 354 "function X() { };"
362 "X.prototype.toString = function () {" 355 "X.prototype.toString = function () {"
363 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'" 356 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'"
364 "};"); 357 "};");
365 CompileRun(f_source); 358 CompileRun(f_source);
366 CompileRun("for (var i = 0; i < 5; i++) {" 359 CompileRun("for (var i = 0; i < 5; i++) {"
367 " f('a+', new X());" 360 " f('a+', new X());"
368 "};"); 361 "};");
369 362
370 // Compile an optimized version of f. 363 // Compile an optimized version of f.
371 i::FLAG_always_opt = true; 364 i::FLAG_always_opt = true;
372 CompileRun(f_source); 365 CompileRun(f_source);
373 CompileRun("f('a+', new X());"); 366 CompileRun("f('a+', new X());");
374 CHECK(!i::V8::UseCrankshaft() || 367 CHECK(!i::V8::UseCrankshaft() ||
375 GetJSFunction(env->Global(), "f")->IsOptimized()); 368 GetJSFunction(env->Global(), "f")->IsOptimized());
376 369
377 // Call f and force deoptimization while processing the binary operation. 370 // Call f and force deoptimization while processing the binary operation.
378 CompileRun("deopt = true;" 371 CompileRun("deopt = true;"
379 "var result = f('a+', new X());" 372 "var result = f('a+', new X());");
380 "gc(); gc();");
381 } 373 }
374 NonIncrementalGC();
382 375
383 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 376 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
384 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 377 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
385 v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result")); 378 v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result"));
386 CHECK(result->IsString()); 379 CHECK(result->IsString());
387 v8::String::AsciiValue ascii(result); 380 v8::String::AsciiValue ascii(result);
388 CHECK_EQ("a+an X", *ascii); 381 CHECK_EQ("a+an X", *ascii);
389 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 382 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
390 } 383 }
391 384
(...skipping 29 matching lines...) Expand all
421 414
422 // Compile an optimized version of f. 415 // Compile an optimized version of f.
423 i::FLAG_always_opt = true; 416 i::FLAG_always_opt = true;
424 CompileRun(f_source); 417 CompileRun(f_source);
425 CompileRun("f(7, new X());"); 418 CompileRun("f(7, new X());");
426 CHECK(!i::V8::UseCrankshaft() || 419 CHECK(!i::V8::UseCrankshaft() ||
427 GetJSFunction((*env)->Global(), "f")->IsOptimized()); 420 GetJSFunction((*env)->Global(), "f")->IsOptimized());
428 421
429 // Call f and force deoptimization while processing the binary operation. 422 // Call f and force deoptimization while processing the binary operation.
430 CompileRun("deopt = true;" 423 CompileRun("deopt = true;"
431 "var result = f(7, new X());" 424 "var result = f(7, new X());");
432 "gc(); gc();"); 425 NonIncrementalGC();
433
434 CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); 426 CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized());
435 } 427 }
436 428
437 429
438 TEST(DeoptimizeBinaryOperationADD) { 430 TEST(DeoptimizeBinaryOperationADD) {
439 v8::HandleScope scope; 431 v8::HandleScope scope;
440 const char* extension_list[] = { "v8/gc" }; 432 LocalContext env;
441 v8::ExtensionConfiguration extensions(1, extension_list);
442 LocalContext env(&extensions);
443 433
444 TestDeoptimizeBinaryOpHelper(&env, "+"); 434 TestDeoptimizeBinaryOpHelper(&env, "+");
445 435
446 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 436 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
447 CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); 437 CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value());
448 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 438 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
449 } 439 }
450 440
451 441
452 TEST(DeoptimizeBinaryOperationSUB) { 442 TEST(DeoptimizeBinaryOperationSUB) {
453 v8::HandleScope scope; 443 v8::HandleScope scope;
454 const char* extension_list[] = { "v8/gc" }; 444 LocalContext env;
455 v8::ExtensionConfiguration extensions(1, extension_list);
456 LocalContext env(&extensions);
457 445
458 TestDeoptimizeBinaryOpHelper(&env, "-"); 446 TestDeoptimizeBinaryOpHelper(&env, "-");
459 447
460 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 448 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
461 CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); 449 CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value());
462 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 450 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
463 } 451 }
464 452
465 453
466 TEST(DeoptimizeBinaryOperationMUL) { 454 TEST(DeoptimizeBinaryOperationMUL) {
467 v8::HandleScope scope; 455 v8::HandleScope scope;
468 const char* extension_list[] = { "v8/gc" }; 456 LocalContext env;
469 v8::ExtensionConfiguration extensions(1, extension_list);
470 LocalContext env(&extensions);
471 457
472 TestDeoptimizeBinaryOpHelper(&env, "*"); 458 TestDeoptimizeBinaryOpHelper(&env, "*");
473 459
474 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 460 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
475 CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); 461 CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value());
476 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 462 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
477 } 463 }
478 464
479 465
480 TEST(DeoptimizeBinaryOperationDIV) { 466 TEST(DeoptimizeBinaryOperationDIV) {
481 v8::HandleScope scope; 467 v8::HandleScope scope;
482 const char* extension_list[] = { "v8/gc" }; 468 LocalContext env;
483 v8::ExtensionConfiguration extensions(1, extension_list);
484 LocalContext env(&extensions);
485 469
486 TestDeoptimizeBinaryOpHelper(&env, "/"); 470 TestDeoptimizeBinaryOpHelper(&env, "/");
487 471
488 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 472 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
489 CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); 473 CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value());
490 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 474 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
491 } 475 }
492 476
493 477
494 TEST(DeoptimizeBinaryOperationMOD) { 478 TEST(DeoptimizeBinaryOperationMOD) {
495 v8::HandleScope scope; 479 v8::HandleScope scope;
496 const char* extension_list[] = { "v8/gc" }; 480 LocalContext env;
497 v8::ExtensionConfiguration extensions(1, extension_list);
498 LocalContext env(&extensions);
499 481
500 TestDeoptimizeBinaryOpHelper(&env, "%"); 482 TestDeoptimizeBinaryOpHelper(&env, "%");
501 483
502 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 484 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
503 CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); 485 CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value());
504 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 486 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
505 } 487 }
506 488
507 489
508 TEST(DeoptimizeCompare) { 490 TEST(DeoptimizeCompare) {
509 v8::HandleScope scope; 491 v8::HandleScope scope;
510 const char* extension_list[] = { "v8/gc" }; 492 LocalContext env;
511 v8::ExtensionConfiguration extensions(1, extension_list);
512 LocalContext env(&extensions);
513 493
514 const char* f_source = "function f(x, y) { return x < y; };"; 494 const char* f_source = "function f(x, y) { return x < y; };";
515 495
516 { 496 {
517 AllowNativesSyntaxNoInlining options; 497 AllowNativesSyntaxNoInlining options;
518 // Compile function f and collect to type feedback to insert compare ic 498 // Compile function f and collect to type feedback to insert compare ic
519 // call in the optimized code. 499 // call in the optimized code.
520 i::FLAG_prepare_always_opt = true; 500 i::FLAG_prepare_always_opt = true;
521 CompileRun("var count = 0;" 501 CompileRun("var count = 0;"
522 "var result = 0;" 502 "var result = 0;"
523 "var deopt = false;" 503 "var deopt = false;"
524 "function X() { };" 504 "function X() { };"
525 "X.prototype.toString = function () {" 505 "X.prototype.toString = function () {"
526 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'" 506 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'"
527 "};"); 507 "};");
528 CompileRun(f_source); 508 CompileRun(f_source);
529 CompileRun("for (var i = 0; i < 5; i++) {" 509 CompileRun("for (var i = 0; i < 5; i++) {"
530 " f('a', new X());" 510 " f('a', new X());"
531 "};"); 511 "};");
532 512
533 // Compile an optimized version of f. 513 // Compile an optimized version of f.
534 i::FLAG_always_opt = true; 514 i::FLAG_always_opt = true;
535 CompileRun(f_source); 515 CompileRun(f_source);
536 CompileRun("f('a', new X());"); 516 CompileRun("f('a', new X());");
537 CHECK(!i::V8::UseCrankshaft() || 517 CHECK(!i::V8::UseCrankshaft() ||
538 GetJSFunction(env->Global(), "f")->IsOptimized()); 518 GetJSFunction(env->Global(), "f")->IsOptimized());
539 519
540 // Call f and force deoptimization while processing the comparison. 520 // Call f and force deoptimization while processing the comparison.
541 CompileRun("deopt = true;" 521 CompileRun("deopt = true;"
542 "var result = f('a', new X());" 522 "var result = f('a', new X());");
543 "gc(); gc();");
544 } 523 }
524 NonIncrementalGC();
545 525
546 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 526 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
547 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 527 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
548 CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); 528 CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue());
549 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 529 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
550 } 530 }
551 531
552 532
553 TEST(DeoptimizeLoadICStoreIC) { 533 TEST(DeoptimizeLoadICStoreIC) {
554 v8::HandleScope scope; 534 v8::HandleScope scope;
555 const char* extension_list[] = { "v8/gc" }; 535 LocalContext env;
556 v8::ExtensionConfiguration extensions(1, extension_list);
557 LocalContext env(&extensions);
558 536
559 // Functions to generate load/store/keyed load/keyed store IC calls. 537 // Functions to generate load/store/keyed load/keyed store IC calls.
560 const char* f1_source = "function f1(x) { return x.y; };"; 538 const char* f1_source = "function f1(x) { return x.y; };";
561 const char* g1_source = "function g1(x) { x.y = 1; };"; 539 const char* g1_source = "function g1(x) { x.y = 1; };";
562 const char* f2_source = "function f2(x, y) { return x[y]; };"; 540 const char* f2_source = "function f2(x, y) { return x[y]; };";
563 const char* g2_source = "function g2(x, y) { x[y] = 1; };"; 541 const char* g2_source = "function g2(x, y) { x[y] = 1; };";
564 542
565 { 543 {
566 AllowNativesSyntaxNoInlining options; 544 AllowNativesSyntaxNoInlining options;
567 // Compile functions and collect to type feedback to insert ic 545 // Compile functions and collect to type feedback to insert ic
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); 589 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
612 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); 590 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
613 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); 591 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
614 } 592 }
615 593
616 // Call functions and force deoptimization while processing the ics. 594 // Call functions and force deoptimization while processing the ics.
617 CompileRun("deopt = true;" 595 CompileRun("deopt = true;"
618 "var result = f1(new X());" 596 "var result = f1(new X());"
619 "g1(new X());" 597 "g1(new X());"
620 "f2(new X(), 'z');" 598 "f2(new X(), 'z');"
621 "g2(new X(), 'z');" 599 "g2(new X(), 'z');");
622 "gc(); gc();");
623 } 600 }
601 NonIncrementalGC();
624 602
625 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); 603 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
626 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); 604 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
627 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); 605 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
628 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); 606 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
629 CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); 607 CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value());
630 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); 608 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
631 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 609 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
632 } 610 }
633 611
634 612
635 TEST(DeoptimizeLoadICStoreICNested) { 613 TEST(DeoptimizeLoadICStoreICNested) {
636 v8::HandleScope scope; 614 v8::HandleScope scope;
637 const char* extension_list[] = { "v8/gc" }; 615 LocalContext env;
638 v8::ExtensionConfiguration extensions(1, extension_list);
639 LocalContext env(&extensions);
640 616
641 // Functions to generate load/store/keyed load/keyed store IC calls. 617 // Functions to generate load/store/keyed load/keyed store IC calls.
642 const char* f1_source = "function f1(x) { return x.y; };"; 618 const char* f1_source = "function f1(x) { return x.y; };";
643 const char* g1_source = "function g1(x) { x.y = 1; };"; 619 const char* g1_source = "function g1(x) { x.y = 1; };";
644 const char* f2_source = "function f2(x, y) { return x[y]; };"; 620 const char* f2_source = "function f2(x, y) { return x[y]; };";
645 const char* g2_source = "function g2(x, y) { x[y] = 1; };"; 621 const char* g2_source = "function g2(x, y) { x[y] = 1; };";
646 622
647 { 623 {
648 AllowNativesSyntaxNoInlining options; 624 AllowNativesSyntaxNoInlining options;
649 // Compile functions and collect to type feedback to insert ic 625 // Compile functions and collect to type feedback to insert ic
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 CompileRun("g2(new X(), 'z');"); 670 CompileRun("g2(new X(), 'z');");
695 if (i::V8::UseCrankshaft()) { 671 if (i::V8::UseCrankshaft()) {
696 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); 672 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
697 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); 673 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
698 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); 674 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
699 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); 675 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
700 } 676 }
701 677
702 // Call functions and force deoptimization while processing the ics. 678 // Call functions and force deoptimization while processing the ics.
703 CompileRun("deopt = true;" 679 CompileRun("deopt = true;"
704 "var result = f1(new X());" 680 "var result = f1(new X());");
705 "gc(); gc();");
706 } 681 }
682 NonIncrementalGC();
707 683
708 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); 684 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
709 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); 685 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
710 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); 686 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
711 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); 687 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
712 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 688 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
713 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); 689 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
714 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 690 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current()));
715 } 691 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698