⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scopeinfo.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include <stdlib.h>#include "v8.h"#include "scopeinfo.h"#include "scopes.h"namespace v8 { namespace internal {static int CompareLocal(Variable* const* v, Variable* const* w) {  Slot* s = (*v)->slot();  Slot* t = (*w)->slot();  // We may have rewritten parameters (that are in the arguments object)  // and which may have a NULL slot... - find a better solution...  int x = (s != NULL ? s->index() : 0);  int y = (t != NULL ? t->index() : 0);  // Consider sorting them according to type as well?  return x - y;}template<class Allocator>ScopeInfo<Allocator>::ScopeInfo(Scope* scope)    : function_name_(Factory::empty_symbol()),      supports_eval_(scope->SupportsEval()),      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->var_uses()->is_used()) {      Slot* slot = var->slot();      if (slot != NULL) {        switch (slot->type()) {          case Slot::PARAMETER:            // explicitly added to parameters_ above - ignore            break;          case Slot::LOCAL:            ASSERT(stack_slots_.length() == slot->index());            stack_slots_.Add(var->name());            break;          case Slot::CONTEXT:            heap_locals.Add(var);            break;          case Slot::LOOKUP:          case Slot::GLOBAL:            // these are currently not used            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]->slot()->index() - Context::MIN_CONTEXT_SLOTS ==             context_slots_.length());      ASSERT(heap_locals[i]->slot()->index() - Context::MIN_CONTEXT_SLOTS ==             context_modes_.length());      context_slots_.Add(heap_locals[i]->name());      context_modes_.Add(heap_locals[i]->mode());    }  } else {    ASSERT(heap_locals.length() == 0);  }  // 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()) {    Variable* var = scope->function();    if (var != NULL &&        var->var_uses()->is_used() &&        var->slot()->type() == Slot::CONTEXT) {      function_name_ = var->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(var->slot()->index() - Context::MIN_CONTEXT_SLOTS ==             context_slots_.length());      ASSERT(var->slot()->index() - Context::MIN_CONTEXT_SLOTS ==             context_modes_.length());      context_slots_.Add(Factory::empty_symbol());      context_modes_.Add(Variable::INTERNAL);    }  }}// Encoding format in the Code object://// - function name// - supports eval info//// - 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)// - NULL (sentinel)//// - number of parameters (smi)// - list of parameter names (starting with parameter 0 first)// - NULL (sentinel)//// - number of variables on the stack (smi)// - list of names of stack-allocated variables (starting with stack slot 0)// - NULL (sentinel)// 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)static inline Object** ReadInt(Object** p, int* x) {  *x = (reinterpret_cast<Smi*>(*p++))->value();  return p;}static inline Object** ReadBool(Object** p, bool* x) {  *x = (reinterpret_cast<Smi*>(*p++))->value() != 0;  return p;}static inline Object** ReadSymbol(Object** p, Handle<String>* s) {  *s = Handle<String>(reinterpret_cast<String*>(*p++));  return p;}static inline Object** ReadSentinel(Object** p) {  ASSERT(*p == NULL);  return p + 1;}template <class Allocator>static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) {  ASSERT(list->is_empty());  int n;  p = ReadInt(p, &n);  while (n-- > 0) {    Handle<String> s;    p = ReadSymbol(p, &s);    list->Add(s);  }  return ReadSentinel(p);}template <class Allocator>static Object** ReadList(Object** p,                         List<Handle<String>, Allocator>* list,                         List<Variable::Mode, Allocator>* modes) {  ASSERT(list->is_empty());  int n;  p = ReadInt(p, &n);  while (n-- > 0) {    Handle<String> s;    int m;    p = ReadSymbol(p, &s);    p = ReadInt(p, &m);    list->Add(s);    modes->Add(static_cast<Variable::Mode>(m));  }  return ReadSentinel(p);}template<class Allocator>ScopeInfo<Allocator>::ScopeInfo(Code* code)  : function_name_(Factory::empty_symbol()),    supports_eval_(false),    parameters_(4),    stack_slots_(8),    context_slots_(8),    context_modes_(8) {  if (code == NULL || code->sinfo_size() == 0) return;  Object** p0 = &Memory::Object_at(code->sinfo_start());  Object** p = p0;  p = ReadSymbol(p, &function_name_);  p = ReadBool(p, &supports_eval_);  p = ReadList<Allocator>(p, &context_slots_, &context_modes_);  p = ReadList<Allocator>(p, &parameters_);  p = ReadList<Allocator>(p, &stack_slots_);  ASSERT((p - p0) * kPointerSize == code->sinfo_size());}static inline Object** WriteInt(Object** p, int x) {  *p++ = Smi::FromInt(x);  return p;}static inline Object** WriteSymbol(Object** p, Handle<String> s) {  *p++ = *s;  return p;}static inline Object** WriteSentinel(Object** p) {  *p++ = NULL;  return p;}template <class Allocator>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -