| OLD | NEW |
| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 private: | 97 private: |
| 98 bool allow_natives_syntax_; | 98 bool allow_natives_syntax_; |
| 99 bool use_inlining_; | 99 bool use_inlining_; |
| 100 bool concurrent_recompilation_; | 100 bool concurrent_recompilation_; |
| 101 }; | 101 }; |
| 102 | 102 |
| 103 | 103 |
| 104 // Abort any ongoing incremental marking to make sure that all weak global | 104 // Abort any ongoing incremental marking to make sure that all weak global |
| 105 // handle callbacks are processed. | 105 // handle callbacks are processed. |
| 106 static void NonIncrementalGC() { | 106 static void NonIncrementalGC() { |
| 107 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 107 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 108 } | 108 } |
| 109 | 109 |
| 110 | 110 |
| 111 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, | 111 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, |
| 112 const char* property_name) { | 112 const char* property_name) { |
| 113 v8::Local<v8::Function> fun = | 113 v8::Local<v8::Function> fun = |
| 114 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); | 114 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); |
| 115 return v8::Utils::OpenHandle(*fun); | 115 return v8::Utils::OpenHandle(*fun); |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 TEST(DeoptimizeSimple) { | 119 TEST(DeoptimizeSimple) { |
| 120 LocalContext env; | 120 LocalContext env; |
| 121 v8::HandleScope scope(env->GetIsolate()); | 121 v8::HandleScope scope(env->GetIsolate()); |
| 122 | 122 |
| 123 // Test lazy deoptimization of a simple function. | 123 // Test lazy deoptimization of a simple function. |
| 124 { | 124 { |
| 125 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 125 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 126 CompileRun( | 126 CompileRun( |
| 127 "var count = 0;" | 127 "var count = 0;" |
| 128 "function h() { %DeoptimizeFunction(f); }" | 128 "function h() { %DeoptimizeFunction(f); }" |
| 129 "function g() { count++; h(); }" | 129 "function g() { count++; h(); }" |
| 130 "function f() { g(); };" | 130 "function f() { g(); };" |
| 131 "f();"); | 131 "f();"); |
| 132 } | 132 } |
| 133 NonIncrementalGC(); | 133 NonIncrementalGC(); |
| 134 | 134 |
| 135 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 135 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 136 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); | 136 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 137 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 137 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 138 | 138 |
| 139 // Test lazy deoptimization of a simple function. Call the function after the | 139 // Test lazy deoptimization of a simple function. Call the function after the |
| 140 // deoptimization while it is still activated further down the stack. | 140 // deoptimization while it is still activated further down the stack. |
| 141 { | 141 { |
| 142 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 142 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 143 CompileRun( | 143 CompileRun( |
| 144 "var count = 0;" | 144 "var count = 0;" |
| 145 "function g() { count++; %DeoptimizeFunction(f); f(false); }" | 145 "function g() { count++; %DeoptimizeFunction(f); f(false); }" |
| 146 "function f(x) { if (x) { g(); } else { return } };" | 146 "function f(x) { if (x) { g(); } else { return } };" |
| 147 "f(true);"); | 147 "f(true);"); |
| 148 } | 148 } |
| 149 NonIncrementalGC(); | 149 NonIncrementalGC(); |
| 150 | 150 |
| 151 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 151 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 152 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); | 152 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 153 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 153 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 154 } | 154 } |
| 155 | 155 |
| 156 | 156 |
| 157 TEST(DeoptimizeSimpleWithArguments) { | 157 TEST(DeoptimizeSimpleWithArguments) { |
| 158 LocalContext env; | 158 LocalContext env; |
| 159 v8::HandleScope scope(env->GetIsolate()); | 159 v8::HandleScope scope(env->GetIsolate()); |
| 160 | 160 |
| 161 // Test lazy deoptimization of a simple function with some arguments. | 161 // Test lazy deoptimization of a simple function with some arguments. |
| 162 { | 162 { |
| 163 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 163 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 164 CompileRun( | 164 CompileRun( |
| 165 "var count = 0;" | 165 "var count = 0;" |
| 166 "function h(x) { %DeoptimizeFunction(f); }" | 166 "function h(x) { %DeoptimizeFunction(f); }" |
| 167 "function g(x, y) { count++; h(x); }" | 167 "function g(x, y) { count++; h(x); }" |
| 168 "function f(x, y, z) { g(1,x); y+z; };" | 168 "function f(x, y, z) { g(1,x); y+z; };" |
| 169 "f(1, \"2\", false);"); | 169 "f(1, \"2\", false);"); |
| 170 } | 170 } |
| 171 NonIncrementalGC(); | 171 NonIncrementalGC(); |
| 172 | 172 |
| 173 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 173 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 174 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); | 174 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 175 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 175 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 176 | 176 |
| 177 // Test lazy deoptimization of a simple function with some arguments. Call the | 177 // Test lazy deoptimization of a simple function with some arguments. Call the |
| 178 // function after the deoptimization while it is still activated further down | 178 // function after the deoptimization while it is still activated further down |
| 179 // the stack. | 179 // the stack. |
| 180 { | 180 { |
| 181 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 181 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 182 CompileRun( | 182 CompileRun( |
| 183 "var count = 0;" | 183 "var count = 0;" |
| 184 "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }" | 184 "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }" |
| 185 "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" | 185 "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" |
| 186 "f(true, 1, \"2\");"); | 186 "f(true, 1, \"2\");"); |
| 187 } | 187 } |
| 188 NonIncrementalGC(); | 188 NonIncrementalGC(); |
| 189 | 189 |
| 190 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 190 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 191 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); | 191 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 192 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 192 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 193 } | 193 } |
| 194 | 194 |
| 195 | 195 |
| 196 TEST(DeoptimizeSimpleNested) { | 196 TEST(DeoptimizeSimpleNested) { |
| 197 LocalContext env; | 197 LocalContext env; |
| 198 v8::HandleScope scope(env->GetIsolate()); | 198 v8::HandleScope scope(env->GetIsolate()); |
| 199 | 199 |
| 200 // Test lazy deoptimization of a simple function. Have a nested function call | 200 // Test lazy deoptimization of a simple function. Have a nested function call |
| 201 // do the deoptimization. | 201 // do the deoptimization. |
| 202 { | 202 { |
| 203 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 203 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 204 CompileRun( | 204 CompileRun( |
| 205 "var count = 0;" | 205 "var count = 0;" |
| 206 "var result = 0;" | 206 "var result = 0;" |
| 207 "function h(x, y, z) { return x + y + z; }" | 207 "function h(x, y, z) { return x + y + z; }" |
| 208 "function g(z) { count++; %DeoptimizeFunction(f); return z;}" | 208 "function g(z) { count++; %DeoptimizeFunction(f); return z;}" |
| 209 "function f(x,y,z) { return h(x, y, g(z)); };" | 209 "function f(x,y,z) { return h(x, y, g(z)); };" |
| 210 "result = f(1, 2, 3);"); | 210 "result = f(1, 2, 3);"); |
| 211 NonIncrementalGC(); | 211 NonIncrementalGC(); |
| 212 | 212 |
| 213 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 213 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 214 CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); | 214 CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 215 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); | 215 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 216 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 216 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 217 } | 217 } |
| 218 } | 218 } |
| 219 | 219 |
| 220 | 220 |
| 221 TEST(DeoptimizeRecursive) { | 221 TEST(DeoptimizeRecursive) { |
| 222 LocalContext env; | 222 LocalContext env; |
| 223 v8::HandleScope scope(env->GetIsolate()); | 223 v8::HandleScope scope(env->GetIsolate()); |
| 224 | 224 |
| 225 { | 225 { |
| 226 // Test lazy deoptimization of a simple function called recursively. Call | 226 // Test lazy deoptimization of a simple function called recursively. Call |
| 227 // the function recursively a number of times before deoptimizing it. | 227 // the function recursively a number of times before deoptimizing it. |
| 228 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 228 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 229 CompileRun( | 229 CompileRun( |
| 230 "var count = 0;" | 230 "var count = 0;" |
| 231 "var calls = 0;" | 231 "var calls = 0;" |
| 232 "function g() { count++; %DeoptimizeFunction(f); }" | 232 "function g() { count++; %DeoptimizeFunction(f); }" |
| 233 "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" | 233 "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" |
| 234 "f(10);"); | 234 "f(10);"); |
| 235 } | 235 } |
| 236 NonIncrementalGC(); | 236 NonIncrementalGC(); |
| 237 | 237 |
| 238 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 238 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 239 CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); | 239 CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); |
| 240 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 240 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 241 | 241 |
| 242 v8::Local<v8::Function> fun = | 242 v8::Local<v8::Function> fun = |
| 243 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); | 243 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); |
| 244 CHECK(!fun.IsEmpty()); | 244 CHECK(!fun.IsEmpty()); |
| 245 } | 245 } |
| 246 | 246 |
| 247 | 247 |
| 248 TEST(DeoptimizeMultiple) { | 248 TEST(DeoptimizeMultiple) { |
| 249 LocalContext env; | 249 LocalContext env; |
| 250 v8::HandleScope scope(env->GetIsolate()); | 250 v8::HandleScope scope(env->GetIsolate()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 262 "function f4(x) { g(); };" | 262 "function f4(x) { g(); };" |
| 263 "function f3(x, y, z) { f4(); return x + y + z; };" | 263 "function f3(x, y, z) { f4(); return x + y + z; };" |
| 264 "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };" | 264 "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };" |
| 265 "function f1(x) { return f2(x + 1, x + 1) + x; };" | 265 "function f1(x) { return f2(x + 1, x + 1) + x; };" |
| 266 "result = f1(1);"); | 266 "result = f1(1);"); |
| 267 } | 267 } |
| 268 NonIncrementalGC(); | 268 NonIncrementalGC(); |
| 269 | 269 |
| 270 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 270 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 271 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); | 271 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 272 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 272 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 273 } | 273 } |
| 274 | 274 |
| 275 | 275 |
| 276 TEST(DeoptimizeConstructor) { | 276 TEST(DeoptimizeConstructor) { |
| 277 LocalContext env; | 277 LocalContext env; |
| 278 v8::HandleScope scope(env->GetIsolate()); | 278 v8::HandleScope scope(env->GetIsolate()); |
| 279 | 279 |
| 280 { | 280 { |
| 281 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 281 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 282 CompileRun( | 282 CompileRun( |
| 283 "var count = 0;" | 283 "var count = 0;" |
| 284 "function g() { count++;" | 284 "function g() { count++;" |
| 285 " %DeoptimizeFunction(f); }" | 285 " %DeoptimizeFunction(f); }" |
| 286 "function f() { g(); };" | 286 "function f() { g(); };" |
| 287 "result = new f() instanceof f;"); | 287 "result = new f() instanceof f;"); |
| 288 } | 288 } |
| 289 NonIncrementalGC(); | 289 NonIncrementalGC(); |
| 290 | 290 |
| 291 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 291 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 292 CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); | 292 CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); |
| 293 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 293 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 294 | 294 |
| 295 { | 295 { |
| 296 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 296 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 297 CompileRun( | 297 CompileRun( |
| 298 "var count = 0;" | 298 "var count = 0;" |
| 299 "var result = 0;" | 299 "var result = 0;" |
| 300 "function g() { count++;" | 300 "function g() { count++;" |
| 301 " %DeoptimizeFunction(f); }" | 301 " %DeoptimizeFunction(f); }" |
| 302 "function f(x, y) { this.x = x; g(); this.y = y; };" | 302 "function f(x, y) { this.x = x; g(); this.y = y; };" |
| 303 "result = new f(1, 2);" | 303 "result = new f(1, 2);" |
| 304 "result = result.x + result.y;"); | 304 "result = result.x + result.y;"); |
| 305 } | 305 } |
| 306 NonIncrementalGC(); | 306 NonIncrementalGC(); |
| 307 | 307 |
| 308 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 308 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 309 CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); | 309 CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 310 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 310 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 311 } | 311 } |
| 312 | 312 |
| 313 | 313 |
| 314 TEST(DeoptimizeConstructorMultiple) { | 314 TEST(DeoptimizeConstructorMultiple) { |
| 315 LocalContext env; | 315 LocalContext env; |
| 316 v8::HandleScope scope(env->GetIsolate()); | 316 v8::HandleScope scope(env->GetIsolate()); |
| 317 | 317 |
| 318 { | 318 { |
| 319 AlwaysOptimizeAllowNativesSyntaxNoInlining options; | 319 AlwaysOptimizeAllowNativesSyntaxNoInlining options; |
| 320 CompileRun( | 320 CompileRun( |
| 321 "var count = 0;" | 321 "var count = 0;" |
| 322 "var result = 0;" | 322 "var result = 0;" |
| 323 "function g() { count++;" | 323 "function g() { count++;" |
| 324 " %DeoptimizeFunction(f1);" | 324 " %DeoptimizeFunction(f1);" |
| 325 " %DeoptimizeFunction(f2);" | 325 " %DeoptimizeFunction(f2);" |
| 326 " %DeoptimizeFunction(f3);" | 326 " %DeoptimizeFunction(f3);" |
| 327 " %DeoptimizeFunction(f4);}" | 327 " %DeoptimizeFunction(f4);}" |
| 328 "function f4(x) { this.result = x; g(); };" | 328 "function f4(x) { this.result = x; g(); };" |
| 329 "function f3(x, y, z) { this.result = new f4(x + y + z).result; };" | 329 "function f3(x, y, z) { this.result = new f4(x + y + z).result; };" |
| 330 "function f2(x, y) {" | 330 "function f2(x, y) {" |
| 331 " this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };" | 331 " this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };" |
| 332 "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" | 332 "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" |
| 333 "result = new f1(1).result;"); | 333 "result = new f1(1).result;"); |
| 334 } | 334 } |
| 335 NonIncrementalGC(); | 335 NonIncrementalGC(); |
| 336 | 336 |
| 337 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 337 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 338 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); | 338 CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 339 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 339 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 340 } | 340 } |
| 341 | 341 |
| 342 | 342 |
| 343 TEST(DeoptimizeBinaryOperationADDString) { | 343 TEST(DeoptimizeBinaryOperationADDString) { |
| 344 LocalContext env; | 344 LocalContext env; |
| 345 v8::HandleScope scope(env->GetIsolate()); | 345 v8::HandleScope scope(env->GetIsolate()); |
| 346 | 346 |
| 347 const char* f_source = "function f(x, y) { return x + y; };"; | 347 const char* f_source = "function f(x, y) { return x + y; };"; |
| 348 | 348 |
| 349 { | 349 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 360 "};"); | 360 "};"); |
| 361 CompileRun(f_source); | 361 CompileRun(f_source); |
| 362 CompileRun("for (var i = 0; i < 5; i++) {" | 362 CompileRun("for (var i = 0; i < 5; i++) {" |
| 363 " f('a+', new X());" | 363 " f('a+', new X());" |
| 364 "};"); | 364 "};"); |
| 365 | 365 |
| 366 // Compile an optimized version of f. | 366 // Compile an optimized version of f. |
| 367 i::FLAG_always_opt = true; | 367 i::FLAG_always_opt = true; |
| 368 CompileRun(f_source); | 368 CompileRun(f_source); |
| 369 CompileRun("f('a+', new X());"); | 369 CompileRun("f('a+', new X());"); |
| 370 CHECK(!i::Isolate::Current()->use_crankshaft() || | 370 CHECK(!CcTest::i_isolate()->use_crankshaft() || |
| 371 GetJSFunction(env->Global(), "f")->IsOptimized()); | 371 GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 372 | 372 |
| 373 // Call f and force deoptimization while processing the binary operation. | 373 // Call f and force deoptimization while processing the binary operation. |
| 374 CompileRun("deopt = true;" | 374 CompileRun("deopt = true;" |
| 375 "var result = f('a+', new X());"); | 375 "var result = f('a+', new X());"); |
| 376 } | 376 } |
| 377 NonIncrementalGC(); | 377 NonIncrementalGC(); |
| 378 | 378 |
| 379 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); | 379 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 380 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 380 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 381 v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result")); | 381 v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result")); |
| 382 CHECK(result->IsString()); | 382 CHECK(result->IsString()); |
| 383 v8::String::Utf8Value utf8(result); | 383 v8::String::Utf8Value utf8(result); |
| 384 CHECK_EQ("a+an X", *utf8); | 384 CHECK_EQ("a+an X", *utf8); |
| 385 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 385 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 386 } | 386 } |
| 387 | 387 |
| 388 | 388 |
| 389 static void CompileConstructorWithDeoptimizingValueOf() { | 389 static void CompileConstructorWithDeoptimizingValueOf() { |
| 390 CompileRun("var count = 0;" | 390 CompileRun("var count = 0;" |
| 391 "var result = 0;" | 391 "var result = 0;" |
| 392 "var deopt = false;" | 392 "var deopt = false;" |
| 393 "function X() { };" | 393 "function X() { };" |
| 394 "X.prototype.valueOf = function () {" | 394 "X.prototype.valueOf = function () {" |
| 395 " if (deopt) { count++; %DeoptimizeFunction(f); } return 8" | 395 " if (deopt) { count++; %DeoptimizeFunction(f); } return 8" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 412 CompileConstructorWithDeoptimizingValueOf(); | 412 CompileConstructorWithDeoptimizingValueOf(); |
| 413 CompileRun(f_source); | 413 CompileRun(f_source); |
| 414 CompileRun("for (var i = 0; i < 5; i++) {" | 414 CompileRun("for (var i = 0; i < 5; i++) {" |
| 415 " f(8, new X());" | 415 " f(8, new X());" |
| 416 "};"); | 416 "};"); |
| 417 | 417 |
| 418 // Compile an optimized version of f. | 418 // Compile an optimized version of f. |
| 419 i::FLAG_always_opt = true; | 419 i::FLAG_always_opt = true; |
| 420 CompileRun(f_source); | 420 CompileRun(f_source); |
| 421 CompileRun("f(7, new X());"); | 421 CompileRun("f(7, new X());"); |
| 422 CHECK(!i::Isolate::Current()->use_crankshaft() || | 422 CHECK(!CcTest::i_isolate()->use_crankshaft() || |
| 423 GetJSFunction((*env)->Global(), "f")->IsOptimized()); | 423 GetJSFunction((*env)->Global(), "f")->IsOptimized()); |
| 424 | 424 |
| 425 // Call f and force deoptimization while processing the binary operation. | 425 // Call f and force deoptimization while processing the binary operation. |
| 426 CompileRun("deopt = true;" | 426 CompileRun("deopt = true;" |
| 427 "var result = f(7, new X());"); | 427 "var result = f(7, new X());"); |
| 428 NonIncrementalGC(); | 428 NonIncrementalGC(); |
| 429 CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); | 429 CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); |
| 430 } | 430 } |
| 431 | 431 |
| 432 | 432 |
| 433 TEST(DeoptimizeBinaryOperationADD) { | 433 TEST(DeoptimizeBinaryOperationADD) { |
| 434 LocalContext env; | 434 LocalContext env; |
| 435 v8::HandleScope scope(env->GetIsolate()); | 435 v8::HandleScope scope(env->GetIsolate()); |
| 436 | 436 |
| 437 TestDeoptimizeBinaryOpHelper(&env, "+"); | 437 TestDeoptimizeBinaryOpHelper(&env, "+"); |
| 438 | 438 |
| 439 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 439 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 440 CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); | 440 CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 441 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 441 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 442 } | 442 } |
| 443 | 443 |
| 444 | 444 |
| 445 TEST(DeoptimizeBinaryOperationSUB) { | 445 TEST(DeoptimizeBinaryOperationSUB) { |
| 446 LocalContext env; | 446 LocalContext env; |
| 447 v8::HandleScope scope(env->GetIsolate()); | 447 v8::HandleScope scope(env->GetIsolate()); |
| 448 | 448 |
| 449 TestDeoptimizeBinaryOpHelper(&env, "-"); | 449 TestDeoptimizeBinaryOpHelper(&env, "-"); |
| 450 | 450 |
| 451 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 451 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 452 CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); | 452 CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 453 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 453 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 454 } | 454 } |
| 455 | 455 |
| 456 | 456 |
| 457 TEST(DeoptimizeBinaryOperationMUL) { | 457 TEST(DeoptimizeBinaryOperationMUL) { |
| 458 LocalContext env; | 458 LocalContext env; |
| 459 v8::HandleScope scope(env->GetIsolate()); | 459 v8::HandleScope scope(env->GetIsolate()); |
| 460 | 460 |
| 461 TestDeoptimizeBinaryOpHelper(&env, "*"); | 461 TestDeoptimizeBinaryOpHelper(&env, "*"); |
| 462 | 462 |
| 463 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 463 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 464 CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); | 464 CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 465 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 465 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 466 } | 466 } |
| 467 | 467 |
| 468 | 468 |
| 469 TEST(DeoptimizeBinaryOperationDIV) { | 469 TEST(DeoptimizeBinaryOperationDIV) { |
| 470 LocalContext env; | 470 LocalContext env; |
| 471 v8::HandleScope scope(env->GetIsolate()); | 471 v8::HandleScope scope(env->GetIsolate()); |
| 472 | 472 |
| 473 TestDeoptimizeBinaryOpHelper(&env, "/"); | 473 TestDeoptimizeBinaryOpHelper(&env, "/"); |
| 474 | 474 |
| 475 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 475 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 476 CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); | 476 CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 477 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 477 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 478 } | 478 } |
| 479 | 479 |
| 480 | 480 |
| 481 TEST(DeoptimizeBinaryOperationMOD) { | 481 TEST(DeoptimizeBinaryOperationMOD) { |
| 482 LocalContext env; | 482 LocalContext env; |
| 483 v8::HandleScope scope(env->GetIsolate()); | 483 v8::HandleScope scope(env->GetIsolate()); |
| 484 | 484 |
| 485 TestDeoptimizeBinaryOpHelper(&env, "%"); | 485 TestDeoptimizeBinaryOpHelper(&env, "%"); |
| 486 | 486 |
| 487 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 487 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 488 CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); | 488 CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 489 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 489 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 490 } | 490 } |
| 491 | 491 |
| 492 | 492 |
| 493 TEST(DeoptimizeCompare) { | 493 TEST(DeoptimizeCompare) { |
| 494 LocalContext env; | 494 LocalContext env; |
| 495 v8::HandleScope scope(env->GetIsolate()); | 495 v8::HandleScope scope(env->GetIsolate()); |
| 496 | 496 |
| 497 const char* f_source = "function f(x, y) { return x < y; };"; | 497 const char* f_source = "function f(x, y) { return x < y; };"; |
| 498 | 498 |
| 499 { | 499 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 510 "};"); | 510 "};"); |
| 511 CompileRun(f_source); | 511 CompileRun(f_source); |
| 512 CompileRun("for (var i = 0; i < 5; i++) {" | 512 CompileRun("for (var i = 0; i < 5; i++) {" |
| 513 " f('a', new X());" | 513 " f('a', new X());" |
| 514 "};"); | 514 "};"); |
| 515 | 515 |
| 516 // Compile an optimized version of f. | 516 // Compile an optimized version of f. |
| 517 i::FLAG_always_opt = true; | 517 i::FLAG_always_opt = true; |
| 518 CompileRun(f_source); | 518 CompileRun(f_source); |
| 519 CompileRun("f('a', new X());"); | 519 CompileRun("f('a', new X());"); |
| 520 CHECK(!i::Isolate::Current()->use_crankshaft() || | 520 CHECK(!CcTest::i_isolate()->use_crankshaft() || |
| 521 GetJSFunction(env->Global(), "f")->IsOptimized()); | 521 GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 522 | 522 |
| 523 // Call f and force deoptimization while processing the comparison. | 523 // Call f and force deoptimization while processing the comparison. |
| 524 CompileRun("deopt = true;" | 524 CompileRun("deopt = true;" |
| 525 "var result = f('a', new X());"); | 525 "var result = f('a', new X());"); |
| 526 } | 526 } |
| 527 NonIncrementalGC(); | 527 NonIncrementalGC(); |
| 528 | 528 |
| 529 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); | 529 CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); |
| 530 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 530 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 531 CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); | 531 CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); |
| 532 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 532 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 533 } | 533 } |
| 534 | 534 |
| 535 | 535 |
| 536 TEST(DeoptimizeLoadICStoreIC) { | 536 TEST(DeoptimizeLoadICStoreIC) { |
| 537 LocalContext env; | 537 LocalContext env; |
| 538 v8::HandleScope scope(env->GetIsolate()); | 538 v8::HandleScope scope(env->GetIsolate()); |
| 539 | 539 |
| 540 // Functions to generate load/store/keyed load/keyed store IC calls. | 540 // Functions to generate load/store/keyed load/keyed store IC calls. |
| 541 const char* f1_source = "function f1(x) { return x.y; };"; | 541 const char* f1_source = "function f1(x) { return x.y; };"; |
| 542 const char* g1_source = "function g1(x) { x.y = 1; };"; | 542 const char* g1_source = "function g1(x) { x.y = 1; };"; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 // Compile an optimized version of the functions. | 580 // Compile an optimized version of the functions. |
| 581 i::FLAG_always_opt = true; | 581 i::FLAG_always_opt = true; |
| 582 CompileRun(f1_source); | 582 CompileRun(f1_source); |
| 583 CompileRun(g1_source); | 583 CompileRun(g1_source); |
| 584 CompileRun(f2_source); | 584 CompileRun(f2_source); |
| 585 CompileRun(g2_source); | 585 CompileRun(g2_source); |
| 586 CompileRun("f1(new X());"); | 586 CompileRun("f1(new X());"); |
| 587 CompileRun("g1(new X());"); | 587 CompileRun("g1(new X());"); |
| 588 CompileRun("f2(new X(), 'z');"); | 588 CompileRun("f2(new X(), 'z');"); |
| 589 CompileRun("g2(new X(), 'z');"); | 589 CompileRun("g2(new X(), 'z');"); |
| 590 if (i::Isolate::Current()->use_crankshaft()) { | 590 if (CcTest::i_isolate()->use_crankshaft()) { |
| 591 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); | 591 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); |
| 592 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); | 592 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); |
| 593 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); | 593 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); |
| 594 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); | 594 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); |
| 595 } | 595 } |
| 596 | 596 |
| 597 // Call functions and force deoptimization while processing the ics. | 597 // Call functions and force deoptimization while processing the ics. |
| 598 CompileRun("deopt = true;" | 598 CompileRun("deopt = true;" |
| 599 "var result = f1(new X());" | 599 "var result = f1(new X());" |
| 600 "g1(new X());" | 600 "g1(new X());" |
| 601 "f2(new X(), 'z');" | 601 "f2(new X(), 'z');" |
| 602 "g2(new X(), 'z');"); | 602 "g2(new X(), 'z');"); |
| 603 } | 603 } |
| 604 NonIncrementalGC(); | 604 NonIncrementalGC(); |
| 605 | 605 |
| 606 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); | 606 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); |
| 607 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); | 607 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); |
| 608 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); | 608 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); |
| 609 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); | 609 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); |
| 610 CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); | 610 CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 611 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); | 611 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 612 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 612 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 613 } | 613 } |
| 614 | 614 |
| 615 | 615 |
| 616 TEST(DeoptimizeLoadICStoreICNested) { | 616 TEST(DeoptimizeLoadICStoreICNested) { |
| 617 LocalContext env; | 617 LocalContext env; |
| 618 v8::HandleScope scope(env->GetIsolate()); | 618 v8::HandleScope scope(env->GetIsolate()); |
| 619 | 619 |
| 620 // Functions to generate load/store/keyed load/keyed store IC calls. | 620 // Functions to generate load/store/keyed load/keyed store IC calls. |
| 621 const char* f1_source = "function f1(x) { return x.y; };"; | 621 const char* f1_source = "function f1(x) { return x.y; };"; |
| 622 const char* g1_source = "function g1(x) { x.y = 1; };"; | 622 const char* g1_source = "function g1(x) { x.y = 1; };"; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 // Compile an optimized version of the functions. | 664 // Compile an optimized version of the functions. |
| 665 i::FLAG_always_opt = true; | 665 i::FLAG_always_opt = true; |
| 666 CompileRun(f1_source); | 666 CompileRun(f1_source); |
| 667 CompileRun(g1_source); | 667 CompileRun(g1_source); |
| 668 CompileRun(f2_source); | 668 CompileRun(f2_source); |
| 669 CompileRun(g2_source); | 669 CompileRun(g2_source); |
| 670 CompileRun("f1(new X());"); | 670 CompileRun("f1(new X());"); |
| 671 CompileRun("g1(new X());"); | 671 CompileRun("g1(new X());"); |
| 672 CompileRun("f2(new X(), 'z');"); | 672 CompileRun("f2(new X(), 'z');"); |
| 673 CompileRun("g2(new X(), 'z');"); | 673 CompileRun("g2(new X(), 'z');"); |
| 674 if (i::Isolate::Current()->use_crankshaft()) { | 674 if (CcTest::i_isolate()->use_crankshaft()) { |
| 675 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); | 675 CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); |
| 676 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); | 676 CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); |
| 677 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); | 677 CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); |
| 678 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); | 678 CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); |
| 679 } | 679 } |
| 680 | 680 |
| 681 // Call functions and force deoptimization while processing the ics. | 681 // Call functions and force deoptimization while processing the ics. |
| 682 CompileRun("deopt = true;" | 682 CompileRun("deopt = true;" |
| 683 "var result = f1(new X());"); | 683 "var result = f1(new X());"); |
| 684 } | 684 } |
| 685 NonIncrementalGC(); | 685 NonIncrementalGC(); |
| 686 | 686 |
| 687 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); | 687 CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); |
| 688 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); | 688 CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); |
| 689 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); | 689 CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); |
| 690 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); | 690 CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); |
| 691 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); | 691 CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); |
| 692 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); | 692 CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); |
| 693 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); | 693 CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); |
| 694 } | 694 } |
| OLD | NEW |