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

Side by Side Diff: src/ast.cc

Issue 8700001: Relax inlining limits for simple leaf functions (second version). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/ast.h ('k') | src/compiler.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 164
165 int FunctionLiteral::end_position() const { 165 int FunctionLiteral::end_position() const {
166 return scope()->end_position(); 166 return scope()->end_position();
167 } 167 }
168 168
169 169
170 StrictModeFlag FunctionLiteral::strict_mode_flag() const { 170 StrictModeFlag FunctionLiteral::strict_mode_flag() const {
171 return scope()->strict_mode_flag(); 171 return scope()->strict_mode_flag();
172 } 172 }
173 173
174 void FunctionLiteral::ComputeAstNodeCountAndInlineableFlags() {
175 is_function_inlineable_ = false;
176 is_function_primitive_ = true;
177 // All declarations must be inlineable.
178 ZoneList<Declaration*>* decls = scope()->declarations();
179 int decl_count = decls->length();
180 for (int i = 0; i < decl_count; ++i) {
181 if (!decls->at(i)->IsInlineable(this)) {
182 is_function_primitive_ = false;
183 return;
184 }
185 }
186 // All statements in the body must be inlineable.
187 for (int i = 0, count = body()->length(); i < count; ++i) {
188 if (!body()->at(i)->IsInlineable(this)) {
189 is_function_primitive_ = false;
190 return;
191 }
192 }
193 is_function_inlineable_ = true;
194 }
195
174 196
175 ObjectLiteral::Property::Property(Literal* key, Expression* value) { 197 ObjectLiteral::Property::Property(Literal* key, Expression* value) {
176 emit_store_ = true; 198 emit_store_ = true;
177 key_ = key; 199 key_ = key;
178 value_ = value; 200 value_ = value;
179 Object* k = *key->handle(); 201 Object* k = *key->handle();
180 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) { 202 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) {
181 kind_ = PROTOTYPE; 203 kind_ = PROTOTYPE;
182 } else if (value_->AsMaterializedLiteral() != NULL) { 204 } else if (value_->AsMaterializedLiteral() != NULL) {
183 kind_ = MATERIALIZED_LITERAL; 205 kind_ = MATERIALIZED_LITERAL;
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 434
413 bool CompareOperation::IsLiteralCompareNull(Expression** expr) { 435 bool CompareOperation::IsLiteralCompareNull(Expression** expr) {
414 return MatchLiteralCompareNull(left_, op_, right_, expr) || 436 return MatchLiteralCompareNull(left_, op_, right_, expr) ||
415 MatchLiteralCompareNull(right_, op_, left_, expr); 437 MatchLiteralCompareNull(right_, op_, left_, expr);
416 } 438 }
417 439
418 440
419 // ---------------------------------------------------------------------------- 441 // ----------------------------------------------------------------------------
420 // Inlining support 442 // Inlining support
421 443
422 bool Declaration::IsInlineable() const { 444 bool Declaration::IsInlineable(FunctionLiteral* function) const {
423 return proxy()->var()->IsStackAllocated() && fun() == NULL; 445 function->increment_ast_node_count();
424 } 446 return (proxy()->var()->IsStackAllocated() && fun() == NULL);
425 447 }
426 448
427 bool TargetCollector::IsInlineable() const { 449
450 bool TargetCollector::IsInlineable(FunctionLiteral* function) const {
428 UNREACHABLE(); 451 UNREACHABLE();
429 return false; 452 return false;
430 } 453 }
431 454
432 455
433 bool ForInStatement::IsInlineable() const { 456 bool ForInStatement::IsInlineable(FunctionLiteral* function) const {
434 return false; 457 return false;
435 } 458 }
436 459
437 460
438 bool WithStatement::IsInlineable() const { 461 bool WithStatement::IsInlineable(FunctionLiteral* function) const {
439 return false; 462 return false;
440 } 463 }
441 464
442 465
443 bool SwitchStatement::IsInlineable() const { 466 bool SwitchStatement::IsInlineable(FunctionLiteral* function) const {
444 return false; 467 return false;
445 } 468 }
446 469
447 470
448 bool TryStatement::IsInlineable() const { 471 bool TryStatement::IsInlineable(FunctionLiteral* function) const {
449 return false; 472 return false;
450 } 473 }
451 474
452 475
453 bool TryCatchStatement::IsInlineable() const { 476 bool TryCatchStatement::IsInlineable(FunctionLiteral* function) const {
454 return false; 477 return false;
455 } 478 }
456 479
457 480
458 bool TryFinallyStatement::IsInlineable() const { 481 bool TryFinallyStatement::IsInlineable(FunctionLiteral* function) const {
459 return false; 482 return false;
460 } 483 }
461 484
462 485
463 bool DebuggerStatement::IsInlineable() const { 486 bool DebuggerStatement::IsInlineable(FunctionLiteral* function) const {
464 return false; 487 return false;
465 } 488 }
466 489
467 490
468 bool Throw::IsInlineable() const { 491 bool Throw::IsInlineable(FunctionLiteral* function) const {
469 return exception()->IsInlineable(); 492 function->increment_ast_node_count();
470 } 493 return exception()->IsInlineable(function);
471 494 }
472 495
473 bool MaterializedLiteral::IsInlineable() const { 496
497 bool MaterializedLiteral::IsInlineable(FunctionLiteral* function) const {
474 // TODO(1322): Allow materialized literals. 498 // TODO(1322): Allow materialized literals.
475 return false; 499 return false;
476 } 500 }
477 501
478 502
479 bool FunctionLiteral::IsInlineable() const { 503 bool FunctionLiteral::IsInlineable(FunctionLiteral* function) const {
480 // TODO(1322): Allow materialized literals. 504 // TODO(1322): Allow materialized literals.
481 return false; 505 return false;
482 } 506 }
483 507
484 508
485 bool ThisFunction::IsInlineable() const { 509 bool ThisFunction::IsInlineable(FunctionLiteral* function) const {
486 return true; 510 function->increment_ast_node_count();
487 } 511 return true;
488 512 }
489 513
490 bool SharedFunctionInfoLiteral::IsInlineable() const { 514
491 return false; 515 bool SharedFunctionInfoLiteral::IsInlineable(FunctionLiteral* function) const {
492 } 516 return false;
493 517 }
494 518
495 bool ForStatement::IsInlineable() const { 519
496 return (init() == NULL || init()->IsInlineable()) 520 bool ForStatement::IsInlineable(FunctionLiteral* function) const {
497 && (cond() == NULL || cond()->IsInlineable()) 521 function->mark_as_not_primitive();
498 && (next() == NULL || next()->IsInlineable()) 522 function->increment_ast_node_count();
499 && body()->IsInlineable(); 523 return (init() == NULL || init()->IsInlineable(function))
500 } 524 && (cond() == NULL || cond()->IsInlineable(function))
501 525 && (next() == NULL || next()->IsInlineable(function))
502 526 && body()->IsInlineable(function);
503 bool WhileStatement::IsInlineable() const { 527 }
504 return cond()->IsInlineable() 528
505 && body()->IsInlineable(); 529
506 } 530 bool WhileStatement::IsInlineable(FunctionLiteral* function) const {
507 531 function->mark_as_not_primitive();
508 532 function->increment_ast_node_count();
509 bool DoWhileStatement::IsInlineable() const { 533 return cond()->IsInlineable(function)
510 return cond()->IsInlineable() 534 && body()->IsInlineable(function);
511 && body()->IsInlineable(); 535 }
512 } 536
513 537
514 538 bool DoWhileStatement::IsInlineable(FunctionLiteral* function) const {
515 bool ContinueStatement::IsInlineable() const { 539 function->mark_as_not_primitive();
516 return true; 540 function->increment_ast_node_count();
517 } 541 return cond()->IsInlineable(function)
518 542 && body()->IsInlineable(function);
519 543 }
520 bool BreakStatement::IsInlineable() const { 544
521 return true; 545
522 } 546 bool ContinueStatement::IsInlineable(FunctionLiteral* function) const {
523 547 function->increment_ast_node_count();
524 548 return true;
525 bool EmptyStatement::IsInlineable() const { 549 }
526 return true; 550
527 } 551
528 552 bool BreakStatement::IsInlineable(FunctionLiteral* function) const {
529 553 function->increment_ast_node_count();
530 bool Literal::IsInlineable() const { 554 return true;
531 return true; 555 }
532 } 556
533 557
534 558 bool EmptyStatement::IsInlineable(FunctionLiteral* function) const {
535 bool Block::IsInlineable() const { 559 function->increment_ast_node_count();
560 return true;
561 }
562
563
564 bool Literal::IsInlineable(FunctionLiteral* function) const {
565 function->increment_ast_node_count();
566 return true;
567 }
568
569
570 bool Block::IsInlineable(FunctionLiteral* function) const {
571 function->increment_ast_node_count();
536 const int count = statements_.length(); 572 const int count = statements_.length();
537 for (int i = 0; i < count; ++i) { 573 for (int i = 0; i < count; ++i) {
538 if (!statements_[i]->IsInlineable()) return false; 574 if (!statements_[i]->IsInlineable(function)) return false;
539 } 575 }
540 return true; 576 return true;
541 } 577 }
542 578
543 579
544 bool ExpressionStatement::IsInlineable() const { 580 bool ExpressionStatement::IsInlineable(FunctionLiteral* function) const {
545 return expression()->IsInlineable(); 581 function->increment_ast_node_count();
546 } 582 return expression()->IsInlineable(function);
547 583 }
548 584
549 bool IfStatement::IsInlineable() const { 585
550 return condition()->IsInlineable() 586 bool IfStatement::IsInlineable(FunctionLiteral* function) const {
551 && then_statement()->IsInlineable() 587 function->increment_ast_node_count();
552 && else_statement()->IsInlineable(); 588 return condition()->IsInlineable(function)
553 } 589 && then_statement()->IsInlineable(function)
554 590 && else_statement()->IsInlineable(function);
555 591 }
556 bool ReturnStatement::IsInlineable() const { 592
557 return expression()->IsInlineable(); 593
558 } 594 bool ReturnStatement::IsInlineable(FunctionLiteral* function) const {
559 595 function->increment_ast_node_count();
560 596 return expression()->IsInlineable(function);
561 bool Conditional::IsInlineable() const { 597 }
562 return condition()->IsInlineable() && then_expression()->IsInlineable() && 598
563 else_expression()->IsInlineable(); 599
564 } 600 bool Conditional::IsInlineable(FunctionLiteral* function) const {
565 601 function->increment_ast_node_count();
566 602 return condition()->IsInlineable(function)
567 bool VariableProxy::IsInlineable() const { 603 && then_expression()->IsInlineable(function)
604 && else_expression()->IsInlineable(function);
605 }
606
607
608 bool VariableProxy::IsInlineable(FunctionLiteral* function) const {
609 function->increment_ast_node_count();
568 return var()->IsUnallocated() 610 return var()->IsUnallocated()
569 || var()->IsStackAllocated() 611 || var()->IsStackAllocated()
570 || var()->IsContextSlot(); 612 || var()->IsContextSlot();
571 } 613 }
572 614
573 615
574 bool Assignment::IsInlineable() const { 616 bool Assignment::IsInlineable(FunctionLiteral* function) const {
575 return target()->IsInlineable() && value()->IsInlineable(); 617 function->increment_ast_node_count();
576 } 618 return target()->IsInlineable(function)
577 619 && value()->IsInlineable(function);
578 620 }
579 bool Property::IsInlineable() const { 621
580 return obj()->IsInlineable() && key()->IsInlineable(); 622
581 } 623 bool Property::IsInlineable(FunctionLiteral* function) const {
582 624 function->increment_ast_node_count();
583 625 return obj()->IsInlineable(function)
584 bool Call::IsInlineable() const { 626 && key()->IsInlineable(function);
585 if (!expression()->IsInlineable()) return false; 627 }
628
629
630 bool Call::IsInlineable(FunctionLiteral* function) const {
631 function->increment_ast_node_count();
632 function->mark_as_not_primitive();
633 if (!expression()->IsInlineable(function)) return false;
586 const int count = arguments()->length(); 634 const int count = arguments()->length();
587 for (int i = 0; i < count; ++i) { 635 for (int i = 0; i < count; ++i) {
588 if (!arguments()->at(i)->IsInlineable()) return false; 636 if (!arguments()->at(i)->IsInlineable(function)) {
637 return false;
638 }
589 } 639 }
590 return true; 640 return true;
591 } 641 }
592 642
593 643
594 bool CallNew::IsInlineable() const { 644 bool CallNew::IsInlineable(FunctionLiteral* function) const {
595 if (!expression()->IsInlineable()) return false; 645 function->increment_ast_node_count();
646 function->mark_as_not_primitive();
647 if (!expression()->IsInlineable(function)) return false;
596 const int count = arguments()->length(); 648 const int count = arguments()->length();
597 for (int i = 0; i < count; ++i) { 649 for (int i = 0; i < count; ++i) {
598 if (!arguments()->at(i)->IsInlineable()) return false; 650 if (!arguments()->at(i)->IsInlineable(function)) {
651 return false;
652 }
599 } 653 }
600 return true; 654 return true;
601 } 655 }
602 656
603 657
604 bool CallRuntime::IsInlineable() const { 658 bool CallRuntime::IsInlineable(FunctionLiteral* function_literal) const {
605 // Don't try to inline JS runtime calls because we don't (currently) even 659 // Don't try to inline JS runtime calls because we don't (currently) even
606 // optimize them. 660 // optimize them.
607 if (is_jsruntime()) return false; 661 if (is_jsruntime()) return false;
608 // Don't inline the %_ArgumentsLength or %_Arguments because their 662 // Don't inline the %_ArgumentsLength or %_Arguments because their
609 // implementation will not work. There is no stack frame to get them 663 // implementation will not work. There is no stack frame to get them
610 // from. 664 // from.
611 if (function()->intrinsic_type == Runtime::INLINE && 665 if (function()->intrinsic_type == Runtime::INLINE &&
612 (name()->IsEqualTo(CStrVector("_ArgumentsLength")) || 666 (name()->IsEqualTo(CStrVector("_ArgumentsLength")) ||
613 name()->IsEqualTo(CStrVector("_Arguments")))) { 667 name()->IsEqualTo(CStrVector("_Arguments")))) {
614 return false; 668 return false;
615 } 669 }
670 function_literal->increment_ast_node_count();
671 function_literal->mark_as_not_primitive();
616 const int count = arguments()->length(); 672 const int count = arguments()->length();
617 for (int i = 0; i < count; ++i) { 673 for (int i = 0; i < count; ++i) {
618 if (!arguments()->at(i)->IsInlineable()) return false; 674 if (!arguments()->at(i)->IsInlineable(function_literal)) {
675 return false;
676 }
619 } 677 }
620 return true; 678 return true;
621 } 679 }
622 680
623 681
624 bool UnaryOperation::IsInlineable() const { 682 bool UnaryOperation::IsInlineable(FunctionLiteral* function) const {
625 return expression()->IsInlineable(); 683 function->increment_ast_node_count();
684 return expression()->IsInlineable(function);
626 } 685 }
627 686
628 687
629 bool BinaryOperation::IsInlineable() const { 688 bool BinaryOperation::IsInlineable(FunctionLiteral* function) const {
630 return left()->IsInlineable() && right()->IsInlineable(); 689 function->increment_ast_node_count();
690 return left()->IsInlineable(function)
691 && right()->IsInlineable(function);
631 } 692 }
632 693
633 694
634 bool CompareOperation::IsInlineable() const { 695 bool CompareOperation::IsInlineable(FunctionLiteral* function) const {
635 return left()->IsInlineable() && right()->IsInlineable(); 696 function->increment_ast_node_count();
697 return left()->IsInlineable(function)
698 && right()->IsInlineable(function);
636 } 699 }
637 700
638 701
639 bool CountOperation::IsInlineable() const { 702 bool CountOperation::IsInlineable(FunctionLiteral* function) const {
640 return expression()->IsInlineable(); 703 function->increment_ast_node_count();
704 return expression()->IsInlineable(function);
641 } 705 }
642 706
643 707
644 // ---------------------------------------------------------------------------- 708 // ----------------------------------------------------------------------------
645 // Recording of type feedback 709 // Recording of type feedback
646 710
647 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { 711 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
648 // Record type feedback from the oracle in the AST. 712 // Record type feedback from the oracle in the AST.
649 is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this); 713 is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
650 receiver_types_.Clear(); 714 receiver_types_.Clear();
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 int pos) 1272 int pos)
1209 : label_(label), 1273 : label_(label),
1210 statements_(statements), 1274 statements_(statements),
1211 position_(pos), 1275 position_(pos),
1212 compare_type_(NONE), 1276 compare_type_(NONE),
1213 compare_id_(AstNode::GetNextId(isolate)), 1277 compare_id_(AstNode::GetNextId(isolate)),
1214 entry_id_(AstNode::GetNextId(isolate)) { 1278 entry_id_(AstNode::GetNextId(isolate)) {
1215 } 1279 }
1216 1280
1217 } } // namespace v8::internal 1281 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698