Move V8 to external/v8

Change-Id: If68025d67453785a651c5dfb34fad298c16676a4
diff --git a/src/frames.h b/src/frames.h
new file mode 100644
index 0000000..768196d
--- /dev/null
+++ b/src/frames.h
@@ -0,0 +1,678 @@
+// 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.
+
+#ifndef V8_FRAMES_H_
+#define V8_FRAMES_H_
+
+namespace v8 {
+namespace internal {
+
+typedef uint32_t RegList;
+
+// Get the number of registers in a given register list.
+int NumRegs(RegList list);
+
+// Return the code of the n-th saved register available to JavaScript.
+int JSCallerSavedCode(int n);
+
+
+// Forward declarations.
+class StackFrameIterator;
+class Top;
+class ThreadLocalTop;
+
+
+class StackHandler BASE_EMBEDDED {
+ public:
+  enum State {
+    ENTRY,
+    TRY_CATCH,
+    TRY_FINALLY
+  };
+
+  // Get the address of this stack handler.
+  inline Address address() const;
+
+  // Get the next stack handler in the chain.
+  inline StackHandler* next() const;
+
+  // Tells whether the given address is inside this handler.
+  inline bool includes(Address address) const;
+
+  // Garbage collection support.
+  inline void Iterate(ObjectVisitor* v) const;
+
+  // Conversion support.
+  static inline StackHandler* FromAddress(Address address);
+
+  // Testers
+  bool is_entry() { return state() == ENTRY; }
+  bool is_try_catch() { return state() == TRY_CATCH; }
+  bool is_try_finally() { return state() == TRY_FINALLY; }
+
+  // Garbage collection support.
+  void Cook(Code* code);
+  void Uncook(Code* code);
+
+ private:
+  // Accessors.
+  inline State state() const;
+
+  inline Address pc() const;
+  inline void set_pc(Address value);
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
+};
+
+
+#define STACK_FRAME_TYPE_LIST(V)              \
+  V(ENTRY,             EntryFrame)            \
+  V(ENTRY_CONSTRUCT,   EntryConstructFrame)   \
+  V(EXIT,              ExitFrame)             \
+  V(EXIT_DEBUG,        ExitDebugFrame)        \
+  V(JAVA_SCRIPT,       JavaScriptFrame)       \
+  V(INTERNAL,          InternalFrame)         \
+  V(CONSTRUCT,         ConstructFrame)        \
+  V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
+
+
+// Abstract base class for all stack frames.
+class StackFrame BASE_EMBEDDED {
+ public:
+#define DECLARE_TYPE(type, ignore) type,
+  enum Type {
+    NONE = 0,
+    STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
+    NUMBER_OF_TYPES
+  };
+#undef DECLARE_TYPE
+
+  // Opaque data type for identifying stack frames. Used extensively
+  // by the debugger.
+  enum Id { NO_ID = 0 };
+
+  // Type testers.
+  bool is_entry() const { return type() == ENTRY; }
+  bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
+  bool is_exit() const { return type() == EXIT; }
+  bool is_exit_debug() const { return type() == EXIT_DEBUG; }
+  bool is_java_script() const { return type() == JAVA_SCRIPT; }
+  bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
+  bool is_internal() const { return type() == INTERNAL; }
+  bool is_construct() const { return type() == CONSTRUCT; }
+  virtual bool is_standard() const { return false; }
+
+  // Accessors.
+  Address sp() const { return state_.sp; }
+  Address fp() const { return state_.fp; }
+  Address caller_sp() const { return GetCallerStackPointer(); }
+
+  Address pc() const { return *pc_address(); }
+  void set_pc(Address pc) { *pc_address() = pc; }
+
+  Address* pc_address() const { return state_.pc_address; }
+
+  // Get the id of this stack frame.
+  Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
+
+  // Checks if this frame includes any stack handlers.
+  bool HasHandler() const;
+
+  // Get the type of this frame.
+  virtual Type type() const = 0;
+
+  // Get the code associated with this frame.
+  virtual Code* code() const = 0;
+
+  // Garbage collection support.
+  static void CookFramesForThread(ThreadLocalTop* thread);
+  static void UncookFramesForThread(ThreadLocalTop* thread);
+
+  virtual void Iterate(ObjectVisitor* v) const { }
+
+  // Printing support.
+  enum PrintMode { OVERVIEW, DETAILS };
+  virtual void Print(StringStream* accumulator,
+                     PrintMode mode,
+                     int index) const { }
+
+ protected:
+  struct State {
+    Address sp;
+    Address fp;
+    Address* pc_address;
+  };
+
+  explicit StackFrame(StackFrameIterator* iterator) : iterator_(iterator) { }
+  virtual ~StackFrame() { }
+
+  // Compute the stack pointer for the calling frame.
+  virtual Address GetCallerStackPointer() const = 0;
+
+  // Printing support.
+  static void PrintIndex(StringStream* accumulator,
+                         PrintMode mode,
+                         int index);
+
+  // Get the top handler from the current stack iterator.
+  inline StackHandler* top_handler() const;
+
+  // Compute the stack frame type for the given state.
+  static Type ComputeType(State* state);
+
+ private:
+  const StackFrameIterator* iterator_;
+  State state_;
+
+  // Fill in the state of the calling frame.
+  virtual void ComputeCallerState(State* state) const = 0;
+
+  // Get the type and the state of the calling frame.
+  virtual Type GetCallerState(State* state) const;
+
+  // Cooking/uncooking support.
+  void Cook();
+  void Uncook();
+
+  friend class StackFrameIterator;
+  friend class StackHandlerIterator;
+  friend class SafeStackFrameIterator;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrame);
+};
+
+
+// Entry frames are used to enter JavaScript execution from C.
+class EntryFrame: public StackFrame {
+ public:
+  virtual Type type() const { return ENTRY; }
+
+  virtual Code* code() const;
+
+  // Garbage collection support.
+  virtual void Iterate(ObjectVisitor* v) const;
+
+  static EntryFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_entry());
+    return static_cast<EntryFrame*>(frame);
+  }
+
+ protected:
+  explicit EntryFrame(StackFrameIterator* iterator) : StackFrame(iterator) { }
+
+  // The caller stack pointer for entry frames is always zero. The
+  // real information about the caller frame is available through the
+  // link to the top exit frame.
+  virtual Address GetCallerStackPointer() const { return 0; }
+
+ private:
+  virtual void ComputeCallerState(State* state) const;
+  virtual Type GetCallerState(State* state) const;
+
+  friend class StackFrameIterator;
+};
+
+
+class EntryConstructFrame: public EntryFrame {
+ public:
+  virtual Type type() const { return ENTRY_CONSTRUCT; }
+
+  virtual Code* code() const;
+
+  static EntryConstructFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_entry_construct());
+    return static_cast<EntryConstructFrame*>(frame);
+  }
+
+ protected:
+  explicit EntryConstructFrame(StackFrameIterator* iterator)
+      : EntryFrame(iterator) { }
+
+ private:
+  friend class StackFrameIterator;
+};
+
+
+// Exit frames are used to exit JavaScript execution and go to C.
+class ExitFrame: public StackFrame {
+ public:
+  virtual Type type() const { return EXIT; }
+
+  virtual Code* code() const;
+
+  // Garbage collection support.
+  virtual void Iterate(ObjectVisitor* v) const;
+
+  static ExitFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_exit());
+    return static_cast<ExitFrame*>(frame);
+  }
+
+  // Compute the state and type of an exit frame given a frame
+  // pointer. Used when constructing the first stack frame seen by an
+  // iterator and the frames following entry frames.
+  static Type GetStateForFramePointer(Address fp, State* state);
+
+ protected:
+  explicit ExitFrame(StackFrameIterator* iterator) : StackFrame(iterator) { }
+
+  virtual Address GetCallerStackPointer() const;
+
+ private:
+  virtual void ComputeCallerState(State* state) const;
+
+  friend class StackFrameIterator;
+};
+
+
+class ExitDebugFrame: public ExitFrame {
+ public:
+  virtual Type type() const { return EXIT_DEBUG; }
+
+  virtual Code* code() const;
+
+  static ExitDebugFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_exit_debug());
+    return static_cast<ExitDebugFrame*>(frame);
+  }
+
+ protected:
+  explicit ExitDebugFrame(StackFrameIterator* iterator)
+      : ExitFrame(iterator) { }
+
+ private:
+  friend class StackFrameIterator;
+};
+
+
+class StandardFrame: public StackFrame {
+ public:
+  // Testers.
+  virtual bool is_standard() const { return true; }
+
+  // Accessors.
+  inline Object* context() const;
+
+  // Access the expressions in the stack frame including locals.
+  inline Object* GetExpression(int index) const;
+  inline void SetExpression(int index, Object* value);
+  int ComputeExpressionsCount() const;
+
+  static StandardFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_standard());
+    return static_cast<StandardFrame*>(frame);
+  }
+
+ protected:
+  explicit StandardFrame(StackFrameIterator* iterator)
+      : StackFrame(iterator) { }
+
+  virtual void ComputeCallerState(State* state) const;
+
+  // Accessors.
+  inline Address caller_fp() const;
+  inline Address caller_pc() const;
+
+  // Computes the address of the PC field in the standard frame given
+  // by the provided frame pointer.
+  static inline Address ComputePCAddress(Address fp);
+
+  // Iterate over expression stack including stack handlers, locals,
+  // and parts of the fixed part including context and code fields.
+  void IterateExpressions(ObjectVisitor* v) const;
+
+  // Returns the address of the n'th expression stack element.
+  Address GetExpressionAddress(int n) const;
+
+  // Determines if the n'th expression stack element is in a stack
+  // handler or not. Requires traversing all handlers in this frame.
+  bool IsExpressionInsideHandler(int n) const;
+
+  // Determines if the standard frame for the given frame pointer is
+  // an arguments adaptor frame.
+  static inline bool IsArgumentsAdaptorFrame(Address fp);
+
+  // Determines if the standard frame for the given frame pointer is a
+  // construct frame.
+  static inline bool IsConstructFrame(Address fp);
+
+ private:
+  friend class StackFrame;
+};
+
+
+class JavaScriptFrame: public StandardFrame {
+ public:
+  virtual Type type() const { return JAVA_SCRIPT; }
+
+  // Accessors.
+  inline Object* function() const;
+  inline Object* receiver() const;
+  inline void set_receiver(Object* value);
+
+  // Access the parameters.
+  Object* GetParameter(int index) const;
+  int ComputeParametersCount() const;
+
+  // Temporary way of getting access to the number of parameters
+  // passed on the stack by the caller. Once argument adaptor frames
+  // has been introduced on ARM, this number will always match the
+  // computed parameters count.
+  int GetProvidedParametersCount() const;
+
+  // Check if this frame is a constructor frame invoked through 'new'.
+  bool IsConstructor() const;
+
+  // Check if this frame has "adapted" arguments in the sense that the
+  // actual passed arguments are available in an arguments adaptor
+  // frame below it on the stack.
+  inline bool has_adapted_arguments() const;
+
+  // Garbage collection support.
+  virtual void Iterate(ObjectVisitor* v) const;
+
+  // Printing support.
+  virtual void Print(StringStream* accumulator,
+                     PrintMode mode,
+                     int index) const;
+
+  // Determine the code for the frame.
+  virtual Code* code() const;
+
+  static JavaScriptFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_java_script());
+    return static_cast<JavaScriptFrame*>(frame);
+  }
+
+ protected:
+  explicit JavaScriptFrame(StackFrameIterator* iterator)
+      : StandardFrame(iterator), disable_heap_access_(false) { }
+
+  virtual Address GetCallerStackPointer() const;
+
+  // When this mode is enabled it is not allowed to access heap objects.
+  // This is a special mode used when gathering stack samples in profiler.
+  // A shortcoming is that caller's SP value will be calculated incorrectly
+  // (see GetCallerStackPointer implementation), but it is not used for stack
+  // sampling.
+  void DisableHeapAccess() { disable_heap_access_ = true; }
+
+ private:
+  bool disable_heap_access_;
+  inline Object* function_slot_object() const;
+
+  friend class StackFrameIterator;
+};
+
+
+// Arguments adaptor frames are automatically inserted below
+// JavaScript frames when the actual number of parameters does not
+// match the formal number of parameters.
+class ArgumentsAdaptorFrame: public JavaScriptFrame {
+ public:
+  virtual Type type() const { return ARGUMENTS_ADAPTOR; }
+
+  // Determine the code for the frame.
+  virtual Code* code() const;
+
+  static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_arguments_adaptor());
+    return static_cast<ArgumentsAdaptorFrame*>(frame);
+  }
+
+  // Printing support.
+  virtual void Print(StringStream* accumulator,
+                     PrintMode mode,
+                     int index) const;
+ protected:
+  explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator)
+      : JavaScriptFrame(iterator) { }
+
+  virtual Address GetCallerStackPointer() const;
+
+ private:
+  friend class StackFrameIterator;
+};
+
+
+class InternalFrame: public StandardFrame {
+ public:
+  virtual Type type() const { return INTERNAL; }
+
+  // Garbage collection support.
+  virtual void Iterate(ObjectVisitor* v) const;
+
+  // Determine the code for the frame.
+  virtual Code* code() const;
+
+  static InternalFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_internal());
+    return static_cast<InternalFrame*>(frame);
+  }
+
+ protected:
+  explicit InternalFrame(StackFrameIterator* iterator)
+      : StandardFrame(iterator) { }
+
+  virtual Address GetCallerStackPointer() const;
+
+ private:
+  friend class StackFrameIterator;
+};
+
+
+// Construct frames are special trampoline frames introduced to handle
+// function invocations through 'new'.
+class ConstructFrame: public InternalFrame {
+ public:
+  virtual Type type() const { return CONSTRUCT; }
+
+  static ConstructFrame* cast(StackFrame* frame) {
+    ASSERT(frame->is_construct());
+    return static_cast<ConstructFrame*>(frame);
+  }
+
+ protected:
+  explicit ConstructFrame(StackFrameIterator* iterator)
+      : InternalFrame(iterator) { }
+
+ private:
+  friend class StackFrameIterator;
+};
+
+
+class StackFrameIterator BASE_EMBEDDED {
+ public:
+  // An iterator that iterates over the current thread's stack.
+  StackFrameIterator();
+
+  // An iterator that iterates over a given thread's stack.
+  explicit StackFrameIterator(ThreadLocalTop* thread);
+
+  // An iterator that can start from a given FP address.
+  // If use_top, then work as usual, if fp isn't NULL, use it,
+  // otherwise, do nothing.
+  StackFrameIterator(bool use_top, Address fp, Address sp);
+
+  StackFrame* frame() const {
+    ASSERT(!done());
+    return frame_;
+  }
+
+  bool done() const { return frame_ == NULL; }
+  void Advance() { (this->*advance_)(); }
+
+  // Go back to the first frame.
+  void Reset();
+
+ private:
+#define DECLARE_SINGLETON(ignore, type) type type##_;
+  STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
+#undef DECLARE_SINGLETON
+  StackFrame* frame_;
+  StackHandler* handler_;
+  ThreadLocalTop* thread_;
+  Address fp_;
+  Address sp_;
+  void (StackFrameIterator::*advance_)();
+
+  StackHandler* handler() const {
+    ASSERT(!done());
+    return handler_;
+  }
+
+  // Get the type-specific frame singleton in a given state.
+  StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
+  // A helper function, can return a NULL pointer.
+  StackFrame* SingletonFor(StackFrame::Type type);
+
+  void AdvanceWithHandler();
+  void AdvanceWithoutHandler();
+
+  friend class StackFrame;
+  friend class SafeStackFrameIterator;
+  DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
+};
+
+
+// Iterator that supports iterating through all JavaScript frames.
+template<typename Iterator>
+class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
+ public:
+  JavaScriptFrameIteratorTemp() { if (!done()) Advance(); }
+
+  explicit JavaScriptFrameIteratorTemp(ThreadLocalTop* thread) :
+      iterator_(thread) {
+    if (!done()) Advance();
+  }
+
+  // Skip frames until the frame with the given id is reached.
+  explicit JavaScriptFrameIteratorTemp(StackFrame::Id id);
+
+  JavaScriptFrameIteratorTemp(Address fp, Address sp,
+                              Address low_bound, Address high_bound) :
+      iterator_(fp, sp, low_bound, high_bound) {
+    if (!done()) Advance();
+  }
+
+  inline JavaScriptFrame* frame() const;
+
+  bool done() const { return iterator_.done(); }
+  void Advance();
+
+  // Advance to the frame holding the arguments for the current
+  // frame. This only affects the current frame if it has adapted
+  // arguments.
+  void AdvanceToArgumentsFrame();
+
+  // Go back to the first frame.
+  void Reset();
+
+ private:
+  Iterator iterator_;
+};
+
+
+typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator;
+
+
+// NOTE: The stack trace frame iterator is an iterator that only
+// traverse proper JavaScript frames; that is JavaScript frames that
+// have proper JavaScript functions. This excludes the problematic
+// functions in runtime.js.
+class StackTraceFrameIterator: public JavaScriptFrameIterator {
+ public:
+  StackTraceFrameIterator();
+  void Advance();
+};
+
+
+class SafeStackFrameIterator BASE_EMBEDDED {
+ public:
+  SafeStackFrameIterator(Address fp, Address sp,
+                         Address low_bound, Address high_bound);
+
+  StackFrame* frame() const {
+    ASSERT(is_working_iterator_);
+    return iterator_.frame();
+  }
+
+  bool done() const { return iteration_done_ ? true : iterator_.done(); }
+
+  void Advance();
+  void Reset();
+
+ private:
+  static bool IsWithinBounds(
+      Address low_bound, Address high_bound, Address addr) {
+    return low_bound <= addr && addr <= high_bound;
+  }
+  bool IsValidStackAddress(Address addr) const {
+    return IsWithinBounds(low_bound_, high_bound_, addr);
+  }
+  bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
+  bool IsValidFrame(StackFrame* frame) const;
+  bool IsValidCaller(StackFrame* frame);
+
+  Address low_bound_;
+  Address high_bound_;
+  const bool is_valid_top_;
+  const bool is_valid_fp_;
+  const bool is_working_iterator_;
+  bool iteration_done_;
+  StackFrameIterator iterator_;
+};
+
+
+#ifdef ENABLE_LOGGING_AND_PROFILING
+typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
+    SafeJavaScriptFrameIterator;
+
+
+class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator {
+ public:
+  explicit SafeStackTraceFrameIterator(Address fp, Address sp,
+                                       Address low_bound, Address high_bound);
+  void Advance();
+};
+#endif
+
+
+class StackFrameLocator BASE_EMBEDDED {
+ public:
+  // Find the nth JavaScript frame on the stack. The caller must
+  // guarantee that such a frame exists.
+  JavaScriptFrame* FindJavaScriptFrame(int n);
+
+ private:
+  StackFrameIterator iterator_;
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_FRAMES_H_