Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Side by Side Diff: src/compiler.cc

Issue 552232: Introduce a stack-allocated structure to encapsulate compile-time information. (Closed)
Patch Set: Remove inadvertently included files. Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler.h ('k') | src/fast-codegen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 30 matching lines...) Expand all
41 #include "usage-analyzer.h" 41 #include "usage-analyzer.h"
42 42
43 namespace v8 { 43 namespace v8 {
44 namespace internal { 44 namespace internal {
45 45
46 46
47 static Handle<Code> MakeCode(FunctionLiteral* literal, 47 static Handle<Code> MakeCode(FunctionLiteral* literal,
48 Handle<Script> script, 48 Handle<Script> script,
49 Handle<Context> context, 49 Handle<Context> context,
50 bool is_eval, 50 bool is_eval,
51 Handle<SharedFunctionInfo> shared, 51 CompilationInfo* info) {
52 Handle<Object> receiver) {
53 ASSERT(literal != NULL); 52 ASSERT(literal != NULL);
54 53
55 // Rewrite the AST by introducing .result assignments where needed. 54 // Rewrite the AST by introducing .result assignments where needed.
56 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) { 55 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) {
57 // Signal a stack overflow by returning a null handle. The stack 56 // Signal a stack overflow by returning a null handle. The stack
58 // overflow exception will be thrown by the caller. 57 // overflow exception will be thrown by the caller.
59 return Handle<Code>::null(); 58 return Handle<Code>::null();
60 } 59 }
61 60
62 { 61 {
(...skipping 28 matching lines...) Expand all
91 // --full-compiler enables the dedicated backend for code we expect to be 90 // --full-compiler enables the dedicated backend for code we expect to be
92 // run once 91 // run once
93 // --fast-compiler enables a speculative optimizing backend (for 92 // --fast-compiler enables a speculative optimizing backend (for
94 // non-run-once code) 93 // non-run-once code)
95 // 94 //
96 // The normal choice of backend can be overridden with the flags 95 // The normal choice of backend can be overridden with the flags
97 // --always-full-compiler and --always-fast-compiler, which are mutually 96 // --always-full-compiler and --always-fast-compiler, which are mutually
98 // incompatible. 97 // incompatible.
99 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler); 98 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
100 99
100 Handle<SharedFunctionInfo> shared = info->shared_info();
101 bool is_run_once = (shared.is_null()) 101 bool is_run_once = (shared.is_null())
102 ? literal->scope()->is_global_scope() 102 ? literal->scope()->is_global_scope()
103 : (shared->is_toplevel() || shared->try_full_codegen()); 103 : (shared->is_toplevel() || shared->try_full_codegen());
104 104
105 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) { 105 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
106 FullCodeGenSyntaxChecker checker; 106 FullCodeGenSyntaxChecker checker;
107 checker.Check(literal); 107 checker.Check(literal);
108 if (checker.has_supported_syntax()) { 108 if (checker.has_supported_syntax()) {
109 return FullCodeGenerator::MakeCode(literal, script, is_eval); 109 return FullCodeGenerator::MakeCode(literal, script, is_eval);
110 } 110 }
111 } else if (FLAG_always_fast_compiler || 111 } else if (FLAG_always_fast_compiler ||
112 (FLAG_fast_compiler && !is_run_once)) { 112 (FLAG_fast_compiler && !is_run_once)) {
113 FastCodeGenSyntaxChecker checker(receiver); 113 FastCodeGenSyntaxChecker checker;
114 checker.Check(literal); 114 checker.Check(literal, info);
115 if (checker.has_supported_syntax()) { 115 if (checker.has_supported_syntax()) {
116 AstLabeler labeler; 116 AstLabeler labeler;
117 labeler.Label(literal); 117 labeler.Label(literal);
118 } 118 }
119 // Does not yet generate code. 119 // Does not yet generate code.
120 } 120 }
121 121
122 return CodeGenerator::MakeCode(literal, script, is_eval); 122 return CodeGenerator::MakeCode(literal, script, is_eval, info);
123 } 123 }
124 124
125 125
126 static bool IsValidJSON(FunctionLiteral* lit) { 126 static bool IsValidJSON(FunctionLiteral* lit) {
127 if (lit->body()->length() != 1) 127 if (lit->body()->length() != 1)
128 return false; 128 return false;
129 Statement* stmt = lit->body()->at(0); 129 Statement* stmt = lit->body()->at(0);
130 if (stmt->AsExpressionStatement() == NULL) 130 if (stmt->AsExpressionStatement() == NULL)
131 return false; 131 return false;
132 Expression* expr = stmt->AsExpressionStatement()->expression(); 132 Expression* expr = stmt->AsExpressionStatement()->expression();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 197
198 // Measure how long it takes to do the compilation; only take the 198 // Measure how long it takes to do the compilation; only take the
199 // rest of the function into account to avoid overlap with the 199 // rest of the function into account to avoid overlap with the
200 // parsing statistics. 200 // parsing statistics.
201 HistogramTimer* rate = is_eval 201 HistogramTimer* rate = is_eval
202 ? &Counters::compile_eval 202 ? &Counters::compile_eval
203 : &Counters::compile; 203 : &Counters::compile;
204 HistogramTimerScope timer(rate); 204 HistogramTimerScope timer(rate);
205 205
206 // Compile the code. 206 // Compile the code.
207 Handle<Code> code = MakeCode(lit, 207 CompilationInfo info(Handle<SharedFunctionInfo>::null(),
208 script, 208 Handle<Object>::null(), // No receiver.
209 context, 209 0); // Not nested in a loop.
210 is_eval, 210 Handle<Code> code = MakeCode(lit, script, context, is_eval, &info);
211 Handle<SharedFunctionInfo>::null(),
212 Handle<Object>::null()); // No receiver.
213 211
214 // Check for stack-overflow exceptions. 212 // Check for stack-overflow exceptions.
215 if (code.is_null()) { 213 if (code.is_null()) {
216 Top::StackOverflow(); 214 Top::StackOverflow();
217 return Handle<JSFunction>::null(); 215 return Handle<JSFunction>::null();
218 } 216 }
219 217
220 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT 218 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
221 // Log the code generation for the script. Check explicit whether logging is 219 // Log the code generation for the script. Check explicit whether logging is
222 // to avoid allocating when not required. 220 // to avoid allocating when not required.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 // For json it's unlikely that we'll ever see exactly the same 361 // For json it's unlikely that we'll ever see exactly the same
364 // string again so we don't use the compilation cache. 362 // string again so we don't use the compilation cache.
365 CompilationCache::PutEval(source, context, is_global, result); 363 CompilationCache::PutEval(source, context, is_global, result);
366 } 364 }
367 } 365 }
368 366
369 return result; 367 return result;
370 } 368 }
371 369
372 370
373 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared, 371 bool Compiler::CompileLazy(CompilationInfo* info) {
374 Handle<Object> receiver,
375 int loop_nesting) {
376 CompilationZoneScope zone_scope(DELETE_ON_EXIT); 372 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
377 373
378 // The VM is in the COMPILER state until exiting this function. 374 // The VM is in the COMPILER state until exiting this function.
379 VMState state(COMPILER); 375 VMState state(COMPILER);
380 376
381 PostponeInterruptsScope postpone; 377 PostponeInterruptsScope postpone;
382 378
383 // Compute name, source code and script data. 379 // Compute name, source code and script data.
380 Handle<SharedFunctionInfo> shared = info->shared_info();
384 Handle<String> name(String::cast(shared->name())); 381 Handle<String> name(String::cast(shared->name()));
385 Handle<Script> script(Script::cast(shared->script())); 382 Handle<Script> script(Script::cast(shared->script()));
386 383
387 int start_position = shared->start_position(); 384 int start_position = shared->start_position();
388 int end_position = shared->end_position(); 385 int end_position = shared->end_position();
389 bool is_expression = shared->is_expression(); 386 bool is_expression = shared->is_expression();
390 Counters::total_compile_size.Increment(end_position - start_position); 387 Counters::total_compile_size.Increment(end_position - start_position);
391 388
392 // Generate the AST for the lazily compiled function. The AST may be 389 // Generate the AST for the lazily compiled function. The AST may be
393 // NULL in case of parser stack overflow. 390 // NULL in case of parser stack overflow.
394 FunctionLiteral* lit = MakeLazyAST(script, name, 391 FunctionLiteral* lit = MakeLazyAST(script, name,
395 start_position, 392 start_position,
396 end_position, 393 end_position,
397 is_expression); 394 is_expression);
398 395
399 // Check for parse errors. 396 // Check for parse errors.
400 if (lit == NULL) { 397 if (lit == NULL) {
401 ASSERT(Top::has_pending_exception()); 398 ASSERT(Top::has_pending_exception());
402 return false; 399 return false;
403 } 400 }
404 401
405 // Update the loop nesting in the function literal.
406 lit->set_loop_nesting(loop_nesting);
407
408 // Measure how long it takes to do the lazy compilation; only take 402 // Measure how long it takes to do the lazy compilation; only take
409 // the rest of the function into account to avoid overlap with the 403 // the rest of the function into account to avoid overlap with the
410 // lazy parsing statistics. 404 // lazy parsing statistics.
411 HistogramTimerScope timer(&Counters::compile_lazy); 405 HistogramTimerScope timer(&Counters::compile_lazy);
412 406
413 // Compile the code. 407 // Compile the code.
414 Handle<Code> code = MakeCode(lit, 408 Handle<Code> code = MakeCode(lit,
415 script, 409 script,
416 Handle<Context>::null(), 410 Handle<Context>::null(),
417 false, 411 false,
418 shared, 412 info);
419 receiver);
420 413
421 // Check for stack-overflow exception. 414 // Check for stack-overflow exception.
422 if (code.is_null()) { 415 if (code.is_null()) {
423 Top::StackOverflow(); 416 Top::StackOverflow();
424 return false; 417 return false;
425 } 418 }
426 419
427 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT 420 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
428 // Log the code generation. If source information is available include script 421 // Log the code generation. If source information is available include script
429 // name and line number. Check explicit whether logging is enabled as finding 422 // name and line number. Check explicit whether logging is enabled as finding
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 } else { 483 } else {
491 // The bodies of function literals have not yet been visited by 484 // The bodies of function literals have not yet been visited by
492 // the AST optimizer/analyzer. 485 // the AST optimizer/analyzer.
493 if (!Rewriter::Optimize(literal)) { 486 if (!Rewriter::Optimize(literal)) {
494 return Handle<JSFunction>::null(); 487 return Handle<JSFunction>::null();
495 } 488 }
496 489
497 // Generate code and return it. The way that the compilation mode 490 // Generate code and return it. The way that the compilation mode
498 // is controlled by the command-line flags is described in 491 // is controlled by the command-line flags is described in
499 // the static helper function MakeCode. 492 // the static helper function MakeCode.
493 CompilationInfo info(Handle<SharedFunctionInfo>::null(),
494 Handle<Object>::null(), // No receiver.
495 0); // Not nested in a loop.
496
500 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler); 497 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
501 bool is_run_once = literal->try_full_codegen(); 498 bool is_run_once = literal->try_full_codegen();
502 bool is_compiled = false; 499 bool is_compiled = false;
503 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) { 500 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
504 FullCodeGenSyntaxChecker checker; 501 FullCodeGenSyntaxChecker checker;
505 checker.Check(literal); 502 checker.Check(literal);
506 if (checker.has_supported_syntax()) { 503 if (checker.has_supported_syntax()) {
507 code = FullCodeGenerator::MakeCode(literal, 504 code = FullCodeGenerator::MakeCode(literal,
508 script, 505 script,
509 false); // Not eval. 506 false); // Not eval.
510 is_compiled = true; 507 is_compiled = true;
511 } 508 }
512 } else if (FLAG_always_fast_compiler || 509 } else if (FLAG_always_fast_compiler ||
513 (FLAG_fast_compiler && !is_run_once)) { 510 (FLAG_fast_compiler && !is_run_once)) {
514 // Since we are not lazily compiling we do not have a receiver to 511 // Since we are not lazily compiling we do not have a receiver to
515 // specialize for. 512 // specialize for.
516 FastCodeGenSyntaxChecker checker(Handle<Object>::null()); 513 FastCodeGenSyntaxChecker checker;
517 checker.Check(literal); 514 checker.Check(literal, &info);
518 if (checker.has_supported_syntax()) { 515 if (checker.has_supported_syntax()) {
519 AstLabeler label_nodes; 516 AstLabeler label_nodes;
520 label_nodes.Label(literal); 517 label_nodes.Label(literal);
521 } 518 }
522 // Generate no code. 519 // Generate no code.
523 } 520 }
524 521
525 if (!is_compiled) { 522 if (!is_compiled) {
526 // We fall back to the classic V8 code generator. 523 // We fall back to the classic V8 code generator.
527 code = CodeGenerator::MakeCode(literal, 524 code = CodeGenerator::MakeCode(literal,
528 script, 525 script,
529 false); // Not eval. 526 false, // Not eval.
527 &info);
530 } 528 }
531 529
532 // Check for stack-overflow exception. 530 // Check for stack-overflow exception.
533 if (code.is_null()) { 531 if (code.is_null()) {
534 caller->SetStackOverflow(); 532 caller->SetStackOverflow();
535 return Handle<JSFunction>::null(); 533 return Handle<JSFunction>::null();
536 } 534 }
537 535
538 // Function compilation complete. 536 // Function compilation complete.
539 LOG(CodeCreateEvent(Logger::FUNCTION_TAG, *code, *literal->name())); 537 LOG(CodeCreateEvent(Logger::FUNCTION_TAG, *code, *literal->name()));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 fun->shared()->set_is_toplevel(is_toplevel); 581 fun->shared()->set_is_toplevel(is_toplevel);
584 fun->shared()->set_inferred_name(*lit->inferred_name()); 582 fun->shared()->set_inferred_name(*lit->inferred_name());
585 fun->shared()->SetThisPropertyAssignmentsInfo( 583 fun->shared()->SetThisPropertyAssignmentsInfo(
586 lit->has_only_simple_this_property_assignments(), 584 lit->has_only_simple_this_property_assignments(),
587 *lit->this_property_assignments()); 585 *lit->this_property_assignments());
588 fun->shared()->set_try_full_codegen(lit->try_full_codegen()); 586 fun->shared()->set_try_full_codegen(lit->try_full_codegen());
589 } 587 }
590 588
591 589
592 } } // namespace v8::internal 590 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/fast-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698