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" |
11 #include "src/asmjs/asm-typer.h" | 11 #include "src/asmjs/asm-typer.h" |
12 #include "src/ast/ast-numbering.h" | 12 #include "src/ast/ast-numbering.h" |
13 #include "src/ast/prettyprinter.h" | 13 #include "src/ast/prettyprinter.h" |
14 #include "src/ast/scopes.h" | 14 #include "src/ast/scopes.h" |
15 #include "src/bootstrapper.h" | 15 #include "src/bootstrapper.h" |
16 #include "src/codegen.h" | 16 #include "src/codegen.h" |
17 #include "src/compilation-cache.h" | 17 #include "src/compilation-cache.h" |
18 #include "src/compiler-dispatcher/compiler-dispatcher.h" | |
19 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" | 18 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" |
20 #include "src/compiler/pipeline.h" | 19 #include "src/compiler/pipeline.h" |
21 #include "src/crankshaft/hydrogen.h" | 20 #include "src/crankshaft/hydrogen.h" |
22 #include "src/debug/debug.h" | 21 #include "src/debug/debug.h" |
23 #include "src/debug/liveedit.h" | 22 #include "src/debug/liveedit.h" |
24 #include "src/frames-inl.h" | 23 #include "src/frames-inl.h" |
25 #include "src/full-codegen/full-codegen.h" | 24 #include "src/full-codegen/full-codegen.h" |
26 #include "src/globals.h" | 25 #include "src/globals.h" |
27 #include "src/heap/heap.h" | 26 #include "src/heap/heap.h" |
28 #include "src/interpreter/interpreter.h" | 27 #include "src/interpreter/interpreter.h" |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 // Checks whether top level functions should be passed by the filter. | 368 // Checks whether top level functions should be passed by the filter. |
370 if (shared->is_toplevel()) { | 369 if (shared->is_toplevel()) { |
371 Vector<const char> filter = CStrVector(FLAG_ignition_filter); | 370 Vector<const char> filter = CStrVector(FLAG_ignition_filter); |
372 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | 371 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); |
373 } | 372 } |
374 | 373 |
375 // Finally respect the filter. | 374 // Finally respect the filter. |
376 return shared->PassesFilter(FLAG_ignition_filter); | 375 return shared->PassesFilter(FLAG_ignition_filter); |
377 } | 376 } |
378 | 377 |
379 bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info, | |
380 bool is_debug) { | |
381 return FLAG_validate_asm && scope->asm_module() && | |
382 !shared_info->is_asm_wasm_broken() && !is_debug; | |
383 } | |
384 | |
385 bool UseCompilerDispatcher(CompilerDispatcher* dispatcher, | |
386 DeclarationScope* scope, | |
387 Handle<SharedFunctionInfo> shared_info, | |
388 bool is_debug, bool will_serialize) { | |
389 return dispatcher->IsEnabled() && !is_debug && !will_serialize && | |
390 !UseAsmWasm(scope, shared_info, is_debug); | |
391 } | |
392 | |
393 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { | 378 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { |
394 // Function should have been parsed and analyzed before creating a compilation | 379 // Function should have been parsed and analyzed before creating a compilation |
395 // job. | 380 // job. |
396 DCHECK_NOT_NULL(info->literal()); | 381 DCHECK_NOT_NULL(info->literal()); |
397 DCHECK_NOT_NULL(info->scope()); | 382 DCHECK_NOT_NULL(info->scope()); |
398 | 383 |
399 if (ShouldUseIgnition(info)) { | 384 if (ShouldUseIgnition(info)) { |
400 return interpreter::Interpreter::NewCompilationJob(info); | 385 return interpreter::Interpreter::NewCompilationJob(info); |
401 } else { | 386 } else { |
402 return FullCodeGenerator::NewCompilationJob(info); | 387 return FullCodeGenerator::NewCompilationJob(info); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 // Update the shared function info with the scope info. | 420 // Update the shared function info with the scope info. |
436 InstallSharedScopeInfo(info, shared); | 421 InstallSharedScopeInfo(info, shared); |
437 | 422 |
438 // Install compilation result on the shared function info | 423 // Install compilation result on the shared function info |
439 InstallSharedCompilationResult(info, shared); | 424 InstallSharedCompilationResult(info, shared); |
440 } | 425 } |
441 | 426 |
442 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { | 427 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { |
443 CompilationJob::Status status = job->FinalizeJob(); | 428 CompilationJob::Status status = job->FinalizeJob(); |
444 if (status == CompilationJob::SUCCEEDED) { | 429 if (status == CompilationJob::SUCCEEDED) { |
445 CompilationInfo* info = job->info(); | 430 EnsureFeedbackMetadata(job->info()); |
446 EnsureFeedbackMetadata(info); | 431 InstallUnoptimizedCode(job->info()); |
447 DCHECK(!info->code().is_null()); | |
448 if (info->parse_info()->literal()->should_be_used_once_hint()) { | |
449 info->code()->MarkToBeExecutedOnce(info->isolate()); | |
450 } | |
451 InstallUnoptimizedCode(info); | |
452 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, info); | |
453 job->RecordUnoptimizedCompilationStats(); | 432 job->RecordUnoptimizedCompilationStats(); |
454 } | 433 } |
455 return status; | 434 return status; |
456 } | 435 } |
457 | 436 |
458 bool Renumber(Isolate* isolate, Zone* zone, FunctionLiteral* literal, | 437 bool Renumber(ParseInfo* parse_info, |
459 Handle<SharedFunctionInfo> shared_info, | |
460 Compiler::EagerInnerFunctionLiterals* eager_literals) { | 438 Compiler::EagerInnerFunctionLiterals* eager_literals) { |
461 RuntimeCallTimerScope runtimeTimer(isolate, | 439 RuntimeCallTimerScope runtimeTimer(parse_info->isolate(), |
462 &RuntimeCallStats::CompileRenumber); | 440 &RuntimeCallStats::CompileRenumber); |
463 if (!AstNumbering::Renumber(isolate->stack_guard()->real_climit(), zone, | 441 if (!AstNumbering::Renumber( |
464 literal, eager_literals)) { | 442 parse_info->isolate()->stack_guard()->real_climit(), |
| 443 parse_info->zone(), parse_info->literal(), eager_literals)) { |
465 return false; | 444 return false; |
466 } | 445 } |
| 446 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
467 if (!shared_info.is_null()) { | 447 if (!shared_info.is_null()) { |
468 shared_info->set_ast_node_count(literal->ast_node_count()); | 448 FunctionLiteral* lit = parse_info->literal(); |
469 if (literal->dont_optimize_reason() != kNoReason) { | 449 shared_info->set_ast_node_count(lit->ast_node_count()); |
470 shared_info->DisableOptimization(literal->dont_optimize_reason()); | 450 if (lit->dont_optimize_reason() != kNoReason) { |
| 451 shared_info->DisableOptimization(lit->dont_optimize_reason()); |
471 } | 452 } |
472 if (literal->flags() & AstProperties::kMustUseIgnitionTurbo) { | 453 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) { |
473 shared_info->set_must_use_ignition_turbo(true); | 454 shared_info->set_must_use_ignition_turbo(true); |
474 } | 455 } |
475 } | 456 } |
476 return true; | 457 return true; |
477 } | 458 } |
478 | 459 |
479 bool GenerateUnoptimizedCode(CompilationInfo* info) { | 460 bool GenerateUnoptimizedCode(CompilationInfo* info) { |
480 if (UseAsmWasm(info->scope(), info->shared_info(), info->is_debug())) { | 461 if (FLAG_validate_asm && info->scope()->asm_module() && |
| 462 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) { |
481 EnsureFeedbackMetadata(info); | 463 EnsureFeedbackMetadata(info); |
482 MaybeHandle<FixedArray> wasm_data; | 464 MaybeHandle<FixedArray> wasm_data; |
483 wasm_data = AsmJs::CompileAsmViaWasm(info); | 465 wasm_data = AsmJs::CompileAsmViaWasm(info); |
484 if (!wasm_data.is_null()) { | 466 if (!wasm_data.is_null()) { |
485 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | 467 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); |
486 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | 468 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); |
487 InstallUnoptimizedCode(info); | 469 InstallUnoptimizedCode(info); |
488 return true; | 470 return true; |
489 } | 471 } |
490 } | 472 } |
491 | 473 |
492 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); | 474 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
493 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; | 475 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; |
494 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; | 476 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; |
495 if (FinalizeUnoptimizedCompilationJob(job.get()) != | 477 if (FinalizeUnoptimizedCompilationJob(job.get()) != |
496 CompilationJob::SUCCEEDED) { | 478 CompilationJob::SUCCEEDED) { |
497 return false; | 479 return false; |
498 } | 480 } |
499 return true; | 481 return true; |
500 } | 482 } |
501 | 483 |
502 bool CompileUnoptimizedInnerFunctionsRecursively( | 484 bool CompileUnoptimizedInnerFunctionsRecursively( |
503 ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals, | 485 ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals, |
504 CompilationInfo* outer_info) { | 486 CompilationInfo* outer_info) { |
505 Isolate* isolate = outer_info->isolate(); | 487 Isolate* isolate = outer_info->isolate(); |
506 Handle<Script> script = outer_info->script(); | 488 Handle<Script> script = outer_info->script(); |
507 bool is_debug = outer_info->is_debug(); | |
508 bool will_serialize = outer_info->will_serialize(); | |
509 RuntimeCallTimerScope runtimeTimer(isolate, | 489 RuntimeCallTimerScope runtimeTimer(isolate, |
510 &RuntimeCallStats::CompileInnerFunction); | 490 &RuntimeCallStats::CompileInnerFunction); |
511 | 491 |
512 for (auto it : *literals) { | 492 for (auto it : *literals) { |
513 FunctionLiteral* literal = it->value(); | 493 FunctionLiteral* literal = it->value(); |
514 Handle<SharedFunctionInfo> shared = | 494 |
515 Compiler::GetSharedFunctionInfo(literal, script, outer_info); | 495 // Find any previously allocated shared function info for the given literal. |
516 if (shared->is_compiled()) continue; | 496 Handle<SharedFunctionInfo> shared; |
| 497 MaybeHandle<SharedFunctionInfo> maybe_existing = |
| 498 script->FindSharedFunctionInfo(isolate, literal); |
| 499 if (maybe_existing.ToHandle(&shared)) { |
| 500 DCHECK(!shared->is_toplevel()); |
| 501 // If we found an existing shared function info with compiled code, |
| 502 // we are done. |
| 503 if (shared->is_compiled()) continue; |
| 504 } else { |
| 505 shared = |
| 506 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script); |
| 507 shared->set_is_toplevel(false); |
| 508 } |
| 509 |
| 510 Zone zone(isolate->allocator(), ZONE_NAME); |
| 511 ParseInfo parse_info(&zone, script); |
| 512 parse_info.set_literal(literal); |
| 513 parse_info.set_shared_info(shared); |
| 514 parse_info.set_function_literal_id(shared->function_literal_id()); |
| 515 parse_info.set_language_mode(literal->scope()->language_mode()); |
| 516 parse_info.set_ast_value_factory( |
| 517 outer_info->parse_info()->ast_value_factory()); |
| 518 parse_info.set_ast_value_factory_owned(false); |
| 519 |
| 520 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
| 521 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
| 522 if (outer_info->is_debug()) info.MarkAsDebug(); |
| 523 |
517 Compiler::EagerInnerFunctionLiterals inner_literals; | 524 Compiler::EagerInnerFunctionLiterals inner_literals; |
518 if (!Renumber(isolate, outer_info->zone(), literal, shared, | 525 if (!Renumber(&parse_info, &inner_literals) || |
519 &inner_literals) || | |
520 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, | 526 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, |
521 outer_info)) { | 527 outer_info) || |
| 528 !GenerateUnoptimizedCode(&info)) { |
522 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 529 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
523 return false; | 530 return false; |
524 } | 531 } |
525 | 532 |
526 // Try to enqueue the eager function on the compiler dispatcher. | 533 DCHECK(!info.code().is_null()); |
527 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); | 534 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); |
528 if (UseCompilerDispatcher(dispatcher, literal->scope(), shared, is_debug, | 535 if (literal->should_be_used_once_hint()) { |
529 will_serialize) && | 536 info.code()->MarkToBeExecutedOnce(isolate); |
530 dispatcher->EnqueueAndStep(shared, literal)) { | |
531 // If we have successfully queued up the function for compilation on the | |
532 // compiler dispatcher then we are done. | |
533 continue; | |
534 } else { | |
535 // Otherwise generate unoptimized code now. | |
536 Zone zone(isolate->allocator(), ZONE_NAME); | |
537 ParseInfo parse_info(&zone, script); | |
538 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | |
539 | |
540 parse_info.set_literal(literal); | |
541 parse_info.set_shared_info(shared); | |
542 parse_info.set_function_literal_id(shared->function_literal_id()); | |
543 parse_info.set_language_mode(literal->scope()->language_mode()); | |
544 parse_info.set_ast_value_factory( | |
545 outer_info->parse_info()->ast_value_factory()); | |
546 parse_info.set_ast_value_factory_owned(false); | |
547 | |
548 if (will_serialize) info.PrepareForSerializing(); | |
549 if (is_debug) info.MarkAsDebug(); | |
550 | |
551 if (!GenerateUnoptimizedCode(&info)) { | |
552 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
553 return false; | |
554 } | |
555 } | 537 } |
556 } | 538 } |
557 return true; | 539 return true; |
558 } | 540 } |
559 | 541 |
560 bool CompileUnoptimizedCode(CompilationInfo* info) { | 542 bool CompileUnoptimizedCode(CompilationInfo* info) { |
561 Isolate* isolate = info->isolate(); | 543 Isolate* isolate = info->isolate(); |
562 DCHECK(AllowCompilation::IsAllowed(isolate)); | 544 DCHECK(AllowCompilation::IsAllowed(isolate)); |
563 | 545 |
564 Compiler::EagerInnerFunctionLiterals inner_literals; | 546 Compiler::EagerInnerFunctionLiterals inner_literals; |
565 if (!Compiler::Analyze(info->parse_info(), &inner_literals) || | 547 if (!Compiler::Analyze(info->parse_info(), &inner_literals) || |
566 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, info) || | 548 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, info) || |
567 !GenerateUnoptimizedCode(info)) { | 549 !GenerateUnoptimizedCode(info)) { |
568 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 550 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
569 return false; | 551 return false; |
570 } | 552 } |
571 | |
572 // TODO(rmcilroy): Remove this once the enqueued tasks can keep the parsed | |
573 // zone and handles alive and replace with a check in CompileLazy to finish | |
574 // the task itself. | |
575 if (isolate->compiler_dispatcher()->IsEnabled() && | |
576 !isolate->compiler_dispatcher()->FinishAllNow()) { | |
577 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
578 return false; | |
579 } | |
580 | 553 |
581 return true; | 554 return true; |
582 } | 555 } |
583 | 556 |
584 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { | 557 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { |
585 DCHECK(info->is_toplevel()); | 558 DCHECK(info->is_toplevel()); |
586 DCHECK(!info->script().is_null()); | 559 DCHECK(!info->script().is_null()); |
587 if (info->script()->shared_function_infos()->length() > 0) { | 560 if (info->script()->shared_function_infos()->length() > 0) { |
588 DCHECK_EQ(info->script()->shared_function_infos()->length(), | 561 DCHECK_EQ(info->script()->shared_function_infos()->length(), |
589 info->max_function_literal_id() + 1); | 562 info->max_function_literal_id() + 1); |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 // ---------------------------------------------------------------------------- | 1119 // ---------------------------------------------------------------------------- |
1147 // Implementation of Compiler | 1120 // Implementation of Compiler |
1148 | 1121 |
1149 bool Compiler::Analyze(ParseInfo* info, | 1122 bool Compiler::Analyze(ParseInfo* info, |
1150 EagerInnerFunctionLiterals* eager_literals) { | 1123 EagerInnerFunctionLiterals* eager_literals) { |
1151 DCHECK_NOT_NULL(info->literal()); | 1124 DCHECK_NOT_NULL(info->literal()); |
1152 RuntimeCallTimerScope runtimeTimer(info->isolate(), | 1125 RuntimeCallTimerScope runtimeTimer(info->isolate(), |
1153 &RuntimeCallStats::CompileAnalyse); | 1126 &RuntimeCallStats::CompileAnalyse); |
1154 if (!Rewriter::Rewrite(info)) return false; | 1127 if (!Rewriter::Rewrite(info)) return false; |
1155 DeclarationScope::Analyze(info, AnalyzeMode::kRegular); | 1128 DeclarationScope::Analyze(info, AnalyzeMode::kRegular); |
1156 if (!Renumber(info->isolate(), info->zone(), info->literal(), | 1129 if (!Renumber(info, eager_literals)) return false; |
1157 info->shared_info(), eager_literals)) { | |
1158 return false; | |
1159 } | |
1160 DCHECK_NOT_NULL(info->scope()); | 1130 DCHECK_NOT_NULL(info->scope()); |
1161 return true; | 1131 return true; |
1162 } | 1132 } |
1163 | 1133 |
1164 bool Compiler::ParseAndAnalyze(ParseInfo* info) { | 1134 bool Compiler::ParseAndAnalyze(ParseInfo* info) { |
1165 if (!parsing::ParseAny(info)) return false; | 1135 if (!parsing::ParseAny(info)) return false; |
1166 if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info); | 1136 if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info); |
1167 if (!Compiler::Analyze(info)) return false; | 1137 if (!Compiler::Analyze(info)) return false; |
1168 DCHECK_NOT_NULL(info->literal()); | 1138 DCHECK_NOT_NULL(info->literal()); |
1169 DCHECK_NOT_NULL(info->scope()); | 1139 DCHECK_NOT_NULL(info->scope()); |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 | 1726 |
1757 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { | 1727 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { |
1758 // Take ownership of compilation job. Deleting job also tears down the zone. | 1728 // Take ownership of compilation job. Deleting job also tears down the zone. |
1759 std::unique_ptr<CompilationJob> job(raw_job); | 1729 std::unique_ptr<CompilationJob> job(raw_job); |
1760 | 1730 |
1761 VMState<COMPILER> state(job->info()->isolate()); | 1731 VMState<COMPILER> state(job->info()->isolate()); |
1762 if (job->info()->IsOptimizing()) { | 1732 if (job->info()->IsOptimizing()) { |
1763 return FinalizeOptimizedCompilationJob(job.get()) == | 1733 return FinalizeOptimizedCompilationJob(job.get()) == |
1764 CompilationJob::SUCCEEDED; | 1734 CompilationJob::SUCCEEDED; |
1765 } else { | 1735 } else { |
1766 return FinalizeUnoptimizedCompilationJob(job.get()) == | 1736 if (FinalizeUnoptimizedCompilationJob(job.get()) == |
1767 CompilationJob::SUCCEEDED; | 1737 CompilationJob::SUCCEEDED) { |
| 1738 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, |
| 1739 job->info()); |
| 1740 return true; |
| 1741 } |
| 1742 return false; |
1768 } | 1743 } |
1769 } | 1744 } |
1770 | 1745 |
1771 void Compiler::PostInstantiation(Handle<JSFunction> function, | 1746 void Compiler::PostInstantiation(Handle<JSFunction> function, |
1772 PretenureFlag pretenure) { | 1747 PretenureFlag pretenure) { |
1773 Handle<SharedFunctionInfo> shared(function->shared()); | 1748 Handle<SharedFunctionInfo> shared(function->shared()); |
1774 | 1749 |
1775 if (FLAG_always_opt && shared->allows_lazy_compilation() && | 1750 if (FLAG_always_opt && shared->allows_lazy_compilation() && |
1776 !function->shared()->HasAsmWasmData() && | 1751 !function->shared()->HasAsmWasmData() && |
1777 function->shared()->is_compiled()) { | 1752 function->shared()->is_compiled()) { |
(...skipping 10 matching lines...) Expand all Loading... |
1788 } | 1763 } |
1789 | 1764 |
1790 if (shared->is_compiled()) { | 1765 if (shared->is_compiled()) { |
1791 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1766 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1792 JSFunction::EnsureLiterals(function); | 1767 JSFunction::EnsureLiterals(function); |
1793 } | 1768 } |
1794 } | 1769 } |
1795 | 1770 |
1796 } // namespace internal | 1771 } // namespace internal |
1797 } // namespace v8 | 1772 } // namespace v8 |
OLD | NEW |