📄 scopeinfo.cc.svn-base
字号:
static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) { const int n = list->length(); p = WriteInt(p, n); for (int i = 0; i < n; i++) { p = WriteSymbol(p, list->at(i)); } return WriteSentinel(p);}template <class Allocator>static Object** WriteList(Object** p, List<Handle<String>, Allocator>* list, List<Variable::Mode, Allocator>* modes) { const int n = list->length(); p = WriteInt(p, n); for (int i = 0; i < n; i++) { p = WriteSymbol(p, list->at(i)); p = WriteInt(p, modes->at(i)); } return WriteSentinel(p);}template<class Allocator>int ScopeInfo<Allocator>::Serialize(Code* code) { // function name, supports eval, length & sentinel for 3 tables: const int extra_slots = 1 + 1 + 2 * 3; int size = (extra_slots + context_slots_.length() * 2 + parameters_.length() + stack_slots_.length()) * kPointerSize; if (code != NULL) { CHECK(code->sinfo_size() == size); Object** p0 = &Memory::Object_at(code->sinfo_start()); Object** p = p0; p = WriteSymbol(p, function_name_); p = WriteInt(p, supports_eval_); p = WriteList(p, &context_slots_, &context_modes_); p = WriteList(p, ¶meters_); p = WriteList(p, &stack_slots_); ASSERT((p - p0) * kPointerSize == size); } return size;}template<class Allocator>void ScopeInfo<Allocator>::IterateScopeInfo(Code* code, ObjectVisitor* v) { Object** start = &Memory::Object_at(code->sinfo_start()); Object** end = &Memory::Object_at(code->sinfo_start() + code->sinfo_size()); v->VisitPointers(start, end);}static Object** ContextEntriesAddr(Code* code) { ASSERT(code->sinfo_size() > 0); // +2 for function name, supports eval: return &Memory::Object_at(code->sinfo_start()) + 2;}static Object** ParameterEntriesAddr(Code* code) { ASSERT(code->sinfo_size() > 0); Object** p = ContextEntriesAddr(code); int n; // number of context slots; p = ReadInt(p, &n); return p + n*2 + 1; // *2 for pairs, +1 for sentinel}static Object** StackSlotEntriesAddr(Code* code) { ASSERT(code->sinfo_size() > 0); Object** p = ParameterEntriesAddr(code); int n; // number of parameter slots; p = ReadInt(p, &n); return p + n + 1; // +1 for sentinel}template<class Allocator>bool ScopeInfo<Allocator>::SupportsEval(Code* code) { bool result = false; if (code->sinfo_size() > 0) { ReadBool(&Memory::Object_at(code->sinfo_start()) + 1, &result); }#ifdef DEBUG { ScopeInfo info(code); ASSERT(result == info.supports_eval_); }#endif return result;}template<class Allocator>int ScopeInfo<Allocator>::NumberOfStackSlots(Code* code) { if (code->sinfo_size() > 0) { Object** p = StackSlotEntriesAddr(code); int n; // number of stack slots; ReadInt(p, &n); return n; } return 0;}template<class Allocator>int ScopeInfo<Allocator>::NumberOfContextSlots(Code* code) { if (code->sinfo_size() > 0) { Object** p = ContextEntriesAddr(code); int n; // number of context slots; ReadInt(p, &n); return n + Context::MIN_CONTEXT_SLOTS; } return 0;}template<class Allocator>int ScopeInfo<Allocator>::StackSlotIndex(Code* code, String* name) { ASSERT(name->IsSymbol()); if (code->sinfo_size() > 0) { // Loop below depends on the NULL sentinel after the stack slot names. ASSERT(NumberOfStackSlots(code) > 0 || *(StackSlotEntriesAddr(code) + 1) == NULL); // slots start after length entry Object** p0 = StackSlotEntriesAddr(code) + 1; Object** p = p0; while (*p != NULL) { if (*p == name) return p - p0; p++; } } return -1;}template<class Allocator>int ScopeInfo<Allocator>::ContextSlotIndex(Code* code, String* name, Variable::Mode* mode) { ASSERT(name->IsSymbol()); if (code->sinfo_size() > 0) { // Loop below depends on the NULL sentinel after the context slot names. ASSERT(NumberOfContextSlots(code) >= Context::MIN_CONTEXT_SLOTS || *(ContextEntriesAddr(code) + 1) == NULL); // slots start after length entry Object** p0 = ContextEntriesAddr(code) + 1; Object** p = p0; // contexts may have no variable slots (in the presence of eval()). while (*p != NULL) { if (*p == name) { ASSERT(((p - p0) & 1) == 0); if (mode != NULL) { ReadInt(p + 1, reinterpret_cast<int*>(mode)); } return ((p - p0) >> 1) + Context::MIN_CONTEXT_SLOTS; } p += 2; } } return -1;}template<class Allocator>int ScopeInfo<Allocator>::ParameterIndex(Code* code, String* name) { ASSERT(name->IsSymbol()); if (code->sinfo_size() > 0) { // We must read parameters from the end since for // multiply declared parameters the value of the // 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(code); int n; // number of parameters Object** p0 = ReadInt(p, &n); p = p0 + n; while (p > p0) { p--; if (*p == name) return p - p0; } } return -1;}template<class Allocator>int ScopeInfo<Allocator>::FunctionContextSlotIndex(Code* code, String* name) { ASSERT(name->IsSymbol()); if (code->sinfo_size() > 0) { Object** p = &Memory::Object_at(code->sinfo_start()); if (*p == name) { p = ContextEntriesAddr(code); int n; // number of context slots ReadInt(p, &n); ASSERT(n != 0); // The function context slot is the last entry. return n + Context::MIN_CONTEXT_SLOTS - 1; } } return -1;}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 the // number Context::MIN_CONTEXT_SLOTS number of fixed allocated slots in the // context. if (i < number_of_stack_slots()) { return stack_slot_name(i); } else { return context_slot_name(i - number_of_stack_slots() + Context::MIN_CONTEXT_SLOTS); }}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; } return number_of_locals;}#ifdef DEBUGtemplate <class Allocator>static void PrintList(const char* list_name, int nof_internal_slots, List<Handle<String>, Allocator>& list) { if (list.length() > 0) { 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(); PrintF("\n"); } }}template<class Allocator>void ScopeInfo<Allocator>::Print() { PrintF("ScopeInfo "); if (function_name_->length() > 0) function_name_->ShortPrint(); else PrintF("/* no function name */"); PrintF("{"); if (supports_eval_) PrintF("\n // supports eval\n"); PrintList<Allocator>("parameters", 0, parameters_); PrintList<Allocator>("stack slots", 0, stack_slots_); PrintList<Allocator>("context slots", Context::MIN_CONTEXT_SLOTS, context_slots_); PrintF("}\n");}#endif // DEBUG// Make sure the classes get instantiated by the template system.template class ScopeInfo<FreeStoreAllocationPolicy>;template class ScopeInfo<PreallocatedStorage>;} } // namespace v8::internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -