scopeinfo.cc revision 3ef787dbeca8a5fb1086949cda830dccee07bfbd
1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdlib.h>
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopeinfo.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopes.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "allocation-inl.h"
363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<ScopeInfo> ScopeInfo::Create(Scope* scope) {
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Collect stack and context locals.
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Variable*> stack_locals(scope->StackLocalCount());
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Variable*> context_locals(scope->ContextLocalCount());
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scope->CollectStackAndContextLocals(&stack_locals, &context_locals);
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int stack_local_count = stack_locals.length();
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int context_local_count = context_locals.length();
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Make sure we allocate the correct amount.
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(scope->StackLocalCount() == stack_local_count);
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(scope->ContextLocalCount() == context_local_count);
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Determine use and location of the function variable if it is present.
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FunctionVariableInfo function_name_info;
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VariableMode function_variable_mode;
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (scope->is_function_scope() && scope->function() != NULL) {
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Variable* var = scope->function()->var();
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!var->is_used()) {
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      function_name_info = UNUSED;
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else if (var->IsContextSlot()) {
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      function_name_info = CONTEXT;
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ASSERT(var->IsStackLocal());
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      function_name_info = STACK;
6485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    }
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    function_variable_mode = var->mode();
6685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  } else {
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    function_name_info = NONE;
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    function_variable_mode = VAR;
69592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  }
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const bool has_function_name = function_name_info != NONE;
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int parameter_count = scope->num_parameters();
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int length = kVariablePartIndex
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      + parameter_count + stack_local_count + 2 * context_local_count
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      + (has_function_name ? 2 : 0);
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<ScopeInfo> scope_info = FACTORY->NewScopeInfo(length);
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Encode the flags.
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int flags = TypeField::encode(scope->type()) |
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      CallsEvalField::encode(scope->calls_eval()) |
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      LanguageModeField::encode(scope->language_mode()) |
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FunctionVariableField::encode(function_name_info) |
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FunctionVariableMode::encode(function_variable_mode);
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scope_info->SetFlags(flags);
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scope_info->SetParameterCount(parameter_count);
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scope_info->SetStackLocalCount(stack_local_count);
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scope_info->SetContextLocalCount(context_local_count);
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int index = kVariablePartIndex;
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Add parameters.
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(index == scope_info->ParameterEntriesIndex());
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < parameter_count; ++i) {
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    scope_info->set(index++, *scope->parameter(i)->name());
95592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  }
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Add stack locals' names. We are assuming that the stack locals'
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // slots are allocated in increasing order, so we can simply add
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // them to the ScopeInfo object.
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(index == scope_info->StackLocalEntriesIndex());
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < stack_local_count; ++i) {
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(stack_locals[i]->index() == i);
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    scope_info->set(index++, *stack_locals[i]->name());
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Due to usage analysis, context-allocated locals are not necessarily in
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // increasing order: Some of them may be parameters which are allocated before
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the non-parameter locals. When the non-parameter locals are sorted
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // according to usage, the allocated slot indices may not be in increasing
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // order with the variable list anymore. Thus, we first need to sort them by
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // context slot index before adding them to the ScopeInfo object.
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  context_locals.Sort(&Variable::CompareIndex);
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Add context locals' names.
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(index == scope_info->ContextLocalNameEntriesIndex());
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < context_local_count; ++i) {
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    scope_info->set(index++, *context_locals[i]->name());
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
11985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Add context locals' info.
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(index == scope_info->ContextLocalInfoEntriesIndex());
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < context_local_count; ++i) {
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Variable* var = context_locals[i];
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    uint32_t value = ContextLocalMode::encode(var->mode()) |
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ContextLocalInitFlag::encode(var->initialization_flag());
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    scope_info->set(index++, Smi::FromInt(value));
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If present, add the function variable name and its index.
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(index == scope_info->FunctionNameEntryIndex());
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (has_function_name) {
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int var_index = scope->function()->var()->index();
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    scope_info->set(index++, *scope->function()->name());
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    scope_info->set(index++, Smi::FromInt(var_index));
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(function_name_info != STACK ||
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch           (var_index == scope_info->StackLocalCount() &&
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            var_index == scope_info->StackSlotCount() - 1));
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(function_name_info != CONTEXT ||
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch           var_index == scope_info->ContextLength() - 1);
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(index == scope_info->length());
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(scope->num_parameters() == scope_info->ParameterCount());
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(scope->num_stack_slots() == scope_info->StackSlotCount());
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(scope->num_heap_slots() == scope_info->ContextLength());
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return scope_info;
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScopeInfo* ScopeInfo::Empty() {
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return reinterpret_cast<ScopeInfo*>(HEAP->empty_fixed_array());
15285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
15385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
15485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScopeType ScopeInfo::Type() {
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(length() > 0);
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return TypeField::decode(Flags());
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool ScopeInfo::CallsEval() {
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return length() > 0 && CallsEvalField::decode(Flags());
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLanguageMode ScopeInfo::language_mode() {
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return length() > 0 ? LanguageModeField::decode(Flags()) : CLASSIC_MODE;
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::LocalCount() {
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return StackLocalCount() + ContextLocalCount();
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::StackSlotCount() {
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (length() > 0) {
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bool function_name_stack_slot =
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        FunctionVariableField::decode(Flags()) == STACK;
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return 0;
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::ContextLength() {
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (length() > 0) {
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int context_locals = ContextLocalCount();
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bool function_name_context_slot =
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        FunctionVariableField::decode(Flags()) == CONTEXT;
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bool has_context = context_locals > 0 ||
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        function_name_context_slot ||
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Type() == WITH_SCOPE ||
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        (Type() == FUNCTION_SCOPE && CallsEval());
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (has_context) {
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return Context::MIN_CONTEXT_SLOTS + context_locals +
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          (function_name_context_slot ? 1 : 0);
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return 0;
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool ScopeInfo::HasFunctionName() {
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (length() > 0) {
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return NONE != FunctionVariableField::decode(Flags());
207592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  } else {
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return false;
2093bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool ScopeInfo::HasHeapAllocatedLocals() {
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (length() > 0) {
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ContextLocalCount() > 0;
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return false;
218592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  }
2193bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
2203bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
2213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool ScopeInfo::HasContext() {
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (length() > 0) {
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ContextLength() > 0;
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return false;
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
228257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochString* ScopeInfo::FunctionName() {
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(HasFunctionName());
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return String::cast(get(FunctionNameEntryIndex()));
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochString* ScopeInfo::ParameterName(int var) {
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(0 <= var && var < ParameterCount());
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int info_index = ParameterEntriesIndex() + var;
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return String::cast(get(info_index));
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochString* ScopeInfo::LocalName(int var) {
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(0 <= var && var < LocalCount());
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(StackLocalEntriesIndex() + StackLocalCount() ==
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         ContextLocalNameEntriesIndex());
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int info_index = StackLocalEntriesIndex() + var;
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return String::cast(get(info_index));
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochString* ScopeInfo::StackLocalName(int var) {
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(0 <= var && var < StackLocalCount());
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int info_index = StackLocalEntriesIndex() + var;
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return String::cast(get(info_index));
2579dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
2589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
2599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochString* ScopeInfo::ContextLocalName(int var) {
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(0 <= var && var < ContextLocalCount());
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int info_index = ContextLocalNameEntriesIndex() + var;
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return String::cast(get(info_index));
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
266592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochVariableMode ScopeInfo::ContextLocalMode(int var) {
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(0 <= var && var < ContextLocalCount());
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int info_index = ContextLocalInfoEntriesIndex() + var;
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int value = Smi::cast(get(info_index))->value();
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ContextLocalMode::decode(value);
27285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
27385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
27485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochInitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(0 <= var && var < ContextLocalCount());
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int info_index = ContextLocalInfoEntriesIndex() + var;
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int value = Smi::cast(get(info_index))->value();
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ContextLocalInitFlag::decode(value);
28085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
28185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
28285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::StackSlotIndex(String* name) {
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(name->IsSymbol());
2853bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (length() > 0) {
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int start = StackLocalEntriesIndex();
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int end = StackLocalEntriesIndex() + StackLocalCount();
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = start; i < end; ++i) {
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (name == get(i)) {
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return i - start;
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
292592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch    }
29385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  }
29485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return -1;
29585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
296592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::ContextSlotIndex(String* name,
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                VariableMode* mode,
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                InitializationFlag* init_flag) {
30185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  ASSERT(name->IsSymbol());
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(mode != NULL);
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(init_flag != NULL);
30485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  if (length() > 0) {
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache();
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int result = context_slot_cache->Lookup(this, name, mode, init_flag);
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (result != ContextSlotCache::kNotFound) {
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ASSERT(result < ContextLength());
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return result;
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int start = ContextLocalNameEntriesIndex();
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int end = ContextLocalNameEntriesIndex() + ContextLocalCount();
3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = start; i < end; ++i) {
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (name == get(i)) {
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        int var = i - start;
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        *mode = ContextLocalMode(var);
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        *init_flag = ContextLocalInitFlag(var);
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        result = Context::MIN_CONTEXT_SLOTS + var;
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        context_slot_cache->Update(this, name, *mode, *init_flag, result);
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ASSERT(result < ContextLength());
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return result;
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    context_slot_cache->Update(this, name, INTERNAL, kNeedsInitialization, -1);
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return -1;
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::ParameterIndex(String* name) {
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(name->IsSymbol());
3333bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (length() > 0) {
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // We must read parameters from the end since for
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // multiply declared parameters the value of the
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // last declaration of that parameter is used
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // inside a function (and thus we need to look
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // at the last index). Was bug# 1110337.
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int start = ParameterEntriesIndex();
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int end = ParameterEntriesIndex() + ParameterCount();
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = end - 1; i >= start; --i) {
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (name == get(i)) {
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return i - start;
3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return -1;
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(name->IsSymbol());
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(mode != NULL);
3543bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (length() > 0) {
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FunctionVariableField::decode(Flags()) == CONTEXT &&
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        FunctionName() == name) {
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      *mode = FunctionVariableMode::decode(Flags());
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return -1;
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::ParameterEntriesIndex() {
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(length() > 0);
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return kVariablePartIndex;
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::StackLocalEntriesIndex() {
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ParameterEntriesIndex() + ParameterCount();
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::ContextLocalNameEntriesIndex() {
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return StackLocalEntriesIndex() + StackLocalCount();
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::ContextLocalInfoEntriesIndex() {
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ContextLocalNameEntriesIndex() + ContextLocalCount();
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ScopeInfo::FunctionNameEntryIndex() {
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ContextLocalInfoEntriesIndex() + ContextLocalCount();
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3913bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochint ContextSlotCache::Hash(Object* data, String* name) {
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Uses only lower 32 bits if pointers are larger.
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uintptr_t addr_hash =
3943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
395402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3993bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochint ContextSlotCache::Lookup(Object* data,
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             String* name,
4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             VariableMode* mode,
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             InitializationFlag* init_flag) {
4033bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  int index = Hash(data, name);
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Key& key = keys_[index];
4053bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if ((key.data == data) && key.name->Equals(name)) {
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Value result(values_[index]);
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (mode != NULL) *mode = result.mode();
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (init_flag != NULL) *init_flag = result.initialization_flag();
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return result.index() + kNotFound;
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return kNotFound;
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4153bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochvoid ContextSlotCache::Update(Object* data,
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              String* name,
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              VariableMode mode,
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              InitializationFlag init_flag,
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              int slot_index) {
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  String* symbol;
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(slot_index > kNotFound);
42244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (HEAP->LookupSymbolIfExists(name, &symbol)) {
4233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    int index = Hash(data, symbol);
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Key& key = keys_[index];
4253bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    key.data = data;
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    key.name = symbol;
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Please note value only takes a uint as index.
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    values_[index] = Value(mode, init_flag, slot_index - kNotFound).raw();
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ValidateEntry(data, name, mode, init_flag, slot_index);
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ContextSlotCache::Clear() {
4373bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  for (int index = 0; index < kLength; index++) keys_[index].data = NULL;
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4433bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochvoid ContextSlotCache::ValidateEntry(Object* data,
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     String* name,
4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     VariableMode mode,
4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     InitializationFlag init_flag,
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     int slot_index) {
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  String* symbol;
44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (HEAP->LookupSymbolIfExists(name, &symbol)) {
4503bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    int index = Hash(data, name);
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Key& key = keys_[index];
4523bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    ASSERT(key.data == data);
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(key.name->Equals(name));
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Value result(values_[index]);
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(result.mode() == mode);
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(result.initialization_flag() == init_flag);
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(result.index() + kNotFound == slot_index);
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void PrintList(const char* list_name,
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      int nof_internal_slots,
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      int start,
4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      int end,
4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      ScopeInfo* scope_info) {
4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (start < end) {
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintF("\n  // %s\n", list_name);
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (nof_internal_slots > 0) {
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      PrintF("  %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1);
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = nof_internal_slots; start < end; ++i, ++start) {
4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrintF("  %2d ", i);
4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      String::cast(scope_info->get(start))->ShortPrint();
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      PrintF("\n");
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid ScopeInfo::Print() {
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintF("ScopeInfo ");
4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (HasFunctionName()) {
4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FunctionName()->ShortPrint();
4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintF("/* no function name */");
4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintF("{");
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintList("parameters", 0,
4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            ParameterEntriesIndex(),
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            ParameterEntriesIndex() + ParameterCount(),
4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            this);
4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintList("stack slots", 0,
4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            StackLocalEntriesIndex(),
4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            StackLocalEntriesIndex() + StackLocalCount(),
4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            this);
4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintList("context slots",
4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            Context::MIN_CONTEXT_SLOTS,
5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            ContextLocalNameEntriesIndex(),
5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            ContextLocalNameEntriesIndex() + ContextLocalCount(),
5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            this);
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintF("}\n");
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // DEBUG
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
509