Cleanup ScopeInfo and SerializedScopeInfo.
authorkeuchel@chromium.org <keuchel@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Nov 2011 10:36:55 +0000 (10:36 +0000)
committerkeuchel@chromium.org <keuchel@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Nov 2011 10:36:55 +0000 (10:36 +0000)
Both classes have been merged into a single ScopeInfo
class that implements the functionality from both.

This CL does not adapt the broken gdb-jit interface.

Review URL: http://codereview.chromium.org/8352039

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9868 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

23 files changed:
src/accessors.cc
src/compiler.cc
src/contexts.cc
src/factory.cc
src/factory.h
src/frames.cc
src/full-codegen.cc
src/gdb-jit.cc
src/heap.cc
src/heap.h
src/hydrogen.cc
src/liveedit.cc
src/objects-inl.h
src/objects.h
src/parser.cc
src/profile-generator.cc
src/runtime.cc
src/scopeinfo.cc
src/scopeinfo.h
src/scopes.cc
src/scopes.h
src/serialize.h
src/v8globals.h

index 02998f9b8ee9f1d0d210c80ff9add4117762be3a..fac8ed96188a8c019aa05d73b414d2e5fc5d61c3 100644 (file)
@@ -621,8 +621,9 @@ MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
 
       if (!frame->is_optimized()) {
         // If there is an arguments variable in the stack, we return that.
-        Handle<SerializedScopeInfo> info(function->shared()->scope_info());
-        int index = info->StackSlotIndex(isolate->heap()->arguments_symbol());
+        Handle<ScopeInfo> scope_info(function->shared()->scope_info());
+        int index = scope_info->StackSlotIndex(
+            isolate->heap()->arguments_symbol());
         if (index >= 0) {
           Handle<Object> arguments(frame->GetExpression(index), isolate);
           if (!arguments->IsArgumentsMarker()) return *arguments;
index 88db467c35e9a688ffae4dbb37716bfa44e3bc5c..4a5f399677a79ef732009fd27fb5914f57fe5ee4 100644 (file)
@@ -326,8 +326,7 @@ bool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) {
   // the compilation info is set if compilation succeeded.
   bool succeeded = MakeCode(info);
   if (!info->shared_info().is_null()) {
-    Handle<SerializedScopeInfo> scope_info =
-        SerializedScopeInfo::Create(info->scope());
+    Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope());
     info->shared_info()->set_scope_info(*scope_info);
   }
   return succeeded;
@@ -395,7 +394,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
           lit->name(),
           lit->materialized_literal_count(),
           info->code(),
-          SerializedScopeInfo::Create(info->scope()));
+          ScopeInfo::Create(info->scope()));
 
   ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
   Compiler::SetFunctionInfo(result, lit, true, script);
@@ -623,7 +622,7 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
       RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
 
       if (info->IsOptimizing()) {
-        ASSERT(shared->scope_info() != SerializedScopeInfo::Empty());
+        ASSERT(shared->scope_info() != ScopeInfo::Empty());
         function->ReplaceCode(*code);
       } else {
         // Update the shared function info with the compiled code and the
@@ -631,8 +630,7 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
         // info initialization is important since set_scope_info might
         // trigger a GC, causing the ASSERT below to be invalid if the code
         // was flushed. By settting the code object last we avoid this.
-        Handle<SerializedScopeInfo> scope_info =
-            SerializedScopeInfo::Create(info->scope());
+        Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope());
         shared->set_scope_info(*scope_info);
         shared->set_code(*code);
         if (!function.is_null()) {
@@ -695,7 +693,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
   bool allow_lazy = literal->AllowsLazyCompilation() &&
       !LiveEditFunctionTracker::IsActive(info.isolate());
 
-  Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty());
+  Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
 
   // Generate code
   if (FLAG_lazy && allow_lazy) {
@@ -704,7 +702,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
   } else if ((V8::UseCrankshaft() && MakeCrankshaftCode(&info)) ||
              (!V8::UseCrankshaft() && FullCodeGenerator::MakeCode(&info))) {
     ASSERT(!info.code().is_null());
-    scope_info = SerializedScopeInfo::Create(info.scope());
+    scope_info = ScopeInfo::Create(info.scope());
   } else {
     return Handle<SharedFunctionInfo>::null();
   }
index b25ffac931323754eac97f7fa21379b4ba89d67a..0e7ef5f607f8ec81c8ca8a05b2ff8d0e5d3add12 100644 (file)
@@ -137,13 +137,13 @@ Handle<Object> Context::Lookup(Handle<String> name,
     if (context->IsFunctionContext() || context->IsBlockContext()) {
       // Use serialized scope information of functions and blocks to search
       // for the context index.
-      Handle<SerializedScopeInfo> scope_info;
+      Handle<ScopeInfo> scope_info;
       if (context->IsFunctionContext()) {
-        scope_info = Handle<SerializedScopeInfo>(
+        scope_info = Handle<ScopeInfo>(
             context->closure()->shared()->scope_info(), isolate);
       } else {
-        scope_info = Handle<SerializedScopeInfo>(
-            SerializedScopeInfo::cast(context->extension()), isolate);
+        scope_info = Handle<ScopeInfo>(
+            ScopeInfo::cast(context->extension()), isolate);
       }
       VariableMode mode;
       int slot_index = scope_info->ContextSlotIndex(*name, &mode);
@@ -250,8 +250,7 @@ bool Context::GlobalIfNotShadowedByEval(Handle<String> name) {
     ASSERT(context->IsFunctionContext());
 
     // Check non-parameter locals.
-    Handle<SerializedScopeInfo> scope_info(
-        context->closure()->shared()->scope_info());
+    Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info());
     VariableMode mode;
     int index = scope_info->ContextSlotIndex(*name, &mode);
     ASSERT(index < 0 || index >= MIN_CONTEXT_SLOTS);
@@ -262,7 +261,7 @@ bool Context::GlobalIfNotShadowedByEval(Handle<String> name) {
     if (param_index >= 0) return false;
 
     // Check context only holding the function name variable.
-    index = scope_info->FunctionContextSlotIndex(*name, NULL);
+    index = scope_info->FunctionContextSlotIndex(*name, &mode);
     if (index >= 0) return false;
     context = context->previous();
   }
@@ -279,9 +278,7 @@ void Context::ComputeEvalScopeInfo(bool* outer_scope_calls_non_strict_eval) {
   Context* context = this;
   while (!context->IsGlobalContext()) {
     if (context->IsFunctionContext()) {
-      Handle<SerializedScopeInfo> scope_info(
-          context->closure()->shared()->scope_info());
-      if (scope_info->CallsEval() && !scope_info->IsStrictMode()) {
+      if (context->closure()->shared()->scope_info()->CallsNonStrictEval()) {
         // No need to go further since the answers will not change from
         // here.
         *outer_scope_calls_non_strict_eval = true;
index 15f640e7e564bf611ee31f87da0853ae978376cd..88684a4fb87ab3907ed501fdbcd5e2d1d16e06f4 100644 (file)
@@ -303,7 +303,7 @@ Handle<Context> Factory::NewWithContext(Handle<JSFunction> function,
 Handle<Context> Factory::NewBlockContext(
     Handle<JSFunction> function,
     Handle<Context> previous,
-    Handle<SerializedScopeInfo> scope_info) {
+    Handle<ScopeInfo> scope_info) {
   CALL_HEAP_FUNCTION(
       isolate(),
       isolate()->heap()->AllocateBlockContext(*function,
@@ -766,11 +766,11 @@ Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
 }
 
 
-Handle<SerializedScopeInfo> Factory::NewSerializedScopeInfo(int length) {
+Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
   CALL_HEAP_FUNCTION(
       isolate(),
-      isolate()->heap()->AllocateSerializedScopeInfo(length),
-      SerializedScopeInfo);
+      isolate()->heap()->AllocateScopeInfo(length),
+      ScopeInfo);
 }
 
 
@@ -985,7 +985,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
     Handle<String> name,
     int number_of_literals,
     Handle<Code> code,
-    Handle<SerializedScopeInfo> scope_info) {
+    Handle<ScopeInfo> scope_info) {
   Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
   shared->set_code(*code);
   shared->set_scope_info(*scope_info);
index 2073ce392626d34a1106d388438c3253861ffa8d..158db5b49c3925fe6d419583cdaa5806601836a6 100644 (file)
@@ -172,7 +172,7 @@ class Factory {
   // Create a 'block' context.
   Handle<Context> NewBlockContext(Handle<JSFunction> function,
                                   Handle<Context> previous,
-                                  Handle<SerializedScopeInfo> scope_info);
+                                  Handle<ScopeInfo> scope_info);
 
   // Return the Symbol matching the passed in string.
   Handle<String> SymbolFromString(Handle<String> value);
@@ -291,7 +291,7 @@ class Factory {
       Handle<Context> context,
       PretenureFlag pretenure = TENURED);
 
-  Handle<SerializedScopeInfo> NewSerializedScopeInfo(int length);
+  Handle<ScopeInfo> NewScopeInfo(int length);
 
   Handle<Code> NewCode(const CodeDesc& desc,
                        Code::Flags flags,
@@ -409,7 +409,7 @@ class Factory {
       Handle<String> name,
       int number_of_literals,
       Handle<Code> code,
-      Handle<SerializedScopeInfo> scope_info);
+      Handle<ScopeInfo> scope_info);
   Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
 
   Handle<JSMessageObject> NewJSMessageObject(
index 7c4c573e127b0c11f3bd6c313edc509dc72d1e33..9fd00422aa07056df0a8b80a49e422894d3c691f 100644 (file)
@@ -1002,11 +1002,15 @@ void JavaScriptFrame::Print(StringStream* accumulator,
   if (IsConstructor()) accumulator->Add("new ");
   accumulator->PrintFunction(function, receiver, &code);
 
-  Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty());
+  // Get scope information for nicer output, if possible. If code is NULL, or
+  // doesn't contain scope info, scope_info will return 0 for the number of
+  // parameters, stack local variables, context local variables, stack slots,
+  // or context slots.
+  Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
 
   if (function->IsJSFunction()) {
     Handle<SharedFunctionInfo> shared(JSFunction::cast(function)->shared());
-    scope_info = Handle<SerializedScopeInfo>(shared->scope_info());
+    scope_info = Handle<ScopeInfo>(shared->scope_info());
     Object* script_obj = shared->script();
     if (script_obj->IsScript()) {
       Handle<Script> script(Script::cast(script_obj));
@@ -1031,11 +1035,6 @@ void JavaScriptFrame::Print(StringStream* accumulator,
 
   accumulator->Add("(this=%o", receiver);
 
-  // Get scope information for nicer output, if possible. If code is
-  // NULL, or doesn't contain scope info, info will return 0 for the
-  // number of parameters, stack slots, or context slots.
-  ScopeInfo<PreallocatedStorage> info(*scope_info);
-
   // Print the parameters.
   int parameters_count = ComputeParametersCount();
   for (int i = 0; i < parameters_count; i++) {
@@ -1043,8 +1042,8 @@ void JavaScriptFrame::Print(StringStream* accumulator,
     // If we have a name for the parameter we print it. Nameless
     // parameters are either because we have more actual parameters
     // than formal parameters or because we have no scope information.
-    if (i < info.number_of_parameters()) {
-      accumulator->PrintName(*info.parameter_name(i));
+    if (i < scope_info->ParameterCount()) {
+      accumulator->PrintName(scope_info->ParameterName(i));
       accumulator->Add("=");
     }
     accumulator->Add("%o", GetParameter(i));
@@ -1062,8 +1061,8 @@ void JavaScriptFrame::Print(StringStream* accumulator,
   accumulator->Add(" {\n");
 
   // Compute the number of locals and expression stack elements.
-  int stack_locals_count = info.number_of_stack_slots();
-  int heap_locals_count = info.number_of_context_slots();
+  int stack_locals_count = scope_info->StackLocalCount();
+  int heap_locals_count = scope_info->ContextLocalCount();
   int expressions_count = ComputeExpressionsCount();
 
   // Print stack-allocated local variables.
@@ -1072,7 +1071,7 @@ void JavaScriptFrame::Print(StringStream* accumulator,
   }
   for (int i = 0; i < stack_locals_count; i++) {
     accumulator->Add("  var ");
-    accumulator->PrintName(*info.stack_slot_name(i));
+    accumulator->PrintName(scope_info->StackLocalName(i));
     accumulator->Add(" = ");
     if (i < expressions_count) {
       accumulator->Add("%o", GetExpression(i));
@@ -1089,16 +1088,16 @@ void JavaScriptFrame::Print(StringStream* accumulator,
   }
 
   // Print heap-allocated local variables.
-  if (heap_locals_count > Context::MIN_CONTEXT_SLOTS) {
+  if (heap_locals_count > 0) {
     accumulator->Add("  // heap-allocated locals\n");
   }
-  for (int i = Context::MIN_CONTEXT_SLOTS; i < heap_locals_count; i++) {
+  for (int i = 0; i < heap_locals_count; i++) {
     accumulator->Add("  var ");
-    accumulator->PrintName(*info.context_slot_name(i));
+    accumulator->PrintName(scope_info->ContextLocalName(i));
     accumulator->Add(" = ");
     if (context != NULL) {
       if (i < context->length()) {
-        accumulator->Add("%o", context->get(i));
+        accumulator->Add("%o", context->get(Context::MIN_CONTEXT_SLOTS + i));
       } else {
         accumulator->Add(
             "// warning: missing context slot - inconsistent frame?");
index e6fac19323847e4c64c4fac78acefe14627c2510..1589b86a59785ea3928aa4ae8b4e724354462131 100644 (file)
@@ -798,9 +798,8 @@ void FullCodeGenerator::VisitBlock(Block* stmt) {
   if (stmt->block_scope() != NULL) {
     { Comment cmnt(masm_, "[ Extend block context");
       scope_ = stmt->block_scope();
-      Handle<SerializedScopeInfo> scope_info = scope_->GetSerializedScopeInfo();
-      int heap_slots =
-          scope_info->NumberOfContextSlots() - Context::MIN_CONTEXT_SLOTS;
+      Handle<ScopeInfo> scope_info = scope_->GetScopeInfo();
+      int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS;
       __ Push(scope_info);
       PushFunctionArgumentForContextAllocation();
       if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) {
index 68cb0533b8e3695eceebc634e0a209a14fc106fb..b386bed177aa3925396bfeddb209c48fce4e8e54 100644 (file)
@@ -1115,13 +1115,13 @@ class DebugInfoSection : public DebugSection {
       int context_slots = scope_info.number_of_context_slots();
       // The real slot ID is internal_slots + context_slot_id.
       int internal_slots = Context::MIN_CONTEXT_SLOTS;
-      int locals = scope_info.NumberOfLocals();
+      int locals = scope_info.LocalCount();
       int current_abbreviation = 4;
 
       for (int param = 0; param < params; ++param) {
         w->WriteULEB128(current_abbreviation++);
         w->WriteString(
-            *scope_info.parameter_name(param)->ToCString(DISALLOW_NULLS));
+            *scope_info.ParameterName(param)->ToCString(DISALLOW_NULLS));
         w->Write<uint32_t>(ty_offset);
         Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
         uintptr_t block_start = w->position();
@@ -1312,7 +1312,7 @@ class DebugAbbrevSection : public DebugSection {
       int context_slots = scope_info.number_of_context_slots();
       // The real slot ID is internal_slots + context_slot_id.
       int internal_slots = Context::MIN_CONTEXT_SLOTS;
-      int locals = scope_info.NumberOfLocals();
+      int locals = scope_info.LocalCount();
       int total_children =
           params + slots + context_slots + internal_slots + locals + 2;
 
index bded80b48f0e1a43f1293ba1996423a33541ad15..7ce8d712c22d4bbc2a420c839be2460c477ad17d 100644 (file)
@@ -1871,7 +1871,7 @@ bool Heap::CreateInitialMaps() {
         AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_serialized_scope_info_map(Map::cast(obj));
+  set_scope_info_map(Map::cast(obj));
 
   { MaybeObject* maybe_obj = AllocateMap(HEAP_NUMBER_TYPE, HeapNumber::kSize);
     if (!maybe_obj->ToObject(&obj)) return false;
@@ -2646,7 +2646,7 @@ MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
   share->set_name(name);
   Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
   share->set_code(illegal);
-  share->set_scope_info(SerializedScopeInfo::Empty());
+  share->set_scope_info(ScopeInfo::Empty());
   Code* construct_stub =
       isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric);
   share->set_construct_stub(construct_stub);
@@ -4394,10 +4394,10 @@ MaybeObject* Heap::AllocateWithContext(JSFunction* function,
 
 MaybeObject* Heap::AllocateBlockContext(JSFunction* function,
                                         Context* previous,
-                                        SerializedScopeInfo* scope_info) {
+                                        ScopeInfo* scope_info) {
   Object* result;
   { MaybeObject* maybe_result =
-        AllocateFixedArrayWithHoles(scope_info->NumberOfContextSlots());
+        AllocateFixedArrayWithHoles(scope_info->ContextLength());
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
   Context* context = reinterpret_cast<Context*>(result);
@@ -4410,14 +4410,11 @@ MaybeObject* Heap::AllocateBlockContext(JSFunction* function,
 }
 
 
-MaybeObject* Heap::AllocateSerializedScopeInfo(int length) {
-  Object* result;
-  { MaybeObject* maybe_result = AllocateFixedArray(length, TENURED);
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-  }
-  SerializedScopeInfo* scope_info =
-      reinterpret_cast<SerializedScopeInfo*>(result);
-  scope_info->set_map(serialized_scope_info_map());
+MaybeObject* Heap::AllocateScopeInfo(int length) {
+  FixedArray* scope_info;
+  MaybeObject* maybe_scope_info = AllocateFixedArray(length, TENURED);
+  if (!maybe_scope_info->To(&scope_info)) return maybe_scope_info;
+  scope_info->set_map(scope_info_map());
   return scope_info;
 }
 
index 7c0b0ea8d6dd31767734331c238e26fcbbc54744..60ea3373f4a7239da94040a0fa029edcf669ea89 100644 (file)
@@ -73,7 +73,7 @@ inline Heap* _inline_get_heap_();
   V(Map, global_context_map, GlobalContextMap)                                 \
   V(Map, fixed_array_map, FixedArrayMap)                                       \
   V(Map, code_map, CodeMap)                                                    \
-  V(Map, serialized_scope_info_map, SerializedScopeInfoMap)                    \
+  V(Map, scope_info_map, ScopeInfoMap)                                         \
   V(Map, fixed_cow_array_map, FixedCOWArrayMap)                                \
   V(Map, fixed_double_array_map, FixedDoubleArrayMap)                          \
   V(Object, no_interceptor_result_sentinel, NoInterceptorResultSentinel)       \
@@ -547,7 +547,7 @@ class Heap {
   MUST_USE_RESULT MaybeObject* AllocateCodeCache();
 
   // Allocates a serialized scope info.
-  MUST_USE_RESULT MaybeObject* AllocateSerializedScopeInfo(int length);
+  MUST_USE_RESULT MaybeObject* AllocateScopeInfo(int length);
 
   // Allocates an empty PolymorphicCodeCache.
   MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
@@ -737,7 +737,7 @@ class Heap {
   // Allocate a block context.
   MUST_USE_RESULT MaybeObject* AllocateBlockContext(JSFunction* function,
                                                     Context* previous,
-                                                    SerializedScopeInfo* info);
+                                                    ScopeInfo* info);
 
   // Allocates a new utility object in the old generation.
   MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
index a7a022d5ec45913baade8bb7b875ba8a56b1b159..fdd9dfb5d27140767812d556006ca0509f46c31d 100644 (file)
@@ -4705,11 +4705,11 @@ bool HGraphBuilder::TryInline(Call* expr, bool drop_extra) {
       TraceInline(target, caller, "could not generate deoptimization info");
       return false;
     }
-    if (target_shared->scope_info() == SerializedScopeInfo::Empty()) {
+    if (target_shared->scope_info() == ScopeInfo::Empty()) {
       // The scope info might not have been set if a lazily compiled
       // function is inlined before being called for the first time.
-      Handle<SerializedScopeInfo> target_scope_info =
-          SerializedScopeInfo::Create(target_info.scope());
+      Handle<ScopeInfo> target_scope_info =
+          ScopeInfo::Create(target_info.scope());
       target_shared->set_scope_info(*target_scope_info);
     }
     target_shared->EnableDeoptimizationSupport(*target_info.code());
index 6107cbf0b4e351253851d7df8b8a9e1b13d9fb13..ce903d1f781cb4e7d52b09fb51f5fe495955e51e 100644 (file)
@@ -1108,7 +1108,7 @@ MaybeObject* LiveEdit::ReplaceFunctionCode(
     ReplaceCodeObject(shared_info->code(), *code);
     Handle<Object> code_scope_info =  compile_info_wrapper.GetCodeScopeInfo();
     if (code_scope_info->IsFixedArray()) {
-      shared_info->set_scope_info(SerializedScopeInfo::cast(*code_scope_info));
+      shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info));
     }
   }
 
index 51d92baad7da8702f35ac10e9cbbaf95699f1d27..1bd3d93676c8f2855d65b65ce482f40dc2138bf3 100644 (file)
@@ -563,10 +563,10 @@ bool Object::IsGlobalContext() {
 }
 
 
-bool Object::IsSerializedScopeInfo() {
+bool Object::IsScopeInfo() {
   return Object::IsHeapObject() &&
       HeapObject::cast(this)->map() ==
-      HeapObject::cast(this)->GetHeap()->serialized_scope_info_map();
+      HeapObject::cast(this)->GetHeap()->scope_info_map();
 }
 
 
@@ -2015,6 +2015,7 @@ CAST_ACCESSOR(DeoptimizationOutputData)
 CAST_ACCESSOR(SymbolTable)
 CAST_ACCESSOR(JSFunctionResultCache)
 CAST_ACCESSOR(NormalizedMapCache)
+CAST_ACCESSOR(ScopeInfo)
 CAST_ACCESSOR(CompilationCacheTable)
 CAST_ACCESSOR(CodeCacheHashTable)
 CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
@@ -3545,13 +3546,12 @@ void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
 }
 
 
-SerializedScopeInfo* SharedFunctionInfo::scope_info() {
-  return reinterpret_cast<SerializedScopeInfo*>(
-      READ_FIELD(this, kScopeInfoOffset));
+ScopeInfo* SharedFunctionInfo::scope_info() {
+  return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
 }
 
 
-void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
+void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
                                         WriteBarrierMode mode) {
   WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
   CONDITIONAL_WRITE_BARRIER(GetHeap(),
index 3187467b380a9cde1d4355ea007238fb1075e317..1805f63dc59fb9309fcd8d8db0062764330e346e 100644 (file)
@@ -78,7 +78,7 @@
 //             - MapCache
 //           - Context
 //           - JSFunctionResultCache
-//           - SerializedScopeInfo
+//           - ScopeInfo
 //         - FixedDoubleArray
 //         - ExternalArray
 //           - ExternalPixelArray
@@ -814,7 +814,7 @@ class MaybeObject BASE_EMBEDDED {
   V(FixedDoubleArray)                          \
   V(Context)                                   \
   V(GlobalContext)                             \
-  V(SerializedScopeInfo)                       \
+  V(ScopeInfo)                                 \
   V(JSFunction)                                \
   V(Code)                                      \
   V(Oddball)                                   \
@@ -3098,14 +3098,16 @@ class JSFunctionResultCache: public FixedArray {
 };
 
 
+// ScopeInfo represents information about different scopes of a source
+// program  and the allocation of the scope's variables. Scope information
+// is stored in a compressed form in ScopeInfo objects and is used
+// at runtime (stack dumps, deoptimization, etc.).
+
 // This object provides quick access to scope info details for runtime
-// routines w/o the need to explicitly create a ScopeInfo object.
-class SerializedScopeInfo : public FixedArray {
- public :
-  static SerializedScopeInfo* cast(Object* object) {
-    ASSERT(object->IsSerializedScopeInfo());
-    return reinterpret_cast<SerializedScopeInfo*>(object);
-  }
+// routines.
+class ScopeInfo : public FixedArray {
+ public:
+  static inline ScopeInfo* cast(Object* object);
 
   // Return the type of this scope.
   ScopeType Type();
@@ -3116,18 +3118,57 @@ class SerializedScopeInfo : public FixedArray {
   // Is this scope a strict mode scope?
   bool IsStrictMode();
 
-  // Return the number of stack slots for code.
-  int NumberOfStackSlots();
+  // Does this scope make a non-strict eval call?
+  bool CallsNonStrictEval() {
+    return CallsEval() && !IsStrictMode();
+  }
+
+  // Return the total number of locals allocated on the stack and in the
+  // context. This includes the parameters that are allocated in the context.
+  int LocalCount();
 
-  // Return the number of context slots for code.
-  int NumberOfContextSlots();
+  // Return the number of stack slots for code. This number consists of two
+  // parts:
+  //  1. One stack slot per stack allocated local.
+  //  2. One stack slot for the function name if it is stack allocated.
+  int StackSlotCount();
 
-  // Return if this has context slots besides MIN_CONTEXT_SLOTS;
+  // Return the number of context slots for code if a context is allocated. This
+  // number consists of three parts:
+  //  1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
+  //  2. One context slot per context allocated local.
+  //  3. One context slot for the function name if it is context allocated.
+  // Parameters allocated in the context count as context allocated locals. If
+  // no contexts are allocated for this scope ContextLength returns 0.
+  int ContextLength();
+
+  // Is this scope the scope of a named function expression?
+  bool HasFunctionName();
+
+  // Return if this has context allocated locals.
   bool HasHeapAllocatedLocals();
 
   // Return if contexts are allocated for this scope.
   bool HasContext();
 
+  // Return the function_name if present.
+  String* FunctionName();
+
+  // Return the name of the given parameter.
+  String* ParameterName(int var);
+
+  // Return the name of the given local.
+  String* LocalName(int var);
+
+  // Return the name of the given stack local.
+  String* StackLocalName(int var);
+
+  // Return the name of the given context local.
+  String* ContextLocalName(int var);
+
+  // Return the mode of the given context local.
+  VariableMode ContextLocalMode(int var);
+
   // Lookup support for serialized scope info. Returns the
   // the stack slot index for a given slot name if the slot is
   // present; otherwise returns a value < 0. The name must be a symbol
@@ -3152,17 +3193,98 @@ class SerializedScopeInfo : public FixedArray {
   // must be a symbol (canonicalized).
   int FunctionContextSlotIndex(String* name, VariableMode* mode);
 
-  static Handle<SerializedScopeInfo> Create(Scope* scope);
+  static Handle<ScopeInfo> Create(Scope* scope);
 
   // Serializes empty scope info.
-  static SerializedScopeInfo* Empty();
+  static ScopeInfo* Empty();
+
+#ifdef DEBUG
+  void Print();
+#endif
+
+  // The layout of the static part of a ScopeInfo is as follows. Each entry is
+  // numeric and occupies one array slot.
+  // 1. A set of properties of the scope
+  // 2. The number of parameters. This only applies to function scopes. For
+  //    non-function scopes this is 0.
+  // 3. The number of non-parameter variables allocated on the stack.
+  // 4. The number of non-parameter and parameter variables allocated in the
+  //    context.
+#define FOR_EACH_NUMERIC_FIELD(V)          \
+  V(Flags)                                 \
+  V(ParameterCount)                        \
+  V(StackLocalCount)                       \
+  V(ContextLocalCount)
+
+#define FIELD_ACCESSORS(name)                            \
+  void Set##name(int value) {                            \
+    set(k##name, Smi::FromInt(value));                   \
+  }                                                      \
+  int name() {                                           \
+    if (length() > 0) {                                  \
+      return Smi::cast(get(k##name))->value();           \
+    } else {                                             \
+      return 0;                                          \
+    }                                                    \
+  }
+  FOR_EACH_NUMERIC_FIELD(FIELD_ACCESSORS)
+#undef FIELD_ACCESSORS
 
  private:
-  Object** ContextEntriesAddr();
+  enum {
+#define DECL_INDEX(name) k##name,
+  FOR_EACH_NUMERIC_FIELD(DECL_INDEX)
+#undef DECL_INDEX
+#undef FOR_EACH_NUMERIC_FIELD
+  kVariablePartIndex
+  };
 
-  Object** ParameterEntriesAddr();
+  // The layout of the variable part of a ScopeInfo is as follows:
+  // 1. ParameterEntries:
+  //    This part stores the names of the parameters for function scopes. One
+  //    slot is used per parameter, so in total this part occupies
+  //    ParameterCount() slots in the array. For other scopes than function
+  //    scopes ParameterCount() is 0.
+  // 2. StackLocalEntries:
+  //    Contains the names of local variables that are allocated on the stack,
+  //    in increasing order of the stack slot index. One slot is used per stack
+  //    local, so in total this part occupies StackLocalCount() slots in the
+  //    array.
+  // 3. ContextLocalNameEntries:
+  //    Contains the names of local variables and parameters that are allocated
+  //    in the context. They are stored in increasing order of the context slot
+  //    index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
+  //    context local, so in total this part occupies ContextLocalCount() slots
+  //    in the array.
+  // 4. ContextLocalModeEntries:
+  //    Contains the variable modes corresponding to the context locals in
+  //    ContextLocalNameEntries. One slot is used per context local, so in total
+  //    this part occupies ContextLocalCount() slots in the array.
+  // 5. FunctionNameEntryIndex:
+  //    If the scope belongs to a named function expression this part contains
+  //    information about the function variable. It always occupies two array
+  //    slots:  a. The name of the function variable.
+  //            b. The context or stack slot index for the variable.
+  int ParameterEntriesIndex();
+  int StackLocalEntriesIndex();
+  int ContextLocalNameEntriesIndex();
+  int ContextLocalModeEntriesIndex();
+  int FunctionNameEntryIndex();
+
+  // Location of the function variable for named function expressions.
+  enum FunctionVariableInfo {
+    NONE,     // No function name present.
+    STACK,    // Function
+    CONTEXT,
+    UNUSED
+  };
 
-  Object** StackSlotEntriesAddr();
+  // Properties of scopes.
+  class TypeField:             public BitField<ScopeType,            0, 3> {};
+  class CallsEvalField:        public BitField<bool,                 3, 1> {};
+  class StrictModeField:       public BitField<bool,                 4, 1> {};
+  class FunctionVariableField: public BitField<FunctionVariableInfo, 5, 2> {};
+  class FunctionVariableMode:  public BitField<VariableMode,         7, 3> {};
 };
 
 
@@ -4685,7 +4807,7 @@ class SharedFunctionInfo: public HeapObject {
   DECL_ACCESSORS(code, Code)
 
   // [scope_info]: Scope info.
-  DECL_ACCESSORS(scope_info, SerializedScopeInfo)
+  DECL_ACCESSORS(scope_info, ScopeInfo)
 
   // [construct stub]: Code stub for constructing instances of this function.
   DECL_ACCESSORS(construct_stub, Code)
index 0a635fcbb0bc547f01c2c3029a03341a30e08d9b..21acb83c6c258d0b5a9d114478dbf42719bc9f88 100644 (file)
@@ -1522,7 +1522,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
   Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
   Handle<SharedFunctionInfo> shared =
       isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
-          Handle<SerializedScopeInfo>(fun->shared()->scope_info()));
+          Handle<ScopeInfo>(fun->shared()->scope_info()));
   shared->set_construct_stub(*construct_stub);
 
   // Copy the function data to the shared function info.
index 9812c26e9e410be711b567bff01a0b8b4d061163..7760d8f90e46feb65b8f2ab3c7a615c12bb93aa1 100644 (file)
@@ -2061,20 +2061,27 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
                                               HeapEntry* entry) {
   if (js_obj->IsJSFunction()) {
-    HandleScope hs;
     JSFunction* func = JSFunction::cast(js_obj);
     Context* context = func->context();
-    ZoneScope zscope(Isolate::Current(), DELETE_ON_EXIT);
-    SerializedScopeInfo* serialized_scope_info =
-        context->closure()->shared()->scope_info();
-    ScopeInfo<ZoneListAllocationPolicy> zone_scope_info(serialized_scope_info);
-    int locals_number = zone_scope_info.NumberOfLocals();
-    for (int i = 0; i < locals_number; ++i) {
-      String* local_name = *zone_scope_info.LocalName(i);
-      int idx = serialized_scope_info->ContextSlotIndex(local_name, NULL);
-      if (idx >= 0 && idx < context->length()) {
-        SetClosureReference(js_obj, entry, local_name, context->get(idx));
-      }
+    ScopeInfo* scope_info = context->closure()->shared()->scope_info();
+
+    // Add context allocated locals.
+    int context_locals = scope_info->ContextLocalCount();
+    for (int i = 0; i < context_locals; ++i) {
+      String* local_name = scope_info->ContextLocalName(i);
+      int idx = Context::MIN_CONTEXT_SLOTS + i;
+      SetClosureReference(js_obj, entry, local_name, context->get(idx));
+    }
+
+    // Add function variable.
+    if (scope_info->HasFunctionName()) {
+      String* name = scope_info->FunctionName();
+      int idx = Context::MIN_CONTEXT_SLOTS + context_locals;
+#ifdef DEBUG
+      VariableMode mode;
+      ASSERT(idx == scope_info->FunctionContextSlotIndex(name, &mode));
+#endif
+      SetClosureReference(js_obj, entry, name, context->get(idx));
     }
   }
 }
index f2e23f4e4e7b27ed2599f0f84516d5188d89ce23..f15fbba37ea92c683f66c3a4908a53044fdb87aa 100644 (file)
@@ -7971,14 +7971,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
         --index;
       }
 
-      ScopeInfo<> scope_info(callee->shared()->scope_info());
+      Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
       while (index >= 0) {
         // Detect duplicate names to the right in the parameter list.
-        Handle<String> name = scope_info.parameter_name(index);
-        int context_slot_count = scope_info.number_of_context_slots();
+        Handle<String> name(scope_info->ParameterName(index));
+        int context_local_count = scope_info->ContextLocalCount();
         bool duplicate = false;
         for (int j = index + 1; j < parameter_count; ++j) {
-          if (scope_info.parameter_name(j).is_identical_to(name)) {
+          if (scope_info->ParameterName(j) == *name) {
             duplicate = true;
             break;
           }
@@ -7993,17 +7993,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
           // The context index goes in the parameter map with a hole in the
           // arguments array.
           int context_index = -1;
-          for (int j = Context::MIN_CONTEXT_SLOTS;
-               j < context_slot_count;
-               ++j) {
-            if (scope_info.context_slot_name(j).is_identical_to(name)) {
+          for (int j = 0; j < context_local_count; ++j) {
+            if (scope_info->ContextLocalName(j) == *name) {
               context_index = j;
               break;
             }
           }
           ASSERT(context_index >= 0);
           arguments->set_the_hole(index);
-          parameter_map->set(index + 2, Smi::FromInt(context_index));
+          parameter_map->set(index + 2, Smi::FromInt(
+              Context::MIN_CONTEXT_SLOTS + context_index));
         }
 
         --index;
@@ -8764,7 +8763,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
   ASSERT(args.length() == 1);
 
   CONVERT_CHECKED(JSFunction, function, args[0]);
-  int length = function->shared()->scope_info()->NumberOfContextSlots();
+  int length = function->shared()->scope_info()->ContextLength();
   Object* result;
   { MaybeObject* maybe_result =
         isolate->heap()->AllocateFunctionContext(length, function);
@@ -8850,7 +8849,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 2);
-  SerializedScopeInfo* scope_info = SerializedScopeInfo::cast(args[0]);
+  ScopeInfo* scope_info = ScopeInfo::cast(args[0]);
   JSFunction* function;
   if (args[1]->IsSmi()) {
     // A smi sentinel indicates a context nested inside global code rather
@@ -10770,9 +10769,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
   // Get scope info and read from it for local variable information.
   Handle<JSFunction> function(JSFunction::cast(it.frame()->function()));
   Handle<SharedFunctionInfo> shared(function->shared());
-  Handle<SerializedScopeInfo> scope_info(shared->scope_info());
-  ASSERT(*scope_info != SerializedScopeInfo::Empty());
-  ScopeInfo<> info(*scope_info);
+  Handle<ScopeInfo> scope_info(shared->scope_info());
+  ASSERT(*scope_info != ScopeInfo::Empty());
 
   // Get the locals names and values into a temporary array.
   //
@@ -10780,24 +10778,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
   // (e.g. .result)?  For users of the debugger, they will probably be
   // confusing.
   Handle<FixedArray> locals =
-      isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
+      isolate->factory()->NewFixedArray(scope_info->LocalCount() * 2);
 
   // Fill in the values of the locals.
   int i = 0;
-  for (; i < info.number_of_stack_slots(); ++i) {
+  for (; i < scope_info->StackLocalCount(); ++i) {
     // Use the value from the stack.
-    locals->set(i * 2, *info.LocalName(i));
+    locals->set(i * 2, scope_info->LocalName(i));
     locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
   }
-  if (i < info.NumberOfLocals()) {
+  if (i < scope_info->LocalCount()) {
     // Get the context containing declarations.
     Handle<Context> context(
         Context::cast(it.frame()->context())->declaration_context());
-    for (; i < info.NumberOfLocals(); ++i) {
-      Handle<String> name = info.LocalName(i);
+    for (; i < scope_info->LocalCount(); ++i) {
+      Handle<String> name(scope_info->LocalName(i));
+      VariableMode mode;
       locals->set(i * 2, *name);
       locals->set(i * 2 + 1,
-                  context->get(scope_info->ContextSlotIndex(*name, NULL)));
+                  context->get(scope_info->ContextSlotIndex(*name, &mode)));
     }
   }
 
@@ -10851,7 +10850,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
 
   // Find the number of arguments to fill. At least fill the number of
   // parameters for the function and fill more if more parameters are provided.
-  int argument_count = info.number_of_parameters();
+  int argument_count = scope_info->ParameterCount();
   if (argument_count < frame_inspector.GetParametersCount()) {
     argument_count = frame_inspector.GetParametersCount();
   }
@@ -10863,7 +10862,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
 
   // Calculate the size of the result.
   int details_size = kFrameDetailsFirstDynamicIndex +
-                     2 * (argument_count + info.NumberOfLocals()) +
+                     2 * (argument_count + scope_info->LocalCount()) +
                      (at_return ? 1 : 0);
   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
 
@@ -10878,7 +10877,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
 
   // Add the locals count
   details->set(kFrameDetailsLocalCountIndex,
-               Smi::FromInt(info.NumberOfLocals()));
+               Smi::FromInt(scope_info->LocalCount()));
 
   // Add the source position.
   if (position != RelocInfo::kNoPosition) {
@@ -10913,8 +10912,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
   // Add arguments name and value.
   for (int i = 0; i < argument_count; i++) {
     // Name of the argument.
-    if (i < info.number_of_parameters()) {
-      details->set(details_index++, *info.parameter_name(i));
+    if (i < scope_info->ParameterCount()) {
+      details->set(details_index++, scope_info->ParameterName(i));
     } else {
       details->set(details_index++, heap->undefined_value());
     }
@@ -10929,7 +10928,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
   }
 
   // Add locals name and value from the temporary copy from the function frame.
-  for (int i = 0; i < info.NumberOfLocals() * 2; i++) {
+  for (int i = 0; i < scope_info->LocalCount() * 2; i++) {
     details->set(details_index++, locals->get(i));
   }
 
@@ -10965,21 +10964,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
 // Copy all the context locals into an object used to materialize a scope.
 static bool CopyContextLocalsToScopeObject(
     Isolate* isolate,
-    Handle<SerializedScopeInfo> serialized_scope_info,
-    ScopeInfo<>& scope_info,
+    Handle<ScopeInfo> scope_info,
     Handle<Context> context,
     Handle<JSObject> scope_object) {
   // Fill all context locals to the context extension.
-  for (int i = Context::MIN_CONTEXT_SLOTS;
-       i < scope_info.number_of_context_slots();
-       i++) {
-    int context_index = serialized_scope_info->ContextSlotIndex(
-        *scope_info.context_slot_name(i), NULL);
+  for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
+    VariableMode mode;
+    int context_index = scope_info->ContextSlotIndex(
+        scope_info->ContextLocalName(i), &mode);
 
     RETURN_IF_EMPTY_HANDLE_VALUE(
         isolate,
         SetProperty(scope_object,
-                    scope_info.context_slot_name(i),
+                    Handle<String>(scope_info->ContextLocalName(i)),
                     Handle<Object>(context->get(context_index), isolate),
                     NONE,
                     kNonStrictMode),
@@ -10998,8 +10995,7 @@ static Handle<JSObject> MaterializeLocalScope(
     int inlined_frame_index) {
   Handle<JSFunction> function(JSFunction::cast(frame->function()));
   Handle<SharedFunctionInfo> shared(function->shared());
-  Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
-  ScopeInfo<> scope_info(*serialized_scope_info);
+  Handle<ScopeInfo> scope_info(shared->scope_info());
   FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
 
   // Allocate and initialize a JSObject with all the arguments, stack locals
@@ -11008,11 +11004,11 @@ static Handle<JSObject> MaterializeLocalScope(
       isolate->factory()->NewJSObject(isolate->object_function());
 
   // First fill all parameters.
-  for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
+  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
     RETURN_IF_EMPTY_HANDLE_VALUE(
         isolate,
         SetProperty(local_scope,
-                    scope_info.parameter_name(i),
+                    Handle<String>(scope_info->ParameterName(i)),
                     Handle<Object>(frame_inspector.GetParameter(i)),
                     NONE,
                     kNonStrictMode),
@@ -11020,24 +11016,23 @@ static Handle<JSObject> MaterializeLocalScope(
   }
 
   // Second fill all stack locals.
-  for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) {
+  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
     RETURN_IF_EMPTY_HANDLE_VALUE(
         isolate,
         SetProperty(local_scope,
-                    scope_info.stack_slot_name(i),
+                    Handle<String>(scope_info->StackLocalName(i)),
                     Handle<Object>(frame_inspector.GetExpression(i)),
                     NONE,
                     kNonStrictMode),
         Handle<JSObject>());
   }
 
-  if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
+  if (scope_info->HasContext()) {
     // Third fill all context locals.
     Handle<Context> frame_context(Context::cast(frame->context()));
     Handle<Context> function_context(frame_context->declaration_context());
-    if (!CopyContextLocalsToScopeObject(isolate,
-                                        serialized_scope_info, scope_info,
-                                        function_context, local_scope)) {
+    if (!CopyContextLocalsToScopeObject(
+            isolate, scope_info, function_context, local_scope)) {
       return Handle<JSObject>();
     }
 
@@ -11080,8 +11075,7 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
   ASSERT(context->IsFunctionContext());
 
   Handle<SharedFunctionInfo> shared(context->closure()->shared());
-  Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
-  ScopeInfo<> scope_info(*serialized_scope_info);
+  Handle<ScopeInfo> scope_info(shared->scope_info());
 
   // Allocate and initialize a JSObject with all the content of theis function
   // closure.
@@ -11089,9 +11083,8 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
       isolate->factory()->NewJSObject(isolate->object_function());
 
   // Fill all context locals to the context extension.
-  if (!CopyContextLocalsToScopeObject(isolate,
-                                      serialized_scope_info, scope_info,
-                                      context, closure_scope)) {
+  if (!CopyContextLocalsToScopeObject(
+          isolate, scope_info, context, closure_scope)) {
     return Handle<JSObject>();
   }
 
@@ -11146,9 +11139,7 @@ static Handle<JSObject> MaterializeBlockScope(
     Isolate* isolate,
     Handle<Context> context) {
   ASSERT(context->IsBlockContext());
-  Handle<SerializedScopeInfo> serialized_scope_info(
-      SerializedScopeInfo::cast(context->extension()));
-  ScopeInfo<> scope_info(*serialized_scope_info);
+  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
 
   // Allocate and initialize a JSObject with all the arguments, stack locals
   // heap locals and extension properties of the debugged function.
@@ -11156,12 +11147,9 @@ static Handle<JSObject> MaterializeBlockScope(
       isolate->factory()->NewJSObject(isolate->object_function());
 
   // Fill all context locals.
-  if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
-    if (!CopyContextLocalsToScopeObject(isolate,
-                                        serialized_scope_info, scope_info,
-                                        context, block_scope)) {
-      return Handle<JSObject>();
-    }
+  if (!CopyContextLocalsToScopeObject(
+          isolate, scope_info, context, block_scope)) {
+    return Handle<JSObject>();
   }
 
   return block_scope;
@@ -11260,7 +11248,7 @@ class ScopeIterator {
   // Return the type of the current scope.
   ScopeType Type() {
     if (!nested_scope_chain_.is_empty()) {
-      Handle<SerializedScopeInfo> scope_info = nested_scope_chain_.last();
+      Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
       switch (scope_info->Type()) {
         case FUNCTION_SCOPE:
           ASSERT(context_->IsFunctionContext() ||
@@ -11324,17 +11312,15 @@ class ScopeIterator {
     return Handle<JSObject>();
   }
 
-  Handle<SerializedScopeInfo> CurrentScopeInfo() {
+  Handle<ScopeInfo> CurrentScopeInfo() {
     if (!nested_scope_chain_.is_empty()) {
       return nested_scope_chain_.last();
     } else if (context_->IsBlockContext()) {
-      return Handle<SerializedScopeInfo>(
-          SerializedScopeInfo::cast(context_->extension()));
+      return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
     } else if (context_->IsFunctionContext()) {
-      return Handle<SerializedScopeInfo>(
-          context_->closure()->shared()->scope_info());
+      return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
     }
-    return Handle<SerializedScopeInfo>::null();
+    return Handle<ScopeInfo>::null();
   }
 
   // Return the context for this scope. For the local context there might not
@@ -11361,8 +11347,7 @@ class ScopeIterator {
 
       case ScopeIterator::ScopeTypeLocal: {
         PrintF("Local:\n");
-        ScopeInfo<> scope_info(function_->shared()->scope_info());
-        scope_info.Print();
+        function_->shared()->scope_info()->Print();
         if (!CurrentContext().is_null()) {
           CurrentContext()->Print();
           if (CurrentContext()->has_extension()) {
@@ -11410,7 +11395,7 @@ class ScopeIterator {
   int inlined_frame_index_;
   Handle<JSFunction> function_;
   Handle<Context> context_;
-  List<Handle<SerializedScopeInfo> > nested_scope_chain_;
+  List<Handle<ScopeInfo> > nested_scope_chain_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
 };
@@ -11879,7 +11864,7 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
                                                    JavaScriptFrame* frame,
                                                    int inlined_frame_index) {
   HandleScope scope(isolate);
-  List<Handle<SerializedScopeInfo> > scope_chain;
+  List<Handle<ScopeInfo> > scope_chain;
   List<Handle<Context> > context_chain;
 
   ScopeIterator it(isolate, frame, inlined_frame_index);
@@ -11895,7 +11880,7 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
 
   // Iteratively copy and or materialize the nested contexts.
   while (!scope_chain.is_empty()) {
-    Handle<SerializedScopeInfo> scope_info = scope_chain.RemoveLast();
+    Handle<ScopeInfo> scope_info = scope_chain.RemoveLast();
     Handle<Context> current = context_chain.RemoveLast();
     ASSERT(!(scope_info->HasContext() & current.is_null()));
 
@@ -11941,23 +11926,23 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate,
                                          JavaScriptFrame* frame,
                                          int inlined_frame_index,
                                          Handle<JSFunction> function,
-                                         Handle<SerializedScopeInfo> scope_info,
-                                         const ScopeInfo<>* sinfo,
+                                         Handle<ScopeInfo> scope_info,
                                          Handle<Context> function_context) {
   // Try to find the value of 'arguments' to pass as parameter. If it is not
   // found (that is the debugged function does not reference 'arguments' and
   // does not support eval) then create an 'arguments' object.
   int index;
-  if (sinfo->number_of_stack_slots() > 0) {
+  if (scope_info->StackLocalCount() > 0) {
     index = scope_info->StackSlotIndex(isolate->heap()->arguments_symbol());
     if (index != -1) {
       return Handle<Object>(frame->GetExpression(index), isolate);
     }
   }
 
-  if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
-    index = scope_info->ContextSlotIndex(isolate->heap()->arguments_symbol(),
-                                         NULL);
+  if (scope_info->HasHeapAllocatedLocals()) {
+    VariableMode mode;
+    index = scope_info->ContextSlotIndex(
+        isolate->heap()->arguments_symbol(), &mode);
     if (index != -1) {
       return Handle<Object>(function_context->get(index), isolate);
     }
@@ -12022,8 +12007,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
   JavaScriptFrameIterator it(isolate, id);
   JavaScriptFrame* frame = it.frame();
   Handle<JSFunction> function(JSFunction::cast(frame->function()));
-  Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
-  ScopeInfo<> sinfo(*scope_info);
+  Handle<ScopeInfo> scope_info(function->shared()->scope_info());
 
   // Traverse the saved contexts chain to find the active context for the
   // selected frame.
@@ -12043,9 +12027,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
                                       isolate->factory()->undefined_value());
   go_between->set_context(function->context());
 #ifdef DEBUG
-  ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info());
-  ASSERT(go_between_sinfo.number_of_parameters() == 0);
-  ASSERT(go_between_sinfo.number_of_context_slots() == 0);
+  Handle<ScopeInfo> go_between_scope_info(go_between->shared()->scope_info());
+  ASSERT(go_between_scope_info->ParameterCount() == 0);
+  ASSERT(go_between_scope_info->ContextLocalCount() == 0);
 #endif
 
   // Materialize the content of the local scope into a JSObject.
@@ -12063,7 +12047,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
   Handle<Context> frame_context(Context::cast(frame->context()));
   Handle<Context> function_context;
   // Get the function's context if it has one.
-  if (scope_info->HasHeapAllocatedLocals()) {
+  if (scope_info->HasContext()) {
     function_context = Handle<Context>(frame_context->declaration_context());
   }
   context = CopyNestedScopeContextChain(isolate,
@@ -12108,9 +12092,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
   if (has_pending_exception) return Failure::Exception();
 
   Handle<Object> arguments = GetArgumentsObject(isolate,
-                                                frame, inlined_frame_index,
-                                                function, scope_info,
-                                                &sinfo, function_context);
+                                                frame,
+                                                inlined_frame_index,
+                                                function,
+                                                scope_info,
+                                                function_context);
 
   // Invoke the evaluation function and return the result.
   Handle<Object> argv[] = { arguments, source };
index 8ea5f1e734151684828637ea1138dbc8250bbe34..16f6b3ce68739467401b1f6e2a03a22e2489682d 100644 (file)
@@ -46,475 +46,304 @@ static int CompareLocal(Variable* const* v, Variable* const* w) {
 }
 
 
-template<class Allocator>
-ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
-    : function_name_(FACTORY->empty_symbol()),
-      calls_eval_(scope->calls_eval()),
-      is_strict_mode_(scope->is_strict_mode()),
-      type_(scope->type()),
-      parameters_(scope->num_parameters()),
-      stack_slots_(scope->num_stack_slots()),
-      context_slots_(scope->num_heap_slots()),
-      context_modes_(scope->num_heap_slots()) {
-  // Add parameters.
-  for (int i = 0; i < scope->num_parameters(); i++) {
-    ASSERT(parameters_.length() == i);
-    parameters_.Add(scope->parameter(i)->name());
-  }
-
-  // Add stack locals and collect heap locals.
-  // We are assuming that the locals' slots are allocated in
-  // increasing order, so we can simply add them to the
-  // ScopeInfo lists. However, due to usage analysis, this is
-  // not true for context-allocated locals: Some of them
-  // may be parameters which are allocated before the
-  // non-parameter locals. When the non-parameter locals are
-  // sorted according to usage, the allocated slot indices may
-  // not be in increasing order with the variable list anymore.
-  // Thus, we first collect the context-allocated locals, and then
-  // sort them by context slot index before adding them to the
-  // ScopeInfo list.
-  List<Variable*, Allocator> locals(32);  // 32 is a wild guess
-  ASSERT(locals.is_empty());
-  scope->CollectUsedVariables(&locals);
-  locals.Sort(&CompareLocal);
-
-  List<Variable*, Allocator> heap_locals(locals.length());
-  for (int i = 0; i < locals.length(); i++) {
-    Variable* var = locals[i];
-    if (var->is_used()) {
-      switch (var->location()) {
-        case Variable::UNALLOCATED:
-        case Variable::PARAMETER:
-          break;
-
-        case Variable::LOCAL:
-          ASSERT(stack_slots_.length() == var->index());
-          stack_slots_.Add(var->name());
-          break;
-
-        case Variable::CONTEXT:
-          heap_locals.Add(var);
-          break;
-
-        case Variable::LOOKUP:
-          // We don't expect lookup variables in the locals list.
-          UNREACHABLE();
-          break;
-      }
+Handle<ScopeInfo> ScopeInfo::Create(Scope* scope) {
+  ZoneList<Variable*> variables(32);  // 32 is a wild guess
+  ASSERT(variables.is_empty());
+  scope->CollectUsedVariables(&variables);
+
+  ZoneList<Variable*> stack_locals(scope->num_stack_slots());
+  ZoneList<Variable*> context_locals(scope->num_heap_slots());
+
+  // Collect stack and context locals.
+  for (int i = 0; i < variables.length(); i++) {
+    Variable* var = variables[i];
+    ASSERT(var->is_used());
+    switch (var->location()) {
+      case Variable::UNALLOCATED:
+      case Variable::PARAMETER:
+        break;
+
+      case Variable::LOCAL:
+        stack_locals.Add(var);
+        break;
+
+      case Variable::CONTEXT:
+        context_locals.Add(var);
+        break;
+
+      case Variable::LOOKUP:
+        // We don't expect lookup variables in the locals list.
+        UNREACHABLE();
+        break;
     }
   }
 
-  // Add heap locals.
-  if (scope->num_heap_slots() > 0) {
-    // Add user-defined slots.
-    for (int i = 0; i < heap_locals.length(); i++) {
-      ASSERT(heap_locals[i]->index() - Context::MIN_CONTEXT_SLOTS ==
-             context_slots_.length());
-      ASSERT(heap_locals[i]->index() - Context::MIN_CONTEXT_SLOTS ==
-             context_modes_.length());
-      context_slots_.Add(heap_locals[i]->name());
-      context_modes_.Add(heap_locals[i]->mode());
+  // Determine use and location of the function variable if it is present.
+  FunctionVariableInfo function_name_info;
+  VariableMode function_variable_mode;
+  if (scope->is_function_scope() && scope->function() != NULL) {
+    Variable* var = scope->function()->var();
+    if (!var->is_used()) {
+      function_name_info = UNUSED;
+    } else if (var->IsContextSlot()) {
+      function_name_info = CONTEXT;
+    } else {
+      ASSERT(var->IsStackLocal());
+      function_name_info = STACK;
     }
-
+    function_variable_mode = var->mode();
   } else {
-    ASSERT(heap_locals.length() == 0);
+    function_name_info = NONE;
+    function_variable_mode = VAR;
   }
 
-  // Add the function context slot, if present.
-  // For now, this must happen at the very end because of the
-  // ordering of the scope info slots and the respective slot indices.
-  if (scope->is_function_scope()) {
-    VariableProxy* proxy = scope->function();
-    if (proxy != NULL &&
-        proxy->var()->is_used() &&
-        proxy->var()->IsContextSlot()) {
-      function_name_ = proxy->name();
-      // Note that we must not find the function name in the context slot
-      // list - instead it must be handled separately in the
-      // Contexts::Lookup() function. Thus record an empty symbol here so we
-      // get the correct number of context slots.
-      ASSERT(proxy->var()->index() - Context::MIN_CONTEXT_SLOTS ==
-             context_slots_.length());
-      ASSERT(proxy->var()->index() - Context::MIN_CONTEXT_SLOTS ==
-             context_modes_.length());
-      context_slots_.Add(FACTORY->empty_symbol());
-      context_modes_.Add(proxy->var()->mode());
-    }
+  const bool has_function_name = function_name_info != NONE;
+  const int parameter_count = scope->num_parameters();
+  const int stack_local_count = stack_locals.length();
+  const int context_local_count = context_locals.length();
+  const int length = kVariablePartIndex
+      + parameter_count + stack_local_count + 2 * context_local_count
+      + (has_function_name ? 2 : 0);
+
+  Handle<ScopeInfo> scope_info = FACTORY->NewScopeInfo(length);
+
+  // Encode the flags.
+  int flags = TypeField::encode(scope->type()) |
+      CallsEvalField::encode(scope->calls_eval()) |
+      StrictModeField::encode(scope->is_strict_mode()) |
+      FunctionVariableField::encode(function_name_info) |
+      FunctionVariableMode::encode(function_variable_mode);
+  scope_info->SetFlags(flags);
+  scope_info->SetParameterCount(parameter_count);
+  scope_info->SetStackLocalCount(stack_local_count);
+  scope_info->SetContextLocalCount(context_local_count);
+
+  int index = kVariablePartIndex;
+  // Add parameters.
+  ASSERT(index == scope_info->ParameterEntriesIndex());
+  for (int i = 0; i < parameter_count; ++i) {
+    scope_info->set(index++, *scope->parameter(i)->name());
   }
-}
 
+  // Add stack locals' names. We are assuming that the stack locals'
+  // slots are allocated in increasing order, so we can simply add
+  // them to the ScopeInfo object.
+  ASSERT(index == scope_info->StackLocalEntriesIndex());
+  for (int i = 0; i < stack_local_count; ++i) {
+    ASSERT(stack_locals[i]->index() == i);
+    scope_info->set(index++, *stack_locals[i]->name());
+  }
 
-// Encoding format in a FixedArray object:
-//
-// - function name
-//
-// - calls eval boolean flag
-//
-// - is strict mode scope
-//
-// - scope type
-//
-// - number of variables in the context object (smi) (= function context
-//   slot index + 1)
-// - list of pairs (name, Var mode) of context-allocated variables (starting
-//   with context slot 0)
-//
-// - number of parameters (smi)
-// - list of parameter names (starting with parameter 0 first)
-//
-// - number of variables on the stack (smi)
-// - list of names of stack-allocated variables (starting with stack slot 0)
+  // Due to usage analysis, context-allocated locals are not necessarily in
+  // increasing order: Some of them may be parameters which are allocated before
+  // the non-parameter locals. When the non-parameter locals are sorted
+  // according to usage, the allocated slot indices may not be in increasing
+  // order with the variable list anymore. Thus, we first need to sort them by
+  // context slot index before adding them to the ScopeInfo object.
+  context_locals.Sort(&CompareLocal);
+
+  // Add context locals' names.
+  ASSERT(index == scope_info->ContextLocalNameEntriesIndex());
+  for (int i = 0; i < context_local_count; ++i) {
+    scope_info->set(index++, *context_locals[i]->name());
+  }
 
-// The ScopeInfo representation could be simplified and the ScopeInfo
-// re-implemented (with almost the same interface). Here is a
-// suggestion for the new format:
-//
-// - have a single list with all variable names (parameters, stack locals,
-//   context locals), followed by a list of non-Object* values containing
-//   the variables information (what kind, index, attributes)
-// - searching the linear list of names is fast and yields an index into the
-//   list if the variable name is found
-// - that list index is then used to find the variable information in the
-//   subsequent list
-// - the list entries don't have to be in any particular order, so all the
-//   current sorting business can go away
-// - the ScopeInfo lookup routines can be reduced to perhaps a single lookup
-//   which returns all information at once
-// - when gathering the information from a Scope, we only need to iterate
-//   through the local variables (parameters and context info is already
-//   present)
+  // Add context locals' modes.
+  ASSERT(index == scope_info->ContextLocalModeEntriesIndex());
+  for (int i = 0; i < context_local_count; ++i) {
+    scope_info->set(index++, Smi::FromInt(context_locals[i]->mode()));
+  }
 
+  // If present, add the function variable name and its index.
+  ASSERT(index == scope_info->FunctionNameEntryIndex());
+  if (has_function_name) {
+    int var_index = scope->function()->var()->index();
+    scope_info->set(index++, *scope->function()->name());
+    scope_info->set(index++, Smi::FromInt(var_index));
+    ASSERT(function_name_info != STACK ||
+           (var_index == scope_info->StackLocalCount() &&
+            var_index == scope_info->StackSlotCount() - 1));
+    ASSERT(function_name_info != CONTEXT ||
+           var_index == scope_info->ContextLength() - 1);
+  }
 
-template <class T>
-static inline Object** ReadInt(Object** p, T* x) {
-  *x = static_cast<T>((reinterpret_cast<Smi*>(*p++))->value());
-  return p;
+  ASSERT(index == scope_info->length());
+  ASSERT(scope->num_parameters() == scope_info->ParameterCount());
+  ASSERT(scope->num_stack_slots() == scope_info->StackSlotCount());
+  ASSERT(scope->num_heap_slots() == scope_info->ContextLength());
+  return scope_info;
 }
 
 
-static inline Object** ReadBool(Object** p, bool* x) {
-  *x = (reinterpret_cast<Smi*>(*p++))->value() != 0;
-  return p;
+ScopeInfo* ScopeInfo::Empty() {
+  return reinterpret_cast<ScopeInfo*>(HEAP->empty_fixed_array());
 }
 
 
-template <class T>
-static inline Object** ReadObject(Object** p, Handle<T>* s) {
-  *s = Handle<T>::cast(Handle<Object>(*p++));
-  return p;
+ScopeType ScopeInfo::Type() {
+  ASSERT(length() > 0);
+  return TypeField::decode(Flags());
 }
 
 
-template <class Allocator, class T>
-static Object** ReadList(Object** p, List<Handle<T>, Allocator >* list) {
-  ASSERT(list->is_empty());
-  int n;
-  p = ReadInt(p, &n);
-  while (n-- > 0) {
-    Handle<T> s;
-    p = ReadObject(p, &s);
-    list->Add(s);
-  }
-  return p;
-}
-
-
-template <class Allocator>
-static Object** ReadList(Object** p,
-                         List<Handle<String>, Allocator>* list,
-                         List<VariableMode, Allocator>* modes) {
-  ASSERT(list->is_empty());
-  int n;
-  p = ReadInt(p, &n);
-  while (n-- > 0) {
-    Handle<String> s;
-    int m;
-    p = ReadObject(p, &s);
-    p = ReadInt(p, &m);
-    list->Add(s);
-    modes->Add(static_cast<VariableMode>(m));
-  }
-  return p;
-}
-
-
-template<class Allocator>
-ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data)
-  : function_name_(FACTORY->empty_symbol()),
-    parameters_(4),
-    stack_slots_(8),
-    context_slots_(8),
-    context_modes_(8) {
-  if (data->length() > 0) {
-    Object** p0 = data->data_start();
-    Object** p = p0;
-    p = ReadObject(p, &function_name_);
-    p = ReadBool(p, &calls_eval_);
-    p = ReadBool(p, &is_strict_mode_);
-    p = ReadInt(p, &type_);
-    p = ReadList<Allocator>(p, &context_slots_, &context_modes_);
-    p = ReadList<Allocator>(p, &parameters_);
-    p = ReadList<Allocator>(p, &stack_slots_);
-    ASSERT((p - p0) == FixedArray::cast(data)->length());
-  }
+bool ScopeInfo::CallsEval() {
+  return length() > 0 && CallsEvalField::decode(Flags());
 }
 
 
-static inline Object** WriteInt(Object** p, int x) {
-  *p++ = Smi::FromInt(x);
-  return p;
+bool ScopeInfo::IsStrictMode() {
+  return length() > 0 && StrictModeField::decode(Flags());
 }
 
 
-static inline Object** WriteBool(Object** p, bool b) {
-  *p++ = Smi::FromInt(b ? 1 : 0);
-  return p;
+int ScopeInfo::LocalCount() {
+  return StackLocalCount() + ContextLocalCount();
 }
 
 
-template <class T>
-static inline Object** WriteObject(Object** p, Handle<T> s) {
-  *p++ = *s;
-  return p;
+int ScopeInfo::StackSlotCount() {
+  if (length() > 0) {
+    bool function_name_stack_slot =
+        FunctionVariableField::decode(Flags()) == STACK;
+    return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
+  }
+  return 0;
 }
 
 
-template <class Allocator, class T>
-static Object** WriteList(Object** p, List<Handle<T>, Allocator >* list) {
-  const int n = list->length();
-  p = WriteInt(p, n);
-  for (int i = 0; i < n; i++) {
-    p = WriteObject(p, list->at(i));
+int ScopeInfo::ContextLength() {
+  if (length() > 0) {
+    int context_locals = ContextLocalCount();
+    bool function_name_context_slot =
+        FunctionVariableField::decode(Flags()) == CONTEXT;
+    bool has_context = context_locals > 0 ||
+        function_name_context_slot ||
+        Type() == WITH_SCOPE ||
+        (Type() == FUNCTION_SCOPE && CallsEval());
+    if (has_context) {
+      return Context::MIN_CONTEXT_SLOTS + context_locals +
+          (function_name_context_slot ? 1 : 0);
+    }
   }
-  return p;
+  return 0;
 }
 
 
-template <class Allocator>
-static Object** WriteList(Object** p,
-                          List<Handle<String>, Allocator>* list,
-                          List<VariableMode, Allocator>* modes) {
-  const int n = list->length();
-  p = WriteInt(p, n);
-  for (int i = 0; i < n; i++) {
-    p = WriteObject(p, list->at(i));
-    p = WriteInt(p, modes->at(i));
-  }
-  return p;
-}
-
-
-template<class Allocator>
-Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() {
-  // function name, calls eval, is_strict_mode, scope type,
-  // length for 3 tables:
-  const int extra_slots = 1 + 1 + 1 + 1 + 3;
-  int length = extra_slots +
-               context_slots_.length() * 2 +
-               parameters_.length() +
-               stack_slots_.length();
-
-  Handle<SerializedScopeInfo> data(
-      SerializedScopeInfo::cast(*FACTORY->NewSerializedScopeInfo(length)));
-  AssertNoAllocation nogc;
-
-  Object** p0 = data->data_start();
-  Object** p = p0;
-  p = WriteObject(p, function_name_);
-  p = WriteBool(p, calls_eval_);
-  p = WriteBool(p, is_strict_mode_);
-  p = WriteInt(p, type_);
-  p = WriteList(p, &context_slots_, &context_modes_);
-  p = WriteList(p, &parameters_);
-  p = WriteList(p, &stack_slots_);
-  ASSERT((p - p0) == length);
-
-  return data;
-}
-
-
-template<class Allocator>
-Handle<String> ScopeInfo<Allocator>::LocalName(int i) const {
-  // A local variable can be allocated either on the stack or in the context.
-  // For variables allocated in the context they are always preceded by
-  // Context::MIN_CONTEXT_SLOTS of fixed allocated slots in the context.
-  if (i < number_of_stack_slots()) {
-    return stack_slot_name(i);
+bool ScopeInfo::HasFunctionName() {
+  if (length() > 0) {
+    return NONE != FunctionVariableField::decode(Flags());
   } else {
-    return context_slot_name(i - number_of_stack_slots() +
-                             Context::MIN_CONTEXT_SLOTS);
+    return false;
   }
 }
 
 
-template<class Allocator>
-int ScopeInfo<Allocator>::NumberOfLocals() const {
-  int number_of_locals = number_of_stack_slots();
-  if (number_of_context_slots() > 0) {
-    ASSERT(number_of_context_slots() >= Context::MIN_CONTEXT_SLOTS);
-    number_of_locals += number_of_context_slots() - Context::MIN_CONTEXT_SLOTS;
+bool ScopeInfo::HasHeapAllocatedLocals() {
+  if (length() > 0) {
+    return ContextLocalCount() > 0;
+  } else {
+    return false;
   }
-  return number_of_locals;
-}
-
-
-Handle<SerializedScopeInfo> SerializedScopeInfo::Create(Scope* scope) {
-  ScopeInfo<ZoneListAllocationPolicy> sinfo(scope);
-  return sinfo.Serialize();
-}
-
-
-SerializedScopeInfo* SerializedScopeInfo::Empty() {
-  return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array());
-}
-
-
-Object** SerializedScopeInfo::ContextEntriesAddr() {
-  ASSERT(length() > 0);
-  // +4 for function name, calls eval, strict mode, scope type.
-  return data_start() + 4;
-}
-
-
-Object** SerializedScopeInfo::ParameterEntriesAddr() {
-  ASSERT(length() > 0);
-  Object** p = ContextEntriesAddr();
-  int number_of_context_slots;
-  p = ReadInt(p, &number_of_context_slots);
-  return p + number_of_context_slots*2;  // *2 for pairs
-}
-
-
-Object** SerializedScopeInfo::StackSlotEntriesAddr() {
-  ASSERT(length() > 0);
-  Object** p = ParameterEntriesAddr();
-  int number_of_parameter_slots;
-  p = ReadInt(p, &number_of_parameter_slots);
-  return p + number_of_parameter_slots;
 }
 
 
-bool SerializedScopeInfo::CallsEval() {
+bool ScopeInfo::HasContext() {
   if (length() > 0) {
-    Object** p = data_start() + 1;  // +1 for function name.
-    bool calls_eval;
-    p = ReadBool(p, &calls_eval);
-    return calls_eval;
+    return ContextLength() > 0;
+  } else {
+    return false;
   }
-  return false;
 }
 
 
-bool SerializedScopeInfo::IsStrictMode() {
-  if (length() > 0) {
-    Object** p = data_start() + 2;  // +2 for function name, calls eval.
-    bool strict_mode;
-    p = ReadBool(p, &strict_mode);
-    return strict_mode;
-  }
-  return false;
+String* ScopeInfo::FunctionName() {
+  ASSERT(HasFunctionName());
+  return String::cast(get(FunctionNameEntryIndex()));
 }
 
 
-ScopeType SerializedScopeInfo::Type() {
-  ASSERT(length() > 0);
-  // +3 for function name, calls eval, strict mode.
-  Object** p = data_start() + 3;
-  ScopeType type;
-  p = ReadInt(p, &type);
-  return type;
+String* ScopeInfo::ParameterName(int var) {
+  ASSERT(0 <= var && var < ParameterCount());
+  int info_index = ParameterEntriesIndex() + var;
+  return String::cast(get(info_index));
 }
 
 
-int SerializedScopeInfo::NumberOfStackSlots() {
-  if (length() > 0) {
-    Object** p = StackSlotEntriesAddr();
-    int number_of_stack_slots;
-    ReadInt(p, &number_of_stack_slots);
-    return number_of_stack_slots;
-  }
-  return 0;
+String* ScopeInfo::LocalName(int var) {
+  ASSERT(0 <= var && var < LocalCount());
+  ASSERT(StackLocalEntriesIndex() + StackLocalCount() ==
+         ContextLocalNameEntriesIndex());
+  int info_index = StackLocalEntriesIndex() + var;
+  return String::cast(get(info_index));
 }
 
 
-int SerializedScopeInfo::NumberOfContextSlots() {
-  if (length() > 0) {
-    Object** p = ContextEntriesAddr();
-    int number_of_context_slots;
-    ReadInt(p, &number_of_context_slots);
-    return number_of_context_slots + Context::MIN_CONTEXT_SLOTS;
-  }
-  return 0;
+String* ScopeInfo::StackLocalName(int var) {
+  ASSERT(0 <= var && var < StackLocalCount());
+  int info_index = StackLocalEntriesIndex() + var;
+  return String::cast(get(info_index));
 }
 
 
-bool SerializedScopeInfo::HasHeapAllocatedLocals() {
-  if (length() > 0) {
-    Object** p = ContextEntriesAddr();
-    int number_of_context_slots;
-    ReadInt(p, &number_of_context_slots);
-    return number_of_context_slots > 0;
-  }
-  return false;
+String* ScopeInfo::ContextLocalName(int var) {
+  ASSERT(0 <= var && var < ContextLocalCount());
+  int info_index = ContextLocalNameEntriesIndex() + var;
+  return String::cast(get(info_index));
 }
 
 
-bool SerializedScopeInfo::HasContext() {
-  return HasHeapAllocatedLocals() ||
-      Type() == WITH_SCOPE;
+VariableMode ScopeInfo::ContextLocalMode(int var) {
+  ASSERT(0 <= var && var < ContextLocalCount());
+  int info_index = ContextLocalModeEntriesIndex() + var;
+  return static_cast<VariableMode>(Smi::cast(get(info_index))->value());
 }
 
 
-int SerializedScopeInfo::StackSlotIndex(String* name) {
+int ScopeInfo::StackSlotIndex(String* name) {
   ASSERT(name->IsSymbol());
   if (length() > 0) {
-    // Slots start after length entry.
-    Object** p0 = StackSlotEntriesAddr();
-    int number_of_stack_slots;
-    p0 = ReadInt(p0, &number_of_stack_slots);
-    Object** p = p0;
-    Object** end = p0 + number_of_stack_slots;
-    while (p != end) {
-      if (*p == name) return static_cast<int>(p - p0);
-      p++;
+    int start = StackLocalEntriesIndex();
+    int end = StackLocalEntriesIndex() + StackLocalCount();
+    for (int i = start; i < end; ++i) {
+      if (name == get(i)) {
+        return i - start;
+      }
     }
   }
   return -1;
 }
 
-int SerializedScopeInfo::ContextSlotIndex(String* name, VariableMode* mode) {
+
+int ScopeInfo::ContextSlotIndex(String* name, VariableMode* mode) {
   ASSERT(name->IsSymbol());
-  Isolate* isolate = GetIsolate();
-  int result = isolate->context_slot_cache()->Lookup(this, name, mode);
-  if (result != ContextSlotCache::kNotFound) return result;
+  ASSERT(mode != NULL);
   if (length() > 0) {
-    // Slots start after length entry.
-    Object** p0 = ContextEntriesAddr();
-    int number_of_context_slots;
-    p0 = ReadInt(p0, &number_of_context_slots);
-    Object** p = p0;
-    Object** end = p0 + number_of_context_slots * 2;
-    while (p != end) {
-      if (*p == name) {
-        ASSERT(((p - p0) & 1) == 0);
-        int v;
-        ReadInt(p + 1, &v);
-        VariableMode mode_value = static_cast<VariableMode>(v);
-        if (mode != NULL) *mode = mode_value;
-        result = static_cast<int>((p - p0) >> 1) + Context::MIN_CONTEXT_SLOTS;
-        isolate->context_slot_cache()->Update(this, name, mode_value, result);
+    ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache();
+    int result = context_slot_cache->Lookup(this, name, mode);
+    if (result != ContextSlotCache::kNotFound) {
+      ASSERT(result < ContextLength());
+      return result;
+    }
+
+    int start = ContextLocalNameEntriesIndex();
+    int end = ContextLocalNameEntriesIndex() + ContextLocalCount();
+    for (int i = start; i < end; ++i) {
+      if (name == get(i)) {
+        int var = i - start;
+        *mode = ContextLocalMode(var);
+        result = Context::MIN_CONTEXT_SLOTS + var;
+        context_slot_cache->Update(this, name, *mode, result);
+        ASSERT(result < ContextLength());
         return result;
       }
-      p += 2;
     }
+    context_slot_cache->Update(this, name, INTERNAL, -1);
   }
-  isolate->context_slot_cache()->Update(this, name, INTERNAL, -1);
   return -1;
 }
 
 
-int SerializedScopeInfo::ParameterIndex(String* name) {
+int ScopeInfo::ParameterIndex(String* name) {
   ASSERT(name->IsSymbol());
   if (length() > 0) {
     // We must read parameters from the end since for
@@ -522,49 +351,58 @@ int SerializedScopeInfo::ParameterIndex(String* name) {
     // last declaration of that parameter is used
     // inside a function (and thus we need to look
     // at the last index). Was bug# 1110337.
-    //
-    // Eventually, we should only register such parameters
-    // once, with corresponding index. This requires a new
-    // implementation of the ScopeInfo code. See also other
-    // comments in this file regarding this.
-    Object** p = ParameterEntriesAddr();
-    int number_of_parameter_slots;
-    Object** p0 = ReadInt(p, &number_of_parameter_slots);
-    p = p0 + number_of_parameter_slots;
-    while (p > p0) {
-      p--;
-      if (*p == name) return static_cast<int>(p - p0);
+    int start = ParameterEntriesIndex();
+    int end = ParameterEntriesIndex() + ParameterCount();
+    for (int i = end - 1; i >= start; --i) {
+      if (name == get(i)) {
+        return i - start;
+      }
     }
   }
   return -1;
 }
 
 
-int SerializedScopeInfo::FunctionContextSlotIndex(String* name,
-                                                  VariableMode* mode) {
+int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
   ASSERT(name->IsSymbol());
+  ASSERT(mode != NULL);
   if (length() > 0) {
-    Object** p = data_start();
-    if (*p == name) {
-      p = ContextEntriesAddr();
-      int number_of_context_slots;
-      p = ReadInt(p, &number_of_context_slots);
-      ASSERT(number_of_context_slots != 0);
-      // The function context slot is the last entry.
-      if (mode != NULL) {
-        // Seek to context slot entry.
-        p += (number_of_context_slots - 1) * 2;
-        // Seek to mode.
-        ++p;
-        ReadInt(p, mode);
-      }
-      return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1;
+    if (FunctionVariableField::decode(Flags()) == CONTEXT &&
+        FunctionName() == name) {
+      *mode = FunctionVariableMode::decode(Flags());
+      return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
     }
   }
   return -1;
 }
 
 
+int ScopeInfo::ParameterEntriesIndex() {
+  ASSERT(length() > 0);
+  return kVariablePartIndex;
+}
+
+
+int ScopeInfo::StackLocalEntriesIndex() {
+  return ParameterEntriesIndex() + ParameterCount();
+}
+
+
+int ScopeInfo::ContextLocalNameEntriesIndex() {
+  return StackLocalEntriesIndex() + StackLocalCount();
+}
+
+
+int ScopeInfo::ContextLocalModeEntriesIndex() {
+  return ContextLocalNameEntriesIndex() + ContextLocalCount();
+}
+
+
+int ScopeInfo::FunctionNameEntryIndex() {
+  return ContextLocalModeEntriesIndex() + ContextLocalCount();
+}
+
+
 int ContextSlotCache::Hash(Object* data, String* name) {
   // Uses only lower 32 bits if pointers are larger.
   uintptr_t addr_hash =
@@ -631,46 +469,50 @@ void ContextSlotCache::ValidateEntry(Object* data,
 }
 
 
-template <class Allocator>
 static void PrintList(const char* list_name,
                       int nof_internal_slots,
-                      List<Handle<String>, Allocator>& list) {
-  if (list.length() > 0) {
+                      int start,
+                      int end,
+                      ScopeInfo* scope_info) {
+  if (start < end) {
     PrintF("\n  // %s\n", list_name);
     if (nof_internal_slots > 0) {
       PrintF("  %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1);
     }
-    for (int i = 0; i < list.length(); i++) {
-      PrintF("  %2d ", i + nof_internal_slots);
-      list[i]->ShortPrint();
+    for (int i = nof_internal_slots; start < end; ++i, ++start) {
+      PrintF("  %2d ", i);
+      String::cast(scope_info->get(start))->ShortPrint();
       PrintF("\n");
     }
   }
 }
 
 
-template<class Allocator>
-void ScopeInfo<Allocator>::Print() {
+void ScopeInfo::Print() {
   PrintF("ScopeInfo ");
-  if (function_name_->length() > 0)
-    function_name_->ShortPrint();
-  else
+  if (HasFunctionName()) {
+    FunctionName()->ShortPrint();
+  } else {
     PrintF("/* no function name */");
+  }
   PrintF("{");
 
-  PrintList<Allocator>("parameters", 0, parameters_);
-  PrintList<Allocator>("stack slots", 0, stack_slots_);
-  PrintList<Allocator>("context slots", Context::MIN_CONTEXT_SLOTS,
-                       context_slots_);
+  PrintList("parameters", 0,
+            ParameterEntriesIndex(),
+            ParameterEntriesIndex() + ParameterCount(),
+            this);
+  PrintList("stack slots", 0,
+            StackLocalEntriesIndex(),
+            StackLocalEntriesIndex() + StackLocalCount(),
+            this);
+  PrintList("context slots",
+            Context::MIN_CONTEXT_SLOTS,
+            ContextLocalNameEntriesIndex(),
+            ContextLocalNameEntriesIndex() + ContextLocalCount(),
+            this);
 
   PrintF("}\n");
 }
 #endif  // DEBUG
 
-
-// Make sure the classes get instantiated by the template system.
-template class ScopeInfo<FreeStoreAllocationPolicy>;
-template class ScopeInfo<PreallocatedStorage>;
-template class ScopeInfo<ZoneListAllocationPolicy>;
-
 } }  // namespace v8::internal
index eeb30475f45008f28cb1aae9cbf4df3b919c7079..4c199d4785946bf1f402b79862ec4fb610cfb32b 100644 (file)
 namespace v8 {
 namespace internal {
 
-// ScopeInfo represents information about different scopes of a source
-// program  and the allocation of the scope's variables. Scope information
-// is stored in a compressed form in SerializedScopeInfo objects and is used
-// at runtime (stack dumps, deoptimization, etc.).
-
-// Forward defined as
-// template <class Allocator = FreeStoreAllocationPolicy> class ScopeInfo;
-template<class Allocator>
-class ScopeInfo BASE_EMBEDDED {
- public:
-  // Create a ScopeInfo instance from a scope.
-  explicit ScopeInfo(Scope* scope);
-
-  // Create a ScopeInfo instance from SerializedScopeInfo.
-  explicit ScopeInfo(SerializedScopeInfo* data);
-
-  // Creates a SerializedScopeInfo holding the serialized scope info.
-  Handle<SerializedScopeInfo> Serialize();
-
-  // --------------------------------------------------------------------------
-  // Lookup
-
-  Handle<String> function_name() const { return function_name_; }
-
-  Handle<String> parameter_name(int i) const { return parameters_[i]; }
-  int number_of_parameters() const { return parameters_.length(); }
-
-  Handle<String> stack_slot_name(int i) const { return stack_slots_[i]; }
-  int number_of_stack_slots() const { return stack_slots_.length(); }
-
-  Handle<String> context_slot_name(int i) const {
-    return context_slots_[i - Context::MIN_CONTEXT_SLOTS];
-  }
-  int number_of_context_slots() const {
-    int l = context_slots_.length();
-    return l == 0 ? 0 : l + Context::MIN_CONTEXT_SLOTS;
-  }
-
-  Handle<String> LocalName(int i) const;
-  int NumberOfLocals() const;
-
-  ScopeType type() const { return type_; }
-  // --------------------------------------------------------------------------
-  // Debugging support
-
-#ifdef DEBUG
-  void Print();
-#endif
-
- private:
-  Handle<String> function_name_;
-  bool calls_eval_;
-  bool is_strict_mode_;
-  ScopeType type_;
-  List<Handle<String>, Allocator > parameters_;
-  List<Handle<String>, Allocator > stack_slots_;
-  List<Handle<String>, Allocator > context_slots_;
-  List<VariableMode, Allocator > context_modes_;
-};
-
-
 // Cache for mapping (data, property name) into context slot index.
 // The cache contains both positive and negative results.
 // Slot index equals -1 means the property is absent.
index a199da6b2b6644365941a3727abb0011cfd626ba..13745f2abdef37cf1ebdc500914007e2038226e8 100644 (file)
@@ -118,7 +118,7 @@ Scope::Scope(Scope* outer_scope, ScopeType type)
       unresolved_(16),
       decls_(4),
       already_resolved_(false) {
-  SetDefaults(type, outer_scope, Handle<SerializedScopeInfo>::null());
+  SetDefaults(type, outer_scope, Handle<ScopeInfo>::null());
   // At some point we might want to provide outer scopes to
   // eval scopes (by walking the stack and reading the scope info).
   // In that case, the ASSERT below needs to be adjusted.
@@ -129,7 +129,7 @@ Scope::Scope(Scope* outer_scope, ScopeType type)
 
 Scope::Scope(Scope* inner_scope,
              ScopeType type,
-             Handle<SerializedScopeInfo> scope_info)
+             Handle<ScopeInfo> scope_info)
     : isolate_(Isolate::Current()),
       inner_scopes_(4),
       variables_(),
@@ -139,8 +139,8 @@ Scope::Scope(Scope* inner_scope,
       decls_(4),
       already_resolved_(true) {
   SetDefaults(type, NULL, scope_info);
-  if (!scope_info.is_null() && scope_info->HasHeapAllocatedLocals()) {
-    num_heap_slots_ = scope_info_->NumberOfContextSlots();
+  if (!scope_info.is_null()) {
+    num_heap_slots_ = scope_info_->ContextLength();
   }
   AddInnerScope(inner_scope);
 }
@@ -155,7 +155,7 @@ Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name)
       unresolved_(0),
       decls_(0),
       already_resolved_(true) {
-  SetDefaults(CATCH_SCOPE, NULL, Handle<SerializedScopeInfo>::null());
+  SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
   AddInnerScope(inner_scope);
   ++num_var_or_const_;
   Variable* variable = variables_.Declare(this,
@@ -169,7 +169,7 @@ Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name)
 
 void Scope::SetDefaults(ScopeType type,
                         Scope* outer_scope,
-                        Handle<SerializedScopeInfo> scope_info) {
+                        Handle<ScopeInfo> scope_info) {
   outer_scope_ = outer_scope;
   type_ = type;
   scope_name_ = isolate_->factory()->empty_symbol();
@@ -206,8 +206,9 @@ Scope* Scope::DeserializeScopeChain(CompilationInfo* info,
   bool contains_with = false;
   while (!context->IsGlobalContext()) {
     if (context->IsWithContext()) {
-      Scope* with_scope = new Scope(current_scope, WITH_SCOPE,
-                                    Handle<SerializedScopeInfo>::null());
+      Scope* with_scope = new Scope(current_scope,
+                                    WITH_SCOPE,
+                                    Handle<ScopeInfo>::null());
       current_scope = with_scope;
       // All the inner scopes are inside a with.
       contains_with = true;
@@ -215,15 +216,15 @@ Scope* Scope::DeserializeScopeChain(CompilationInfo* info,
         s->scope_inside_with_ = true;
       }
     } else if (context->IsFunctionContext()) {
-      SerializedScopeInfo* scope_info =
-          context->closure()->shared()->scope_info();
-      current_scope = new Scope(current_scope, FUNCTION_SCOPE,
-                                Handle<SerializedScopeInfo>(scope_info));
+      ScopeInfo* scope_info = context->closure()->shared()->scope_info();
+      current_scope = new Scope(current_scope,
+                                FUNCTION_SCOPE,
+                                Handle<ScopeInfo>(scope_info));
     } else if (context->IsBlockContext()) {
-      SerializedScopeInfo* scope_info =
-          SerializedScopeInfo::cast(context->extension());
-      current_scope = new Scope(current_scope, BLOCK_SCOPE,
-                                Handle<SerializedScopeInfo>(scope_info));
+      ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
+      current_scope = new Scope(current_scope,
+                                BLOCK_SCOPE,
+                                Handle<ScopeInfo>(scope_info));
     } else {
       ASSERT(context->IsCatchContext());
       String* name = String::cast(context->extension());
@@ -361,7 +362,7 @@ Variable* Scope::LocalLookup(Handle<String> name) {
     index = scope_info_->ParameterIndex(*name);
     if (index < 0) {
       // Check the function name.
-      index = scope_info_->FunctionContextSlotIndex(*name, NULL);
+      index = scope_info_->FunctionContextSlotIndex(*name, &mode);
       if (index < 0) return NULL;
     }
   }
@@ -504,8 +505,7 @@ Declaration* Scope::CheckConflictingVarDeclarations() {
 }
 
 
-template<class Allocator>
-void Scope::CollectUsedVariables(List<Variable*, Allocator>* locals) {
+void Scope::CollectUsedVariables(ZoneList<Variable*>* locals) {
   // Collect variables in this scope.
   // Note that the function_ variable - if present - is not
   // collected here but handled separately in ScopeInfo
@@ -527,15 +527,6 @@ void Scope::CollectUsedVariables(List<Variable*, Allocator>* locals) {
 }
 
 
-// Make sure the method gets instantiated by the template system.
-template void Scope::CollectUsedVariables(
-    List<Variable*, FreeStoreAllocationPolicy>* locals);
-template void Scope::CollectUsedVariables(
-    List<Variable*, PreallocatedStorage>* locals);
-template void Scope::CollectUsedVariables(
-    List<Variable*, ZoneListAllocationPolicy>* locals);
-
-
 void Scope::AllocateVariables(Handle<Context> context) {
   ASSERT(outer_scope_ == NULL);  // eval or global scopes only
 
@@ -610,18 +601,18 @@ Scope* Scope::DeclarationScope() {
 }
 
 
-Handle<SerializedScopeInfo> Scope::GetSerializedScopeInfo() {
+Handle<ScopeInfo> Scope::GetScopeInfo() {
   if (scope_info_.is_null()) {
-    scope_info_ = SerializedScopeInfo::Create(this);
+    scope_info_ = ScopeInfo::Create(this);
   }
   return scope_info_;
 }
 
 
 void Scope::GetNestedScopeChain(
-    List<Handle<SerializedScopeInfo> >* chain,
+    List<Handle<ScopeInfo> >* chain,
     int position) {
-  chain->Add(Handle<SerializedScopeInfo>(GetSerializedScopeInfo()));
+  chain->Add(Handle<ScopeInfo>(GetScopeInfo()));
 
   for (int i = 0; i < inner_scopes_.length(); i++) {
     Scope* scope = inner_scopes_[i];
@@ -1126,21 +1117,15 @@ void Scope::AllocateVariablesRecursively() {
   if (is_function_scope()) AllocateParameterLocals();
   AllocateNonParameterLocals();
 
-  // Allocate context if necessary.
-  bool must_have_local_context = false;
-  if (scope_calls_eval_ || scope_contains_with_) {
-    // The context for the eval() call or 'with' statement in this scope.
-    // Unless we are in the global or an eval scope, we need a local
-    // context even if we didn't statically allocate any locals in it,
-    // and the compiler will access the context variable. If we are
-    // not in an inner scope, the scope is provided from the outside.
-    must_have_local_context = is_function_scope();
-  }
+  // Force allocation of a context for this scope if necessary. For a 'with'
+  // scope and for a function scope that makes an 'eval' call we need a context,
+  // even if no local variables were statically allocated in the scope.
+  bool must_have_context = is_with_scope() ||
+      (is_function_scope() && calls_eval());
 
   // If we didn't allocate any locals in the local context, then we only
-  // need the minimal number of slots if we must have a local context.
-  if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
-      !must_have_local_context) {
+  // need the minimal number of slots if we must have a context.
+  if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
     num_heap_slots_ = 0;
   }
 
index 0cd3be5b123664e56e07f713c0ef7889fb6681a5..c255debd5ad451c9a80220931c71188f742c39d4 100644 (file)
@@ -301,8 +301,7 @@ class Scope: public ZoneObject {
   // Variable allocation.
 
   // Collect all used locals in this scope.
-  template<class Allocator>
-  void CollectUsedVariables(List<Variable*, Allocator>* locals);
+  void CollectUsedVariables(ZoneList<Variable*>* locals);
 
   // Resolve and fill in the allocation information for all variables
   // in this scopes. Must be called *after* all scopes have been
@@ -337,13 +336,13 @@ class Scope: public ZoneObject {
   // where var declarations will be hoisted to in the implementation.
   Scope* DeclarationScope();
 
-  Handle<SerializedScopeInfo> GetSerializedScopeInfo();
+  Handle<ScopeInfo> GetScopeInfo();
 
   // Get the chain of nested scopes within this scope for the source statement
   // position. The scopes will be added to the list from the outermost scope to
   // the innermost scope. Only nested block, catch or with scopes are tracked
   // and will be returned, but no inner function scopes.
-  void GetNestedScopeChain(List<Handle<SerializedScopeInfo> >* chain,
+  void GetNestedScopeChain(List<Handle<ScopeInfo> >* chain,
                            int statement_position);
 
   // ---------------------------------------------------------------------------
@@ -438,8 +437,8 @@ class Scope: public ZoneObject {
   int num_stack_slots_;
   int num_heap_slots_;
 
-  // Serialized scopes support.
-  Handle<SerializedScopeInfo> scope_info_;
+  // Serialized scope info support.
+  Handle<ScopeInfo> scope_info_;
   bool already_resolved() { return already_resolved_; }
 
   // Create a non-local variable with a given name.
@@ -523,9 +522,7 @@ class Scope: public ZoneObject {
 
  private:
   // Construct a scope based on the scope info.
-  Scope(Scope* inner_scope,
-        ScopeType type,
-        Handle<SerializedScopeInfo> scope_info);
+  Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info);
 
   // Construct a catch scope with a binding for the name.
   Scope(Scope* inner_scope, Handle<String> catch_variable_name);
@@ -539,7 +536,7 @@ class Scope: public ZoneObject {
 
   void SetDefaults(ScopeType type,
                    Scope* outer_scope,
-                   Handle<SerializedScopeInfo> scope_info);
+                   Handle<ScopeInfo> scope_info);
 };
 
 } }  // namespace v8::internal
index 49695ec964271257817d48be7e0703797bdd081a..b598c6ce3fc9fa6263860fd275f2b53288267e43 100644 (file)
@@ -608,7 +608,7 @@ class PartialSerializer : public Serializer {
     ASSERT(!o->IsScript());
     return o->IsString() || o->IsSharedFunctionInfo() ||
            o->IsHeapNumber() || o->IsCode() ||
-           o->IsSerializedScopeInfo() ||
+           o->IsScopeInfo() ||
            o->map() == HEAP->fixed_cow_array_map();
   }
 
index 40ce30c1d550511dd6d7b4edec3ee37466ea7141..7179454b43cefa9ed45b3ffc473cd40f87202787 100644 (file)
@@ -160,8 +160,7 @@ class RegExpTree;
 class RegExpCompiler;
 class RegExpVisitor;
 class Scope;
-template<class Allocator = FreeStoreAllocationPolicy> class ScopeInfo;
-class SerializedScopeInfo;
+class ScopeInfo;
 class Script;
 class Slot;
 class Smi;