OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
11 #include "src/compilation-cache.h" | 11 #include "src/compilation-cache.h" |
| 12 #include "src/compiler/pipeline.h" |
12 #include "src/cpu-profiler.h" | 13 #include "src/cpu-profiler.h" |
13 #include "src/debug.h" | 14 #include "src/debug.h" |
14 #include "src/deoptimizer.h" | 15 #include "src/deoptimizer.h" |
15 #include "src/full-codegen.h" | 16 #include "src/full-codegen.h" |
16 #include "src/gdb-jit.h" | 17 #include "src/gdb-jit.h" |
17 #include "src/hydrogen.h" | 18 #include "src/hydrogen.h" |
18 #include "src/isolate-inl.h" | 19 #include "src/isolate-inl.h" |
19 #include "src/lithium.h" | 20 #include "src/lithium.h" |
20 #include "src/liveedit.h" | 21 #include "src/liveedit.h" |
21 #include "src/parser.h" | 22 #include "src/parser.h" |
(...skipping 28 matching lines...) Expand all Loading... |
50 osr_ast_id_(BailoutId::None()), | 51 osr_ast_id_(BailoutId::None()), |
51 parameter_count_(0), | 52 parameter_count_(0), |
52 this_has_uses_(true), | 53 this_has_uses_(true), |
53 optimization_id_(-1), | 54 optimization_id_(-1), |
54 ast_value_factory_(NULL), | 55 ast_value_factory_(NULL), |
55 ast_value_factory_owned_(false) { | 56 ast_value_factory_owned_(false) { |
56 Initialize(script->GetIsolate(), BASE, zone); | 57 Initialize(script->GetIsolate(), BASE, zone); |
57 } | 58 } |
58 | 59 |
59 | 60 |
| 61 CompilationInfo::CompilationInfo(Isolate* isolate, Zone* zone) |
| 62 : flags_(StrictModeField::encode(SLOPPY)), |
| 63 script_(Handle<Script>::null()), |
| 64 osr_ast_id_(BailoutId::None()), |
| 65 parameter_count_(0), |
| 66 this_has_uses_(true), |
| 67 optimization_id_(-1), |
| 68 ast_value_factory_(NULL), |
| 69 ast_value_factory_owned_(false) { |
| 70 Initialize(isolate, STUB, zone); |
| 71 } |
| 72 |
| 73 |
60 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, | 74 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, |
61 Zone* zone) | 75 Zone* zone) |
62 : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)), | 76 : flags_(StrictModeField::encode(SLOPPY) | IsLazy::encode(true)), |
63 shared_info_(shared_info), | 77 shared_info_(shared_info), |
64 script_(Handle<Script>(Script::cast(shared_info->script()))), | 78 script_(Handle<Script>(Script::cast(shared_info->script()))), |
65 osr_ast_id_(BailoutId::None()), | 79 osr_ast_id_(BailoutId::None()), |
66 parameter_count_(0), | 80 parameter_count_(0), |
67 this_has_uses_(true), | 81 this_has_uses_(true), |
68 optimization_id_(-1), | 82 optimization_id_(-1), |
69 ast_value_factory_(NULL), | 83 ast_value_factory_(NULL), |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 const int locals_limit = LUnallocated::kMaxFixedSlotIndex; | 361 const int locals_limit = LUnallocated::kMaxFixedSlotIndex; |
348 if (info()->is_osr() && | 362 if (info()->is_osr() && |
349 scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit) { | 363 scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit) { |
350 return AbortAndDisableOptimization(kTooManyParametersLocals); | 364 return AbortAndDisableOptimization(kTooManyParametersLocals); |
351 } | 365 } |
352 | 366 |
353 if (scope->HasIllegalRedeclaration()) { | 367 if (scope->HasIllegalRedeclaration()) { |
354 return AbortAndDisableOptimization(kFunctionWithIllegalRedeclaration); | 368 return AbortAndDisableOptimization(kFunctionWithIllegalRedeclaration); |
355 } | 369 } |
356 | 370 |
357 // Take --hydrogen-filter into account. | 371 // Check the whitelist for Crankshaft. |
358 if (!info()->closure()->PassesFilter(FLAG_hydrogen_filter)) { | 372 if (!info()->closure()->PassesFilter(FLAG_hydrogen_filter)) { |
359 return AbortOptimization(kHydrogenFilter); | 373 return AbortOptimization(kHydrogenFilter); |
360 } | 374 } |
361 | 375 |
| 376 // Crankshaft requires a version of fullcode with deoptimization support. |
362 // Recompile the unoptimized version of the code if the current version | 377 // Recompile the unoptimized version of the code if the current version |
363 // doesn't have deoptimization support. Alternatively, we may decide to | 378 // doesn't have deoptimization support already. |
364 // run the full code generator to get a baseline for the compile-time | 379 // Otherwise, if we are gathering compilation time and space statistics |
365 // performance of the hydrogen-based compiler. | 380 // for hydrogen, gather baseline statistics for a fullcode compilation. |
366 bool should_recompile = !info()->shared_info()->has_deoptimization_support(); | 381 bool should_recompile = !info()->shared_info()->has_deoptimization_support(); |
367 if (should_recompile || FLAG_hydrogen_stats) { | 382 if (should_recompile || FLAG_hydrogen_stats) { |
368 base::ElapsedTimer timer; | 383 base::ElapsedTimer timer; |
369 if (FLAG_hydrogen_stats) { | 384 if (FLAG_hydrogen_stats) { |
370 timer.Start(); | 385 timer.Start(); |
371 } | 386 } |
372 CompilationInfoWithZone unoptimized(info()->shared_info()); | 387 CompilationInfoWithZone unoptimized(info()->shared_info()); |
373 // Note that we use the same AST that we will use for generating the | 388 // Note that we use the same AST that we will use for generating the |
374 // optimized code. | 389 // optimized code. |
375 unoptimized.SetFunction(info()->function()); | 390 unoptimized.SetFunction(info()->function()); |
376 unoptimized.PrepareForCompilation(info()->scope()); | 391 unoptimized.PrepareForCompilation(info()->scope()); |
377 unoptimized.SetContext(info()->context()); | 392 unoptimized.SetContext(info()->context()); |
378 if (should_recompile) unoptimized.EnableDeoptimizationSupport(); | 393 if (should_recompile) unoptimized.EnableDeoptimizationSupport(); |
379 bool succeeded = FullCodeGenerator::MakeCode(&unoptimized); | 394 bool succeeded = FullCodeGenerator::MakeCode(&unoptimized); |
380 if (should_recompile) { | 395 if (should_recompile) { |
381 if (!succeeded) return SetLastStatus(FAILED); | 396 if (!succeeded) return SetLastStatus(FAILED); |
382 Handle<SharedFunctionInfo> shared = info()->shared_info(); | 397 Handle<SharedFunctionInfo> shared = info()->shared_info(); |
383 shared->EnableDeoptimizationSupport(*unoptimized.code()); | 398 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
384 // The existing unoptimized code was replaced with the new one. | 399 // The existing unoptimized code was replaced with the new one. |
385 Compiler::RecordFunctionCompilation( | 400 Compiler::RecordFunctionCompilation( |
386 Logger::LAZY_COMPILE_TAG, &unoptimized, shared); | 401 Logger::LAZY_COMPILE_TAG, &unoptimized, shared); |
387 } | 402 } |
388 if (FLAG_hydrogen_stats) { | 403 if (FLAG_hydrogen_stats) { |
389 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); | 404 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); |
390 } | 405 } |
391 } | 406 } |
392 | 407 |
393 // Check that the unoptimized, shared code is ready for | |
394 // optimizations. When using the always_opt flag we disregard the | |
395 // optimizable marker in the code object and optimize anyway. This | |
396 // is safe as long as the unoptimized code has deoptimization | |
397 // support. | |
398 ASSERT(FLAG_always_opt || info()->shared_info()->code()->optimizable()); | |
399 ASSERT(info()->shared_info()->has_deoptimization_support()); | 408 ASSERT(info()->shared_info()->has_deoptimization_support()); |
400 | 409 |
| 410 // Check the whitelist for TurboFan. |
| 411 if (info()->closure()->PassesFilter(FLAG_turbo_filter) && |
| 412 // TODO(turbofan): Make try-catch work and remove this bailout. |
| 413 info()->function()->dont_optimize_reason() != kTryCatchStatement && |
| 414 info()->function()->dont_optimize_reason() != kTryFinallyStatement && |
| 415 // TODO(turbofan): Make OSR work and remove this bailout. |
| 416 !info()->is_osr()) { |
| 417 compiler::Pipeline pipeline(info()); |
| 418 pipeline.GenerateCode(); |
| 419 return SetLastStatus(SUCCEEDED); |
| 420 } |
| 421 |
401 if (FLAG_trace_hydrogen) { | 422 if (FLAG_trace_hydrogen) { |
402 Handle<String> name = info()->function()->debug_name(); | 423 Handle<String> name = info()->function()->debug_name(); |
403 PrintF("-----------------------------------------------------------\n"); | 424 PrintF("-----------------------------------------------------------\n"); |
404 PrintF("Compiling method %s using hydrogen\n", name->ToCString().get()); | 425 PrintF("Compiling method %s using hydrogen\n", name->ToCString().get()); |
405 isolate()->GetHTracer()->TraceCompilation(info()); | 426 isolate()->GetHTracer()->TraceCompilation(info()); |
406 } | 427 } |
407 | 428 |
408 // Type-check the function. | 429 // Type-check the function. |
409 AstTyper::Run(info()); | 430 AstTyper::Run(info()); |
410 | 431 |
(...skipping 29 matching lines...) Expand all Loading... |
440 } | 461 } |
441 | 462 |
442 | 463 |
443 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { | 464 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { |
444 DisallowHeapAllocation no_allocation; | 465 DisallowHeapAllocation no_allocation; |
445 DisallowHandleAllocation no_handles; | 466 DisallowHandleAllocation no_handles; |
446 DisallowHandleDereference no_deref; | 467 DisallowHandleDereference no_deref; |
447 DisallowCodeDependencyChange no_dependency_change; | 468 DisallowCodeDependencyChange no_dependency_change; |
448 | 469 |
449 ASSERT(last_status() == SUCCEEDED); | 470 ASSERT(last_status() == SUCCEEDED); |
| 471 // TODO(turbofan): Currently everything is done in the first phase. |
| 472 if (!info()->code().is_null()) { |
| 473 return last_status(); |
| 474 } |
| 475 |
450 Timer t(this, &time_taken_to_optimize_); | 476 Timer t(this, &time_taken_to_optimize_); |
451 ASSERT(graph_ != NULL); | 477 ASSERT(graph_ != NULL); |
452 BailoutReason bailout_reason = kNoReason; | 478 BailoutReason bailout_reason = kNoReason; |
453 | 479 |
454 if (graph_->Optimize(&bailout_reason)) { | 480 if (graph_->Optimize(&bailout_reason)) { |
455 chunk_ = LChunk::NewChunk(graph_); | 481 chunk_ = LChunk::NewChunk(graph_); |
456 if (chunk_ != NULL) return SetLastStatus(SUCCEEDED); | 482 if (chunk_ != NULL) return SetLastStatus(SUCCEEDED); |
457 } else if (bailout_reason != kNoReason) { | 483 } else if (bailout_reason != kNoReason) { |
458 graph_builder_->Bailout(bailout_reason); | 484 graph_builder_->Bailout(bailout_reason); |
459 } | 485 } |
460 | 486 |
461 return AbortOptimization(); | 487 return AbortOptimization(); |
462 } | 488 } |
463 | 489 |
464 | 490 |
465 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { | 491 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { |
466 ASSERT(last_status() == SUCCEEDED); | 492 ASSERT(last_status() == SUCCEEDED); |
| 493 // TODO(turbofan): Currently everything is done in the first phase. |
| 494 if (!info()->code().is_null()) { |
| 495 RecordOptimizationStats(); |
| 496 return last_status(); |
| 497 } |
| 498 |
467 ASSERT(!info()->HasAbortedDueToDependencyChange()); | 499 ASSERT(!info()->HasAbortedDueToDependencyChange()); |
468 DisallowCodeDependencyChange no_dependency_change; | 500 DisallowCodeDependencyChange no_dependency_change; |
469 DisallowJavascriptExecution no_js(isolate()); | 501 DisallowJavascriptExecution no_js(isolate()); |
470 { // Scope for timer. | 502 { // Scope for timer. |
471 Timer timer(this, &time_taken_to_codegen_); | 503 Timer timer(this, &time_taken_to_codegen_); |
472 ASSERT(chunk_ != NULL); | 504 ASSERT(chunk_ != NULL); |
473 ASSERT(graph_ != NULL); | 505 ASSERT(graph_ != NULL); |
474 // Deferred handles reference objects that were accessible during | 506 // Deferred handles reference objects that were accessible during |
475 // graph creation. To make sure that we don't encounter inconsistencies | 507 // graph creation. To make sure that we don't encounter inconsistencies |
476 // between graph creation and code generation, we disallow accessing | 508 // between graph creation and code generation, we disallow accessing |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 } | 1140 } |
1109 } | 1141 } |
1110 return MaybeHandle<Code>(); | 1142 return MaybeHandle<Code>(); |
1111 } | 1143 } |
1112 | 1144 |
1113 | 1145 |
1114 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { | 1146 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { |
1115 Handle<Code> code = info->code(); | 1147 Handle<Code> code = info->code(); |
1116 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. | 1148 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. |
1117 | 1149 |
| 1150 // Context specialization folds-in the context, so no sharing can occur. |
| 1151 if (code->is_turbofanned() && FLAG_context_specialization) return; |
| 1152 |
1118 // Cache optimized code. | 1153 // Cache optimized code. |
1119 if (FLAG_cache_optimized_code) { | 1154 if (FLAG_cache_optimized_code) { |
1120 Handle<JSFunction> function = info->closure(); | 1155 Handle<JSFunction> function = info->closure(); |
1121 Handle<SharedFunctionInfo> shared(function->shared()); | 1156 Handle<SharedFunctionInfo> shared(function->shared()); |
1122 // Do not cache bound functions. | 1157 // Do not cache bound functions. |
1123 if (shared->bound()) return; | 1158 if (shared->bound()) return; |
1124 Handle<FixedArray> literals(function->literals()); | 1159 Handle<FixedArray> literals(function->literals()); |
1125 Handle<Context> native_context(function->context()->native_context()); | 1160 Handle<Context> native_context(function->context()->native_context()); |
1126 SharedFunctionInfo::AddToOptimizedCodeMap( | 1161 SharedFunctionInfo::AddToOptimizedCodeMap( |
1127 shared, native_context, code, literals, info->osr_ast_id()); | 1162 shared, native_context, code, literals, info->osr_ast_id()); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1345 AllowHandleDereference allow_deref; | 1380 AllowHandleDereference allow_deref; |
1346 bool tracing_on = info()->IsStub() | 1381 bool tracing_on = info()->IsStub() |
1347 ? FLAG_trace_hydrogen_stubs | 1382 ? FLAG_trace_hydrogen_stubs |
1348 : (FLAG_trace_hydrogen && | 1383 : (FLAG_trace_hydrogen && |
1349 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1384 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
1350 return (tracing_on && | 1385 return (tracing_on && |
1351 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1386 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
1352 } | 1387 } |
1353 | 1388 |
1354 } } // namespace v8::internal | 1389 } } // namespace v8::internal |
OLD | NEW |