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

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

Issue 583153002: Reland 24052 - Require V8 to be explicitly initialized before an Isolate is created (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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 | « test/cctest/test-debug.cc ('k') | test/cctest/test-heap.cc » ('j') | 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 } 91 }
92 92
93 private: 93 private:
94 bool allow_natives_syntax_; 94 bool allow_natives_syntax_;
95 bool use_inlining_; 95 bool use_inlining_;
96 }; 96 };
97 97
98 98
99 // Abort any ongoing incremental marking to make sure that all weak global 99 // Abort any ongoing incremental marking to make sure that all weak global
100 // handle callbacks are processed. 100 // handle callbacks are processed.
101 static void NonIncrementalGC() { 101 static void NonIncrementalGC(i::Isolate* isolate) {
102 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 102 isolate->heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
103 } 103 }
104 104
105 105
106 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, 106 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
107 const char* property_name) { 107 const char* property_name) {
108 v8::Local<v8::Function> fun = 108 v8::Local<v8::Function> fun =
109 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); 109 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name)));
110 return v8::Utils::OpenHandle(*fun); 110 return v8::Utils::OpenHandle(*fun);
111 } 111 }
112 112
113 113
114 TEST(DeoptimizeSimple) { 114 TEST(DeoptimizeSimple) {
115 i::FLAG_turbo_deoptimization = true; 115 i::FLAG_turbo_deoptimization = true;
116 116
117 LocalContext env; 117 LocalContext env;
118 v8::HandleScope scope(env->GetIsolate()); 118 v8::HandleScope scope(env->GetIsolate());
119 119
120 // Test lazy deoptimization of a simple function. 120 // Test lazy deoptimization of a simple function.
121 { 121 {
122 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 122 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
123 CompileRun( 123 CompileRun(
124 "var count = 0;" 124 "var count = 0;"
125 "function h() { %DeoptimizeFunction(f); }" 125 "function h() { %DeoptimizeFunction(f); }"
126 "function g() { count++; h(); }" 126 "function g() { count++; h(); }"
127 "function f() { g(); };" 127 "function f() { g(); };"
128 "f();"); 128 "f();");
129 } 129 }
130 NonIncrementalGC(); 130 NonIncrementalGC(CcTest::i_isolate());
131 131
132 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 132 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
133 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 133 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
134 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 134 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
135 135
136 // 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
137 // deoptimization while it is still activated further down the stack. 137 // deoptimization while it is still activated further down the stack.
138 { 138 {
139 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 139 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
140 CompileRun( 140 CompileRun(
141 "var count = 0;" 141 "var count = 0;"
142 "function g() { count++; %DeoptimizeFunction(f); f(false); }" 142 "function g() { count++; %DeoptimizeFunction(f); f(false); }"
143 "function f(x) { if (x) { g(); } else { return } };" 143 "function f(x) { if (x) { g(); } else { return } };"
144 "f(true);"); 144 "f(true);");
145 } 145 }
146 NonIncrementalGC(); 146 NonIncrementalGC(CcTest::i_isolate());
147 147
148 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 148 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
149 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 149 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
150 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 150 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
151 } 151 }
152 152
153 153
154 TEST(DeoptimizeSimpleWithArguments) { 154 TEST(DeoptimizeSimpleWithArguments) {
155 i::FLAG_turbo_deoptimization = true; 155 i::FLAG_turbo_deoptimization = true;
156 156
157 LocalContext env; 157 LocalContext env;
158 v8::HandleScope scope(env->GetIsolate()); 158 v8::HandleScope scope(env->GetIsolate());
159 159
160 // Test lazy deoptimization of a simple function with some arguments. 160 // Test lazy deoptimization of a simple function with some arguments.
161 { 161 {
162 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 162 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
163 CompileRun( 163 CompileRun(
164 "var count = 0;" 164 "var count = 0;"
165 "function h(x) { %DeoptimizeFunction(f); }" 165 "function h(x) { %DeoptimizeFunction(f); }"
166 "function g(x, y) { count++; h(x); }" 166 "function g(x, y) { count++; h(x); }"
167 "function f(x, y, z) { g(1,x); y+z; };" 167 "function f(x, y, z) { g(1,x); y+z; };"
168 "f(1, \"2\", false);"); 168 "f(1, \"2\", false);");
169 } 169 }
170 NonIncrementalGC(); 170 NonIncrementalGC(CcTest::i_isolate());
171 171
172 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 172 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
173 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 173 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
174 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 174 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
175 175
176 // Test lazy deoptimization of a simple function with some arguments. Call the 176 // Test lazy deoptimization of a simple function with some arguments. Call the
177 // function after the deoptimization while it is still activated further down 177 // function after the deoptimization while it is still activated further down
178 // the stack. 178 // the stack.
179 { 179 {
180 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 180 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
181 CompileRun( 181 CompileRun(
182 "var count = 0;" 182 "var count = 0;"
183 "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }" 183 "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }"
184 "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" 184 "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };"
185 "f(true, 1, \"2\");"); 185 "f(true, 1, \"2\");");
186 } 186 }
187 NonIncrementalGC(); 187 NonIncrementalGC(CcTest::i_isolate());
188 188
189 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 189 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
190 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 190 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
191 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 191 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
192 } 192 }
193 193
194 194
195 TEST(DeoptimizeSimpleNested) { 195 TEST(DeoptimizeSimpleNested) {
196 i::FLAG_turbo_deoptimization = true; 196 i::FLAG_turbo_deoptimization = true;
197 197
198 LocalContext env; 198 LocalContext env;
199 v8::HandleScope scope(env->GetIsolate()); 199 v8::HandleScope scope(env->GetIsolate());
200 200
201 // Test lazy deoptimization of a simple function. Have a nested function call 201 // Test lazy deoptimization of a simple function. Have a nested function call
202 // do the deoptimization. 202 // do the deoptimization.
203 { 203 {
204 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 204 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
205 CompileRun( 205 CompileRun(
206 "var count = 0;" 206 "var count = 0;"
207 "var result = 0;" 207 "var result = 0;"
208 "function h(x, y, z) { return x + y + z; }" 208 "function h(x, y, z) { return x + y + z; }"
209 "function g(z) { count++; %DeoptimizeFunction(f); return z;}" 209 "function g(z) { count++; %DeoptimizeFunction(f); return z;}"
210 "function f(x,y,z) { return h(x, y, g(z)); };" 210 "function f(x,y,z) { return h(x, y, g(z)); };"
211 "result = f(1, 2, 3);"); 211 "result = f(1, 2, 3);");
212 NonIncrementalGC(); 212 NonIncrementalGC(CcTest::i_isolate());
213 213
214 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 214 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
215 CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); 215 CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value());
216 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 216 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
217 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 217 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
218 } 218 }
219 } 219 }
220 220
221 221
222 TEST(DeoptimizeRecursive) { 222 TEST(DeoptimizeRecursive) {
223 i::FLAG_turbo_deoptimization = true; 223 i::FLAG_turbo_deoptimization = true;
224 LocalContext env; 224 LocalContext env;
225 v8::HandleScope scope(env->GetIsolate()); 225 v8::HandleScope scope(env->GetIsolate());
226 226
227 { 227 {
228 // Test lazy deoptimization of a simple function called recursively. Call 228 // Test lazy deoptimization of a simple function called recursively. Call
229 // the function recursively a number of times before deoptimizing it. 229 // the function recursively a number of times before deoptimizing it.
230 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 230 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
231 CompileRun( 231 CompileRun(
232 "var count = 0;" 232 "var count = 0;"
233 "var calls = 0;" 233 "var calls = 0;"
234 "function g() { count++; %DeoptimizeFunction(f); }" 234 "function g() { count++; %DeoptimizeFunction(f); }"
235 "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" 235 "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };"
236 "f(10);"); 236 "f(10);");
237 } 237 }
238 NonIncrementalGC(); 238 NonIncrementalGC(CcTest::i_isolate());
239 239
240 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 240 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
241 CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); 241 CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value());
242 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 242 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
243 243
244 v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast( 244 v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast(
245 env->Global()->Get(v8::String::NewFromUtf8(CcTest::isolate(), "f"))); 245 env->Global()->Get(v8::String::NewFromUtf8(CcTest::isolate(), "f")));
246 CHECK(!fun.IsEmpty()); 246 CHECK(!fun.IsEmpty());
247 } 247 }
248 248
(...skipping 12 matching lines...) Expand all
261 " %DeoptimizeFunction(f1);" 261 " %DeoptimizeFunction(f1);"
262 " %DeoptimizeFunction(f2);" 262 " %DeoptimizeFunction(f2);"
263 " %DeoptimizeFunction(f3);" 263 " %DeoptimizeFunction(f3);"
264 " %DeoptimizeFunction(f4);}" 264 " %DeoptimizeFunction(f4);}"
265 "function f4(x) { g(); };" 265 "function f4(x) { g(); };"
266 "function f3(x, y, z) { f4(); return x + y + z; };" 266 "function f3(x, y, z) { f4(); return x + y + z; };"
267 "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };" 267 "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };"
268 "function f1(x) { return f2(x + 1, x + 1) + x; };" 268 "function f1(x) { return f2(x + 1, x + 1) + x; };"
269 "result = f1(1);"); 269 "result = f1(1);");
270 } 270 }
271 NonIncrementalGC(); 271 NonIncrementalGC(CcTest::i_isolate());
272 272
273 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 273 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
274 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); 274 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value());
275 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 275 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
276 } 276 }
277 277
278 278
279 TEST(DeoptimizeConstructor) { 279 TEST(DeoptimizeConstructor) {
280 i::FLAG_turbo_deoptimization = true; 280 i::FLAG_turbo_deoptimization = true;
281 LocalContext env; 281 LocalContext env;
282 v8::HandleScope scope(env->GetIsolate()); 282 v8::HandleScope scope(env->GetIsolate());
283 283
284 { 284 {
285 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 285 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
286 CompileRun( 286 CompileRun(
287 "var count = 0;" 287 "var count = 0;"
288 "function g() { count++;" 288 "function g() { count++;"
289 " %DeoptimizeFunction(f); }" 289 " %DeoptimizeFunction(f); }"
290 "function f() { g(); };" 290 "function f() { g(); };"
291 "result = new f() instanceof f;"); 291 "result = new f() instanceof f;");
292 } 292 }
293 NonIncrementalGC(); 293 NonIncrementalGC(CcTest::i_isolate());
294 294
295 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 295 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
296 CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); 296 CHECK(env->Global()->Get(v8_str("result"))->IsTrue());
297 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 297 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
298 298
299 { 299 {
300 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 300 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
301 CompileRun( 301 CompileRun(
302 "var count = 0;" 302 "var count = 0;"
303 "var result = 0;" 303 "var result = 0;"
304 "function g() { count++;" 304 "function g() { count++;"
305 " %DeoptimizeFunction(f); }" 305 " %DeoptimizeFunction(f); }"
306 "function f(x, y) { this.x = x; g(); this.y = y; };" 306 "function f(x, y) { this.x = x; g(); this.y = y; };"
307 "result = new f(1, 2);" 307 "result = new f(1, 2);"
308 "result = result.x + result.y;"); 308 "result = result.x + result.y;");
309 } 309 }
310 NonIncrementalGC(); 310 NonIncrementalGC(CcTest::i_isolate());
311 311
312 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 312 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
313 CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); 313 CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value());
314 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 314 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
315 } 315 }
316 316
317 317
318 TEST(DeoptimizeConstructorMultiple) { 318 TEST(DeoptimizeConstructorMultiple) {
319 i::FLAG_turbo_deoptimization = true; 319 i::FLAG_turbo_deoptimization = true;
320 LocalContext env; 320 LocalContext env;
321 v8::HandleScope scope(env->GetIsolate()); 321 v8::HandleScope scope(env->GetIsolate());
322 322
323 { 323 {
324 AlwaysOptimizeAllowNativesSyntaxNoInlining options; 324 AlwaysOptimizeAllowNativesSyntaxNoInlining options;
325 CompileRun( 325 CompileRun(
326 "var count = 0;" 326 "var count = 0;"
327 "var result = 0;" 327 "var result = 0;"
328 "function g() { count++;" 328 "function g() { count++;"
329 " %DeoptimizeFunction(f1);" 329 " %DeoptimizeFunction(f1);"
330 " %DeoptimizeFunction(f2);" 330 " %DeoptimizeFunction(f2);"
331 " %DeoptimizeFunction(f3);" 331 " %DeoptimizeFunction(f3);"
332 " %DeoptimizeFunction(f4);}" 332 " %DeoptimizeFunction(f4);}"
333 "function f4(x) { this.result = x; g(); };" 333 "function f4(x) { this.result = x; g(); };"
334 "function f3(x, y, z) { this.result = new f4(x + y + z).result; };" 334 "function f3(x, y, z) { this.result = new f4(x + y + z).result; };"
335 "function f2(x, y) {" 335 "function f2(x, y) {"
336 " this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };" 336 " this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };"
337 "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" 337 "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };"
338 "result = new f1(1).result;"); 338 "result = new f1(1).result;");
339 } 339 }
340 NonIncrementalGC(); 340 NonIncrementalGC(CcTest::i_isolate());
341 341
342 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 342 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
343 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); 343 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value());
344 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 344 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
345 } 345 }
346 346
347 347
348 TEST(DeoptimizeBinaryOperationADDString) { 348 UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) {
349 i::FLAG_turbo_deoptimization = true; 349 i::FLAG_turbo_deoptimization = true;
350 i::FLAG_concurrent_recompilation = false; 350 i::FLAG_concurrent_recompilation = false;
351 AllowNativesSyntaxNoInlining options; 351 AllowNativesSyntaxNoInlining options;
352 LocalContext env; 352 v8::Isolate* isolate = v8::Isolate::New();
353 v8::HandleScope scope(env->GetIsolate()); 353 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
354 isolate->Enter();
355 {
356 LocalContext env(isolate);
357 v8::HandleScope scope(env->GetIsolate());
354 358
355 const char* f_source = "function f(x, y) { return x + y; };"; 359 const char* f_source = "function f(x, y) { return x + y; };";
356 360
357 { 361 {
358 // Compile function f and collect to type feedback to insert binary op stub 362 // Compile function f and collect to type feedback to insert binary op
359 // call in the optimized code. 363 // stub call in the optimized code.
360 i::FLAG_prepare_always_opt = true; 364 i::FLAG_prepare_always_opt = true;
361 CompileRun("var count = 0;" 365 CompileRun(
362 "var result = 0;" 366 "var count = 0;"
363 "var deopt = false;" 367 "var result = 0;"
364 "function X() { };" 368 "var deopt = false;"
365 "X.prototype.toString = function () {" 369 "function X() { };"
366 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'" 370 "X.prototype.toString = function () {"
367 "};"); 371 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'"
368 CompileRun(f_source); 372 "};");
369 CompileRun("for (var i = 0; i < 5; i++) {" 373 CompileRun(f_source);
370 " f('a+', new X());" 374 CompileRun(
371 "};"); 375 "for (var i = 0; i < 5; i++) {"
376 " f('a+', new X());"
377 "};");
372 378
373 // Compile an optimized version of f. 379 // Compile an optimized version of f.
374 i::FLAG_always_opt = true; 380 i::FLAG_always_opt = true;
375 CompileRun(f_source); 381 CompileRun(f_source);
376 CompileRun("f('a+', new X());"); 382 CompileRun("f('a+', new X());");
377 CHECK(!CcTest::i_isolate()->use_crankshaft() || 383 CHECK(!i_isolate->use_crankshaft() ||
378 GetJSFunction(env->Global(), "f")->IsOptimized()); 384 GetJSFunction(env->Global(), "f")->IsOptimized());
379 385
380 // Call f and force deoptimization while processing the binary operation. 386 // Call f and force deoptimization while processing the binary operation.
381 CompileRun("deopt = true;" 387 CompileRun(
382 "var result = f('a+', new X());"); 388 "deopt = true;"
389 "var result = f('a+', new X());");
390 }
391 NonIncrementalGC(i_isolate);
392
393 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
394 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
395 v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result"));
396 CHECK(result->IsString());
397 v8::String::Utf8Value utf8(result);
398 CHECK_EQ("a+an X", *utf8);
399 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
383 } 400 }
384 NonIncrementalGC(); 401 isolate->Exit();
385 402 isolate->Dispose();
386 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
387 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
388 v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result"));
389 CHECK(result->IsString());
390 v8::String::Utf8Value utf8(result);
391 CHECK_EQ("a+an X", *utf8);
392 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
393 } 403 }
394 404
395 405
396 static void CompileConstructorWithDeoptimizingValueOf() { 406 static void CompileConstructorWithDeoptimizingValueOf() {
397 CompileRun("var count = 0;" 407 CompileRun("var count = 0;"
398 "var result = 0;" 408 "var result = 0;"
399 "var deopt = false;" 409 "var deopt = false;"
400 "function X() { };" 410 "function X() { };"
401 "X.prototype.valueOf = function () {" 411 "X.prototype.valueOf = function () {"
402 " if (deopt) { count++; %DeoptimizeFunction(f); } return 8" 412 " if (deopt) { count++; %DeoptimizeFunction(f); } return 8"
403 "};"); 413 "};");
404 } 414 }
405 415
406 416
407 static void TestDeoptimizeBinaryOpHelper(LocalContext* env, 417 static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
408 const char* binary_op) { 418 const char* binary_op) {
419 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>((*env)->GetIsolate());
409 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer; 420 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer;
410 SNPrintF(f_source_buffer, 421 SNPrintF(f_source_buffer,
411 "function f(x, y) { return x %s y; };", 422 "function f(x, y) { return x %s y; };",
412 binary_op); 423 binary_op);
413 char* f_source = f_source_buffer.start(); 424 char* f_source = f_source_buffer.start();
414 425
415 AllowNativesSyntaxNoInlining options; 426 AllowNativesSyntaxNoInlining options;
416 // Compile function f and collect to type feedback to insert binary op stub 427 // Compile function f and collect to type feedback to insert binary op stub
417 // call in the optimized code. 428 // call in the optimized code.
418 i::FLAG_prepare_always_opt = true; 429 i::FLAG_prepare_always_opt = true;
419 CompileConstructorWithDeoptimizingValueOf(); 430 CompileConstructorWithDeoptimizingValueOf();
420 CompileRun(f_source); 431 CompileRun(f_source);
421 CompileRun("for (var i = 0; i < 5; i++) {" 432 CompileRun("for (var i = 0; i < 5; i++) {"
422 " f(8, new X());" 433 " f(8, new X());"
423 "};"); 434 "};");
424 435
425 // Compile an optimized version of f. 436 // Compile an optimized version of f.
426 i::FLAG_always_opt = true; 437 i::FLAG_always_opt = true;
427 CompileRun(f_source); 438 CompileRun(f_source);
428 CompileRun("f(7, new X());"); 439 CompileRun("f(7, new X());");
429 CHECK(!CcTest::i_isolate()->use_crankshaft() || 440 CHECK(!i_isolate->use_crankshaft() ||
430 GetJSFunction((*env)->Global(), "f")->IsOptimized()); 441 GetJSFunction((*env)->Global(), "f")->IsOptimized());
431 442
432 // Call f and force deoptimization while processing the binary operation. 443 // Call f and force deoptimization while processing the binary operation.
433 CompileRun("deopt = true;" 444 CompileRun("deopt = true;"
434 "var result = f(7, new X());"); 445 "var result = f(7, new X());");
435 NonIncrementalGC(); 446 NonIncrementalGC(i_isolate);
436 CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); 447 CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized());
437 } 448 }
438 449
439 450
440 TEST(DeoptimizeBinaryOperationADD) { 451 UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) {
441 i::FLAG_turbo_deoptimization = true; 452 i::FLAG_turbo_deoptimization = true;
442 i::FLAG_concurrent_recompilation = false; 453 i::FLAG_concurrent_recompilation = false;
443 LocalContext env; 454 v8::Isolate* isolate = v8::Isolate::New();
444 v8::HandleScope scope(env->GetIsolate()); 455 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
445 456 isolate->Enter();
446 TestDeoptimizeBinaryOpHelper(&env, "+"); 457 {
447 458 LocalContext env(isolate);
448 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 459 v8::HandleScope scope(env->GetIsolate());
449 CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); 460
450 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 461 TestDeoptimizeBinaryOpHelper(&env, "+");
451 } 462
452 463 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
453 464 CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value());
454 TEST(DeoptimizeBinaryOperationSUB) { 465 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
455 i::FLAG_turbo_deoptimization = true; 466 }
456 i::FLAG_concurrent_recompilation = false; 467 isolate->Exit();
457 LocalContext env; 468 isolate->Dispose();
458 v8::HandleScope scope(env->GetIsolate()); 469 }
459 470
460 TestDeoptimizeBinaryOpHelper(&env, "-"); 471
461 472 UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) {
462 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 473 i::FLAG_turbo_deoptimization = true;
463 CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); 474 i::FLAG_concurrent_recompilation = false;
464 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 475 v8::Isolate* isolate = v8::Isolate::New();
465 } 476 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
466 477 isolate->Enter();
467 478 {
468 TEST(DeoptimizeBinaryOperationMUL) { 479 LocalContext env(isolate);
469 i::FLAG_turbo_deoptimization = true; 480 v8::HandleScope scope(env->GetIsolate());
470 i::FLAG_concurrent_recompilation = false; 481
471 LocalContext env; 482 TestDeoptimizeBinaryOpHelper(&env, "-");
472 v8::HandleScope scope(env->GetIsolate()); 483
473 484 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
474 TestDeoptimizeBinaryOpHelper(&env, "*"); 485 CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value());
475 486 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
476 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 487 }
477 CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); 488 isolate->Exit();
478 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 489 isolate->Dispose();
479 } 490 }
480 491
481 492
482 TEST(DeoptimizeBinaryOperationDIV) { 493 UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) {
483 i::FLAG_turbo_deoptimization = true; 494 i::FLAG_turbo_deoptimization = true;
484 i::FLAG_concurrent_recompilation = false; 495 i::FLAG_concurrent_recompilation = false;
485 LocalContext env; 496 v8::Isolate* isolate = v8::Isolate::New();
486 v8::HandleScope scope(env->GetIsolate()); 497 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
487 498 isolate->Enter();
488 TestDeoptimizeBinaryOpHelper(&env, "/"); 499 {
489 500 LocalContext env(isolate);
490 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 501 v8::HandleScope scope(env->GetIsolate());
491 CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); 502
492 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 503 TestDeoptimizeBinaryOpHelper(&env, "*");
493 } 504
494 505 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
495 506 CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value());
496 TEST(DeoptimizeBinaryOperationMOD) { 507 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
497 i::FLAG_turbo_deoptimization = true; 508 }
498 i::FLAG_concurrent_recompilation = false; 509 isolate->Exit();
499 LocalContext env; 510 isolate->Dispose();
500 v8::HandleScope scope(env->GetIsolate()); 511 }
501 512
502 TestDeoptimizeBinaryOpHelper(&env, "%"); 513
503 514 UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) {
504 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 515 i::FLAG_turbo_deoptimization = true;
505 CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); 516 i::FLAG_concurrent_recompilation = false;
506 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 517 v8::Isolate* isolate = v8::Isolate::New();
507 } 518 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
508 519 isolate->Enter();
509 520 {
510 TEST(DeoptimizeCompare) { 521 LocalContext env(isolate);
511 i::FLAG_turbo_deoptimization = true; 522 v8::HandleScope scope(env->GetIsolate());
512 i::FLAG_concurrent_recompilation = false; 523
513 LocalContext env; 524 TestDeoptimizeBinaryOpHelper(&env, "/");
514 v8::HandleScope scope(env->GetIsolate()); 525
515 526 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
516 const char* f_source = "function f(x, y) { return x < y; };"; 527 CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value());
517 528 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
518 { 529 }
519 AllowNativesSyntaxNoInlining options; 530 isolate->Exit();
520 // Compile function f and collect to type feedback to insert compare ic 531 isolate->Dispose();
521 // call in the optimized code. 532 }
522 i::FLAG_prepare_always_opt = true; 533
523 CompileRun("var count = 0;" 534
524 "var result = 0;" 535 UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) {
525 "var deopt = false;" 536 i::FLAG_turbo_deoptimization = true;
526 "function X() { };" 537 i::FLAG_concurrent_recompilation = false;
527 "X.prototype.toString = function () {" 538 v8::Isolate* isolate = v8::Isolate::New();
528 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'" 539 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
529 "};"); 540 isolate->Enter();
530 CompileRun(f_source); 541 {
531 CompileRun("for (var i = 0; i < 5; i++) {" 542 LocalContext env(isolate);
532 " f('a', new X());" 543 v8::HandleScope scope(env->GetIsolate());
533 "};"); 544
534 545 TestDeoptimizeBinaryOpHelper(&env, "%");
535 // Compile an optimized version of f. 546
536 i::FLAG_always_opt = true; 547 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
537 CompileRun(f_source); 548 CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value());
538 CompileRun("f('a', new X());"); 549 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
539 CHECK(!CcTest::i_isolate()->use_crankshaft() || 550 }
540 GetJSFunction(env->Global(), "f")->IsOptimized()); 551 isolate->Exit();
541 552 isolate->Dispose();
542 // Call f and force deoptimization while processing the comparison. 553 }
543 CompileRun("deopt = true;" 554
544 "var result = f('a', new X());"); 555
545 } 556 UNINITIALIZED_TEST(DeoptimizeCompare) {
546 NonIncrementalGC(); 557 i::FLAG_turbo_deoptimization = true;
547 558 i::FLAG_concurrent_recompilation = false;
548 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 559 v8::Isolate* isolate = v8::Isolate::New();
549 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 560 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
550 CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); 561 isolate->Enter();
551 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); 562 {
552 } 563 LocalContext env(isolate);
553 564 v8::HandleScope scope(env->GetIsolate());
554 565
555 TEST(DeoptimizeLoadICStoreIC) { 566 const char* f_source = "function f(x, y) { return x < y; };";
556 i::FLAG_turbo_deoptimization = true; 567
557 i::FLAG_concurrent_recompilation = false; 568 {
558 LocalContext env; 569 AllowNativesSyntaxNoInlining options;
559 v8::HandleScope scope(env->GetIsolate()); 570 // Compile function f and collect to type feedback to insert compare ic
560 571 // call in the optimized code.
561 // Functions to generate load/store/keyed load/keyed store IC calls. 572 i::FLAG_prepare_always_opt = true;
562 const char* f1_source = "function f1(x) { return x.y; };"; 573 CompileRun(
563 const char* g1_source = "function g1(x) { x.y = 1; };"; 574 "var count = 0;"
564 const char* f2_source = "function f2(x, y) { return x[y]; };"; 575 "var result = 0;"
565 const char* g2_source = "function g2(x, y) { x[y] = 1; };"; 576 "var deopt = false;"
566 577 "function X() { };"
567 { 578 "X.prototype.toString = function () {"
568 AllowNativesSyntaxNoInlining options; 579 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'"
569 // Compile functions and collect to type feedback to insert ic 580 "};");
570 // calls in the optimized code. 581 CompileRun(f_source);
571 i::FLAG_prepare_always_opt = true; 582 CompileRun(
572 CompileRun("var count = 0;" 583 "for (var i = 0; i < 5; i++) {"
573 "var result = 0;" 584 " f('a', new X());"
574 "var deopt = false;" 585 "};");
575 "function X() { };" 586
576 "X.prototype.__defineGetter__('y', function () {" 587 // Compile an optimized version of f.
577 " if (deopt) { count++; %DeoptimizeFunction(f1); };" 588 i::FLAG_always_opt = true;
578 " return 13;" 589 CompileRun(f_source);
579 "});" 590 CompileRun("f('a', new X());");
580 "X.prototype.__defineSetter__('y', function () {" 591 CHECK(!i_isolate->use_crankshaft() ||
581 " if (deopt) { count++; %DeoptimizeFunction(g1); };" 592 GetJSFunction(env->Global(), "f")->IsOptimized());
582 "});" 593
583 "X.prototype.__defineGetter__('z', function () {" 594 // Call f and force deoptimization while processing the comparison.
584 " if (deopt) { count++; %DeoptimizeFunction(f2); };" 595 CompileRun(
585 " return 13;" 596 "deopt = true;"
586 "});" 597 "var result = f('a', new X());");
587 "X.prototype.__defineSetter__('z', function () {"
588 " if (deopt) { count++; %DeoptimizeFunction(g2); };"
589 "});");
590 CompileRun(f1_source);
591 CompileRun(g1_source);
592 CompileRun(f2_source);
593 CompileRun(g2_source);
594 CompileRun("for (var i = 0; i < 5; i++) {"
595 " f1(new X());"
596 " g1(new X());"
597 " f2(new X(), 'z');"
598 " g2(new X(), 'z');"
599 "};");
600
601 // Compile an optimized version of the functions.
602 i::FLAG_always_opt = true;
603 CompileRun(f1_source);
604 CompileRun(g1_source);
605 CompileRun(f2_source);
606 CompileRun(g2_source);
607 CompileRun("f1(new X());");
608 CompileRun("g1(new X());");
609 CompileRun("f2(new X(), 'z');");
610 CompileRun("g2(new X(), 'z');");
611 if (CcTest::i_isolate()->use_crankshaft()) {
612 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
613 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
614 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
615 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
616 } 598 }
617 599 NonIncrementalGC(i_isolate);
618 // Call functions and force deoptimization while processing the ics. 600
619 CompileRun("deopt = true;" 601 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
620 "var result = f1(new X());" 602 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
621 "g1(new X());" 603 CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue());
622 "f2(new X(), 'z');" 604 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
623 "g2(new X(), 'z');"); 605 }
624 } 606 isolate->Exit();
625 NonIncrementalGC(); 607 isolate->Dispose();
626 608 }
627 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); 609
628 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); 610
629 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); 611 UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) {
630 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); 612 i::FLAG_turbo_deoptimization = true;
631 CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); 613 i::FLAG_concurrent_recompilation = false;
632 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); 614 v8::Isolate* isolate = v8::Isolate::New();
633 } 615 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
634 616 isolate->Enter();
635 617 {
636 TEST(DeoptimizeLoadICStoreICNested) { 618 LocalContext env(isolate);
637 i::FLAG_turbo_deoptimization = true; 619 v8::HandleScope scope(env->GetIsolate());
638 i::FLAG_concurrent_recompilation = false; 620
639 LocalContext env; 621 // Functions to generate load/store/keyed load/keyed store IC calls.
640 v8::HandleScope scope(env->GetIsolate()); 622 const char* f1_source = "function f1(x) { return x.y; };";
641 623 const char* g1_source = "function g1(x) { x.y = 1; };";
642 // Functions to generate load/store/keyed load/keyed store IC calls. 624 const char* f2_source = "function f2(x, y) { return x[y]; };";
643 const char* f1_source = "function f1(x) { return x.y; };"; 625 const char* g2_source = "function g2(x, y) { x[y] = 1; };";
644 const char* g1_source = "function g1(x) { x.y = 1; };"; 626
645 const char* f2_source = "function f2(x, y) { return x[y]; };"; 627 {
646 const char* g2_source = "function g2(x, y) { x[y] = 1; };"; 628 AllowNativesSyntaxNoInlining options;
647 629 // Compile functions and collect to type feedback to insert ic
648 { 630 // calls in the optimized code.
649 AllowNativesSyntaxNoInlining options; 631 i::FLAG_prepare_always_opt = true;
650 // Compile functions and collect to type feedback to insert ic 632 CompileRun(
651 // calls in the optimized code. 633 "var count = 0;"
652 i::FLAG_prepare_always_opt = true; 634 "var result = 0;"
653 CompileRun("var count = 0;" 635 "var deopt = false;"
654 "var result = 0;" 636 "function X() { };"
655 "var deopt = false;" 637 "X.prototype.__defineGetter__('y', function () {"
656 "function X() { };" 638 " if (deopt) { count++; %DeoptimizeFunction(f1); };"
657 "X.prototype.__defineGetter__('y', function () {" 639 " return 13;"
658 " g1(this);" 640 "});"
659 " return 13;" 641 "X.prototype.__defineSetter__('y', function () {"
660 "});" 642 " if (deopt) { count++; %DeoptimizeFunction(g1); };"
661 "X.prototype.__defineSetter__('y', function () {" 643 "});"
662 " f2(this, 'z');" 644 "X.prototype.__defineGetter__('z', function () {"
663 "});" 645 " if (deopt) { count++; %DeoptimizeFunction(f2); };"
664 "X.prototype.__defineGetter__('z', function () {" 646 " return 13;"
665 " g2(this, 'z');" 647 "});"
666 "});" 648 "X.prototype.__defineSetter__('z', function () {"
667 "X.prototype.__defineSetter__('z', function () {" 649 " if (deopt) { count++; %DeoptimizeFunction(g2); };"
668 " if (deopt) {" 650 "});");
669 " count++;" 651 CompileRun(f1_source);
670 " %DeoptimizeFunction(f1);" 652 CompileRun(g1_source);
671 " %DeoptimizeFunction(g1);" 653 CompileRun(f2_source);
672 " %DeoptimizeFunction(f2);" 654 CompileRun(g2_source);
673 " %DeoptimizeFunction(g2); };" 655 CompileRun(
674 "});"); 656 "for (var i = 0; i < 5; i++) {"
675 CompileRun(f1_source); 657 " f1(new X());"
676 CompileRun(g1_source); 658 " g1(new X());"
677 CompileRun(f2_source); 659 " f2(new X(), 'z');"
678 CompileRun(g2_source); 660 " g2(new X(), 'z');"
679 CompileRun("for (var i = 0; i < 5; i++) {" 661 "};");
680 " f1(new X());" 662
681 " g1(new X());" 663 // Compile an optimized version of the functions.
682 " f2(new X(), 'z');" 664 i::FLAG_always_opt = true;
683 " g2(new X(), 'z');" 665 CompileRun(f1_source);
684 "};"); 666 CompileRun(g1_source);
685 667 CompileRun(f2_source);
686 // Compile an optimized version of the functions. 668 CompileRun(g2_source);
687 i::FLAG_always_opt = true; 669 CompileRun("f1(new X());");
688 CompileRun(f1_source); 670 CompileRun("g1(new X());");
689 CompileRun(g1_source); 671 CompileRun("f2(new X(), 'z');");
690 CompileRun(f2_source); 672 CompileRun("g2(new X(), 'z');");
691 CompileRun(g2_source); 673 if (i_isolate->use_crankshaft()) {
692 CompileRun("f1(new X());"); 674 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
693 CompileRun("g1(new X());"); 675 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
694 CompileRun("f2(new X(), 'z');"); 676 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
695 CompileRun("g2(new X(), 'z');"); 677 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
696 if (CcTest::i_isolate()->use_crankshaft()) { 678 }
697 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); 679
698 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); 680 // Call functions and force deoptimization while processing the ics.
699 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); 681 CompileRun(
700 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); 682 "deopt = true;"
683 "var result = f1(new X());"
684 "g1(new X());"
685 "f2(new X(), 'z');"
686 "g2(new X(), 'z');");
701 } 687 }
702 688 NonIncrementalGC(i_isolate);
703 // Call functions and force deoptimization while processing the ics. 689
704 CompileRun("deopt = true;" 690 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
705 "var result = f1(new X());"); 691 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
706 } 692 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
707 NonIncrementalGC(); 693 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
708 694 CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value());
709 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); 695 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
710 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); 696 }
711 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); 697 isolate->Exit();
712 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); 698 isolate->Dispose();
713 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 699 }
714 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); 700
715 } 701
702 UNINITIALIZED_TEST(DeoptimizeLoadICStoreICNested) {
703 i::FLAG_turbo_deoptimization = true;
704 i::FLAG_concurrent_recompilation = false;
705 v8::Isolate* isolate = v8::Isolate::New();
706 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
707 isolate->Enter();
708 {
709 LocalContext env(isolate);
710 v8::HandleScope scope(env->GetIsolate());
711
712 // Functions to generate load/store/keyed load/keyed store IC calls.
713 const char* f1_source = "function f1(x) { return x.y; };";
714 const char* g1_source = "function g1(x) { x.y = 1; };";
715 const char* f2_source = "function f2(x, y) { return x[y]; };";
716 const char* g2_source = "function g2(x, y) { x[y] = 1; };";
717
718 {
719 AllowNativesSyntaxNoInlining options;
720 // Compile functions and collect to type feedback to insert ic
721 // calls in the optimized code.
722 i::FLAG_prepare_always_opt = true;
723 CompileRun(
724 "var count = 0;"
725 "var result = 0;"
726 "var deopt = false;"
727 "function X() { };"
728 "X.prototype.__defineGetter__('y', function () {"
729 " g1(this);"
730 " return 13;"
731 "});"
732 "X.prototype.__defineSetter__('y', function () {"
733 " f2(this, 'z');"
734 "});"
735 "X.prototype.__defineGetter__('z', function () {"
736 " g2(this, 'z');"
737 "});"
738 "X.prototype.__defineSetter__('z', function () {"
739 " if (deopt) {"
740 " count++;"
741 " %DeoptimizeFunction(f1);"
742 " %DeoptimizeFunction(g1);"
743 " %DeoptimizeFunction(f2);"
744 " %DeoptimizeFunction(g2); };"
745 "});");
746 CompileRun(f1_source);
747 CompileRun(g1_source);
748 CompileRun(f2_source);
749 CompileRun(g2_source);
750 CompileRun(
751 "for (var i = 0; i < 5; i++) {"
752 " f1(new X());"
753 " g1(new X());"
754 " f2(new X(), 'z');"
755 " g2(new X(), 'z');"
756 "};");
757
758 // Compile an optimized version of the functions.
759 i::FLAG_always_opt = true;
760 CompileRun(f1_source);
761 CompileRun(g1_source);
762 CompileRun(f2_source);
763 CompileRun(g2_source);
764 CompileRun("f1(new X());");
765 CompileRun("g1(new X());");
766 CompileRun("f2(new X(), 'z');");
767 CompileRun("g2(new X(), 'z');");
768 if (i_isolate->use_crankshaft()) {
769 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
770 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
771 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
772 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
773 }
774
775 // Call functions and force deoptimization while processing the ics.
776 CompileRun(
777 "deopt = true;"
778 "var result = f1(new X());");
779 }
780 NonIncrementalGC(i_isolate);
781
782 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
783 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
784 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
785 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
786 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
787 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
788 }
789 isolate->Exit();
790 isolate->Dispose();
791 }
OLDNEW
« no previous file with comments | « test/cctest/test-debug.cc ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698