| 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 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 if (shared->is_compiled()) continue; | 540 if (shared->is_compiled()) continue; |
| 541 | 541 |
| 542 // The {literal} has already been numbered because AstNumbering decends into | 542 // The {literal} has already been numbered because AstNumbering decends into |
| 543 // eagerly compiled function literals. | 543 // eagerly compiled function literals. |
| 544 SetSharedFunctionFlagsFromLiteral(literal, shared); | 544 SetSharedFunctionFlagsFromLiteral(literal, shared); |
| 545 | 545 |
| 546 // Try to enqueue the eager function on the compiler dispatcher. | 546 // Try to enqueue the eager function on the compiler dispatcher. |
| 547 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); | 547 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); |
| 548 if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(), | 548 if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(), |
| 549 shared, is_debug, will_serialize) && | 549 shared, is_debug, will_serialize) && |
| 550 dispatcher->EnqueueAndStep(shared, literal, parse_zone, | 550 dispatcher->EnqueueAndStep(outer_info->script(), shared, literal, |
| 551 parse_zone, |
| 551 outer_info->parse_info()->deferred_handles(), | 552 outer_info->parse_info()->deferred_handles(), |
| 552 outer_info->deferred_handles())) { | 553 outer_info->deferred_handles())) { |
| 553 // If we have successfully queued up the function for compilation on the | 554 // If we have successfully queued up the function for compilation on the |
| 554 // compiler dispatcher then we are done. | 555 // compiler dispatcher then we are done. |
| 555 continue; | 556 continue; |
| 556 } else { | 557 } else { |
| 557 // Otherwise generate unoptimized code now. | 558 // Otherwise generate unoptimized code now. |
| 558 ParseInfo parse_info(script); | 559 ParseInfo parse_info(script); |
| 559 CompilationInfo info(parse_info.zone(), &parse_info, | 560 CompilationInfo info(parse_info.zone(), &parse_info, |
| 560 Handle<JSFunction>::null()); | 561 Handle<JSFunction>::null()); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 parse_zone->Seal(); | 623 parse_zone->Seal(); |
| 623 } | 624 } |
| 624 | 625 |
| 625 if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode, | 626 if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode, |
| 626 parse_zone, info) || | 627 parse_zone, info) || |
| 627 !GenerateUnoptimizedCode(info)) { | 628 !GenerateUnoptimizedCode(info)) { |
| 628 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 629 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 629 return false; | 630 return false; |
| 630 } | 631 } |
| 631 | 632 |
| 632 // TODO(rmcilroy): Remove this once the enqueued tasks can keep the parsed | |
| 633 // zone and handles alive and replace with a check in CompileLazy to finish | |
| 634 // the task itself. | |
| 635 RuntimeCallTimerScope runtimeTimer( | |
| 636 isolate, &RuntimeCallStats::CompileWaitForDispatcher); | |
| 637 if (isolate->compiler_dispatcher()->IsEnabled() && | |
| 638 !isolate->compiler_dispatcher()->FinishAllNow()) { | |
| 639 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
| 640 return false; | |
| 641 } | |
| 642 | |
| 643 return true; | 633 return true; |
| 644 } | 634 } |
| 645 | 635 |
| 646 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { | 636 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { |
| 647 DCHECK(info->is_toplevel()); | 637 DCHECK(info->is_toplevel()); |
| 648 DCHECK(!info->script().is_null()); | 638 DCHECK(!info->script().is_null()); |
| 649 if (info->script()->shared_function_infos()->length() > 0) { | 639 if (info->script()->shared_function_infos()->length() > 0) { |
| 650 DCHECK_EQ(info->script()->shared_function_infos()->length(), | 640 DCHECK_EQ(info->script()->shared_function_infos()->length(), |
| 651 info->max_function_literal_id() + 1); | 641 info->max_function_literal_id() + 1); |
| 652 return; | 642 return; |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 DCHECK_NOT_NULL(info->literal()); | 1241 DCHECK_NOT_NULL(info->literal()); |
| 1252 DCHECK_NOT_NULL(info->scope()); | 1242 DCHECK_NOT_NULL(info->scope()); |
| 1253 return true; | 1243 return true; |
| 1254 } | 1244 } |
| 1255 | 1245 |
| 1256 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | 1246 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
| 1257 if (function->is_compiled()) return true; | 1247 if (function->is_compiled()) return true; |
| 1258 Isolate* isolate = function->GetIsolate(); | 1248 Isolate* isolate = function->GetIsolate(); |
| 1259 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1249 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1260 | 1250 |
| 1261 // Start a compilation. | 1251 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); |
| 1252 Handle<SharedFunctionInfo> shared(function->shared(), isolate); |
| 1262 Handle<Code> code; | 1253 Handle<Code> code; |
| 1263 if (!GetLazyCode(function).ToHandle(&code)) { | 1254 if (dispatcher->IsEnqueued(shared)) { |
| 1264 if (flag == CLEAR_EXCEPTION) { | 1255 if (!dispatcher->FinishNow(shared)) { |
| 1265 isolate->clear_pending_exception(); | 1256 if (flag == CLEAR_EXCEPTION) { |
| 1257 isolate->clear_pending_exception(); |
| 1258 } |
| 1259 return false; |
| 1266 } | 1260 } |
| 1267 return false; | 1261 code = handle(shared->code(), isolate); |
| 1262 } else { |
| 1263 // Start a compilation. |
| 1264 if (!GetLazyCode(function).ToHandle(&code)) { |
| 1265 if (flag == CLEAR_EXCEPTION) { |
| 1266 isolate->clear_pending_exception(); |
| 1267 } |
| 1268 return false; |
| 1269 } |
| 1268 } | 1270 } |
| 1269 | 1271 |
| 1270 // Install code on closure. | 1272 // Install code on closure. |
| 1271 function->ReplaceCode(*code); | 1273 function->ReplaceCode(*code); |
| 1272 JSFunction::EnsureLiterals(function); | 1274 JSFunction::EnsureLiterals(function); |
| 1273 | 1275 |
| 1274 // Check postconditions on success. | 1276 // Check postconditions on success. |
| 1275 DCHECK(!isolate->has_pending_exception()); | 1277 DCHECK(!isolate->has_pending_exception()); |
| 1276 DCHECK(function->shared()->is_compiled()); | 1278 DCHECK(function->shared()->is_compiled()); |
| 1277 DCHECK(function->is_compiled()); | 1279 DCHECK(function->is_compiled()); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 // Restore the original function info list in order to remain side-effect | 1382 // Restore the original function info list in order to remain side-effect |
| 1381 // free as much as possible, since some code expects the old shared function | 1383 // free as much as possible, since some code expects the old shared function |
| 1382 // infos to stick around. | 1384 // infos to stick around. |
| 1383 script->set_shared_function_infos(*old_function_infos); | 1385 script->set_shared_function_infos(*old_function_infos); |
| 1384 | 1386 |
| 1385 return infos; | 1387 return infos; |
| 1386 } | 1388 } |
| 1387 | 1389 |
| 1388 bool Compiler::EnsureBytecode(CompilationInfo* info) { | 1390 bool Compiler::EnsureBytecode(CompilationInfo* info) { |
| 1389 if (!info->shared_info()->is_compiled()) { | 1391 if (!info->shared_info()->is_compiled()) { |
| 1390 if (GetUnoptimizedCode(info, Compiler::NOT_CONCURRENT).is_null()) { | 1392 CompilerDispatcher* dispatcher = info->isolate()->compiler_dispatcher(); |
| 1393 if (dispatcher->IsEnqueued(info->shared_info())) { |
| 1394 if (!dispatcher->FinishNow(info->shared_info())) return false; |
| 1395 } else if (GetUnoptimizedCode(info, Compiler::NOT_CONCURRENT).is_null()) { |
| 1391 return false; | 1396 return false; |
| 1392 } | 1397 } |
| 1393 } | 1398 } |
| 1394 DCHECK(info->shared_info()->is_compiled()); | 1399 DCHECK(info->shared_info()->is_compiled()); |
| 1395 | 1400 |
| 1396 if (info->shared_info()->HasAsmWasmData()) return false; | 1401 if (info->shared_info()->HasAsmWasmData()) return false; |
| 1397 | 1402 |
| 1398 DCHECK_EQ(ShouldUseIgnition(info), info->shared_info()->HasBytecodeArray()); | 1403 DCHECK_EQ(ShouldUseIgnition(info), info->shared_info()->HasBytecodeArray()); |
| 1399 return info->shared_info()->HasBytecodeArray(); | 1404 return info->shared_info()->HasBytecodeArray(); |
| 1400 } | 1405 } |
| 1401 | 1406 |
| 1402 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1407 // TODO(turbofan): In the future, unoptimized code with deopt support could |
| 1403 // be generated lazily once deopt is triggered. | 1408 // be generated lazily once deopt is triggered. |
| 1404 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1409 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
| 1405 DCHECK_NOT_NULL(info->literal()); | 1410 DCHECK_NOT_NULL(info->literal()); |
| 1406 DCHECK_NOT_NULL(info->scope()); | 1411 DCHECK_NOT_NULL(info->scope()); |
| 1407 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1412 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 1413 |
| 1414 CompilerDispatcher* dispatcher = info->isolate()->compiler_dispatcher(); |
| 1415 if (dispatcher->IsEnqueued(shared)) { |
| 1416 if (!dispatcher->FinishNow(shared)) return false; |
| 1417 } |
| 1418 |
| 1408 if (!shared->has_deoptimization_support()) { | 1419 if (!shared->has_deoptimization_support()) { |
| 1409 Zone compile_zone(info->isolate()->allocator(), ZONE_NAME); | 1420 Zone compile_zone(info->isolate()->allocator(), ZONE_NAME); |
| 1410 CompilationInfo unoptimized(&compile_zone, info->parse_info(), | 1421 CompilationInfo unoptimized(&compile_zone, info->parse_info(), |
| 1411 info->closure()); | 1422 info->closure()); |
| 1412 unoptimized.EnableDeoptimizationSupport(); | 1423 unoptimized.EnableDeoptimizationSupport(); |
| 1413 | 1424 |
| 1414 // Don't generate full-codegen code for functions it can't support. | 1425 // Don't generate full-codegen code for functions it can't support. |
| 1415 if (shared->must_use_ignition_turbo()) return false; | 1426 if (shared->must_use_ignition_turbo()) return false; |
| 1416 DCHECK(!IsResumableFunction(shared->kind())); | 1427 DCHECK(!IsResumableFunction(shared->kind())); |
| 1417 | 1428 |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1911 } | 1922 } |
| 1912 | 1923 |
| 1913 if (shared->is_compiled()) { | 1924 if (shared->is_compiled()) { |
| 1914 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1925 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1915 JSFunction::EnsureLiterals(function); | 1926 JSFunction::EnsureLiterals(function); |
| 1916 } | 1927 } |
| 1917 } | 1928 } |
| 1918 | 1929 |
| 1919 } // namespace internal | 1930 } // namespace internal |
| 1920 } // namespace v8 | 1931 } // namespace v8 |
| OLD | NEW |