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

📄 frames.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 "v8.h"#include "frames-inl.h"#include "scopeinfo.h"#include "string-stream.h"#include "top.h"#include "zone-inl.h"namespace v8 { namespace internal {// Iterator that supports traversing the stack handlers of a// particular frame. Needs to know the top of the handler chain.class StackHandlerIterator BASE_EMBEDDED { public:  StackHandlerIterator(const StackFrame* frame, StackHandler* handler)      : limit_(frame->fp()), handler_(handler) {    // Make sure the handler has already been unwound to this frame.    ASSERT(frame->sp() <= handler->address());  }  StackHandler* handler() const { return handler_; }  bool done() { return handler_->address() > limit_; }  void Advance() {    ASSERT(!done());    handler_ = handler_->next();  } private:  const Address limit_;  StackHandler* handler_;};// -------------------------------------------------------------------------#define INITIALIZE_SINGLETON(type, field) field##_(this),StackFrameIterator::StackFrameIterator()    : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)      frame_(NULL), handler_(NULL), thread_(Top::GetCurrentThread()) {  Reset();}StackFrameIterator::StackFrameIterator(ThreadLocalTop* t)    : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)      frame_(NULL), handler_(NULL), thread_(t) {  Reset();}#undef INITIALIZE_SINGLETONvoid StackFrameIterator::Advance() {  ASSERT(!done());  // Compute the state of the calling frame before restoring  // callee-saved registers and unwinding handlers. This allows the  // frame code that computes the caller state to access the top  // handler and the value of any callee-saved register if needed.  StackFrame::State state;  StackFrame::Type type = frame_->GetCallerState(&state);  // Unwind handlers corresponding to the current frame.  StackHandlerIterator it(frame_, handler_);  while (!it.done()) it.Advance();  handler_ = it.handler();  // Advance to the calling frame.  frame_ = SingletonFor(type, &state);  // When we're done iterating over the stack frames, the handler  // chain must have been completely unwound.  ASSERT(!done() || handler_ == NULL);}void StackFrameIterator::Reset() {  Address fp = Top::c_entry_fp(thread_);  StackFrame::State state;  StackFrame::Type type = ExitFrame::GetStateForFramePointer(fp, &state);  frame_ = SingletonFor(type, &state);  handler_ = StackHandler::FromAddress(Top::handler(thread_));}StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type,                                             StackFrame::State* state) {#define FRAME_TYPE_CASE(type, field) \  case StackFrame::type: result = &field##_; break;  StackFrame* result = NULL;  switch (type) {    case StackFrame::NONE: return NULL;    STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)    default: break;  }  ASSERT(result != NULL);  result->state_ = *state;  return result;#undef FRAME_TYPE_CASE}// -------------------------------------------------------------------------JavaScriptFrameIterator::JavaScriptFrameIterator(StackFrame::Id id) {  while (true) {    Advance();    if (frame()->id() == id) return;  }}void JavaScriptFrameIterator::Advance() {  do {    iterator_.Advance();  } while (!iterator_.done() && !iterator_.frame()->is_java_script());}void JavaScriptFrameIterator::AdvanceToArgumentsFrame() {  if (!frame()->has_adapted_arguments()) return;  iterator_.Advance();  ASSERT(iterator_.frame()->is_arguments_adaptor());}void JavaScriptFrameIterator::Reset() {  iterator_.Reset();  Advance();}// -------------------------------------------------------------------------void StackHandler::Cook(Code* code) {  ASSERT(code->contains(pc()));  set_pc(AddressFrom<Address>(pc() - code->instruction_start()));}void StackHandler::Uncook(Code* code) {  set_pc(code->instruction_start() + OffsetFrom(pc()));  ASSERT(code->contains(pc()));}// -------------------------------------------------------------------------bool StackFrame::HasHandler() const {  StackHandlerIterator it(this, top_handler());  return !it.done();}void StackFrame::CookFramesForThread(ThreadLocalTop* thread) {  ASSERT(!thread->stack_is_cooked());  for (StackFrameIterator it(thread); !it.done(); it.Advance()) {    it.frame()->Cook();  }  thread->set_stack_is_cooked(true);}void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) {  ASSERT(thread->stack_is_cooked());  for (StackFrameIterator it(thread); !it.done(); it.Advance()) {    it.frame()->Uncook();  }  thread->set_stack_is_cooked(false);}void StackFrame::Cook() {  Code* code = FindCode();  for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {    it.handler()->Cook(code);  }  ASSERT(code->contains(pc()));  set_pc(AddressFrom<Address>(pc() - code->instruction_start()));}void StackFrame::Uncook() {  Code* code = FindCode();  for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {    it.handler()->Uncook(code);  }  set_pc(code->instruction_start() + OffsetFrom(pc()));  ASSERT(code->contains(pc()));}Code* EntryFrame::FindCode() const {  return Heap::js_entry_code();}StackFrame::Type EntryFrame::GetCallerState(State* state) const {  const int offset = EntryFrameConstants::kCallerFPOffset;  Address fp = Memory::Address_at(this->fp() + offset);  return ExitFrame::GetStateForFramePointer(fp, state);}Code* EntryConstructFrame::FindCode() const {  return Heap::js_construct_entry_code();}Code* ExitFrame::FindCode() const {  return Heap::c_entry_code();}StackFrame::Type ExitFrame::GetCallerState(State* state) const {  // Setup the caller state.  state->sp = pp();  state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);  state->pc_address      = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset);  return ComputeType(state);}Address ExitFrame::GetCallerStackPointer() const {  return fp() + ExitFrameConstants::kPPDisplacement;}Code* ExitDebugFrame::FindCode() const {  return Heap::c_entry_debug_break_code();}Address StandardFrame::GetExpressionAddress(int n) const {  const int offset = StandardFrameConstants::kExpressionsOffset;  return fp() + offset - n * kPointerSize;}int StandardFrame::ComputeExpressionsCount() const {  const int offset =      StandardFrameConstants::kExpressionsOffset + kPointerSize;  Address base = fp() + offset;  Address limit = sp();  ASSERT(base >= limit);  // stack grows downwards  // Include register-allocated locals in number of expressions.  return (base - limit) / kPointerSize;}StackFrame::Type StandardFrame::GetCallerState(State* state) const {  state->sp = caller_sp();  state->fp = caller_fp();  state->pc_address = reinterpret_cast<Address*>(ComputePCAddress(fp()));  return ComputeType(state);}bool StandardFrame::IsExpressionInsideHandler(int n) const {  Address address = GetExpressionAddress(n);  for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {    if (it.handler()->includes(address)) return true;  }

⌨️ 快捷键说明

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