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

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

Issue 582953002: Revert "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(i::Isolate* isolate) { 101 static void NonIncrementalGC() {
102 isolate->heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 102 CcTest::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(CcTest::i_isolate()); 130 NonIncrementalGC();
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(CcTest::i_isolate()); 146 NonIncrementalGC();
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(CcTest::i_isolate()); 170 NonIncrementalGC();
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(CcTest::i_isolate()); 187 NonIncrementalGC();
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(CcTest::i_isolate()); 212 NonIncrementalGC();
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(CcTest::i_isolate()); 238 NonIncrementalGC();
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(CcTest::i_isolate()); 271 NonIncrementalGC();
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(CcTest::i_isolate()); 293 NonIncrementalGC();
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(CcTest::i_isolate()); 310 NonIncrementalGC();
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(CcTest::i_isolate()); 340 NonIncrementalGC();
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 UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) { 348 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 v8::Isolate* isolate = v8::Isolate::New(); 352 LocalContext env;
353 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 353 v8::HandleScope scope(env->GetIsolate());
354 isolate->Enter(); 354
355 const char* f_source = "function f(x, y) { return x + y; };";
356
355 { 357 {
356 LocalContext env(isolate); 358 // Compile function f and collect to type feedback to insert binary op stub
357 v8::HandleScope scope(env->GetIsolate()); 359 // call in the optimized code.
360 i::FLAG_prepare_always_opt = true;
361 CompileRun("var count = 0;"
362 "var result = 0;"
363 "var deopt = false;"
364 "function X() { };"
365 "X.prototype.toString = function () {"
366 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'"
367 "};");
368 CompileRun(f_source);
369 CompileRun("for (var i = 0; i < 5; i++) {"
370 " f('a+', new X());"
371 "};");
358 372
359 const char* f_source = "function f(x, y) { return x + y; };"; 373 // Compile an optimized version of f.
374 i::FLAG_always_opt = true;
375 CompileRun(f_source);
376 CompileRun("f('a+', new X());");
377 CHECK(!CcTest::i_isolate()->use_crankshaft() ||
378 GetJSFunction(env->Global(), "f")->IsOptimized());
360 379
361 { 380 // Call f and force deoptimization while processing the binary operation.
362 // Compile function f and collect to type feedback to insert binary op 381 CompileRun("deopt = true;"
363 // stub call in the optimized code. 382 "var result = f('a+', new X());");
364 i::FLAG_prepare_always_opt = true; 383 }
365 CompileRun( 384 NonIncrementalGC();
366 "var count = 0;"
367 "var result = 0;"
368 "var deopt = false;"
369 "function X() { };"
370 "X.prototype.toString = function () {"
371 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'"
372 "};");
373 CompileRun(f_source);
374 CompileRun(
375 "for (var i = 0; i < 5; i++) {"
376 " f('a+', new X());"
377 "};");
378 385
379 // Compile an optimized version of f. 386 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
380 i::FLAG_always_opt = true; 387 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
381 CompileRun(f_source); 388 v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result"));
382 CompileRun("f('a+', new X());"); 389 CHECK(result->IsString());
383 CHECK(!i_isolate->use_crankshaft() || 390 v8::String::Utf8Value utf8(result);
384 GetJSFunction(env->Global(), "f")->IsOptimized()); 391 CHECK_EQ("a+an X", *utf8);
385 392 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
386 // Call f and force deoptimization while processing the binary operation.
387 CompileRun(
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));
400 }
401 isolate->Exit();
402 isolate->Dispose();
403 } 393 }
404 394
405 395
406 static void CompileConstructorWithDeoptimizingValueOf() { 396 static void CompileConstructorWithDeoptimizingValueOf() {
407 CompileRun("var count = 0;" 397 CompileRun("var count = 0;"
408 "var result = 0;" 398 "var result = 0;"
409 "var deopt = false;" 399 "var deopt = false;"
410 "function X() { };" 400 "function X() { };"
411 "X.prototype.valueOf = function () {" 401 "X.prototype.valueOf = function () {"
412 " if (deopt) { count++; %DeoptimizeFunction(f); } return 8" 402 " if (deopt) { count++; %DeoptimizeFunction(f); } return 8"
413 "};"); 403 "};");
414 } 404 }
415 405
416 406
417 static void TestDeoptimizeBinaryOpHelper(LocalContext* env, 407 static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
418 const char* binary_op) { 408 const char* binary_op) {
419 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>((*env)->GetIsolate());
420 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer; 409 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer;
421 SNPrintF(f_source_buffer, 410 SNPrintF(f_source_buffer,
422 "function f(x, y) { return x %s y; };", 411 "function f(x, y) { return x %s y; };",
423 binary_op); 412 binary_op);
424 char* f_source = f_source_buffer.start(); 413 char* f_source = f_source_buffer.start();
425 414
426 AllowNativesSyntaxNoInlining options; 415 AllowNativesSyntaxNoInlining options;
427 // Compile function f and collect to type feedback to insert binary op stub 416 // Compile function f and collect to type feedback to insert binary op stub
428 // call in the optimized code. 417 // call in the optimized code.
429 i::FLAG_prepare_always_opt = true; 418 i::FLAG_prepare_always_opt = true;
430 CompileConstructorWithDeoptimizingValueOf(); 419 CompileConstructorWithDeoptimizingValueOf();
431 CompileRun(f_source); 420 CompileRun(f_source);
432 CompileRun("for (var i = 0; i < 5; i++) {" 421 CompileRun("for (var i = 0; i < 5; i++) {"
433 " f(8, new X());" 422 " f(8, new X());"
434 "};"); 423 "};");
435 424
436 // Compile an optimized version of f. 425 // Compile an optimized version of f.
437 i::FLAG_always_opt = true; 426 i::FLAG_always_opt = true;
438 CompileRun(f_source); 427 CompileRun(f_source);
439 CompileRun("f(7, new X());"); 428 CompileRun("f(7, new X());");
440 CHECK(!i_isolate->use_crankshaft() || 429 CHECK(!CcTest::i_isolate()->use_crankshaft() ||
441 GetJSFunction((*env)->Global(), "f")->IsOptimized()); 430 GetJSFunction((*env)->Global(), "f")->IsOptimized());
442 431
443 // Call f and force deoptimization while processing the binary operation. 432 // Call f and force deoptimization while processing the binary operation.
444 CompileRun("deopt = true;" 433 CompileRun("deopt = true;"
445 "var result = f(7, new X());"); 434 "var result = f(7, new X());");
446 NonIncrementalGC(i_isolate); 435 NonIncrementalGC();
447 CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); 436 CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized());
448 } 437 }
449 438
450 439
451 UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) { 440 TEST(DeoptimizeBinaryOperationADD) {
452 i::FLAG_turbo_deoptimization = true; 441 i::FLAG_turbo_deoptimization = true;
453 i::FLAG_concurrent_recompilation = false; 442 i::FLAG_concurrent_recompilation = false;
454 v8::Isolate* isolate = v8::Isolate::New(); 443 LocalContext env;
455 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 444 v8::HandleScope scope(env->GetIsolate());
456 isolate->Enter(); 445
446 TestDeoptimizeBinaryOpHelper(&env, "+");
447
448 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
449 CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value());
450 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
451 }
452
453
454 TEST(DeoptimizeBinaryOperationSUB) {
455 i::FLAG_turbo_deoptimization = true;
456 i::FLAG_concurrent_recompilation = false;
457 LocalContext env;
458 v8::HandleScope scope(env->GetIsolate());
459
460 TestDeoptimizeBinaryOpHelper(&env, "-");
461
462 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
463 CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value());
464 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
465 }
466
467
468 TEST(DeoptimizeBinaryOperationMUL) {
469 i::FLAG_turbo_deoptimization = true;
470 i::FLAG_concurrent_recompilation = false;
471 LocalContext env;
472 v8::HandleScope scope(env->GetIsolate());
473
474 TestDeoptimizeBinaryOpHelper(&env, "*");
475
476 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
477 CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value());
478 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
479 }
480
481
482 TEST(DeoptimizeBinaryOperationDIV) {
483 i::FLAG_turbo_deoptimization = true;
484 i::FLAG_concurrent_recompilation = false;
485 LocalContext env;
486 v8::HandleScope scope(env->GetIsolate());
487
488 TestDeoptimizeBinaryOpHelper(&env, "/");
489
490 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
491 CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value());
492 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
493 }
494
495
496 TEST(DeoptimizeBinaryOperationMOD) {
497 i::FLAG_turbo_deoptimization = true;
498 i::FLAG_concurrent_recompilation = false;
499 LocalContext env;
500 v8::HandleScope scope(env->GetIsolate());
501
502 TestDeoptimizeBinaryOpHelper(&env, "%");
503
504 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
505 CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value());
506 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
507 }
508
509
510 TEST(DeoptimizeCompare) {
511 i::FLAG_turbo_deoptimization = true;
512 i::FLAG_concurrent_recompilation = false;
513 LocalContext env;
514 v8::HandleScope scope(env->GetIsolate());
515
516 const char* f_source = "function f(x, y) { return x < y; };";
517
457 { 518 {
458 LocalContext env(isolate); 519 AllowNativesSyntaxNoInlining options;
459 v8::HandleScope scope(env->GetIsolate()); 520 // Compile function f and collect to type feedback to insert compare ic
460 521 // call in the optimized code.
461 TestDeoptimizeBinaryOpHelper(&env, "+"); 522 i::FLAG_prepare_always_opt = true;
462 523 CompileRun("var count = 0;"
463 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 524 "var result = 0;"
464 CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); 525 "var deopt = false;"
465 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); 526 "function X() { };"
527 "X.prototype.toString = function () {"
528 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'"
529 "};");
530 CompileRun(f_source);
531 CompileRun("for (var i = 0; i < 5; i++) {"
532 " f('a', new X());"
533 "};");
534
535 // Compile an optimized version of f.
536 i::FLAG_always_opt = true;
537 CompileRun(f_source);
538 CompileRun("f('a', new X());");
539 CHECK(!CcTest::i_isolate()->use_crankshaft() ||
540 GetJSFunction(env->Global(), "f")->IsOptimized());
541
542 // Call f and force deoptimization while processing the comparison.
543 CompileRun("deopt = true;"
544 "var result = f('a', new X());");
466 } 545 }
467 isolate->Exit(); 546 NonIncrementalGC();
468 isolate->Dispose(); 547
469 } 548 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
470 549 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
471 550 CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue());
472 UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) { 551 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
473 i::FLAG_turbo_deoptimization = true; 552 }
474 i::FLAG_concurrent_recompilation = false; 553
475 v8::Isolate* isolate = v8::Isolate::New(); 554
476 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 555 TEST(DeoptimizeLoadICStoreIC) {
477 isolate->Enter(); 556 i::FLAG_turbo_deoptimization = true;
557 i::FLAG_concurrent_recompilation = false;
558 LocalContext env;
559 v8::HandleScope scope(env->GetIsolate());
560
561 // Functions to generate load/store/keyed load/keyed store IC calls.
562 const char* f1_source = "function f1(x) { return x.y; };";
563 const char* g1_source = "function g1(x) { x.y = 1; };";
564 const char* f2_source = "function f2(x, y) { return x[y]; };";
565 const char* g2_source = "function g2(x, y) { x[y] = 1; };";
566
478 { 567 {
479 LocalContext env(isolate); 568 AllowNativesSyntaxNoInlining options;
480 v8::HandleScope scope(env->GetIsolate()); 569 // Compile functions and collect to type feedback to insert ic
481 570 // calls in the optimized code.
482 TestDeoptimizeBinaryOpHelper(&env, "-"); 571 i::FLAG_prepare_always_opt = true;
483 572 CompileRun("var count = 0;"
484 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 573 "var result = 0;"
485 CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); 574 "var deopt = false;"
486 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); 575 "function X() { };"
576 "X.prototype.__defineGetter__('y', function () {"
577 " if (deopt) { count++; %DeoptimizeFunction(f1); };"
578 " return 13;"
579 "});"
580 "X.prototype.__defineSetter__('y', function () {"
581 " if (deopt) { count++; %DeoptimizeFunction(g1); };"
582 "});"
583 "X.prototype.__defineGetter__('z', function () {"
584 " if (deopt) { count++; %DeoptimizeFunction(f2); };"
585 " return 13;"
586 "});"
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 }
617
618 // Call functions and force deoptimization while processing the ics.
619 CompileRun("deopt = true;"
620 "var result = f1(new X());"
621 "g1(new X());"
622 "f2(new X(), 'z');"
623 "g2(new X(), 'z');");
487 } 624 }
488 isolate->Exit(); 625 NonIncrementalGC();
489 isolate->Dispose(); 626
490 } 627 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
491 628 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
492 629 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
493 UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) { 630 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
494 i::FLAG_turbo_deoptimization = true; 631 CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value());
495 i::FLAG_concurrent_recompilation = false; 632 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
496 v8::Isolate* isolate = v8::Isolate::New(); 633 }
497 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 634
498 isolate->Enter(); 635
636 TEST(DeoptimizeLoadICStoreICNested) {
637 i::FLAG_turbo_deoptimization = true;
638 i::FLAG_concurrent_recompilation = false;
639 LocalContext env;
640 v8::HandleScope scope(env->GetIsolate());
641
642 // Functions to generate load/store/keyed load/keyed store IC calls.
643 const char* f1_source = "function f1(x) { return x.y; };";
644 const char* g1_source = "function g1(x) { x.y = 1; };";
645 const char* f2_source = "function f2(x, y) { return x[y]; };";
646 const char* g2_source = "function g2(x, y) { x[y] = 1; };";
647
499 { 648 {
500 LocalContext env(isolate); 649 AllowNativesSyntaxNoInlining options;
501 v8::HandleScope scope(env->GetIsolate()); 650 // Compile functions and collect to type feedback to insert ic
502 651 // calls in the optimized code.
503 TestDeoptimizeBinaryOpHelper(&env, "*"); 652 i::FLAG_prepare_always_opt = true;
504 653 CompileRun("var count = 0;"
505 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 654 "var result = 0;"
506 CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); 655 "var deopt = false;"
507 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); 656 "function X() { };"
657 "X.prototype.__defineGetter__('y', function () {"
658 " g1(this);"
659 " return 13;"
660 "});"
661 "X.prototype.__defineSetter__('y', function () {"
662 " f2(this, 'z');"
663 "});"
664 "X.prototype.__defineGetter__('z', function () {"
665 " g2(this, 'z');"
666 "});"
667 "X.prototype.__defineSetter__('z', function () {"
668 " if (deopt) {"
669 " count++;"
670 " %DeoptimizeFunction(f1);"
671 " %DeoptimizeFunction(g1);"
672 " %DeoptimizeFunction(f2);"
673 " %DeoptimizeFunction(g2); };"
674 "});");
675 CompileRun(f1_source);
676 CompileRun(g1_source);
677 CompileRun(f2_source);
678 CompileRun(g2_source);
679 CompileRun("for (var i = 0; i < 5; i++) {"
680 " f1(new X());"
681 " g1(new X());"
682 " f2(new X(), 'z');"
683 " g2(new X(), 'z');"
684 "};");
685
686 // Compile an optimized version of the functions.
687 i::FLAG_always_opt = true;
688 CompileRun(f1_source);
689 CompileRun(g1_source);
690 CompileRun(f2_source);
691 CompileRun(g2_source);
692 CompileRun("f1(new X());");
693 CompileRun("g1(new X());");
694 CompileRun("f2(new X(), 'z');");
695 CompileRun("g2(new X(), 'z');");
696 if (CcTest::i_isolate()->use_crankshaft()) {
697 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
698 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
699 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
700 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
701 }
702
703 // Call functions and force deoptimization while processing the ics.
704 CompileRun("deopt = true;"
705 "var result = f1(new X());");
508 } 706 }
509 isolate->Exit(); 707 NonIncrementalGC();
510 isolate->Dispose(); 708
511 } 709 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
512 710 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
513 711 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
514 UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) { 712 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
515 i::FLAG_turbo_deoptimization = true; 713 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
516 i::FLAG_concurrent_recompilation = false; 714 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
517 v8::Isolate* isolate = v8::Isolate::New(); 715 }
518 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
519 isolate->Enter();
520 {
521 LocalContext env(isolate);
522 v8::HandleScope scope(env->GetIsolate());
523
524 TestDeoptimizeBinaryOpHelper(&env, "/");
525
526 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
527 CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value());
528 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
529 }
530 isolate->Exit();
531 isolate->Dispose();
532 }
533
534
535 UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) {
536 i::FLAG_turbo_deoptimization = true;
537 i::FLAG_concurrent_recompilation = false;
538 v8::Isolate* isolate = v8::Isolate::New();
539 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
540 isolate->Enter();
541 {
542 LocalContext env(isolate);
543 v8::HandleScope scope(env->GetIsolate());
544
545 TestDeoptimizeBinaryOpHelper(&env, "%");
546
547 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
548 CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value());
549 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
550 }
551 isolate->Exit();
552 isolate->Dispose();
553 }
554
555
556 UNINITIALIZED_TEST(DeoptimizeCompare) {
557 i::FLAG_turbo_deoptimization = true;
558 i::FLAG_concurrent_recompilation = false;
559 v8::Isolate* isolate = v8::Isolate::New();
560 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
561 isolate->Enter();
562 {
563 LocalContext env(isolate);
564 v8::HandleScope scope(env->GetIsolate());
565
566 const char* f_source = "function f(x, y) { return x < y; };";
567
568 {
569 AllowNativesSyntaxNoInlining options;
570 // Compile function f and collect to type feedback to insert compare ic
571 // call in the optimized code.
572 i::FLAG_prepare_always_opt = true;
573 CompileRun(
574 "var count = 0;"
575 "var result = 0;"
576 "var deopt = false;"
577 "function X() { };"
578 "X.prototype.toString = function () {"
579 " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'"
580 "};");
581 CompileRun(f_source);
582 CompileRun(
583 "for (var i = 0; i < 5; i++) {"
584 " f('a', new X());"
585 "};");
586
587 // Compile an optimized version of f.
588 i::FLAG_always_opt = true;
589 CompileRun(f_source);
590 CompileRun("f('a', new X());");
591 CHECK(!i_isolate->use_crankshaft() ||
592 GetJSFunction(env->Global(), "f")->IsOptimized());
593
594 // Call f and force deoptimization while processing the comparison.
595 CompileRun(
596 "deopt = true;"
597 "var result = f('a', new X());");
598 }
599 NonIncrementalGC(i_isolate);
600
601 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
602 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
603 CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue());
604 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
605 }
606 isolate->Exit();
607 isolate->Dispose();
608 }
609
610
611 UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) {
612 i::FLAG_turbo_deoptimization = true;
613 i::FLAG_concurrent_recompilation = false;
614 v8::Isolate* isolate = v8::Isolate::New();
615 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
616 isolate->Enter();
617 {
618 LocalContext env(isolate);
619 v8::HandleScope scope(env->GetIsolate());
620
621 // Functions to generate load/store/keyed load/keyed store IC calls.
622 const char* f1_source = "function f1(x) { return x.y; };";
623 const char* g1_source = "function g1(x) { x.y = 1; };";
624 const char* f2_source = "function f2(x, y) { return x[y]; };";
625 const char* g2_source = "function g2(x, y) { x[y] = 1; };";
626
627 {
628 AllowNativesSyntaxNoInlining options;
629 // Compile functions and collect to type feedback to insert ic
630 // calls in the optimized code.
631 i::FLAG_prepare_always_opt = true;
632 CompileRun(
633 "var count = 0;"
634 "var result = 0;"
635 "var deopt = false;"
636 "function X() { };"
637 "X.prototype.__defineGetter__('y', function () {"
638 " if (deopt) { count++; %DeoptimizeFunction(f1); };"
639 " return 13;"
640 "});"
641 "X.prototype.__defineSetter__('y', function () {"
642 " if (deopt) { count++; %DeoptimizeFunction(g1); };"
643 "});"
644 "X.prototype.__defineGetter__('z', function () {"
645 " if (deopt) { count++; %DeoptimizeFunction(f2); };"
646 " return 13;"
647 "});"
648 "X.prototype.__defineSetter__('z', function () {"
649 " if (deopt) { count++; %DeoptimizeFunction(g2); };"
650 "});");
651 CompileRun(f1_source);
652 CompileRun(g1_source);
653 CompileRun(f2_source);
654 CompileRun(g2_source);
655 CompileRun(
656 "for (var i = 0; i < 5; i++) {"
657 " f1(new X());"
658 " g1(new X());"
659 " f2(new X(), 'z');"
660 " g2(new X(), 'z');"
661 "};");
662
663 // Compile an optimized version of the functions.
664 i::FLAG_always_opt = true;
665 CompileRun(f1_source);
666 CompileRun(g1_source);
667 CompileRun(f2_source);
668 CompileRun(g2_source);
669 CompileRun("f1(new X());");
670 CompileRun("g1(new X());");
671 CompileRun("f2(new X(), 'z');");
672 CompileRun("g2(new X(), 'z');");
673 if (i_isolate->use_crankshaft()) {
674 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
675 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
676 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
677 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
678 }
679
680 // Call functions and force deoptimization while processing the ics.
681 CompileRun(
682 "deopt = true;"
683 "var result = f1(new X());"
684 "g1(new X());"
685 "f2(new X(), 'z');"
686 "g2(new X(), 'z');");
687 }
688 NonIncrementalGC(i_isolate);
689
690 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
691 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
692 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
693 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
694 CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value());
695 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
696 }
697 isolate->Exit();
698 isolate->Dispose();
699 }
700
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