| OLD | NEW | 
|     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 22 matching lines...) Expand all  Loading... | 
|    33 #include "compiler.h" |    33 #include "compiler.h" | 
|    34 #include "prettyprinter.h" |    34 #include "prettyprinter.h" | 
|    35 #include "scopeinfo.h" |    35 #include "scopeinfo.h" | 
|    36  |    36  | 
|    37 namespace v8 { |    37 namespace v8 { | 
|    38 namespace internal { |    38 namespace internal { | 
|    39  |    39  | 
|    40 // ---------------------------------------------------------------------------- |    40 // ---------------------------------------------------------------------------- | 
|    41 // A Zone allocator for use with LocalsMap. |    41 // A Zone allocator for use with LocalsMap. | 
|    42  |    42  | 
 |    43 // TODO(isolates): It is probably worth it to change the Allocator class to | 
 |    44 //                 take a pointer to an isolate. | 
|    43 class ZoneAllocator: public Allocator { |    45 class ZoneAllocator: public Allocator { | 
|    44  public: |    46  public: | 
|    45   /* nothing to do */ |    47   /* nothing to do */ | 
|    46   virtual ~ZoneAllocator()  {} |    48   virtual ~ZoneAllocator()  {} | 
|    47  |    49  | 
|    48   virtual void* New(size_t size)  { return Zone::New(static_cast<int>(size)); } |    50   virtual void* New(size_t size)  { return ZONE->New(static_cast<int>(size)); } | 
|    49  |    51  | 
|    50   /* ignored - Zone is freed in one fell swoop */ |    52   /* ignored - Zone is freed in one fell swoop */ | 
|    51   virtual void Delete(void* p)  {} |    53   virtual void Delete(void* p)  {} | 
|    52 }; |    54 }; | 
|    53  |    55  | 
|    54  |    56  | 
|    55 static ZoneAllocator LocalsMapAllocator; |    57 static ZoneAllocator LocalsMapAllocator; | 
|    56  |    58  | 
|    57  |    59  | 
|    58 // ---------------------------------------------------------------------------- |    60 // ---------------------------------------------------------------------------- | 
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   152   ASSERT(resolved()); |   154   ASSERT(resolved()); | 
|   153   if (scope_info->HasHeapAllocatedLocals()) { |   155   if (scope_info->HasHeapAllocatedLocals()) { | 
|   154     num_heap_slots_ = scope_info_->NumberOfContextSlots(); |   156     num_heap_slots_ = scope_info_->NumberOfContextSlots(); | 
|   155   } |   157   } | 
|   156  |   158  | 
|   157   AddInnerScope(inner_scope); |   159   AddInnerScope(inner_scope); | 
|   158  |   160  | 
|   159   // This scope's arguments shadow (if present) is context-allocated if an inner |   161   // This scope's arguments shadow (if present) is context-allocated if an inner | 
|   160   // scope accesses this one's parameters.  Allocate the arguments_shadow_ |   162   // scope accesses this one's parameters.  Allocate the arguments_shadow_ | 
|   161   // variable if necessary. |   163   // variable if necessary. | 
 |   164   Isolate* isolate = Isolate::Current(); | 
|   162   Variable::Mode mode; |   165   Variable::Mode mode; | 
|   163   int arguments_shadow_index = |   166   int arguments_shadow_index = | 
|   164       scope_info_->ContextSlotIndex(Heap::arguments_shadow_symbol(), &mode); |   167       scope_info_->ContextSlotIndex( | 
 |   168           isolate->heap()->arguments_shadow_symbol(), &mode); | 
|   165   if (arguments_shadow_index >= 0) { |   169   if (arguments_shadow_index >= 0) { | 
|   166     ASSERT(mode == Variable::INTERNAL); |   170     ASSERT(mode == Variable::INTERNAL); | 
|   167     arguments_shadow_ = new Variable(this, |   171     arguments_shadow_ = new Variable( | 
|   168                                      Factory::arguments_shadow_symbol(), |   172         this, | 
|   169                                      Variable::INTERNAL, |   173         isolate->factory()->arguments_shadow_symbol(), | 
|   170                                      true, |   174         Variable::INTERNAL, | 
|   171                                      Variable::ARGUMENTS); |   175         true, | 
 |   176         Variable::ARGUMENTS); | 
|   172     arguments_shadow_->set_rewrite( |   177     arguments_shadow_->set_rewrite( | 
|   173         new Slot(arguments_shadow_, Slot::CONTEXT, arguments_shadow_index)); |   178         new Slot(arguments_shadow_, Slot::CONTEXT, arguments_shadow_index)); | 
|   174     arguments_shadow_->set_is_used(true); |   179     arguments_shadow_->set_is_used(true); | 
|   175   } |   180   } | 
|   176 } |   181 } | 
|   177  |   182  | 
|   178  |   183  | 
|   179 Scope* Scope::DeserializeScopeChain(CompilationInfo* info, |   184 Scope* Scope::DeserializeScopeChain(CompilationInfo* info, | 
|   180                                     Scope* global_scope) { |   185                                     Scope* global_scope) { | 
|   181   ASSERT(!info->closure().is_null()); |   186   ASSERT(!info->closure().is_null()); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|   206  |   211  | 
|   207  |   212  | 
|   208 bool Scope::Analyze(CompilationInfo* info) { |   213 bool Scope::Analyze(CompilationInfo* info) { | 
|   209   ASSERT(info->function() != NULL); |   214   ASSERT(info->function() != NULL); | 
|   210   Scope* top = info->function()->scope(); |   215   Scope* top = info->function()->scope(); | 
|   211  |   216  | 
|   212   while (top->outer_scope() != NULL) top = top->outer_scope(); |   217   while (top->outer_scope() != NULL) top = top->outer_scope(); | 
|   213   top->AllocateVariables(info->calling_context()); |   218   top->AllocateVariables(info->calling_context()); | 
|   214  |   219  | 
|   215 #ifdef DEBUG |   220 #ifdef DEBUG | 
|   216   if (Bootstrapper::IsActive() |   221   if (info->isolate()->bootstrapper()->IsActive() | 
|   217           ? FLAG_print_builtin_scopes |   222           ? FLAG_print_builtin_scopes | 
|   218           : FLAG_print_scopes) { |   223           : FLAG_print_scopes) { | 
|   219     info->function()->scope()->Print(); |   224     info->function()->scope()->Print(); | 
|   220   } |   225   } | 
|   221 #endif |   226 #endif | 
|   222  |   227  | 
|   223   info->SetScope(info->function()->scope()); |   228   info->SetScope(info->function()->scope()); | 
|   224   return true;  // Can not fail. |   229   return true;  // Can not fail. | 
|   225 } |   230 } | 
|   226  |   231  | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   238  |   243  | 
|   239   // Declare convenience variables. |   244   // Declare convenience variables. | 
|   240   // Declare and allocate receiver (even for the global scope, and even |   245   // Declare and allocate receiver (even for the global scope, and even | 
|   241   // if naccesses_ == 0). |   246   // if naccesses_ == 0). | 
|   242   // NOTE: When loading parameters in the global scope, we must take |   247   // NOTE: When loading parameters in the global scope, we must take | 
|   243   // care not to access them as properties of the global object, but |   248   // care not to access them as properties of the global object, but | 
|   244   // instead load them directly from the stack. Currently, the only |   249   // instead load them directly from the stack. Currently, the only | 
|   245   // such parameter is 'this' which is passed on the stack when |   250   // such parameter is 'this' which is passed on the stack when | 
|   246   // invoking scripts |   251   // invoking scripts | 
|   247   Variable* var = |   252   Variable* var = | 
|   248       variables_.Declare(this, Factory::this_symbol(), Variable::VAR, |   253       variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR, | 
|   249                          false, Variable::THIS); |   254                          false, Variable::THIS); | 
|   250   var->set_rewrite(new Slot(var, Slot::PARAMETER, -1)); |   255   var->set_rewrite(new Slot(var, Slot::PARAMETER, -1)); | 
|   251   receiver_ = var; |   256   receiver_ = var; | 
|   252  |   257  | 
|   253   if (is_function_scope()) { |   258   if (is_function_scope()) { | 
|   254     // Declare 'arguments' variable which exists in all functions. |   259     // Declare 'arguments' variable which exists in all functions. | 
|   255     // Note that it might never be accessed, in which case it won't be |   260     // Note that it might never be accessed, in which case it won't be | 
|   256     // allocated during variable allocation. |   261     // allocated during variable allocation. | 
|   257     variables_.Declare(this, Factory::arguments_symbol(), Variable::VAR, |   262     variables_.Declare(this, FACTORY->arguments_symbol(), Variable::VAR, | 
|   258                        true, Variable::ARGUMENTS); |   263                        true, Variable::ARGUMENTS); | 
|   259   } |   264   } | 
|   260 } |   265 } | 
|   261  |   266  | 
|   262  |   267  | 
|   263 Variable* Scope::LocalLookup(Handle<String> name) { |   268 Variable* Scope::LocalLookup(Handle<String> name) { | 
|   264   Variable* result = variables_.Lookup(name); |   269   Variable* result = variables_.Lookup(name); | 
|   265   if (result != NULL || !resolved()) { |   270   if (result != NULL || !resolved()) { | 
|   266     return result; |   271     return result; | 
|   267   } |   272   } | 
|   268   // If the scope is resolved, we can find a variable in serialized scope info. |   273   // If the scope is resolved, we can find a variable in serialized scope info. | 
|   269  |   274  | 
|   270   // We should never lookup 'arguments' in this scope |   275   // We should never lookup 'arguments' in this scope | 
|   271   // as it is implicitly present in any scope. |   276   // as it is implicitly present in any scope. | 
|   272   ASSERT(*name != *Factory::arguments_symbol()); |   277   ASSERT(*name != *FACTORY->arguments_symbol()); | 
|   273  |   278  | 
|   274   // Assert that there is no local slot with the given name. |   279   // Assert that there is no local slot with the given name. | 
|   275   ASSERT(scope_info_->StackSlotIndex(*name) < 0); |   280   ASSERT(scope_info_->StackSlotIndex(*name) < 0); | 
|   276  |   281  | 
|   277   // Check context slot lookup. |   282   // Check context slot lookup. | 
|   278   Variable::Mode mode; |   283   Variable::Mode mode; | 
|   279   int index = scope_info_->ContextSlotIndex(*name, &mode); |   284   int index = scope_info_->ContextSlotIndex(*name, &mode); | 
|   280   if (index >= 0) { |   285   if (index >= 0) { | 
|   281     Variable* var = |   286     Variable* var = | 
|   282         variables_.Declare(this, name, mode, true, Variable::NORMAL); |   287         variables_.Declare(this, name, mode, true, Variable::NORMAL); | 
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   861   return |   866   return | 
|   862     var->mode() != Variable::TEMPORARY && |   867     var->mode() != Variable::TEMPORARY && | 
|   863     (var->is_accessed_from_inner_scope() || |   868     (var->is_accessed_from_inner_scope() || | 
|   864      scope_calls_eval_ || inner_scope_calls_eval_ || |   869      scope_calls_eval_ || inner_scope_calls_eval_ || | 
|   865      scope_contains_with_ || var->is_global()); |   870      scope_contains_with_ || var->is_global()); | 
|   866 } |   871 } | 
|   867  |   872  | 
|   868  |   873  | 
|   869 bool Scope::HasArgumentsParameter() { |   874 bool Scope::HasArgumentsParameter() { | 
|   870   for (int i = 0; i < params_.length(); i++) { |   875   for (int i = 0; i < params_.length(); i++) { | 
|   871     if (params_[i]->name().is_identical_to(Factory::arguments_symbol())) |   876     if (params_[i]->name().is_identical_to(FACTORY->arguments_symbol())) | 
|   872       return true; |   877       return true; | 
|   873   } |   878   } | 
|   874   return false; |   879   return false; | 
|   875 } |   880 } | 
|   876  |   881  | 
|   877  |   882  | 
|   878 void Scope::AllocateStackSlot(Variable* var) { |   883 void Scope::AllocateStackSlot(Variable* var) { | 
|   879   var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++)); |   884   var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++)); | 
|   880 } |   885 } | 
|   881  |   886  | 
|   882  |   887  | 
|   883 void Scope::AllocateHeapSlot(Variable* var) { |   888 void Scope::AllocateHeapSlot(Variable* var) { | 
|   884   var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++)); |   889   var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++)); | 
|   885 } |   890 } | 
|   886  |   891  | 
|   887  |   892  | 
|   888 void Scope::AllocateParameterLocals() { |   893 void Scope::AllocateParameterLocals() { | 
|   889   ASSERT(is_function_scope()); |   894   ASSERT(is_function_scope()); | 
|   890   Variable* arguments = LocalLookup(Factory::arguments_symbol()); |   895   Variable* arguments = LocalLookup(FACTORY->arguments_symbol()); | 
|   891   ASSERT(arguments != NULL);  // functions have 'arguments' declared implicitly |   896   ASSERT(arguments != NULL);  // functions have 'arguments' declared implicitly | 
|   892  |   897  | 
|   893   // Parameters are rewritten to arguments[i] if 'arguments' is used in |   898   // Parameters are rewritten to arguments[i] if 'arguments' is used in | 
|   894   // a non-strict mode function. Strict mode code doesn't alias arguments. |   899   // a non-strict mode function. Strict mode code doesn't alias arguments. | 
|   895   bool rewrite_parameters = false; |   900   bool rewrite_parameters = false; | 
|   896  |   901  | 
|   897   if (MustAllocate(arguments) && !HasArgumentsParameter()) { |   902   if (MustAllocate(arguments) && !HasArgumentsParameter()) { | 
|   898     // 'arguments' is used. Unless there is also a parameter called |   903     // 'arguments' is used. Unless there is also a parameter called | 
|   899     // 'arguments', we must be conservative and access all parameters via |   904     // 'arguments', we must be conservative and access all parameters via | 
|   900     // the arguments object: The i'th parameter is rewritten into |   905     // the arguments object: The i'th parameter is rewritten into | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   935     // We also need the '.arguments' shadow variable. Declare it and create |   940     // We also need the '.arguments' shadow variable. Declare it and create | 
|   936     // and bind the corresponding proxy. It's ok to declare it only now |   941     // and bind the corresponding proxy. It's ok to declare it only now | 
|   937     // because it's a local variable that is allocated after the parameters |   942     // because it's a local variable that is allocated after the parameters | 
|   938     // have been allocated. |   943     // have been allocated. | 
|   939     // |   944     // | 
|   940     // Note: This is "almost" at temporary variable but we cannot use |   945     // Note: This is "almost" at temporary variable but we cannot use | 
|   941     // NewTemporary() because the mode needs to be INTERNAL since this |   946     // NewTemporary() because the mode needs to be INTERNAL since this | 
|   942     // variable may be allocated in the heap-allocated context (temporaries |   947     // variable may be allocated in the heap-allocated context (temporaries | 
|   943     // are never allocated in the context). |   948     // are never allocated in the context). | 
|   944     arguments_shadow_ = new Variable(this, |   949     arguments_shadow_ = new Variable(this, | 
|   945                                      Factory::arguments_shadow_symbol(), |   950                                      FACTORY->arguments_shadow_symbol(), | 
|   946                                      Variable::INTERNAL, |   951                                      Variable::INTERNAL, | 
|   947                                      true, |   952                                      true, | 
|   948                                      Variable::ARGUMENTS); |   953                                      Variable::ARGUMENTS); | 
|   949     arguments_shadow_->set_is_used(true); |   954     arguments_shadow_->set_is_used(true); | 
|   950     temps_.Add(arguments_shadow_); |   955     temps_.Add(arguments_shadow_); | 
|   951  |   956  | 
|   952     // Allocate the parameters by rewriting them into '.arguments[i]' accesses. |   957     // Allocate the parameters by rewriting them into '.arguments[i]' accesses. | 
|   953     for (int i = 0; i < params_.length(); i++) { |   958     for (int i = 0; i < params_.length(); i++) { | 
|   954       Variable* var = params_[i]; |   959       Variable* var = params_[i]; | 
|   955       ASSERT(var->scope() == this); |   960       ASSERT(var->scope() == this); | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1001         } |  1006         } | 
|  1002       } |  1007       } | 
|  1003     } |  1008     } | 
|  1004   } |  1009   } | 
|  1005 } |  1010 } | 
|  1006  |  1011  | 
|  1007  |  1012  | 
|  1008 void Scope::AllocateNonParameterLocal(Variable* var) { |  1013 void Scope::AllocateNonParameterLocal(Variable* var) { | 
|  1009   ASSERT(var->scope() == this); |  1014   ASSERT(var->scope() == this); | 
|  1010   ASSERT(var->rewrite() == NULL || |  1015   ASSERT(var->rewrite() == NULL || | 
|  1011          (!var->IsVariable(Factory::result_symbol())) || |  1016          (!var->IsVariable(FACTORY->result_symbol())) || | 
|  1012          (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL)); |  1017          (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL)); | 
|  1013   if (var->rewrite() == NULL && MustAllocate(var)) { |  1018   if (var->rewrite() == NULL && MustAllocate(var)) { | 
|  1014     if (MustAllocateInContext(var)) { |  1019     if (MustAllocateInContext(var)) { | 
|  1015       AllocateHeapSlot(var); |  1020       AllocateHeapSlot(var); | 
|  1016     } else { |  1021     } else { | 
|  1017       AllocateStackSlot(var); |  1022       AllocateStackSlot(var); | 
|  1018     } |  1023     } | 
|  1019   } |  1024   } | 
|  1020 } |  1025 } | 
|  1021  |  1026  | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1077   if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && |  1082   if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && | 
|  1078       !must_have_local_context) { |  1083       !must_have_local_context) { | 
|  1079     num_heap_slots_ = 0; |  1084     num_heap_slots_ = 0; | 
|  1080   } |  1085   } | 
|  1081  |  1086  | 
|  1082   // Allocation done. |  1087   // Allocation done. | 
|  1083   ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |  1088   ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 
|  1084 } |  1089 } | 
|  1085  |  1090  | 
|  1086 } }  // namespace v8::internal |  1091 } }  // namespace v8::internal | 
| OLD | NEW |