| 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/compiler.h" | 5 #include "src/compiler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/asmjs/asm-js.h" | 10 #include "src/asmjs/asm-js.h" |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 } | 245 } |
| 246 code->set_can_have_weak_objects(true); | 246 code->set_can_have_weak_objects(true); |
| 247 } | 247 } |
| 248 | 248 |
| 249 // ---------------------------------------------------------------------------- | 249 // ---------------------------------------------------------------------------- |
| 250 // Local helper methods that make up the compilation pipeline. | 250 // Local helper methods that make up the compilation pipeline. |
| 251 | 251 |
| 252 namespace { | 252 namespace { |
| 253 | 253 |
| 254 bool Parse(ParseInfo* info) { | 254 bool Parse(ParseInfo* info) { |
| 255 // Create a canonical handle scope if compiling ignition bytecode. This is | 255 // Create a canonical handle scope for compiling Ignition bytecode. This is |
| 256 // required by the constant array builder to de-duplicate objects without | 256 // required by the constant array builder to de-duplicate objects without |
| 257 // dereferencing handles. | 257 // dereferencing handles. |
| 258 std::unique_ptr<CanonicalHandleScope> canonical; | 258 CanonicalHandleScope canonical(info->isolate()); |
| 259 if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(info->isolate())); | |
| 260 | 259 |
| 261 return Parser::ParseStatic(info); | 260 return Parser::ParseStatic(info); |
| 262 } | 261 } |
| 263 | 262 |
| 264 void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, | 263 void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, |
| 265 CompilationInfo* info) { | 264 CompilationInfo* info) { |
| 266 // Log the code generation. If source information is available include | 265 // Log the code generation. If source information is available include |
| 267 // script name and line number. Check explicitly whether logging is | 266 // script name and line number. Check explicitly whether logging is |
| 268 // enabled as finding the line number is not free. | 267 // enabled as finding the line number is not free. |
| 269 if (info->isolate()->logger()->is_logging_code_events() || | 268 if (info->isolate()->logger()->is_logging_code_events() || |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 info->isolate(), info->literal()->feedback_vector_spec()); | 306 info->isolate(), info->literal()->feedback_vector_spec()); |
| 308 info->shared_info()->set_feedback_metadata(*feedback_metadata); | 307 info->shared_info()->set_feedback_metadata(*feedback_metadata); |
| 309 } | 308 } |
| 310 | 309 |
| 311 // It's very important that recompiles do not alter the structure of the type | 310 // It's very important that recompiles do not alter the structure of the type |
| 312 // feedback vector. Verify that the structure fits the function literal. | 311 // feedback vector. Verify that the structure fits the function literal. |
| 313 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( | 312 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( |
| 314 info->literal()->feedback_vector_spec())); | 313 info->literal()->feedback_vector_spec())); |
| 315 } | 314 } |
| 316 | 315 |
| 316 bool UseTurboFan(Handle<SharedFunctionInfo> shared) { |
| 317 bool optimization_disabled = shared->optimization_disabled(); |
| 318 bool dont_crankshaft = shared->dont_crankshaft(); |
| 319 |
| 320 // Check the enabling conditions for Turbofan. |
| 321 // 1. "use asm" code. |
| 322 bool is_turbofanable_asm = |
| 323 FLAG_turbo_asm && shared->asm_function() && !optimization_disabled; |
| 324 |
| 325 // 2. Fallback for features unsupported by Crankshaft. |
| 326 bool is_unsupported_by_crankshaft_but_turbofanable = |
| 327 dont_crankshaft && strcmp(FLAG_turbo_filter, "~~") == 0 && |
| 328 !optimization_disabled; |
| 329 |
| 330 // 3. Explicitly enabled by the command-line filter. |
| 331 bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter); |
| 332 |
| 333 return is_turbofanable_asm || is_unsupported_by_crankshaft_but_turbofanable || |
| 334 passes_turbo_filter; |
| 335 } |
| 336 |
| 317 bool ShouldUseIgnition(CompilationInfo* info) { | 337 bool ShouldUseIgnition(CompilationInfo* info) { |
| 318 if (!FLAG_ignition) return false; | 338 DCHECK(info->has_shared_info()); |
| 319 | 339 |
| 320 DCHECK(info->has_shared_info()); | 340 // Skip Ignition for asm.js functions. |
| 341 if (info->shared_info()->asm_function()) { |
| 342 return false; |
| 343 } |
| 321 | 344 |
| 322 // When requesting debug code as a replacement for existing code, we provide | 345 // When requesting debug code as a replacement for existing code, we provide |
| 323 // the same kind as the existing code (to prevent implicit tier-change). | 346 // the same kind as the existing code (to prevent implicit tier-change). |
| 324 if (info->is_debug() && info->shared_info()->is_compiled()) { | 347 if (info->is_debug() && info->shared_info()->is_compiled()) { |
| 325 return !info->shared_info()->HasBaselineCode(); | 348 return !info->shared_info()->HasBaselineCode(); |
| 326 } | 349 } |
| 327 | 350 |
| 328 // Since we can't OSR from Ignition, skip Ignition for asm.js functions. | 351 // Code destined for TurboFan should be compiled with Ignition first. |
| 329 if (info->shared_info()->asm_function()) { | 352 if (UseTurboFan(info->shared_info())) return true; |
| 330 return false; | 353 |
| 331 } | 354 // Only use Ignition for any other function if FLAG_ignition is true. |
| 355 if (!FLAG_ignition) return false; |
| 332 | 356 |
| 333 // Checks whether top level functions should be passed by the filter. | 357 // Checks whether top level functions should be passed by the filter. |
| 334 if (info->shared_info()->is_toplevel()) { | 358 if (info->shared_info()->is_toplevel()) { |
| 335 Vector<const char> filter = CStrVector(FLAG_ignition_filter); | 359 Vector<const char> filter = CStrVector(FLAG_ignition_filter); |
| 336 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | 360 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); |
| 337 } | 361 } |
| 338 | 362 |
| 339 // Finally respect the filter. | 363 // Finally respect the filter. |
| 340 return info->shared_info()->PassesFilter(FLAG_ignition_filter); | 364 return info->shared_info()->PassesFilter(FLAG_ignition_filter); |
| 341 } | 365 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 // Cache optimized context-specific code. | 509 // Cache optimized context-specific code. |
| 486 Handle<JSFunction> function = info->closure(); | 510 Handle<JSFunction> function = info->closure(); |
| 487 Handle<SharedFunctionInfo> shared(function->shared()); | 511 Handle<SharedFunctionInfo> shared(function->shared()); |
| 488 Handle<LiteralsArray> literals(function->literals()); | 512 Handle<LiteralsArray> literals(function->literals()); |
| 489 Handle<Context> native_context(function->context()->native_context()); | 513 Handle<Context> native_context(function->context()->native_context()); |
| 490 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 514 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
| 491 literals, info->osr_ast_id()); | 515 literals, info->osr_ast_id()); |
| 492 } | 516 } |
| 493 | 517 |
| 494 bool Renumber(ParseInfo* parse_info) { | 518 bool Renumber(ParseInfo* parse_info) { |
| 495 // Create a canonical handle scope if compiling ignition bytecode. This is | 519 // Create a canonical handle scope for compiling Ignition bytecode. This is |
| 496 // required by the constant array builder to de-duplicate objects without | 520 // required by the constant array builder to de-duplicate objects without |
| 497 // dereferencing handles. | 521 // dereferencing handles. |
| 498 std::unique_ptr<CanonicalHandleScope> canonical; | 522 CanonicalHandleScope canonical(parse_info->isolate()); |
| 499 if (FLAG_ignition) { | |
| 500 canonical.reset(new CanonicalHandleScope(parse_info->isolate())); | |
| 501 } | |
| 502 | 523 |
| 503 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), | 524 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), |
| 504 parse_info->literal())) { | 525 parse_info->literal())) { |
| 505 return false; | 526 return false; |
| 506 } | 527 } |
| 507 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | 528 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
| 508 if (!shared_info.is_null()) { | 529 if (!shared_info.is_null()) { |
| 509 FunctionLiteral* lit = parse_info->literal(); | 530 FunctionLiteral* lit = parse_info->literal(); |
| 510 shared_info->set_ast_node_count(lit->ast_node_count()); | 531 shared_info->set_ast_node_count(lit->ast_node_count()); |
| 511 if (lit->dont_optimize_reason() != kNoReason) { | 532 if (lit->dont_optimize_reason() != kNoReason) { |
| 512 shared_info->DisableOptimization(lit->dont_optimize_reason()); | 533 shared_info->DisableOptimization(lit->dont_optimize_reason()); |
| 513 } | 534 } |
| 514 if (lit->flags() & AstProperties::kDontCrankshaft) { | 535 if (lit->flags() & AstProperties::kDontCrankshaft) { |
| 515 shared_info->set_dont_crankshaft(true); | 536 shared_info->set_dont_crankshaft(true); |
| 516 } | 537 } |
| 517 } | 538 } |
| 518 return true; | 539 return true; |
| 519 } | 540 } |
| 520 | 541 |
| 521 bool UseTurboFan(Handle<SharedFunctionInfo> shared) { | |
| 522 bool optimization_disabled = shared->optimization_disabled(); | |
| 523 bool dont_crankshaft = shared->dont_crankshaft(); | |
| 524 | |
| 525 // Check the enabling conditions for Turbofan. | |
| 526 // 1. "use asm" code. | |
| 527 bool is_turbofanable_asm = | |
| 528 FLAG_turbo_asm && shared->asm_function() && !optimization_disabled; | |
| 529 | |
| 530 // 2. Fallback for features unsupported by Crankshaft. | |
| 531 bool is_unsupported_by_crankshaft_but_turbofanable = | |
| 532 dont_crankshaft && strcmp(FLAG_turbo_filter, "~~") == 0 && | |
| 533 !optimization_disabled; | |
| 534 | |
| 535 // 3. Explicitly enabled by the command-line filter. | |
| 536 bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter); | |
| 537 | |
| 538 return is_turbofanable_asm || is_unsupported_by_crankshaft_but_turbofanable || | |
| 539 passes_turbo_filter; | |
| 540 } | |
| 541 | |
| 542 bool GetOptimizedCodeNow(CompilationJob* job) { | 542 bool GetOptimizedCodeNow(CompilationJob* job) { |
| 543 CompilationInfo* info = job->info(); | 543 CompilationInfo* info = job->info(); |
| 544 Isolate* isolate = info->isolate(); | 544 Isolate* isolate = info->isolate(); |
| 545 | 545 |
| 546 // Parsing is not required when optimizing from existing bytecode. | 546 // Parsing is not required when optimizing from existing bytecode. |
| 547 if (!info->is_optimizing_from_bytecode()) { | 547 if (!info->is_optimizing_from_bytecode()) { |
| 548 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; | 548 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
| 549 EnsureFeedbackMetadata(info); | 549 EnsureFeedbackMetadata(info); |
| 550 } | 550 } |
| 551 | 551 |
| (...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1812 DCHECK(shared->is_compiled()); | 1812 DCHECK(shared->is_compiled()); |
| 1813 function->set_literals(cached.literals); | 1813 function->set_literals(cached.literals); |
| 1814 } else if (shared->is_compiled()) { | 1814 } else if (shared->is_compiled()) { |
| 1815 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1815 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1816 JSFunction::EnsureLiterals(function); | 1816 JSFunction::EnsureLiterals(function); |
| 1817 } | 1817 } |
| 1818 } | 1818 } |
| 1819 | 1819 |
| 1820 } // namespace internal | 1820 } // namespace internal |
| 1821 } // namespace v8 | 1821 } // namespace v8 |
| OLD | NEW |