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 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 | 599 |
600 HGraphBuilder::HGraphBuilder(CompilationInfo* info, | 600 HGraphBuilder::HGraphBuilder(CompilationInfo* info, |
601 TypeFeedbackOracle* oracle) | 601 TypeFeedbackOracle* oracle) |
602 : function_state_(NULL), | 602 : function_state_(NULL), |
603 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 603 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
604 ast_context_(NULL), | 604 ast_context_(NULL), |
605 break_scope_(NULL), | 605 break_scope_(NULL), |
606 graph_(NULL), | 606 graph_(NULL), |
607 current_block_(NULL), | 607 current_block_(NULL), |
608 inlined_count_(0), | 608 inlined_count_(0), |
| 609 globals_(10), |
609 zone_(info->isolate()->zone()), | 610 zone_(info->isolate()->zone()), |
610 inline_bailout_(false) { | 611 inline_bailout_(false) { |
611 // This is not initialized in the initializer list because the | 612 // This is not initialized in the initializer list because the |
612 // constructor for the initial state relies on function_state_ == NULL | 613 // constructor for the initial state relies on function_state_ == NULL |
613 // to know it's the initial state. | 614 // to know it's the initial state. |
614 function_state_= &initial_function_state_; | 615 function_state_= &initial_function_state_; |
615 } | 616 } |
616 | 617 |
617 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, | 618 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, |
618 HBasicBlock* second, | 619 HBasicBlock* second, |
(...skipping 6283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6902 ASSERT(!HasStackOverflow()); | 6903 ASSERT(!HasStackOverflow()); |
6903 ASSERT(current_block() != NULL); | 6904 ASSERT(current_block() != NULL); |
6904 ASSERT(current_block()->HasPredecessor()); | 6905 ASSERT(current_block()->HasPredecessor()); |
6905 HThisFunction* self = new(zone()) HThisFunction( | 6906 HThisFunction* self = new(zone()) HThisFunction( |
6906 function_state()->compilation_info()->closure()); | 6907 function_state()->compilation_info()->closure()); |
6907 return ast_context()->ReturnInstruction(self, expr->id()); | 6908 return ast_context()->ReturnInstruction(self, expr->id()); |
6908 } | 6909 } |
6909 | 6910 |
6910 | 6911 |
6911 void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { | 6912 void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { |
6912 int length = declarations->length(); | 6913 ASSERT(globals_.is_empty()); |
6913 int save_global_count = global_count_; | |
6914 global_count_ = 0; | |
6915 | |
6916 AstVisitor::VisitDeclarations(declarations); | 6914 AstVisitor::VisitDeclarations(declarations); |
6917 | 6915 if (!globals_.is_empty()) { |
6918 // Batch declare global functions and variables. | |
6919 if (global_count_ > 0) { | |
6920 Handle<FixedArray> array = | 6916 Handle<FixedArray> array = |
6921 isolate()->factory()->NewFixedArray(2 * global_count_, TENURED); | 6917 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); |
6922 for (int j = 0, i = 0; i < length; i++) { | 6918 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); |
6923 Declaration* decl = declarations->at(i); | |
6924 Variable* var = decl->proxy()->var(); | |
6925 | |
6926 if (var->IsUnallocated()) { | |
6927 array->set(j++, *(var->name())); | |
6928 FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration(); | |
6929 if (fun_decl == NULL) { | |
6930 if (var->binding_needs_init()) { | |
6931 // In case this binding needs initialization use the hole. | |
6932 array->set_the_hole(j++); | |
6933 } else { | |
6934 array->set_undefined(j++); | |
6935 } | |
6936 } else { | |
6937 Handle<SharedFunctionInfo> function = | |
6938 Compiler::BuildFunctionInfo(fun_decl->fun(), info()->script()); | |
6939 // Check for stack-overflow exception. | |
6940 if (function.is_null()) { | |
6941 SetStackOverflow(); | |
6942 return; | |
6943 } | |
6944 array->set(j++, *function); | |
6945 } | |
6946 } | |
6947 } | |
6948 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | | 6919 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | |
6949 DeclareGlobalsNativeFlag::encode(info()->is_native()) | | 6920 DeclareGlobalsNativeFlag::encode(info()->is_native()) | |
6950 DeclareGlobalsLanguageMode::encode(info()->language_mode()); | 6921 DeclareGlobalsLanguageMode::encode(info()->language_mode()); |
6951 HInstruction* result = | 6922 HInstruction* result = new(zone()) HDeclareGlobals( |
6952 new(zone()) HDeclareGlobals(environment()->LookupContext(), | 6923 environment()->LookupContext(), array, flags); |
6953 array, | |
6954 flags); | |
6955 AddInstruction(result); | 6924 AddInstruction(result); |
| 6925 globals_.Clear(); |
6956 } | 6926 } |
6957 | |
6958 global_count_ = save_global_count; | |
6959 } | 6927 } |
6960 | 6928 |
6961 | 6929 |
6962 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { | 6930 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { |
6963 VariableProxy* proxy = declaration->proxy(); | 6931 VariableProxy* proxy = declaration->proxy(); |
6964 VariableMode mode = declaration->mode(); | 6932 VariableMode mode = declaration->mode(); |
6965 Variable* var = proxy->var(); | 6933 Variable* variable = proxy->var(); |
6966 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 6934 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
6967 switch (var->location()) { | 6935 switch (variable->location()) { |
6968 case Variable::UNALLOCATED: | 6936 case Variable::UNALLOCATED: |
6969 ++global_count_; | 6937 globals_.Add(variable->name()); |
| 6938 globals_.Add(variable->binding_needs_init() |
| 6939 ? isolate()->factory()->the_hole_value() |
| 6940 : isolate()->factory()->undefined_value()); |
6970 return; | 6941 return; |
6971 case Variable::PARAMETER: | 6942 case Variable::PARAMETER: |
6972 case Variable::LOCAL: | 6943 case Variable::LOCAL: |
6973 if (hole_init) { | 6944 if (hole_init) { |
6974 HValue* value = graph()->GetConstantHole(); | 6945 HValue* value = graph()->GetConstantHole(); |
6975 environment()->Bind(var, value); | 6946 environment()->Bind(variable, value); |
6976 } | 6947 } |
6977 break; | 6948 break; |
6978 case Variable::CONTEXT: | 6949 case Variable::CONTEXT: |
6979 if (hole_init) { | 6950 if (hole_init) { |
6980 HValue* value = graph()->GetConstantHole(); | 6951 HValue* value = graph()->GetConstantHole(); |
6981 HValue* context = environment()->LookupContext(); | 6952 HValue* context = environment()->LookupContext(); |
6982 HStoreContextSlot* store = new HStoreContextSlot( | 6953 HStoreContextSlot* store = new HStoreContextSlot( |
6983 context, var->index(), HStoreContextSlot::kNoCheck, value); | 6954 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
6984 AddInstruction(store); | 6955 AddInstruction(store); |
6985 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 6956 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
6986 } | 6957 } |
6987 break; | 6958 break; |
6988 case Variable::LOOKUP: | 6959 case Variable::LOOKUP: |
6989 return Bailout("unsupported lookup slot in declaration"); | 6960 return Bailout("unsupported lookup slot in declaration"); |
6990 } | 6961 } |
6991 } | 6962 } |
6992 | 6963 |
6993 | 6964 |
6994 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { | 6965 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { |
6995 VariableProxy* proxy = declaration->proxy(); | 6966 VariableProxy* proxy = declaration->proxy(); |
6996 Variable* var = proxy->var(); | 6967 Variable* variable = proxy->var(); |
6997 switch (var->location()) { | 6968 switch (variable->location()) { |
6998 case Variable::UNALLOCATED: | 6969 case Variable::UNALLOCATED: { |
6999 ++global_count_; | 6970 globals_.Add(variable->name()); |
| 6971 Handle<SharedFunctionInfo> function = |
| 6972 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); |
| 6973 // Check for stack-overflow exception. |
| 6974 if (function.is_null()) return SetStackOverflow(); |
| 6975 globals_.Add(function); |
7000 return; | 6976 return; |
| 6977 } |
7001 case Variable::PARAMETER: | 6978 case Variable::PARAMETER: |
7002 case Variable::LOCAL: { | 6979 case Variable::LOCAL: { |
7003 CHECK_ALIVE(VisitForValue(declaration->fun())); | 6980 CHECK_ALIVE(VisitForValue(declaration->fun())); |
7004 HValue* value = Pop(); | 6981 HValue* value = Pop(); |
7005 environment()->Bind(var, value); | 6982 environment()->Bind(variable, value); |
7006 break; | 6983 break; |
7007 } | 6984 } |
7008 case Variable::CONTEXT: { | 6985 case Variable::CONTEXT: { |
7009 CHECK_ALIVE(VisitForValue(declaration->fun())); | 6986 CHECK_ALIVE(VisitForValue(declaration->fun())); |
7010 HValue* value = Pop(); | 6987 HValue* value = Pop(); |
7011 HValue* context = environment()->LookupContext(); | 6988 HValue* context = environment()->LookupContext(); |
7012 HStoreContextSlot* store = new HStoreContextSlot( | 6989 HStoreContextSlot* store = new HStoreContextSlot( |
7013 context, var->index(), HStoreContextSlot::kNoCheck, value); | 6990 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
7014 AddInstruction(store); | 6991 AddInstruction(store); |
7015 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 6992 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
7016 break; | 6993 break; |
7017 } | 6994 } |
7018 case Variable::LOOKUP: | 6995 case Variable::LOOKUP: |
7019 return Bailout("unsupported lookup slot in declaration"); | 6996 return Bailout("unsupported lookup slot in declaration"); |
7020 } | 6997 } |
7021 } | 6998 } |
7022 | 6999 |
7023 | 7000 |
7024 void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 7001 void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
7025 VariableProxy* proxy = declaration->proxy(); | 7002 VariableProxy* proxy = declaration->proxy(); |
7026 Variable* var = proxy->var(); | 7003 Variable* var = proxy->var(); |
7027 switch (var->location()) { | 7004 switch (var->location()) { |
7028 case Variable::UNALLOCATED: | 7005 case Variable::UNALLOCATED: { |
7029 ++global_count_; | 7006 // TODO(rossberg) |
7030 return; | 7007 return; |
| 7008 } |
7031 case Variable::CONTEXT: { | 7009 case Variable::CONTEXT: { |
7032 // TODO(rossberg) | 7010 // TODO(rossberg) |
7033 break; | 7011 break; |
7034 } | 7012 } |
7035 case Variable::PARAMETER: | 7013 case Variable::PARAMETER: |
7036 case Variable::LOCAL: | 7014 case Variable::LOCAL: |
7037 case Variable::LOOKUP: | 7015 case Variable::LOOKUP: |
7038 UNREACHABLE(); | 7016 UNREACHABLE(); |
7039 } | 7017 } |
7040 } | 7018 } |
7041 | 7019 |
7042 | 7020 |
7043 void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) { | 7021 void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) { |
7044 VariableProxy* proxy = declaration->proxy(); | 7022 VariableProxy* proxy = declaration->proxy(); |
7045 Variable* var = proxy->var(); | 7023 Variable* var = proxy->var(); |
7046 switch (var->location()) { | 7024 switch (var->location()) { |
7047 case Variable::UNALLOCATED: | 7025 case Variable::UNALLOCATED: { |
7048 ++global_count_; | 7026 // TODO(rossberg) |
7049 return; | 7027 return; |
| 7028 } |
7050 case Variable::CONTEXT: { | 7029 case Variable::CONTEXT: { |
7051 // TODO(rossberg) | 7030 // TODO(rossberg) |
7052 break; | 7031 break; |
7053 } | 7032 } |
7054 case Variable::PARAMETER: | 7033 case Variable::PARAMETER: |
7055 case Variable::LOCAL: | 7034 case Variable::LOCAL: |
7056 case Variable::LOOKUP: | 7035 case Variable::LOOKUP: |
7057 UNREACHABLE(); | 7036 UNREACHABLE(); |
7058 } | 7037 } |
7059 } | 7038 } |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8163 } | 8142 } |
8164 } | 8143 } |
8165 | 8144 |
8166 #ifdef DEBUG | 8145 #ifdef DEBUG |
8167 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 8146 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
8168 if (allocator_ != NULL) allocator_->Verify(); | 8147 if (allocator_ != NULL) allocator_->Verify(); |
8169 #endif | 8148 #endif |
8170 } | 8149 } |
8171 | 8150 |
8172 } } // namespace v8::internal | 8151 } } // namespace v8::internal |
OLD | NEW |