OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2436 // not replayed by the Lithium translation. | 2436 // not replayed by the Lithium translation. |
2437 HEnvironment* initial_env = environment()->CopyWithoutHistory(); | 2437 HEnvironment* initial_env = environment()->CopyWithoutHistory(); |
2438 HBasicBlock* body_entry = CreateBasicBlock(initial_env); | 2438 HBasicBlock* body_entry = CreateBasicBlock(initial_env); |
2439 current_block()->Goto(body_entry); | 2439 current_block()->Goto(body_entry); |
2440 body_entry->SetJoinId(AstNode::kFunctionEntryId); | 2440 body_entry->SetJoinId(AstNode::kFunctionEntryId); |
2441 set_current_block(body_entry); | 2441 set_current_block(body_entry); |
2442 | 2442 |
2443 // Handle implicit declaration of the function name in named function | 2443 // Handle implicit declaration of the function name in named function |
2444 // expressions before other declarations. | 2444 // expressions before other declarations. |
2445 if (scope->is_function_scope() && scope->function() != NULL) { | 2445 if (scope->is_function_scope() && scope->function() != NULL) { |
2446 HandleVariableDeclaration(scope->function(), CONST, NULL); | 2446 HandleVariableDeclaration(scope->function(), CONST, NULL, NULL); |
2447 } | 2447 } |
2448 VisitDeclarations(scope->declarations()); | 2448 VisitDeclarations(scope->declarations()); |
2449 AddSimulate(AstNode::kDeclarationsId); | 2449 AddSimulate(AstNode::kDeclarationsId); |
2450 | 2450 |
2451 HValue* context = environment()->LookupContext(); | 2451 HValue* context = environment()->LookupContext(); |
2452 AddInstruction( | 2452 AddInstruction( |
2453 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); | 2453 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); |
2454 | 2454 |
2455 VisitStatements(info()->function()->body()); | 2455 VisitStatements(info()->function()->body()); |
2456 if (HasStackOverflow()) return NULL; | 2456 if (HasStackOverflow()) return NULL; |
(...skipping 2453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4910 || target_shared->SourceSize() > kUnlimitedMaxSourceSize) { | 4910 || target_shared->SourceSize() > kUnlimitedMaxSourceSize) { |
4911 TraceInline(target, caller, "target text too big"); | 4911 TraceInline(target, caller, "target text too big"); |
4912 return false; | 4912 return false; |
4913 } | 4913 } |
4914 | 4914 |
4915 // Target must be inlineable. | 4915 // Target must be inlineable. |
4916 if (!target->IsInlineable()) { | 4916 if (!target->IsInlineable()) { |
4917 TraceInline(target, caller, "target not inlineable"); | 4917 TraceInline(target, caller, "target not inlineable"); |
4918 return false; | 4918 return false; |
4919 } | 4919 } |
4920 if (target_shared->dont_inline() || target_shared->dont_crankshaft()) { | 4920 if (target_shared->dont_inline() || target_shared->dont_optimize()) { |
4921 TraceInline(target, caller, "target contains unsupported syntax [early]"); | 4921 TraceInline(target, caller, "target contains unsupported syntax [early]"); |
4922 return false; | 4922 return false; |
4923 } | 4923 } |
4924 | 4924 |
4925 int nodes_added = target_shared->ast_node_count(); | 4925 int nodes_added = target_shared->ast_node_count(); |
4926 if ((FLAG_limit_inlining && nodes_added > kMaxInlinedSize) || | 4926 if ((FLAG_limit_inlining && nodes_added > kMaxInlinedSize) || |
4927 nodes_added > kUnlimitedMaxInlinedSize) { | 4927 nodes_added > kUnlimitedMaxInlinedSize) { |
4928 TraceInline(target, caller, "target AST is too large [early]"); | 4928 TraceInline(target, caller, "target AST is too large [early]"); |
4929 return false; | 4929 return false; |
4930 } | 4930 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4972 return false; | 4972 return false; |
4973 } | 4973 } |
4974 | 4974 |
4975 // Parse and allocate variables. | 4975 // Parse and allocate variables. |
4976 CompilationInfo target_info(target); | 4976 CompilationInfo target_info(target); |
4977 if (!ParserApi::Parse(&target_info, kNoParsingFlags) || | 4977 if (!ParserApi::Parse(&target_info, kNoParsingFlags) || |
4978 !Scope::Analyze(&target_info)) { | 4978 !Scope::Analyze(&target_info)) { |
4979 if (target_info.isolate()->has_pending_exception()) { | 4979 if (target_info.isolate()->has_pending_exception()) { |
4980 // Parse or scope error, never optimize this function. | 4980 // Parse or scope error, never optimize this function. |
4981 SetStackOverflow(); | 4981 SetStackOverflow(); |
4982 target_shared->DisableOptimization(*target); | 4982 target_shared->DisableOptimization(); |
4983 } | 4983 } |
4984 TraceInline(target, caller, "parse failure"); | 4984 TraceInline(target, caller, "parse failure"); |
4985 return false; | 4985 return false; |
4986 } | 4986 } |
4987 | 4987 |
4988 if (target_info.scope()->num_heap_slots() > 0) { | 4988 if (target_info.scope()->num_heap_slots() > 0) { |
4989 TraceInline(target, caller, "target has context-allocated variables"); | 4989 TraceInline(target, caller, "target has context-allocated variables"); |
4990 return false; | 4990 return false; |
4991 } | 4991 } |
4992 FunctionLiteral* function = target_info.function(); | 4992 FunctionLiteral* function = target_info.function(); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5085 AddInstruction(new(zone()) HEnterInlined(target, | 5085 AddInstruction(new(zone()) HEnterInlined(target, |
5086 expr->arguments()->length(), | 5086 expr->arguments()->length(), |
5087 function, | 5087 function, |
5088 call_kind)); | 5088 call_kind)); |
5089 VisitDeclarations(target_info.scope()->declarations()); | 5089 VisitDeclarations(target_info.scope()->declarations()); |
5090 VisitStatements(function->body()); | 5090 VisitStatements(function->body()); |
5091 if (HasStackOverflow()) { | 5091 if (HasStackOverflow()) { |
5092 // Bail out if the inline function did, as we cannot residualize a call | 5092 // Bail out if the inline function did, as we cannot residualize a call |
5093 // instead. | 5093 // instead. |
5094 TraceInline(target, caller, "inline graph construction failed"); | 5094 TraceInline(target, caller, "inline graph construction failed"); |
5095 target_shared->DisableOptimization(*target); | 5095 target_shared->DisableOptimization(); |
5096 inline_bailout_ = true; | 5096 inline_bailout_ = true; |
5097 delete target_state; | 5097 delete target_state; |
5098 return true; | 5098 return true; |
5099 } | 5099 } |
5100 | 5100 |
5101 // Update inlined nodes count. | 5101 // Update inlined nodes count. |
5102 inlined_count_ += nodes_added; | 5102 inlined_count_ += nodes_added; |
5103 | 5103 |
5104 TraceInline(target, caller, NULL); | 5104 TraceInline(target, caller, NULL); |
5105 | 5105 |
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6534 ASSERT(!HasStackOverflow()); | 6534 ASSERT(!HasStackOverflow()); |
6535 ASSERT(current_block() != NULL); | 6535 ASSERT(current_block() != NULL); |
6536 ASSERT(current_block()->HasPredecessor()); | 6536 ASSERT(current_block()->HasPredecessor()); |
6537 HThisFunction* self = new(zone()) HThisFunction( | 6537 HThisFunction* self = new(zone()) HThisFunction( |
6538 function_state()->compilation_info()->closure()); | 6538 function_state()->compilation_info()->closure()); |
6539 return ast_context()->ReturnInstruction(self, expr->id()); | 6539 return ast_context()->ReturnInstruction(self, expr->id()); |
6540 } | 6540 } |
6541 | 6541 |
6542 | 6542 |
6543 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { | 6543 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { |
6544 HandleVariableDeclaration(decl->proxy(), decl->mode(), decl->fun()); | 6544 UNREACHABLE(); |
| 6545 } |
| 6546 |
| 6547 void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { |
| 6548 int length = declarations->length(); |
| 6549 int global_count = 0; |
| 6550 for (int i = 0; i < declarations->length(); i++) { |
| 6551 VariableDeclaration* decl = declarations->at(i)->AsVariableDeclaration(); |
| 6552 if (decl == NULL) continue; |
| 6553 HandleVariableDeclaration(decl->proxy(), |
| 6554 decl->mode(), |
| 6555 decl->fun(), |
| 6556 &global_count); |
| 6557 } |
| 6558 |
| 6559 // Batch declare global functions and variables. |
| 6560 if (global_count > 0) { |
| 6561 Handle<FixedArray> array = |
| 6562 isolate()->factory()->NewFixedArray(2 * global_count, TENURED); |
| 6563 for (int j = 0, i = 0; i < length; i++) { |
| 6564 VariableDeclaration* decl = declarations->at(i)->AsVariableDeclaration(); |
| 6565 if (decl == NULL) continue; |
| 6566 Variable* var = decl->proxy()->var(); |
| 6567 |
| 6568 if (var->IsUnallocated()) { |
| 6569 array->set(j++, *(var->name())); |
| 6570 if (decl->fun() == NULL) { |
| 6571 if (var->binding_needs_init()) { |
| 6572 // In case this binding needs initialization use the hole. |
| 6573 array->set_the_hole(j++); |
| 6574 } else { |
| 6575 array->set_undefined(j++); |
| 6576 } |
| 6577 } else { |
| 6578 Handle<SharedFunctionInfo> function = |
| 6579 Compiler::BuildFunctionInfo(decl->fun(), info()->script()); |
| 6580 // Check for stack-overflow exception. |
| 6581 if (function.is_null()) { |
| 6582 SetStackOverflow(); |
| 6583 return; |
| 6584 } |
| 6585 array->set(j++, *function); |
| 6586 } |
| 6587 } |
| 6588 } |
| 6589 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | |
| 6590 DeclareGlobalsNativeFlag::encode(info()->is_native()) | |
| 6591 DeclareGlobalsLanguageMode::encode(info()->language_mode()); |
| 6592 HInstruction* result = |
| 6593 new(zone()) HDeclareGlobals(environment()->LookupContext(), |
| 6594 array, |
| 6595 flags); |
| 6596 AddInstruction(result); |
| 6597 } |
6545 } | 6598 } |
6546 | 6599 |
6547 | 6600 |
6548 void HGraphBuilder::HandleVariableDeclaration(VariableProxy* proxy, | 6601 void HGraphBuilder::HandleVariableDeclaration(VariableProxy* proxy, |
6549 VariableMode mode, | 6602 VariableMode mode, |
6550 FunctionLiteral* function) { | 6603 FunctionLiteral* function, |
| 6604 int* global_count) { |
6551 Variable* var = proxy->var(); | 6605 Variable* var = proxy->var(); |
6552 bool binding_needs_init = | 6606 bool binding_needs_init = |
6553 (mode == CONST || mode == CONST_HARMONY || mode == LET); | 6607 (mode == CONST || mode == CONST_HARMONY || mode == LET); |
6554 switch (var->location()) { | 6608 switch (var->location()) { |
6555 case Variable::UNALLOCATED: | 6609 case Variable::UNALLOCATED: |
6556 return Bailout("unsupported global declaration"); | 6610 ++(*global_count); |
| 6611 return; |
6557 case Variable::PARAMETER: | 6612 case Variable::PARAMETER: |
6558 case Variable::LOCAL: | 6613 case Variable::LOCAL: |
6559 case Variable::CONTEXT: | 6614 case Variable::CONTEXT: |
6560 if (binding_needs_init || function != NULL) { | 6615 if (binding_needs_init || function != NULL) { |
6561 HValue* value = NULL; | 6616 HValue* value = NULL; |
6562 if (function != NULL) { | 6617 if (function != NULL) { |
6563 VisitForValue(function); | 6618 CHECK_ALIVE(VisitForValue(function)); |
6564 value = Pop(); | 6619 value = Pop(); |
6565 } else { | 6620 } else { |
6566 value = graph()->GetConstantHole(); | 6621 value = graph()->GetConstantHole(); |
6567 } | 6622 } |
6568 if (var->IsContextSlot()) { | 6623 if (var->IsContextSlot()) { |
6569 HValue* context = environment()->LookupContext(); | 6624 HValue* context = environment()->LookupContext(); |
6570 HStoreContextSlot* store = new HStoreContextSlot( | 6625 HStoreContextSlot* store = new HStoreContextSlot( |
6571 context, var->index(), HStoreContextSlot::kNoCheck, value); | 6626 context, var->index(), HStoreContextSlot::kNoCheck, value); |
6572 AddInstruction(store); | 6627 AddInstruction(store); |
6573 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 6628 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
(...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7653 } | 7708 } |
7654 } | 7709 } |
7655 | 7710 |
7656 #ifdef DEBUG | 7711 #ifdef DEBUG |
7657 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 7712 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
7658 if (allocator_ != NULL) allocator_->Verify(); | 7713 if (allocator_ != NULL) allocator_->Verify(); |
7659 #endif | 7714 #endif |
7660 } | 7715 } |
7661 | 7716 |
7662 } } // namespace v8::internal | 7717 } } // namespace v8::internal |
OLD | NEW |