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

Side by Side Diff: src/ast.cc

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 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/ast.h ('k') | src/ast-inl.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "ast.h" 30 #include "ast.h"
31 #include "jump-target-inl.h"
31 #include "parser.h" 32 #include "parser.h"
32 #include "scopes.h" 33 #include "scopes.h"
33 #include "string-stream.h" 34 #include "string-stream.h"
34 #include "ast-inl.h"
35 #include "jump-target-inl.h"
36 35
37 namespace v8 { 36 namespace v8 {
38 namespace internal { 37 namespace internal {
39 38
40
41 AstSentinels::AstSentinels() 39 AstSentinels::AstSentinels()
42 : this_proxy_(true), 40 : this_proxy_(true),
43 identifier_proxy_(false), 41 identifier_proxy_(false),
44 valid_left_hand_side_sentinel_(), 42 valid_left_hand_side_sentinel_(),
45 this_property_(&this_proxy_, NULL, 0), 43 this_property_(&this_proxy_, NULL, 0),
46 call_sentinel_(NULL, NULL, 0) { 44 call_sentinel_(NULL, NULL, 0) {
47 } 45 }
48 46
49 47
50 // ---------------------------------------------------------------------------- 48 // ----------------------------------------------------------------------------
51 // All the Accept member functions for each syntax tree node type. 49 // All the Accept member functions for each syntax tree node type.
52 50
51 void Slot::Accept(AstVisitor* v) { v->VisitSlot(this); }
52
53 #define DECL_ACCEPT(type) \ 53 #define DECL_ACCEPT(type) \
54 void type::Accept(AstVisitor* v) { v->Visit##type(this); } 54 void type::Accept(AstVisitor* v) { v->Visit##type(this); }
55 AST_NODE_LIST(DECL_ACCEPT) 55 AST_NODE_LIST(DECL_ACCEPT)
56 #undef DECL_ACCEPT 56 #undef DECL_ACCEPT
57 57
58 58
59 // ---------------------------------------------------------------------------- 59 // ----------------------------------------------------------------------------
60 // Implementation of other node functionality. 60 // Implementation of other node functionality.
61 61
62 Assignment* ExpressionStatement::StatementAsSimpleAssignment() { 62 Assignment* ExpressionStatement::StatementAsSimpleAssignment() {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 // Ideally CONST-ness should match. However, this is very hard to achieve 110 // Ideally CONST-ness should match. However, this is very hard to achieve
111 // because we don't know the exact semantics of conflicting (const and 111 // because we don't know the exact semantics of conflicting (const and
112 // non-const) multiple variable declarations, const vars introduced via 112 // non-const) multiple variable declarations, const vars introduced via
113 // eval() etc. Const-ness and variable declarations are a complete mess 113 // eval() etc. Const-ness and variable declarations are a complete mess
114 // in JS. Sigh... 114 // in JS. Sigh...
115 var_ = var; 115 var_ = var;
116 var->set_is_used(true); 116 var->set_is_used(true);
117 } 117 }
118 118
119 119
120 Assignment::Assignment(Token::Value op,
121 Expression* target,
122 Expression* value,
123 int pos)
124 : op_(op),
125 target_(target),
126 value_(value),
127 pos_(pos),
128 compound_bailout_id_(kNoNumber),
129 block_start_(false),
130 block_end_(false),
131 is_monomorphic_(false),
132 receiver_types_(NULL) {
133 ASSERT(Token::IsAssignmentOp(op));
134 binary_operation_ = is_compound()
135 ? new BinaryOperation(binary_op(), target, value, pos + 1)
136 : NULL;
137 if (is_compound()) {
138 compound_bailout_id_ = GetNextId();
139 }
140 }
141
142
120 Token::Value Assignment::binary_op() const { 143 Token::Value Assignment::binary_op() const {
121 switch (op_) { 144 switch (op_) {
122 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; 145 case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
123 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; 146 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
124 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; 147 case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
125 case Token::ASSIGN_SHL: return Token::SHL; 148 case Token::ASSIGN_SHL: return Token::SHL;
126 case Token::ASSIGN_SAR: return Token::SAR; 149 case Token::ASSIGN_SAR: return Token::SAR;
127 case Token::ASSIGN_SHR: return Token::SHR; 150 case Token::ASSIGN_SHR: return Token::SHR;
128 case Token::ASSIGN_ADD: return Token::ADD; 151 case Token::ASSIGN_ADD: return Token::ADD;
129 case Token::ASSIGN_SUB: return Token::SUB; 152 case Token::ASSIGN_SUB: return Token::SUB;
130 case Token::ASSIGN_MUL: return Token::MUL; 153 case Token::ASSIGN_MUL: return Token::MUL;
131 case Token::ASSIGN_DIV: return Token::DIV; 154 case Token::ASSIGN_DIV: return Token::DIV;
132 case Token::ASSIGN_MOD: return Token::MOD; 155 case Token::ASSIGN_MOD: return Token::MOD;
133 default: UNREACHABLE(); 156 default: UNREACHABLE();
134 } 157 }
135 return Token::ILLEGAL; 158 return Token::ILLEGAL;
136 } 159 }
137 160
138 161
139 bool FunctionLiteral::AllowsLazyCompilation() { 162 bool FunctionLiteral::AllowsLazyCompilation() {
140 return scope()->AllowsLazyCompilation(); 163 return scope()->AllowsLazyCompilation();
141 } 164 }
142 165
143 166
167 bool FunctionLiteral::AllowOptimize() {
168 // We can't deal with heap-allocated locals.
169 return scope()->num_heap_slots() == 0;
170 }
171
172
144 ObjectLiteral::Property::Property(Literal* key, Expression* value) { 173 ObjectLiteral::Property::Property(Literal* key, Expression* value) {
145 emit_store_ = true; 174 emit_store_ = true;
146 key_ = key; 175 key_ = key;
147 value_ = value; 176 value_ = value;
148 Object* k = *key->handle(); 177 Object* k = *key->handle();
149 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) { 178 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) {
150 kind_ = PROTOTYPE; 179 kind_ = PROTOTYPE;
151 } else if (value_->AsMaterializedLiteral() != NULL) { 180 } else if (value_->AsMaterializedLiteral() != NULL) {
152 kind_ = MATERIALIZED_LITERAL; 181 kind_ = MATERIALIZED_LITERAL;
153 } else if (value_->AsLiteral() != NULL) { 182 } else if (value_->AsLiteral() != NULL) {
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 ASSERT(assignment->is_compound()); 397 ASSERT(assignment->is_compound());
369 op_ = assignment->binary_op(); 398 op_ = assignment->binary_op();
370 left_ = assignment->target(); 399 left_ = assignment->target();
371 right_ = assignment->value(); 400 right_ = assignment->value();
372 pos_ = assignment->position(); 401 pos_ = assignment->position();
373 CopyAnalysisResultsFrom(assignment); 402 CopyAnalysisResultsFrom(assignment);
374 } 403 }
375 404
376 405
377 // ---------------------------------------------------------------------------- 406 // ----------------------------------------------------------------------------
407 // Inlining support
408
409 bool Block::IsInlineable() const {
410 const int count = statements_.length();
411 for (int i = 0; i < count; ++i) {
412 if (!statements_[i]->IsInlineable()) return false;
413 }
414 return true;
415 }
416
417
418 bool ExpressionStatement::IsInlineable() const {
419 return expression()->IsInlineable();
420 }
421
422
423 bool IfStatement::IsInlineable() const {
424 return condition()->IsInlineable() && then_statement()->IsInlineable() &&
425 else_statement()->IsInlineable();
426 }
427
428
429 bool ReturnStatement::IsInlineable() const {
430 return expression()->IsInlineable();
431 }
432
433
434 bool Conditional::IsInlineable() const {
435 return condition()->IsInlineable() && then_expression()->IsInlineable() &&
436 else_expression()->IsInlineable();
437 }
438
439
440 bool VariableProxy::IsInlineable() const {
441 return var()->is_global() || var()->IsStackAllocated();
442 }
443
444
445 bool Assignment::IsInlineable() const {
446 return target()->IsInlineable() && value()->IsInlineable();
447 }
448
449
450 bool Property::IsInlineable() const {
451 return obj()->IsInlineable() && key()->IsInlineable();
452 }
453
454
455 bool Call::IsInlineable() const {
456 if (!expression()->IsInlineable()) return false;
457 const int count = arguments()->length();
458 for (int i = 0; i < count; ++i) {
459 if (!arguments()->at(i)->IsInlineable()) return false;
460 }
461 return true;
462 }
463
464
465 bool CallNew::IsInlineable() const {
466 if (!expression()->IsInlineable()) return false;
467 const int count = arguments()->length();
468 for (int i = 0; i < count; ++i) {
469 if (!arguments()->at(i)->IsInlineable()) return false;
470 }
471 return true;
472 }
473
474
475 bool CallRuntime::IsInlineable() const {
476 const int count = arguments()->length();
477 for (int i = 0; i < count; ++i) {
478 if (!arguments()->at(i)->IsInlineable()) return false;
479 }
480 return true;
481 }
482
483
484 bool UnaryOperation::IsInlineable() const {
485 return expression()->IsInlineable();
486 }
487
488
489 bool BinaryOperation::IsInlineable() const {
490 return left()->IsInlineable() && right()->IsInlineable();
491 }
492
493
494 bool CompareOperation::IsInlineable() const {
495 return left()->IsInlineable() && right()->IsInlineable();
496 }
497
498
499 bool CompareToNull::IsInlineable() const {
500 return expression()->IsInlineable();
501 }
502
503
504 bool CountOperation::IsInlineable() const {
505 return expression()->IsInlineable();
506 }
507
508
509 // ----------------------------------------------------------------------------
510 // Recording of type feedback
511
512 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
513 // Record type feedback from the oracle in the AST.
514 is_monomorphic_ = oracle->LoadIsMonomorphic(this);
515 if (key()->IsPropertyName()) {
516 if (oracle->LoadIsBuiltin(this, Builtins::LoadIC_ArrayLength)) {
517 is_array_length_ = true;
518 } else {
519 Literal* lit_key = key()->AsLiteral();
520 ASSERT(lit_key != NULL && lit_key->handle()->IsString());
521 Handle<String> name = Handle<String>::cast(lit_key->handle());
522 ZoneMapList* types = oracle->LoadReceiverTypes(this, name);
523 receiver_types_ = types;
524 }
525 } else if (is_monomorphic_) {
526 monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this);
527 }
528 }
529
530
531 void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
532 Property* prop = target()->AsProperty();
533 ASSERT(prop != NULL);
534 is_monomorphic_ = oracle->StoreIsMonomorphic(this);
535 if (prop->key()->IsPropertyName()) {
536 Literal* lit_key = prop->key()->AsLiteral();
537 ASSERT(lit_key != NULL && lit_key->handle()->IsString());
538 Handle<String> name = Handle<String>::cast(lit_key->handle());
539 ZoneMapList* types = oracle->StoreReceiverTypes(this, name);
540 receiver_types_ = types;
541 } else if (is_monomorphic_) {
542 // Record receiver type for monomorphic keyed loads.
543 monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this);
544 }
545 }
546
547
548 void CaseClause::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
549 TypeInfo info = oracle->SwitchType(this);
550 if (info.IsSmi()) {
551 compare_type_ = SMI_ONLY;
552 } else if (info.IsNonPrimitive()) {
553 compare_type_ = OBJECT_ONLY;
554 } else {
555 ASSERT(compare_type_ == NONE);
556 }
557 }
558
559
560 static bool CallWithoutIC(Handle<JSFunction> target, int arity) {
561 if (target->NeedsArgumentsAdaption()) {
562 // If the number of formal parameters of the target function
563 // does not match the number of arguments we're passing, we
564 // don't want to deal with it.
565 return target->shared()->formal_parameter_count() == arity;
566 } else {
567 // If the target doesn't need arguments adaption, we can call
568 // it directly, but we avoid to do so if it has a custom call
569 // generator, because that is likely to generate better code.
570 return !target->shared()->HasCustomCallGenerator();
571 }
572 }
573
574
575 bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
576 holder_ = Handle<JSObject>::null();
577 while (true) {
578 LookupResult lookup;
579 type->LookupInDescriptors(NULL, *name, &lookup);
580 // If the function wasn't found directly in the map, we start
581 // looking upwards through the prototype chain.
582 if (!lookup.IsFound() && type->prototype()->IsJSObject()) {
583 holder_ = Handle<JSObject>(JSObject::cast(type->prototype()));
584 type = Handle<Map>(holder()->map());
585 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) {
586 target_ = Handle<JSFunction>(lookup.GetConstantFunctionFromMap(*type));
587 return CallWithoutIC(target_, arguments()->length());
588 } else {
589 return false;
590 }
591 }
592 }
593
594
595 bool Call::ComputeGlobalTarget(Handle<GlobalObject> global,
596 Handle<String> name) {
597 target_ = Handle<JSFunction>::null();
598 cell_ = Handle<JSGlobalPropertyCell>::null();
599 LookupResult lookup;
600 global->Lookup(*name, &lookup);
601 if (lookup.IsProperty() && lookup.type() == NORMAL) {
602 cell_ = Handle<JSGlobalPropertyCell>(global->GetPropertyCell(&lookup));
603 if (cell_->value()->IsJSFunction()) {
604 Handle<JSFunction> candidate(JSFunction::cast(cell_->value()));
605 // If the function is in new space we assume it's more likely to
606 // change and thus prefer the general IC code.
607 if (!Isolate::Current()->heap()->InNewSpace(*candidate)
608 && CallWithoutIC(candidate, arguments()->length())) {
609 target_ = candidate;
610 return true;
611 }
612 }
613 }
614 return false;
615 }
616
617
618 void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
619 Property* property = expression()->AsProperty();
620 ASSERT(property != NULL);
621 // Specialize for the receiver types seen at runtime.
622 Literal* key = property->key()->AsLiteral();
623 ASSERT(key != NULL && key->handle()->IsString());
624 Handle<String> name = Handle<String>::cast(key->handle());
625 receiver_types_ = oracle->CallReceiverTypes(this, name);
626 #ifdef DEBUG
627 if (FLAG_enable_slow_asserts) {
628 if (receiver_types_ != NULL) {
629 int length = receiver_types_->length();
630 for (int i = 0; i < length; i++) {
631 Handle<Map> map = receiver_types_->at(i);
632 ASSERT(!map.is_null() && *map != NULL);
633 }
634 }
635 }
636 #endif
637 if (receiver_types_ != NULL && receiver_types_->length() > 0) {
638 Handle<Map> type = receiver_types_->at(0);
639 is_monomorphic_ = oracle->CallIsMonomorphic(this);
640 if (is_monomorphic_) is_monomorphic_ = ComputeTarget(type, name);
641 }
642 }
643
644
645 void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
646 TypeInfo left = oracle->BinaryType(this, TypeFeedbackOracle::LEFT);
647 TypeInfo right = oracle->BinaryType(this, TypeFeedbackOracle::RIGHT);
648 is_smi_only_ = left.IsSmi() && right.IsSmi();
649 }
650
651
652 void CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
653 TypeInfo left = oracle->CompareType(this, TypeFeedbackOracle::LEFT);
654 TypeInfo right = oracle->CompareType(this, TypeFeedbackOracle::RIGHT);
655 if (left.IsSmi() && right.IsSmi()) {
656 compare_type_ = SMI_ONLY;
657 } else if (left.IsNonPrimitive() && right.IsNonPrimitive()) {
658 compare_type_ = OBJECT_ONLY;
659 } else {
660 ASSERT(compare_type_ == NONE);
661 }
662 }
663
664
665 // ----------------------------------------------------------------------------
378 // Implementation of AstVisitor 666 // Implementation of AstVisitor
379 667
380 bool AstVisitor::CheckStackOverflow() { 668 bool AstVisitor::CheckStackOverflow() {
381 if (stack_overflow_) return true; 669 if (stack_overflow_) return true;
382 StackLimitCheck check(Isolate::Current()); 670 StackLimitCheck check(Isolate::Current());
383 if (!check.HasOverflowed()) return false; 671 if (!check.HasOverflowed()) return false;
384 return (stack_overflow_ = true); 672 return (stack_overflow_ = true);
385 } 673 }
386 674
387 675
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 int node_max_match = node->max_match(); 1025 int node_max_match = node->max_match();
738 if (kInfinity - max_match_ < node_max_match) { 1026 if (kInfinity - max_match_ < node_max_match) {
739 max_match_ = kInfinity; 1027 max_match_ = kInfinity;
740 } else { 1028 } else {
741 max_match_ += node->max_match(); 1029 max_match_ += node->max_match();
742 } 1030 }
743 } 1031 }
744 } 1032 }
745 1033
746 1034
747 WhileStatement::WhileStatement(ZoneStringList* labels) 1035 CaseClause::CaseClause(Expression* label,
748 : IterationStatement(labels), 1036 ZoneList<Statement*>* statements,
749 cond_(NULL), 1037 int pos)
750 may_have_function_literal_(true) { 1038 : label_(label),
751 } 1039 statements_(statements),
752 1040 position_(pos),
753 1041 compare_type_(NONE) {}
754 CaseClause::CaseClause(Expression* label, ZoneList<Statement*>* statements)
755 : label_(label), statements_(statements) {
756 }
757 1042
758 } } // namespace v8::internal 1043 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/ast-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698