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

Side by Side Diff: src/ast.cc

Issue 8139027: Version 3.6.5 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/ast.h ('k') | src/bootstrapper.cc » ('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 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 case Token::DIV: 320 case Token::DIV:
321 case Token::MOD: 321 case Token::MOD:
322 return true; 322 return true;
323 default: 323 default:
324 UNREACHABLE(); 324 UNREACHABLE();
325 } 325 }
326 return false; 326 return false;
327 } 327 }
328 328
329 329
330 static bool IsTypeof(Expression* expr) {
331 UnaryOperation* maybe_unary = expr->AsUnaryOperation();
332 return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;
333 }
334
335
336 // Check for the pattern: typeof <expression> equals <string literal>.
337 static bool MatchLiteralCompareTypeof(Expression* left,
338 Token::Value op,
339 Expression* right,
340 Expression** expr,
341 Handle<String>* check) {
342 if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) {
343 *expr = left->AsUnaryOperation()->expression();
344 *check = Handle<String>::cast(right->AsLiteral()->handle());
345 return true;
346 }
347 return false;
348 }
349
350
330 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr, 351 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
331 Handle<String>* check) { 352 Handle<String>* check) {
332 if (op_ != Token::EQ && op_ != Token::EQ_STRICT) return false; 353 return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) ||
354 MatchLiteralCompareTypeof(right_, op_, left_, expr, check);
355 }
333 356
334 UnaryOperation* left_unary = left_->AsUnaryOperation();
335 UnaryOperation* right_unary = right_->AsUnaryOperation();
336 Literal* left_literal = left_->AsLiteral();
337 Literal* right_literal = right_->AsLiteral();
338 357
339 // Check for the pattern: typeof <expression> == <string literal>. 358 static bool IsVoidOfLiteral(Expression* expr) {
340 if (left_unary != NULL && left_unary->op() == Token::TYPEOF && 359 UnaryOperation* maybe_unary = expr->AsUnaryOperation();
341 right_literal != NULL && right_literal->handle()->IsString()) { 360 return maybe_unary != NULL &&
342 *expr = left_unary->expression(); 361 maybe_unary->op() == Token::VOID &&
343 *check = Handle<String>::cast(right_literal->handle()); 362 maybe_unary->expression()->AsLiteral() != NULL;
363 }
364
365
366 // Check for the pattern: void <literal> equals <expression>
367 static bool MatchLiteralCompareUndefined(Expression* left,
368 Token::Value op,
369 Expression* right,
370 Expression** expr) {
371 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
372 *expr = right;
344 return true; 373 return true;
345 } 374 }
346
347 // Check for the pattern: <string literal> == typeof <expression>.
348 if (right_unary != NULL && right_unary->op() == Token::TYPEOF &&
349 left_literal != NULL && left_literal->handle()->IsString()) {
350 *expr = right_unary->expression();
351 *check = Handle<String>::cast(left_literal->handle());
352 return true;
353 }
354
355 return false; 375 return false;
356 } 376 }
357 377
358 378
359 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) { 379 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) {
360 if (op_ != Token::EQ_STRICT) return false; 380 return MatchLiteralCompareUndefined(left_, op_, right_, expr) ||
381 MatchLiteralCompareUndefined(right_, op_, left_, expr);
382 }
361 383
362 UnaryOperation* left_unary = left_->AsUnaryOperation();
363 UnaryOperation* right_unary = right_->AsUnaryOperation();
364 384
365 // Check for the pattern: <expression> === void <literal>. 385 // Check for the pattern: null equals <expression>
366 if (right_unary != NULL && right_unary->op() == Token::VOID && 386 static bool MatchLiteralCompareNull(Expression* left,
367 right_unary->expression()->AsLiteral() != NULL) { 387 Token::Value op,
368 *expr = left_; 388 Expression* right,
389 Expression** expr) {
390 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) {
391 *expr = right;
369 return true; 392 return true;
370 } 393 }
371
372 // Check for the pattern: void <literal> === <expression>.
373 if (left_unary != NULL && left_unary->op() == Token::VOID &&
374 left_unary->expression()->AsLiteral() != NULL) {
375 *expr = right_;
376 return true;
377 }
378
379 return false; 394 return false;
380 } 395 }
381 396
382 397
398 bool CompareOperation::IsLiteralCompareNull(Expression** expr) {
399 return MatchLiteralCompareNull(left_, op_, right_, expr) ||
400 MatchLiteralCompareNull(right_, op_, left_, expr);
401 }
402
403
383 // ---------------------------------------------------------------------------- 404 // ----------------------------------------------------------------------------
384 // Inlining support 405 // Inlining support
385 406
386 bool Declaration::IsInlineable() const { 407 bool Declaration::IsInlineable() const {
387 return proxy()->var()->IsStackAllocated() && fun() == NULL; 408 return proxy()->var()->IsStackAllocated() && fun() == NULL;
388 } 409 }
389 410
390 411
391 bool TargetCollector::IsInlineable() const { 412 bool TargetCollector::IsInlineable() const {
392 UNREACHABLE(); 413 UNREACHABLE();
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 } 543 }
523 544
524 545
525 bool Conditional::IsInlineable() const { 546 bool Conditional::IsInlineable() const {
526 return condition()->IsInlineable() && then_expression()->IsInlineable() && 547 return condition()->IsInlineable() && then_expression()->IsInlineable() &&
527 else_expression()->IsInlineable(); 548 else_expression()->IsInlineable();
528 } 549 }
529 550
530 551
531 bool VariableProxy::IsInlineable() const { 552 bool VariableProxy::IsInlineable() const {
532 return var()->IsUnallocated() || var()->IsStackAllocated(); 553 return var()->IsUnallocated()
554 || var()->IsStackAllocated()
555 || var()->IsContextSlot();
533 } 556 }
534 557
535 558
536 bool Assignment::IsInlineable() const { 559 bool Assignment::IsInlineable() const {
537 return target()->IsInlineable() && value()->IsInlineable(); 560 return target()->IsInlineable() && value()->IsInlineable();
538 } 561 }
539 562
540 563
541 bool Property::IsInlineable() const { 564 bool Property::IsInlineable() const {
542 return obj()->IsInlineable() && key()->IsInlineable(); 565 return obj()->IsInlineable() && key()->IsInlineable();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 bool BinaryOperation::IsInlineable() const { 614 bool BinaryOperation::IsInlineable() const {
592 return left()->IsInlineable() && right()->IsInlineable(); 615 return left()->IsInlineable() && right()->IsInlineable();
593 } 616 }
594 617
595 618
596 bool CompareOperation::IsInlineable() const { 619 bool CompareOperation::IsInlineable() const {
597 return left()->IsInlineable() && right()->IsInlineable(); 620 return left()->IsInlineable() && right()->IsInlineable();
598 } 621 }
599 622
600 623
601 bool CompareToNull::IsInlineable() const {
602 return expression()->IsInlineable();
603 }
604
605
606 bool CountOperation::IsInlineable() const { 624 bool CountOperation::IsInlineable() const {
607 return expression()->IsInlineable(); 625 return expression()->IsInlineable();
608 } 626 }
609 627
610 628
611 // ---------------------------------------------------------------------------- 629 // ----------------------------------------------------------------------------
612 // Recording of type feedback 630 // Recording of type feedback
613 631
614 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { 632 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
615 // Record type feedback from the oracle in the AST. 633 // Record type feedback from the oracle in the AST.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 target_ = candidate; 757 target_ = candidate;
740 return true; 758 return true;
741 } 759 }
742 } 760 }
743 return false; 761 return false;
744 } 762 }
745 763
746 764
747 void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle, 765 void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
748 CallKind call_kind) { 766 CallKind call_kind) {
767 is_monomorphic_ = oracle->CallIsMonomorphic(this);
749 Property* property = expression()->AsProperty(); 768 Property* property = expression()->AsProperty();
750 ASSERT(property != NULL); 769 if (property == NULL) {
751 // Specialize for the receiver types seen at runtime. 770 // Function call. Specialize for monomorphic calls.
752 Literal* key = property->key()->AsLiteral(); 771 if (is_monomorphic_) target_ = oracle->GetCallTarget(this);
753 ASSERT(key != NULL && key->handle()->IsString()); 772 } else {
754 Handle<String> name = Handle<String>::cast(key->handle()); 773 // Method call. Specialize for the receiver types seen at runtime.
755 receiver_types_.Clear(); 774 Literal* key = property->key()->AsLiteral();
756 oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_); 775 ASSERT(key != NULL && key->handle()->IsString());
776 Handle<String> name = Handle<String>::cast(key->handle());
777 receiver_types_.Clear();
778 oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_);
757 #ifdef DEBUG 779 #ifdef DEBUG
758 if (FLAG_enable_slow_asserts) { 780 if (FLAG_enable_slow_asserts) {
759 int length = receiver_types_.length(); 781 int length = receiver_types_.length();
760 for (int i = 0; i < length; i++) { 782 for (int i = 0; i < length; i++) {
761 Handle<Map> map = receiver_types_.at(i); 783 Handle<Map> map = receiver_types_.at(i);
762 ASSERT(!map.is_null() && *map != NULL); 784 ASSERT(!map.is_null() && *map != NULL);
785 }
763 } 786 }
764 }
765 #endif 787 #endif
766 is_monomorphic_ = oracle->CallIsMonomorphic(this); 788 check_type_ = oracle->GetCallCheckType(this);
767 check_type_ = oracle->GetCallCheckType(this); 789 if (is_monomorphic_) {
768 if (is_monomorphic_) { 790 Handle<Map> map;
769 Handle<Map> map; 791 if (receiver_types_.length() > 0) {
770 if (receiver_types_.length() > 0) { 792 ASSERT(check_type_ == RECEIVER_MAP_CHECK);
771 ASSERT(check_type_ == RECEIVER_MAP_CHECK); 793 map = receiver_types_.at(0);
772 map = receiver_types_.at(0); 794 } else {
773 } else { 795 ASSERT(check_type_ != RECEIVER_MAP_CHECK);
774 ASSERT(check_type_ != RECEIVER_MAP_CHECK); 796 holder_ = Handle<JSObject>(
775 holder_ = Handle<JSObject>( 797 oracle->GetPrototypeForPrimitiveCheck(check_type_));
776 oracle->GetPrototypeForPrimitiveCheck(check_type_)); 798 map = Handle<Map>(holder_->map());
777 map = Handle<Map>(holder_->map()); 799 }
800 is_monomorphic_ = ComputeTarget(map, name);
778 } 801 }
779 is_monomorphic_ = ComputeTarget(map, name);
780 } 802 }
781 } 803 }
782 804
783 805
784 void CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) { 806 void CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
785 TypeInfo info = oracle->CompareType(this); 807 TypeInfo info = oracle->CompareType(this);
786 if (info.IsSmi()) { 808 if (info.IsSmi()) {
787 compare_type_ = SMI_ONLY; 809 compare_type_ = SMI_ONLY;
788 } else if (info.IsNonPrimitive()) { 810 } else if (info.IsNonPrimitive()) {
789 compare_type_ = OBJECT_ONLY; 811 compare_type_ = OBJECT_ONLY;
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 int pos) 1191 int pos)
1170 : label_(label), 1192 : label_(label),
1171 statements_(statements), 1193 statements_(statements),
1172 position_(pos), 1194 position_(pos),
1173 compare_type_(NONE), 1195 compare_type_(NONE),
1174 compare_id_(AstNode::GetNextId(isolate)), 1196 compare_id_(AstNode::GetNextId(isolate)),
1175 entry_id_(AstNode::GetNextId(isolate)) { 1197 entry_id_(AstNode::GetNextId(isolate)) {
1176 } 1198 }
1177 1199
1178 } } // namespace v8::internal 1200 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/bootstrapper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698